diff --git a/README.md b/README.md index 0a53906..b0e3717 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,36 @@ Repository for Kevinmonitor and co.'s Touhou Station Jam 3 game. -How to install & play available attacks: +All attacks are now available as of 22/8/2022. + ++ Remilia Nonspell 1 ++ Remilia Nonspell 2 ++ Remilia Nonspell 3 ++ Remilia Spell 1 (Remilia Card) ++ Remilia Spell 2 (Patchouli Card) ++ Remilia Spell 3 (Sakuya Card) + +"Boss Mode" is also done - players can now play the entire 6-attack boss fight at once. + +How to install: + Install all files in this repo. + Open either th_dnh_ph3sx.exe or th_dnh_ph3sx_legacy.exe (if you cannot open the latter) -+ Select "Single" in the Menu. + +To play attacks individually: + ++ Select "Single" in the title screen. + Remilia's attacks have all been titled properly. Other scripts in the list are placeholders or engine samples. -+ Select "Chimata" as the player. Other scripts in the list are placeholders or engine samples. ++ The fourth spell (Meiling) is unfinished and will not be in the jam version. Please ignore it for now. ++ Select "Chimata" as the player. + +To play all attacks in a row (boss mode): + ++ Select "Plural" in the title screen. ++ Select "Boss Plural" in the drop-down menu. ++ Select "Chimata" as the player. + +Currently, Boss Mode can only be played in Normal difficulty. How to change the difficulty of the attacks: @@ -19,10 +42,9 @@ How to change the difficulty of the attacks: + Find the "difficultySelect = 0; // debug" line. + Change 0 to the difficulty you want to play: -0: Normal -1: Hyper/Hard -2: Unparalleled/Lunatic - -NOTE THAT LUNATIC IS STILL NOT BALANCED OR PROPERLY TESTED, AND WILL NOT BE IN THE INITIAL JAM VERSION. + + 0: Normal + + 1: Hyper/Hard + + 2: Unparalleled/Lunatic + + (NOTE THAT LUNATIC IS STILL NOT BALANCED OR PROPERLY TESTED, AND WILL NOT BE IN THE INITIAL JAM VERSION.) + Save the file and re-open the attack. \ No newline at end of file diff --git a/gamedescandmanual.txt b/gamedescandmanual.txt new file mode 100644 index 0000000..04e15f3 --- /dev/null +++ b/gamedescandmanual.txt @@ -0,0 +1,73 @@ +Game Description (on Game Page): + +ENGLISH: + +A fan-made side story to the brand new instalment of Touhou Project, “100th Black Market”, starring the heroic Chimata Tenkyuu. + +A black market at the Scarlet Devil Mansion has opened up! Play as the market god and face the mischievous vampire using the cards for wicked purposes! + +Read the in-game manual for more information! + +Credits: + +Game Programmer & Designer +Character & Background Artwork +Spritework +Kevin Minh (@kevinminh_alt) + +Spritework & Card Artwork +Japanese Translation +Aqwa (@aqwwa58) + +Composer (Boss Theme) +Yal (@GameDevYal) + +JAPANESE: + +[INSERT JP TRANSLATION HERE] + +—— + +Game Manual (preferably in-game, but may probably be transferred into a separate text file if I run out of time) + +ENGLISH: + +1. Gameplay + +This is an exciting shooting game like a Touhou game. +Play as Chimata Tenkyuu and use your clever dodging and shooting to defeat Remilia Scarlet’s relentless attacks! +(Also, try obtaining a high score!) + +2. Controls: + +Z (Hold): Shoot/Confirm +X: Use Spell Card (limited use)/Cancel +Esc: Pause Game +Esc+R: Quick Retry +Esc+Q: Quick Exit to Title + +See config.exe to rebind keys. + +3. Gameplay Guide: Player + +This time around, taking inspiration from her own spellcard “Danmaku Asylum”, Chimata has packed a lot (a lot) of knives on her adventure. + +Her unfocused shot is a wide spread of knives that covers the entire screen. It deals a lot of damage if you hit an enemy with all the knives! +Her focused shot has knives that are weaker, but they will automatically aim at the enemy. +Her bomb is a simple “Lunar Shield” that clears bullets and deals damage. It follows her while active. + +4. Gameplay Guide: Boss + + Remilia has three nonspells and three spells this time around. + Her attacks are based on her and others’ Ability Cards, so she’ll be using some very familiar patterns. + But that can’t stop you, right? + +5. Gameplay Tips + ++ Bosses drop rainbow point items after every attack if you defeat them without losing a life. If you lose a life, they’ll just drop normal blue point items which are worth fewer points. Try your best to survive and score high! ++ Pink petals, which are dropped by the boss, add 0.2x to your score multiplier. ++ The closer you are to the boss, the faster petals will drop. Therefore, playing risky can help you earn more points! ++ Don’t forget to use your bombs often! You get three every life. ++ You can set the number of starting lives, player shot opacity, item opacity and background opacity in the Options menu. + +JAPANESE: \ No newline at end of file diff --git a/script/KevinSystem/KevinShot/KevinShot_Alt_HD.png b/script/KevinSystem/KevinShot/KevinShot_Alt_HD.png index f9284dc..446509f 100644 Binary files a/script/KevinSystem/KevinShot/KevinShot_Alt_HD.png and b/script/KevinSystem/KevinShot/KevinShot_Alt_HD.png differ diff --git a/script/KevinSystem/Kevin_System.txt b/script/KevinSystem/Kevin_System.txt index 791442f..bfbe9f3 100644 --- a/script/KevinSystem/Kevin_System.txt +++ b/script/KevinSystem/Kevin_System.txt @@ -622,18 +622,18 @@ task TBossLife ascent(iDiv in 1 .. length(listLifeDiv)-1) { let rate = listLifeDiv[iDiv]; - let x = (GetStgFrameWidth()) * (1-rate); - ObjSpriteList2D_SetDestRect(objDivision, x-3, 65, x+24, 115); + let x = (GetStgFrameWidth()) * 0.98 * (1-rate); + ObjSpriteList2D_SetDestRect(objDivision, x-4, 62, x+24, 118); ObjSpriteList2D_AddVertex(objDivision); } //Boss star rendering - ObjRender_SetScaleXYZ(objStar, 0.5, 0.5, 1); + ObjRender_SetScaleXYZ(objStar, 0.6, 0.6, 1); ObjSpriteList2D_SetSourceRect(objStar, 0, 169, 268, 430); Obj_SetRenderPriority(objStar, 1); ascent(iStep in 0 .. countRemStep) { - ObjRender_SetPosition(objStar, GetStgFrameWidth()*1.36-iStep*32, 30, 1); + ObjRender_SetPosition(objStar, GetStgFrameWidth()*1.6, 35+45*iStep, 1); ObjSpriteList2D_SetDestCenter(objStar); ObjSpriteList2D_AddVertex(objStar); } diff --git a/script/game/Boss_Plural.dnh b/script/game/Boss_Plural.dnh new file mode 100644 index 0000000..6d8e359 --- /dev/null +++ b/script/game/Boss_Plural.dnh @@ -0,0 +1,70 @@ +#TouhouDanmakufu[Plural] +#ScriptVersion[3] +#Title["Boss Plural"] +#Text["..."] +#System["script/KevinSystem/Kevin_System.txt"] +//#Player["script/KevinPackage/KevinScript_Players/PankevKouda/KevKou_Main.dnh", "script/KevinPackage/KevinScript_Players/MariHousui/MariHousui_Main.dnh"] + +let csd = GetCurrentScriptDirectory(); + +let obj = ObjEnemyBossScene_Create(); + +#include "script/KevinSystem/Universal_Lib.txt" +#include "script/game/Stage_Background.dnh" + +@Event{ + +} + +@Initialize{ + + if(!IsCommonDataAreaExists("PIV")){ + CreateCommonDataArea("PIV"); + SetAreaCommonData("PIV", "currentvalue", 10000); + } + else{} + + SetAutoDeleteObject(true); + _ScrollBackground(); + PluralTask(); + +} + +@MainLoop{ + yield; +} + +@Finalize +{ +} + + +/* TO DO: + ++ Single *syncing* - ensure that the boss stays at the same position +*/ +// Task to handle the plural's boss scene + +task PluralTask(){ + // Registering individual singles + + ObjEnemyBossScene_Add(obj, 0, csd ~ "Non1.dnh"); + ObjEnemyBossScene_Add(obj, 0, csd ~ "Spell1.dnh"); + ObjEnemyBossScene_Add(obj, 0, csd ~ "Non2.dnh"); + ObjEnemyBossScene_Add(obj, 0, csd ~ "Spell2.dnh"); + ObjEnemyBossScene_Add(obj, 0, csd ~ "Non3.dnh"); + ObjEnemyBossScene_Add(obj, 0, csd ~ "Spell3.dnh"); + + // Loading and registering the boss scene + ObjEnemyBossScene_LoadInThread(obj); + ObjEnemyBossScene_Regist(obj); + + while(!Obj_IsDeleted(obj)){ + yield; + } + + _ExplosionEffect(GetCommonData("Boss Position X", STG_WIDTH/2), GetCommonData("Boss Position Y", STG_WIDTH/2), PetalEffect); + SetAutoDeleteObject(true); + wait(120); + CloseScript(GetOwnScriptID()); +} \ No newline at end of file diff --git a/script/game/Non1.dnh b/script/game/Non1.dnh index 9799779..ff394b2 100644 --- a/script/game/Non1.dnh +++ b/script/game/Non1.dnh @@ -72,26 +72,7 @@ int[] speedSpiral = [6, 8, 8]; ObjMove_SetPosition(bossObj, GetCommonData("Boss Position X", STG_WIDTH/2), GetCommonData("Boss Position Y", STG_HEIGHT/2)); ObjEnemy_SetMaximumDamage(bossObj, 999); - // PLACEHOLDER! - let imgExRumia = GetModuleDirectory() ~ "script/ExRumia/ExRumia.png"; - ObjPrim_SetTexture(bossObj, imgExRumia); - ObjSprite2D_SetSourceRect(bossObj, 64, 1, 127, 64); - ObjSprite2D_SetDestCenter(bossObj); - ObjRender_SetScaleXYZ(bossObj, 2, 2, 1); - ObjRender_SetColor(bossObj, 0xB93C3C); - ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, 550, 1); - // PLACEHOLDER! - - /*_SoloCutin( - "script/invalid.png", - 0, 0, 1, 1, - bossObj, objScene, "\"Euphoric Blooming of a New Market\"", - 40, 4, 0x2868B9, 0x1D115D, - 10, STG_HEIGHT*1/10-30, 41 - );*/ - - //WriteLog(spellPIV); - WriteLog(ObjEnemyBossScene_GetInfo(objScene, INFO_SPELL_SCORE)); + _RenderBoss(bossObj); mainTask(); _FadeInvincibility(bossObj, 150, 150, 1); @@ -121,7 +102,7 @@ int[] speedSpiral = [6, 8, 8]; bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); - ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 100); + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); yield; diff --git a/script/game/Non2.dnh b/script/game/Non2.dnh index d71b444..de8979c 100644 --- a/script/game/Non2.dnh +++ b/script/game/Non2.dnh @@ -24,59 +24,29 @@ let bossdiesnd = ObjSound_Create(); /*Parameters: -// Trail Burst ++ Laser ring density ++ Laser spin speed -- Density of red bubble spiral -- Angular velocity of bubbles -- Speed of bubbles ++ Spiral density ++ Spiral speed ++ Spiral angle offset ++ Spiral delay -- Density of each bullet curve left behind -- Delay between each bullet in curve -- Delay between each bullet curve -- Movement speed of bullet curve - -- Delay between trail and aimed burst */ -int[] denseTrailSpiral = [7, 8, 10]; -float[] wvelTrailBubble = [2.5, 3.5, 4.5]; -float[] spdTrailBubble = [13, 14, 16]; +int[] denseLaser = [7, 8, 9]; +float[] speedspinLaser = [0.35, 0.35, 0.35]; +int[] timeLaser = [60, 70, 80]; +int[] timeDelayLaser = [45, 40, 30]; -int[] denseTrailCurve = [1, 1, 1]; -int[] delayCurveIndividual = [0, 0, 0]; -int[] delayCurve = [8, 7, 6]; -float[] speedCurve = [5, 6, 7]; - -int[] delayTrailAimed = [110, 100, 90]; +int[] denseSpiral = [5, 6, 7]; +float[] angleoffsetSpiral = [1.618*8, 1.618*7, 1.618*6]; +float[] speedSpiral = [8.5, 9.5, 10.5]; +int[] delaySpiral = [5, 5, 4]; /* -// Aimed Burst - -- Density of red bubble spiral -- Angular velocity of bubbles -- Speed of bubbles - -- Delay between each bullet left behind -- Bullet acceleration -- Bullet max speed - -// Final Trail Burst - -See trail burst above but x2. -- Delay between the two trail burst */ -int[] denseAimedSpiral = [9, 10, 11]; -float[] wvelAimedBubble = [1.15, 1.35, 1.7]; -float[] spdAimedBubble = [12, 14, 16]; - -int[] delayAimed = [12, 10, 8]; -float[] accelAimed = [8/60, 9/50, 10/40]; -float[] maxspdAimed = [8, 9, 10]; - -int[] delayBeforeAim = [40, 30, 20]; -int[] delayFinalBurst = [45, 35, 30]; -int[] thresholdStopSpin = [80, 70, 60]; // Includes ahoy @@ -90,7 +60,7 @@ int[] thresholdStopSpin = [80, 70, 60]; _InitDifficulty(difficultySelect); - difficultySelect = 1; // debug + //difficultySelect = 0; // debug SetShotAutoDeleteClip(64, 64, 64, 64); @@ -107,26 +77,7 @@ int[] thresholdStopSpin = [80, 70, 60]; ObjMove_SetPosition(bossObj, GetCommonData("Boss Position X", STG_WIDTH/2), GetCommonData("Boss Position Y", STG_HEIGHT/2)); ObjEnemy_SetMaximumDamage(bossObj, 999); - // PLACEHOLDER! - let imgExRumia = GetModuleDirectory() ~ "script/ExRumia/ExRumia.png"; - ObjPrim_SetTexture(bossObj, imgExRumia); - ObjSprite2D_SetSourceRect(bossObj, 64, 1, 127, 64); - ObjSprite2D_SetDestCenter(bossObj); - ObjRender_SetScaleXYZ(bossObj, 2, 2, 1); - ObjRender_SetColor(bossObj, 0xB93C3C); - ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, 550, 1); - // PLACEHOLDER! - - /*_SoloCutin( - "script/invalid.png", - 0, 0, 1, 1, - bossObj, objScene, "\"Euphoric Blooming of a New Market\"", - 40, 4, 0x2868B9, 0x1D115D, - 10, STG_HEIGHT*1/10-30, 41 - );*/ - - //WriteLog(spellPIV); - WriteLog(ObjEnemyBossScene_GetInfo(objScene, INFO_SPELL_SCORE)); + _RenderBoss(bossObj); mainTask(); _FadeInvincibility(bossObj, 150, 150, 1); @@ -156,7 +107,7 @@ int[] thresholdStopSpin = [80, 70, 60]; bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); - ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 100); + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); yield; @@ -166,196 +117,131 @@ int[] thresholdStopSpin = [80, 70, 60]; } -/*Nonspell 1: +/*Nonspell 2 (Patchouli): -Reference to Remi final from EoSD (Red Magic/Scarlet Gensokyo). - -Fires red bubbles that leave behind trails of bullets. -See: My BHA5 script’s second nonspell +Non-directional Laser with Bubble Spiral Parameters: -// Trail Burst ++ Laser ring density ++ Laser spin speed -- Density of red bubble spiral -- Angular velocity of bubbles -- Speed of bubbles - -- Density of each bullet curve left behind -- Delay between each bullet in curve -- Delay between each bullet curve -- Movement speed of bullet curve - -- Delay between trail and aimed burst - -// Aimed Burst - -- Density of red bubble spiral -- Angular velocity of bubbles -- Speed of bubbles - -- Delay between each bullet left behind -- Bullet acceleration -- Bullet max speed - -// Final Trail Burst - -See trail burst above but x2. -- Delay between the two trail burst ++ Spiral density ++ Spiral speed ++ Spiral angle offset */ task mainTask { + ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/6+30, 45, LERP_DECELERATE); + wait(60); + int multiplier = 1; + while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ - FireTrail(rand(1.5*STG_WIDTH/8, 2.5*STG_WIDTH/8)); - FireAimed(rand(6.5*STG_WIDTH/8, 7.5*STG_WIDTH/8)); - wait(delayTrailAimed[difficultySelect]/2); - FireAimed(rand(1.5*STG_WIDTH/8, 2.5*STG_WIDTH/8)); - FireTrail(rand(6.5*STG_WIDTH/8, 7.5*STG_WIDTH/8)); - wait(delayTrailAimed[difficultySelect]*1.25); - - } - -} - -function FireTrail(destX){ - - //float destX = rand(1.5*STG_WIDTH/8, 2.5*STG_WIDTH/8); - - ObjMove_SetDestAtFrame(bossObj, destX, STG_HEIGHT/4, 30, LERP_DECELERATE); - wait(30); - - float ang = GetAngleToPlayer(bossObj); - - loop(denseTrailSpiral[difficultySelect]){ - int shot = CreateShotA2(bossX, bossY, spdTrailBubble[difficultySelect], ang, 0, spdTrailBubble[difficultySelect], wvelTrailBubble[difficultySelect], KEV_BUBBLE_RED, 5); - - ObjMove_AddPatternA2(shot, thresholdStopSpin[difficultySelect], NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, wvelTrailBubble[difficultySelect]*0.25); - - if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(shot);} - else{ - _Delay(shot, 10); - _BulletRescale(shot, 0.85, true, 1); - Shoot1; + ascent(i in 0..denseLaser[difficultySelect]){ + SpawnNDLaser(i, multiplier); } - _ShotTrail(shot, ang); - ang += 360/denseTrailSpiral[difficultySelect]; - } - wait(delayTrailAimed[difficultySelect]); - -} - -task _ShotTrail(shot, ang){ - - wait(10); - - int del = 5; - - async{ - ObjShot_SetAutoDelete(shot, false); - wait(thresholdStopSpin[difficultySelect]+30); - ObjShot_SetAutoDelete(shot, true); - } - - while(!Obj_IsDeleted(shot) && ObjMove_GetY(shot) <= STG_HEIGHT-30 && ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ - - Shoot2; - loop(denseTrailCurve[difficultySelect]){ - float x2 = ObjMove_GetX(shot); - float y2 = ObjMove_GetY(shot); - let bullet = CreateShotA1(x2, y2, 0, ObjMove_GetAngle(shot), KEV_AURABALL_RED, 15); + wait(timeDelayLaser[difficultySelect]); + + float ang = 0; + + loop(90/delaySpiral[difficultySelect]){ + float ang2 = ang; + + loop(denseSpiral[difficultySelect]){ + + int shot = CreateShotA1(bossX, bossY, speedSpiral[difficultySelect], ang2, KEV_BUBBLE_RED, 10); + + if (multiplier == -1) {ObjShot_SetGraphic(shot, KEV_BUBBLE_AQUA);} + else{} + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){Obj_Delete(shot);} + else{ + _Delay(shot, 10); + _BulletRescale(shot, 0.65, true, 1); + Shoot1; + } + + ang2 += 360/denseSpiral[difficultySelect]; - if(Obj_IsDeleted(shot)){Obj_Delete(bullet);} - - Obj_SetRenderPriorityI(bullet, Obj_GetRenderPriorityI(shot)+1); - ObjMove_AddPatternA2(bullet, 60, NO_CHANGE, NO_CHANGE, -accelAimed[difficultySelect], -speedCurve[difficultySelect], 0); - _BulletRescale(bullet, 0.7, true, 1); - _Delay(bullet, 15); - - wait(delayCurveIndividual[difficultySelect]); - - } - wait(delayCurve[difficultySelect]); - del += 5; - } - -} - -function FireAimed(destX){ - - //float destX = rand(6.5*STG_WIDTH/8, 7.5*STG_WIDTH/8); - - ObjMove_SetDestAtFrame(bossObj, destX, STG_HEIGHT/4, 30, LERP_DECELERATE); - wait(30); - - float ang = GetAngleToPlayer(bossObj); - - loop(denseAimedSpiral[difficultySelect]){ - int shot = CreateShotA2(bossX, bossY, spdAimedBubble[difficultySelect], ang, 0, spdAimedBubble[difficultySelect], -1*wvelAimedBubble[difficultySelect], KEV_BUBBLE_LAVENDER, 5); - - ObjMove_AddPatternA2(shot, thresholdStopSpin[difficultySelect], NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, wvelTrailBubble[difficultySelect]*-0.25); // Stop spinning after a while - - if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(shot);} - else{ - _Delay(shot, 10); - _BulletRescale(shot, 0.85, true, 1); - Shoot1; - } - _ShotAimed(shot, ang); - ang += 360/denseAimedSpiral[difficultySelect]; - } - - wait(delayTrailAimed[difficultySelect]); - -} - -task _ShotAimed(shot, ang){ - - wait(10); - - int del = 1; - - async{ - ObjShot_SetAutoDelete(shot, false); - wait(thresholdStopSpin[difficultySelect]+30); - ObjShot_SetAutoDelete(shot, true); - } - - while(!Obj_IsDeleted(shot) && ObjMove_GetY(shot) <= STG_HEIGHT-30 && ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ - - Shoot2; - - float x2 = ObjMove_GetX(shot); - float y2 = ObjMove_GetY(shot); - let bullet = CreateShotA1(x2, y2, 0, ObjMove_GetAngle(shot), KEV_KNIFE_LAVENDER, 15); - - if(Obj_IsDeleted(shot)){Obj_Delete(bullet);} - - Obj_SetRenderPriorityI(bullet, Obj_GetRenderPriorityI(shot)+1); - Pattern(bullet, del); - - task Pattern(bullet, del){ - float ang = ObjMove_GetAngle(bullet); - ascent(i in 0..10){ - ObjMove_AddPatternA2(bullet, delayBeforeAim[difficultySelect]-del+i, NO_CHANGE, Interpolate_Decelerate(ang, GetAngleToPlayer(bullet), i/10), accelAimed[difficultySelect], maxspdAimed[difficultySelect], 0); - yield; } - } - _BulletRescale(bullet, 1.25, true, 1); - _Delay(bullet, 15); - - wait(delayAimed[difficultySelect]); - del += 1; + ang += angleoffsetSpiral[difficultySelect]*-multiplier; + wait(delaySpiral[difficultySelect]); + } + + multiplier *= -1; + + yield; + } - - ObjMove_AddPatternA2(shot, 80, NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, 0); // Stop spinning after a while - + } + +task SpawnNDLaser(int ID, int multiplier){ + + float objcount = 0; + + int obj = CreateStraightLaserA1(bossX + -45*cos(ID*360/denseLaser[difficultySelect]), bossY + -45*sin(ID*360/denseLaser[difficultySelect]), ID * 360/denseLaser[difficultySelect], STG_HEIGHT*1.5, 100, timeLaser[difficultySelect], KEV_AMULET_RED, timeDelayLaser[difficultySelect]); + + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(obj);} + + int shot = CreateShotA1(bossX + 120*cos(ID*360/denseLaser[difficultySelect]), bossY + 120*sin(ID*360/denseLaser[difficultySelect]), 0, ID * 360/denseLaser[difficultySelect], KEV_AURABALL_RED, 10); + + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(shot);} + + else{ + _Delay(shot, 10); + _BulletRescale(shot, 2, true, 1); + Shoot1; + } + + if(multiplier == -1){ + ObjShot_SetGraphic(obj, KEV_AMULET_AQUA); + ObjShot_SetGraphic(shot, KEV_AURABALL_AQUA); + } + + ObjShot_SetAutoDelete(obj, false); + ObjShot_SetAutoDelete(shot, false); + ObjRender_SetBlendType(obj, BLEND_ADD_ARGB); + ObjRender_SetBlendType(shot, BLEND_ADD_ARGB); + ObjLaser_SetInvalidLength(obj, 0.25, 0.25); + ObjStLaser_SetSource(obj, true); + ObjStLaser_SetEnd(obj, true); + ObjStLaser_SetEndGraphic(obj, ObjShot_GetImageID(obj)-33); + + async{ + wait(timeDelayLaser[difficultySelect]); + Shoot2; + } + + while(!Obj_IsDeleted(obj)){ + ObjMove_SetPosition(obj, bossX + -45*cos(ID*360/denseLaser[difficultySelect] + objcount), bossY + -45 * sin(ID*360/denseLaser[difficultySelect] + objcount)); + ObjMove_SetPosition(shot, bossX + 120*cos(ID*360/denseLaser[difficultySelect] + objcount), bossY + 120*sin(ID*360/denseLaser[difficultySelect] + objcount)); + ObjStLaser_SetAngle(obj, ID*360/denseLaser[difficultySelect] + objcount); + objcount += speedspinLaser[difficultySelect]*multiplier; + yield; + } + + ObjShot_FadeDelete(shot); + +} + +/*task SpawnNDLaser(ID, multiplier){ + let objcount = 0; + let obj = CreateStraightLaserA1(ObjMove_GetX(bossObj) + 60*cos(ID*360/denseLaser[difficultySelect]), ObjMove_GetY(bossObj) + 60*sin(ID*360/denseLaser[difficultySelect]), ID * 360/denseLaser[difficultySelect], 512, 24, 300, KEV_AMULET_RED, 60); + while(!Obj_IsDeleted(obj)){ + ObjMove_SetPosition(obj, ObjMove_GetX(bossObj) + 60*cos(ID*360/denseLaser[difficultySelect] + objcount), ObjMove_GetY(bossObj) + 60*sin(ID*360/denseLaser[difficultySelect] + objcount)); + ObjStLaser_SetAngle(obj, ID*360/denseLaser[difficultySelect] + objcount); + //objcount += 1 * multiplier; + objcount += 0.5; + yield; + } +}*/ + task endingnew(){ while(ObjEnemy_GetInfo(bossObj, INFO_LIFE)>0){ diff --git a/script/game/Non3.dnh b/script/game/Non3.dnh new file mode 100644 index 0000000..e6f0b59 --- /dev/null +++ b/script/game/Non3.dnh @@ -0,0 +1,354 @@ +#TouhouDanmakufu[Single] +#ScriptVersion[3] +#Title["Remilia Nonspell 3"] +#Text["yassification"] +#System["script/KevinSystem/Kevin_System.txt"] + +int difficultySelect = 0; + +let objScene = GetEnemyBossSceneObjectID(); +let csd = GetCurrentScriptDirectory(); + +let bossObj; + +float bossX = 0; +float bossY = 0; +float playerY = 0; +float playerX = 0; + +let aniframe = 0; +let aniframe2 = 0; + +let spellsnd = ObjSound_Create(); +let bossdiesnd = ObjSound_Create(); + +/*Parameters: + +// Trail Burst + +- Density of red bubble spiral +- Angular velocity of bubbles +- Speed of bubbles + +- Density of each bullet curve left behind +- Delay between each bullet in curve +- Delay between each bullet curve +- Movement speed of bullet curve + +- Delay between trail and aimed burst +*/ + +int[] denseTrailSpiral = [7, 8, 10]; +float[] wvelTrailBubble = [2.5, 3.5, 4.5]; +float[] spdTrailBubble = [13, 14, 16]; + +int[] denseTrailCurve = [1, 1, 1]; +int[] delayCurveIndividual = [0, 0, 0]; +int[] delayCurve = [8, 7, 6]; +float[] speedCurve = [5, 6, 7]; + +int[] delayTrailAimed = [110, 100, 90]; + +/* +// Aimed Burst + +- Density of red bubble spiral +- Angular velocity of bubbles +- Speed of bubbles + +- Delay between each bullet left behind +- Bullet acceleration +- Bullet max speed + +// Final Trail Burst + +See trail burst above but x2. +- Delay between the two trail burst +*/ + +int[] denseAimedSpiral = [9, 10, 11]; +float[] wvelAimedBubble = [1.15, 1.35, 1.7]; +float[] spdAimedBubble = [12, 14, 16]; + +int[] delayAimed = [12, 10, 8]; +float[] accelAimed = [8/60, 9/50, 10/40]; +float[] maxspdAimed = [8, 9, 10]; + +int[] delayBeforeAim = [40, 30, 20]; +int[] delayFinalBurst = [45, 35, 30]; +int[] thresholdStopSpin = [80, 70, 60]; + +// Includes ahoy + +#include "script/KevinSystem/Universal_Lib.txt" // The library to include all libraries :sans: :nail_care: + +@Initialize { + + //SetIntersectionVisualization(true); + + SetAutoDeleteObject(true); + + _InitDifficulty(difficultySelect); + + difficultySelect = 1; // debug + + SetShotAutoDeleteClip(64, 64, 64, 64); + + if(!IsCommonDataAreaExists("PIV")){ + CreateCommonDataArea("PIV"); + SetAreaCommonData("PIV", "currentvalue", 10000); + } + else{} + + // Create the boss object itself + bossObj = ObjEnemy_Create(OBJ_ENEMY_BOSS); + ObjEnemy_Regist(bossObj); + + ObjMove_SetPosition(bossObj, GetCommonData("Boss Position X", STG_WIDTH/2), GetCommonData("Boss Position Y", STG_HEIGHT/2)); + ObjEnemy_SetMaximumDamage(bossObj, 999); + + _RenderBoss(bossObj); + + mainTask(); + _FadeInvincibility(bossObj, 150, 150, 1); + endingnew(); +} + +@Event { + + alternative(GetEventType()) + + case(EV_REQUEST_LIFE) { + SetScriptResult(3000); + } + + case(EV_REQUEST_TIMER) { + SetScriptResult(25); + } + +} + +@MainLoop { + + playerY = GetPlayerY(); + playerX = GetPlayerX(); + //The player position is ALWAYS UPDATED + + bossX = ObjMove_GetX(bossObj); + bossY = ObjMove_GetY(bossObj); + + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); + + yield; + +} + +@Finalize { + +} + +/*Nonspell 1: + +Reference to Remi final from EoSD (Red Magic/Scarlet Gensokyo). + +Fires red bubbles that leave behind trails of bullets. +See: My BHA5 script’s second nonspell + +Parameters: + +// Trail Burst + +- Density of red bubble spiral +- Angular velocity of bubbles +- Speed of bubbles + +- Density of each bullet curve left behind +- Delay between each bullet in curve +- Delay between each bullet curve +- Movement speed of bullet curve + +- Delay between trail and aimed burst + +// Aimed Burst + +- Density of red bubble spiral +- Angular velocity of bubbles +- Speed of bubbles + +- Delay between each bullet left behind +- Bullet acceleration +- Bullet max speed + +// Final Trail Burst + +See trail burst above but x2. +- Delay between the two trail burst + +*/ + +task mainTask { + + while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ + + FireTrail(rand(1.5*STG_WIDTH/8, 2.5*STG_WIDTH/8)); + FireAimed(rand(6.5*STG_WIDTH/8, 7.5*STG_WIDTH/8)); + wait(delayTrailAimed[difficultySelect]/2); + FireAimed(rand(1.5*STG_WIDTH/8, 2.5*STG_WIDTH/8)); + FireTrail(rand(6.5*STG_WIDTH/8, 7.5*STG_WIDTH/8)); + wait(delayTrailAimed[difficultySelect]*1.25); + + } + +} + +function FireTrail(destX){ + + //float destX = rand(1.5*STG_WIDTH/8, 2.5*STG_WIDTH/8); + + ObjMove_SetDestAtFrame(bossObj, destX, STG_HEIGHT/4, 30, LERP_DECELERATE); + wait(30); + + float ang = GetAngleToPlayer(bossObj); + + loop(denseTrailSpiral[difficultySelect]){ + int shot = CreateShotA2(bossX, bossY, spdTrailBubble[difficultySelect], ang, 0, spdTrailBubble[difficultySelect], wvelTrailBubble[difficultySelect], KEV_BUBBLE_RED, 5); + + ObjMove_AddPatternA2(shot, thresholdStopSpin[difficultySelect], NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, wvelTrailBubble[difficultySelect]*0.25); + + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(shot);} + else{ + _Delay(shot, 10); + _BulletRescale(shot, 0.85, true, 1); + Shoot1; + } + _ShotTrail(shot, ang); + ang += 360/denseTrailSpiral[difficultySelect]; + } + + wait(delayTrailAimed[difficultySelect]); + +} + +task _ShotTrail(shot, ang){ + + wait(10); + + int del = 5; + + async{ + ObjShot_SetAutoDelete(shot, false); + wait(thresholdStopSpin[difficultySelect]+30); + ObjShot_SetAutoDelete(shot, true); + } + + while(!Obj_IsDeleted(shot) && ObjMove_GetY(shot) <= STG_HEIGHT-30 && ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ + + Shoot2; + loop(denseTrailCurve[difficultySelect]){ + float x2 = ObjMove_GetX(shot); + float y2 = ObjMove_GetY(shot); + let bullet = CreateShotA1(x2, y2, 0, ObjMove_GetAngle(shot), KEV_AURABALL_RED, 15); + + if(Obj_IsDeleted(shot)){Obj_Delete(bullet);} + + Obj_SetRenderPriorityI(bullet, Obj_GetRenderPriorityI(shot)+1); + ObjMove_AddPatternA2(bullet, 60, NO_CHANGE, NO_CHANGE, -accelAimed[difficultySelect], -speedCurve[difficultySelect], 0); + _BulletRescale(bullet, 0.6, true, 1); + _Delay(bullet, 15); + + wait(delayCurveIndividual[difficultySelect]); + + } + wait(delayCurve[difficultySelect]); + del += 5; + } + +} + +function FireAimed(destX){ + + //float destX = rand(6.5*STG_WIDTH/8, 7.5*STG_WIDTH/8); + + ObjMove_SetDestAtFrame(bossObj, destX, STG_HEIGHT/4, 30, LERP_DECELERATE); + wait(30); + + float ang = GetAngleToPlayer(bossObj); + + loop(denseAimedSpiral[difficultySelect]){ + int shot = CreateShotA2(bossX, bossY, spdAimedBubble[difficultySelect], ang, 0, spdAimedBubble[difficultySelect], -1*wvelAimedBubble[difficultySelect], KEV_BUBBLE_LAVENDER, 5); + + ObjMove_AddPatternA2(shot, thresholdStopSpin[difficultySelect], NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, wvelTrailBubble[difficultySelect]*-0.25); // Stop spinning after a while + + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(shot);} + else{ + _Delay(shot, 10); + _BulletRescale(shot, 0.85, true, 1); + Shoot1; + } + _ShotAimed(shot, ang); + ang += 360/denseAimedSpiral[difficultySelect]; + } + + wait(delayTrailAimed[difficultySelect]); + +} + +task _ShotAimed(shot, ang){ + + wait(10); + + int del = 1; + + async{ + ObjShot_SetAutoDelete(shot, false); + wait(thresholdStopSpin[difficultySelect]+30); + ObjShot_SetAutoDelete(shot, true); + } + + while(!Obj_IsDeleted(shot) && ObjMove_GetY(shot) <= STG_HEIGHT-30 && ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ + + Shoot2; + + float x2 = ObjMove_GetX(shot); + float y2 = ObjMove_GetY(shot); + let bullet = CreateShotA1(x2, y2, 0, ObjMove_GetAngle(shot), KEV_KNIFE_LAVENDER, 15); + + if(Obj_IsDeleted(shot)){Obj_Delete(bullet);} + + Obj_SetRenderPriorityI(bullet, Obj_GetRenderPriorityI(shot)+1); + Pattern(bullet, del); + + task Pattern(bullet, del){ + float ang = ObjMove_GetAngle(bullet); + ascent(i in 0..10){ + ObjMove_AddPatternA2(bullet, delayBeforeAim[difficultySelect]-del+i, NO_CHANGE, Interpolate_Decelerate(ang, GetAngleToPlayer(bullet), i/10), accelAimed[difficultySelect], maxspdAimed[difficultySelect], 0); + yield; + } + } + + _BulletRescale(bullet, 1.25, true, 1); + _Delay(bullet, 15); + + wait(delayAimed[difficultySelect]); + del += 1; + } + + ObjMove_AddPatternA2(shot, 80, NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, 0); // Stop spinning after a while + +} + +task endingnew(){ + + while(ObjEnemy_GetInfo(bossObj, INFO_LIFE)>0){ + yield; + } + + _GoToBrazil(objScene, bossObj, 12, 24); + wait(120); + ObjSound_SetVolumeRate(fire2, 20); + + CloseScript(GetOwnScriptID); + +} + + diff --git a/script/game/Spell1.dnh b/script/game/Spell1.dnh index 8759960..06f2e01 100644 --- a/script/game/Spell1.dnh +++ b/script/game/Spell1.dnh @@ -36,13 +36,14 @@ Parameters: */ -int denseSpiral = [12, 15, 18]; -int angleoffsetSpiral = [3, 4, 6]; +int[] denseSpiral = [6, 7, 8]; +float[] angleoffsetSpiral = [1.618*7, 1.618*6, 1.618*5]; +float[] speedSpiral = [8, 9.25, 11]; int[] denseRing = [10, 12, 14]; -float[] maxspeedRing = [8, 9, 11]; -int[] deceltimeRing = [20, 30, 40]; -int[] acceltimeRing = [60, 45, 35]; +float[] maxspeedRing = [7.5, 8.5, 10]; +int[] deceltimeRing = [20, 25, 32]; +int[] acceltimeRing = [60, 50, 40]; // Remilia takes 36 frames. Preferably, pick a number 36 can divide with. @@ -50,11 +51,10 @@ int[] delayRing = [9, 6, 5]; // How much time Remilia takes to charge her attack and you get to GTFO. -int[] waittimeRemi = [75, 60, 50]; +int[] waittimeRemi = [80, 70, 60]; string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; - -//LoadTextureEx(tex, true, true); +//LoadTextureEx(tex, true, false); // Includes ahoy @@ -65,10 +65,11 @@ string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; //SetIntersectionVisualization(true); SetAutoDeleteObject(true); + LoadTextureEx(tex, true, false); _InitDifficulty(difficultySelect); - difficultySelect = 0; // debug + //difficultySelect = 2; // debug SetShotAutoDeleteClip(64, 64, 64, 64); @@ -118,7 +119,7 @@ string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); - ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 100); + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); yield; @@ -152,28 +153,175 @@ Parameters: task mainTask { + int multiplier = 1; + + ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/2 + , 45, LERP_DECELERATE); + + wait(45); + + _UseCard(); + + while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){ + + loop(3){ + _VampireChase(); + } + FitfulNightmare(multiplier); + wait(90); + multiplier *= -1; + + } + +} + +function _UseCard(){ + + // Remi spell + + int cardImg = _Create2DImage(tex, [0, 256, 256, 512]); + + ObjRender_SetPosition(cardImg, bossX, bossY, 0); + + ascent(i in 0..30){ + ObjRender_SetY(cardImg, Interpolate_Decelerate(bossY, bossY - 256, i/30)); + ObjRender_SetAlpha(cardImg, Interpolate_Decelerate(0, 255, i/30)); + yield; + } + + wait(30); + + ascent(i in 0..15){ + ObjRender_SetAlpha(cardImg, Interpolate_Decelerate(255, 0, i/15)); + yield; + } + + Obj_Delete(cardImg); + } function _VampireChase(){ + + float chaseX = playerX; + float chaseY = playerY; - ObjMove_SetDestAtFrame(bossObj, playerX, playerY, 36, LERP_DECELERATE); + ChargeSFX; + + ObjMove_SetDestAtFrame(bossObj, Interpolate_Decelerate(bossX, chaseX, -0.08), Interpolate_Decelerate(bossY, chaseY, -0.08), 30, LERP_DECELERATE); + wait(25); + + ObjMove_SetDestAtFrame(bossObj, Interpolate_Decelerate(bossX, chaseX, 1), Interpolate_Decelerate(bossY, chaseY, 1), 36, LERP_DECELERATE); + + float ang = GetAngleToPlayer(bossObj); loop(36/delayRing){ - + ascent(i in 0..denseRing[difficultySelect]){ - int shot = CreateShotA2(bossX, bossY, maxspeedRing[difficultySelect], ang + 360/denseRing[difficultySelect] * i, -maxspeedRing[difficultySelect]/deceltimeRing[difficultySelect], 0, 0, color, 10); + int shot = CreateShotA2(bossX, bossY, maxspeedRing[difficultySelect], ang + 360/denseRing[difficultySelect] * i, -maxspeedRing[difficultySelect]/deceltimeRing[difficultySelect], 0, 0, KEV_AURABALL_RED, 10); if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){Obj_Delete(shot);} else{ _Delay(shot, 10); ObjMove_AddPatternA2(shot, 30, NO_CHANGE, NO_CHANGE, maxspeedRing[difficultySelect]/acceltimeRing[difficultySelect], maxspeedRing[difficultySelect], 0); - _BulletRescale(shot, 0.65, true, 1); - //Shoot1; + _BulletRescale(shot, 0.6, true, 1); + Shoot2; } } + + ang += 18; wait(delayRing); } + //wait(36); + + // BOOM + _FireExplosion(bossObj); + + wait(waittimeRemi[difficultySelect]); + +} + +function FitfulNightmare(int spin){ + + ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/3, 60, LERP_DECELERATE); + ChargeSFX; + + wait(75); + + float ang = 0; + + loop(40){ + float ang2 = ang; + + loop(denseSpiral[difficultySelect]){ + + int shot = CreateShotA1(bossX, bossY, speedSpiral[difficultySelect], ang2, KEV_KNIFE_RED, 10); + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0){Obj_Delete(shot);} + else{ + _Delay(shot, 10); + _BulletRescale(shot, 1.25, true, 1); + Shoot1; + } + + ang2 += 360/denseSpiral[difficultySelect]*spin; + + } + + ang += angleoffsetSpiral[difficultySelect]; + wait(3); + } + +} + +task _FireExplosion(int target){ + + int objPattern = ObjPatternShot_Create(); + + ObjPatternShot_SetParentObject(objPattern, target); + + if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) == 0){Obj_Delete(objPattern); return;} + + ObjPatternShot_SetPatternType(objPattern, PATTERN_SCATTER_ANGLE); + ObjPatternShot_SetShotType(objPattern, OBJ_SHOT); + ObjPatternShot_SetInitialBlendMode(objPattern, BLEND_ADD_ARGB); + + ObjPatternShot_SetShotCount(objPattern, 24, 6); + ObjPatternShot_SetSpeed(objPattern, 18, 2); + ObjPatternShot_SetAngle(objPattern, 360, 360); + + ObjPatternShot_SetDelay(objPattern, 5); + ObjPatternShot_SetGraphic(objPattern, KEV_LEAF_RED); + + Shoot2; + int[] arrayPattern = ObjPatternShot_FireReturn(objPattern); + + int i = 0; + + for each (int bullet in ref arrayPattern){ + + _BulletRescale(bullet, 1.2, true, 1); + _Delay(bullet, 15); + + Obj_SetRenderPriorityI(bullet, 50); + + _DeletionHandling(bullet, waittimeRemi[difficultySelect]+i); + + //ObjMove_SetAcceleration(bullet, -0.25); + //ObjMove_SetMaxSpeed(bullet, 5); + } + +} + +task _DeletionHandling(int target, int frameDel){ + + float spd = ObjMove_GetSpeed(target); + + ObjMove_SetAcceleration(target, -spd/[30, 34, 38][difficultySelect]); + ObjMove_SetMaxSpeed(target, 0.2); + + wait(frameDel); + ObjShot_FadeDelete(target); + } task endingnew(){ diff --git a/script/game/Spell2.dnh b/script/game/Spell2.dnh index ddb5ae8..b7454d5 100644 --- a/script/game/Spell2.dnh +++ b/script/game/Spell2.dnh @@ -62,8 +62,6 @@ bool bookShooting = false; // it's a secret tool that will help us later string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; -//LoadTextureEx(tex, true, true); - // Includes ahoy #include "script/KevinSystem/Universal_Lib.txt" // The library to include all libraries :sans: :nail_care: @@ -73,10 +71,11 @@ string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; //SetIntersectionVisualization(true); SetAutoDeleteObject(true); + LoadTextureEx(tex, true, false); _InitDifficulty(difficultySelect); - difficultySelect = 0; // debug + //difficultySelect = 0; // debug SetShotAutoDeleteClip(64, 64, 64, 64); @@ -136,7 +135,7 @@ string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); - ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 100); + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); yield; @@ -174,8 +173,11 @@ Parameters: task mainTask { + ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/2 + , 45, LERP_DECELERATE); wait(45); + _UseCard(); // Create 5 books CreateBook([0, 0, 256, 256], STG_WIDTH*1/6, 0.65, KEV_LEAF_RED); @@ -228,6 +230,31 @@ task mainTask { } +function _UseCard(){ + + // Remi spell + + int cardImg = _Create2DImage(tex, [256, 256, 512, 512]); + + ObjRender_SetPosition(cardImg, bossX, bossY, 0); + + ascent(i in 0..30){ + ObjRender_SetY(cardImg, Interpolate_Decelerate(bossY, bossY - 256, i/30)); + ObjRender_SetAlpha(cardImg, Interpolate_Decelerate(0, 255, i/30)); + yield; + } + + wait(30); + + ascent(i in 0..15){ + ObjRender_SetAlpha(cardImg, Interpolate_Decelerate(255, 0, i/15)); + yield; + } + + Obj_Delete(cardImg); + +} + /* Fire: 0, 0, 256, 256 Water: 256, 0, 512, 256 @@ -288,7 +315,7 @@ function ChargeAttack(float x, int colorselect){ else{ _Delay(shot, 10); ObjMove_AddPatternA2(shot, 30, NO_CHANGE, NO_CHANGE, maxspeedRing[difficultySelect]/acceltimeRing[difficultySelect], maxspeedRing[difficultySelect], 0); - _BulletRescale(shot, 0.65, true, 1); + _BulletRescale(shot, 0.6, true, 1); //Shoot1; } } diff --git a/script/game/Spell3.dnh b/script/game/Spell3.dnh index acb0ad2..661fd43 100644 --- a/script/game/Spell3.dnh +++ b/script/game/Spell3.dnh @@ -50,6 +50,8 @@ int[] ringdenseKnife = [10, 12, 14]; float[] ringspeedKnife = [8, 9, 10]; // Includes ahoy +string tex = "script/game/resourceLib/Spritesheet_StationJam.png"; +//LoadTextureEx(tex, true, false); #include "script/KevinSystem/Universal_Lib.txt" // The library to include all libraries :sans: :nail_care: @@ -58,10 +60,11 @@ float[] ringspeedKnife = [8, 9, 10]; //SetIntersectionVisualization(true); SetAutoDeleteObject(true); + LoadTextureEx(tex, true, false); _InitDifficulty(difficultySelect); - difficultySelect = 0; // debug + //difficultySelect = 0; // debug SetShotAutoDeleteClip(64, 64, 64, 64); @@ -111,7 +114,7 @@ float[] ringspeedKnife = [8, 9, 10]; bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); - ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 100); + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); yield; @@ -145,6 +148,12 @@ Parameters: task mainTask { + ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/2 + , 45, LERP_DECELERATE); + wait(45); + + _UseCard(); + _Warn(); wait(45); @@ -153,11 +162,36 @@ task mainTask { MoveToBottom(); //BurstAttack(); //wait(360); - wait(frameMove[difficultySelect]*2); + wait(frameMove[difficultySelect]*1.75); } } +function _UseCard(){ + + // Remi spell + + int cardImg = _Create2DImage(tex, [512, 256, 768, 512]); + + ObjRender_SetPosition(cardImg, bossX, bossY, 0); + + ascent(i in 0..30){ + ObjRender_SetY(cardImg, Interpolate_Decelerate(bossY, bossY - 256, i/30)); + ObjRender_SetAlpha(cardImg, Interpolate_Decelerate(0, 255, i/30)); + yield; + } + + wait(30); + + ascent(i in 0..15){ + ObjRender_SetAlpha(cardImg, Interpolate_Decelerate(255, 0, i/15)); + yield; + } + + Obj_Delete(cardImg); + +} + task _Warn(){ int time = 30; diff --git a/script/game/Spell4.dnh b/script/game/Spell4.dnh index 25a8d7e..0248e32 100644 --- a/script/game/Spell4.dnh +++ b/script/game/Spell4.dnh @@ -156,7 +156,7 @@ int[] thresholdStopSpin = [80, 70, 60]; bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); - ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 100); + ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180); yield; diff --git a/script/game/Stage_Background.dnh b/script/game/Stage_Background.dnh new file mode 100644 index 0000000..903b3a7 --- /dev/null +++ b/script/game/Stage_Background.dnh @@ -0,0 +1,87 @@ +let bossBG = "script/game/resourceLib/BGFight.png"; +let sound = ObjSound_Create(); +let alphaMax = 255*((GetAreaCommonData("Config", "BGOpacity", 100))/100); +let blipVol = GetAreaCommonData("Config", "SEVol", 100) * 0.01; + +ObjSound_Load(sound, "script/game/resourceLib/dialogueblip.wav"); +ObjSound_SetVolumeRate(sound, 100 * blipVol); +ObjSound_SetSoundDivision(sound, SOUND_SE); + +//LoadSound("script/game/StageLib/dialogueblip.wav"); + +LoadTextureEx(bossBG, true, true); + +function _ScrollBackground(){ + + int BossImg = _Create2DImage(bossBG, [0, 0, 910, 1200]); + ObjRender_SetPosition(BossImg, STG_WIDTH/2, STG_HEIGHT/2-150, 0); + Obj_SetRenderPriorityI(BossImg, 24); + + ascent(i in 0..30){ + ObjRender_SetAlpha(BossImg, Interpolate_Decelerate(0, alphaMax, i/30)); + yield; + } + + Dialogue(); + //ObjRender_SetAlpha(BossImg, 255*((GetAreaCommonData("Config", "BGOpacity", 100))/100)); + +} + +function Dialogue(){ + + int objText = CreateTextObject( + + STG_WIDTH/2, 2*STG_HEIGHT/5+125, 45, + " ", "Origami Mommy", + 0x9F9FFF, 0xDCD6FF, + 0x000000, 3, + 71 + + ); + + ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER); + TTextScroll(objText, "AN AWESOME VAMPIRE/IS CONFLICT WITH US//KEEP YOUR SEXINESS"); + + Obj_Delete(objText); + +} + +// by Mugenri! + +function TTextScroll(int obj_, string text_) { //Makes text fill gradually in text boxes + + bool dialogEnd = false; + bool sentenceEnd = false; + string[] tempStrings = SplitString(text_, "/"); //use / for newlines instead of [r] + string tempString = ""; + char lastChar; + int waitTime; + + async{ + while(!dialogEnd){ + if(sentenceEnd){wait(4); continue;} + else{ObjSound_Play(sound); wait(4);} + } + } + + if (GetVirtualKeyState(VK_OK) == KEY_PUSH) { //Prevents skipping the yield + SetVirtualKeyState(VK_OK, KEY_FREE); + } + + ascent (i in 0..length(tempStrings)) { //list of substrings + ascent (j in 0..length(tempStrings[i])) { //for each character in a substring + tempString ~= [tempStrings[i][j]]; + lastChar = tempString[-1]; + ObjText_SetText(obj_, tempString); + if([tempStrings[i][j]] == "." || + [tempStrings[i][j]] == "," || + [tempStrings[i][j]] == "!" ) {sentenceEnd = true; wait(10);} + else {wait(2); sentenceEnd = false;} + } + tempString ~= ['[','r',']']; //append a newline after each substring + } + + dialogEnd = true; + wait(90); + +} \ No newline at end of file diff --git a/script/game/replay/Non2_replay01.dat b/script/game/replay/Non2_replay01.dat index 60c0428..b2478b6 100644 Binary files a/script/game/replay/Non2_replay01.dat and b/script/game/replay/Non2_replay01.dat differ diff --git a/script/game/replay/Non3_replay01.dat b/script/game/replay/Non3_replay01.dat new file mode 100644 index 0000000..e7c6464 Binary files /dev/null and b/script/game/replay/Non3_replay01.dat differ diff --git a/script/game/replay/Spell1_replay01.dat b/script/game/replay/Spell1_replay01.dat new file mode 100644 index 0000000..5e9c15c Binary files /dev/null and b/script/game/replay/Spell1_replay01.dat differ diff --git a/script/game/replay/Spell1_replay03.dat b/script/game/replay/Spell1_replay03.dat new file mode 100644 index 0000000..7d504a3 Binary files /dev/null and b/script/game/replay/Spell1_replay03.dat differ diff --git a/script/game/replay/Spell1_replay04.dat b/script/game/replay/Spell1_replay04.dat new file mode 100644 index 0000000..645b74d Binary files /dev/null and b/script/game/replay/Spell1_replay04.dat differ diff --git a/script/game/replay/Spell2_replay01.dat b/script/game/replay/Spell2_replay01.dat index 0ed3c40..82410ba 100644 Binary files a/script/game/replay/Spell2_replay01.dat and b/script/game/replay/Spell2_replay01.dat differ diff --git a/script/game/replay/Spell3_replay01.dat b/script/game/replay/Spell3_replay01.dat index 9013aaa..acaf4e7 100644 Binary files a/script/game/replay/Spell3_replay01.dat and b/script/game/replay/Spell3_replay01.dat differ diff --git a/script/game/resourceLib/BGFight.png b/script/game/resourceLib/BGFight.png new file mode 100644 index 0000000..0a5233d Binary files /dev/null and b/script/game/resourceLib/BGFight.png differ diff --git a/script/game/resourceLib/Spritesheet_StationJam.png b/script/game/resourceLib/Spritesheet_StationJam.png index 4839e50..3edb277 100644 Binary files a/script/game/resourceLib/Spritesheet_StationJam.png and b/script/game/resourceLib/Spritesheet_StationJam.png differ diff --git a/script/game/resourceLib/abilitycards-patchouli.png b/script/game/resourceLib/abilitycards-patchouli.png new file mode 100644 index 0000000..35cf0bb Binary files /dev/null and b/script/game/resourceLib/abilitycards-patchouli.png differ diff --git a/script/game/resourceLib/abilitycards-remilia.png b/script/game/resourceLib/abilitycards-remilia.png new file mode 100644 index 0000000..a4a406d Binary files /dev/null and b/script/game/resourceLib/abilitycards-remilia.png differ diff --git a/script/game/resourceLib/abilitycards-sakuya.png b/script/game/resourceLib/abilitycards-sakuya.png new file mode 100644 index 0000000..4dd32fb Binary files /dev/null and b/script/game/resourceLib/abilitycards-sakuya.png differ diff --git a/script/game/resourceLib/bossTheme.ogg b/script/game/resourceLib/bossTheme.ogg new file mode 100644 index 0000000..85d638b Binary files /dev/null and b/script/game/resourceLib/bossTheme.ogg differ diff --git a/script/game/resourceLib/dialogueblip.wav b/script/game/resourceLib/dialogueblip.wav new file mode 100644 index 0000000..8f78fc7 Binary files /dev/null and b/script/game/resourceLib/dialogueblip.wav differ diff --git a/script/game/resourceLib/yassBackground.mdp b/script/game/resourceLib/yassBackground.mdp new file mode 100644 index 0000000..195defd Binary files /dev/null and b/script/game/resourceLib/yassBackground.mdp differ