1973 lines
45 KiB
Plaintext
1973 lines
45 KiB
Plaintext
|
#TouhouDanmakufu[Single]
|
||
|
#ScriptVersion[3]
|
||
|
#Title["Gunner Parade"]
|
||
|
#Text["This bitch empty - would you like to yeet?"]
|
||
|
#System["script/KevinSystem/Kevin_System.txt"]
|
||
|
|
||
|
int imgCharacter = _Create2DImage("script/GunnerParade/PackageLib/Character_Kouda.png", [0, 0, 900, 1080]);
|
||
|
int imgTitle = _Create2DImage("script/GunnerParade/PackageLib/Boss_Title.png", [0, 0, 1600, 1080]);
|
||
|
|
||
|
ObjRender_SetAlpha(imgCharacter, 0);
|
||
|
ObjRender_SetAlpha(imgTitle, 0);
|
||
|
|
||
|
float rank = 1; // Increases through time
|
||
|
|
||
|
let RANK_PTR = LoadCommonDataValuePointer("Rank", 1);
|
||
|
|
||
|
let objScene = GetEnemyBossSceneObjectID();
|
||
|
let csd = GetCurrentScriptDirectory();
|
||
|
|
||
|
let bossObj;
|
||
|
|
||
|
float bossX = 0;
|
||
|
float bossY = 0;
|
||
|
float playerY = 0;
|
||
|
float playerX = 0;
|
||
|
|
||
|
bool bossIntro = false;
|
||
|
|
||
|
let spellsnd = ObjSound_Create();
|
||
|
let bossdiesnd = ObjSound_Create();
|
||
|
|
||
|
int[] enmFly = [];
|
||
|
int[] enmGround = [];
|
||
|
|
||
|
int[] rankAvg = [];
|
||
|
|
||
|
let POINTER_CHAIN = LoadAreaCommonDataValuePointer("PIV", "ChainAmount", 1);
|
||
|
|
||
|
//let SYSTEMID_PTR_2 = LoadAreaCommonDataValuePointer("ScriptID", "SystemID", 0);
|
||
|
|
||
|
// Includes ahoy
|
||
|
|
||
|
#include "script/KevinSystem/Universal_Lib.txt"
|
||
|
#include "script/GunnerParade/GunnerParade_EnmLib.dnh"
|
||
|
#include "script/GunnerParade/GunnerParade_ConstLib.dnh"
|
||
|
#include "script/KevinSystem/kevin_system/Lib_Const.dnh"
|
||
|
|
||
|
@Initialize {
|
||
|
|
||
|
//SetIntersectionVisualization(true);
|
||
|
|
||
|
SetAutoDeleteObject(true);
|
||
|
|
||
|
SetCommonData("Rank", clamp(GetCommonData("Rank", 1), RANK_MIN, RANK_MAX));
|
||
|
//difficultySelect = _InitDifficulty(difficultySelect);
|
||
|
|
||
|
//difficultySelect = 2; // debug
|
||
|
|
||
|
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, STG_WIDTH/2, -256);
|
||
|
|
||
|
ObjEnemy_SetDamageRate(bossObj, 0, 0);
|
||
|
|
||
|
_RenderBossFight(bossObj);
|
||
|
SetEnemyAutoDeleteClip(165, 257, 165, 256);
|
||
|
|
||
|
//testTask();
|
||
|
|
||
|
groundTask();
|
||
|
flyingTask();
|
||
|
UpdateDrops();
|
||
|
|
||
|
bossFight();
|
||
|
|
||
|
curEnmManage();
|
||
|
|
||
|
//SetCommonData("Rank", 9);
|
||
|
|
||
|
//_FadeInvincibility(bossObj, 150, 150, 1);
|
||
|
//endingnew();
|
||
|
}
|
||
|
|
||
|
@Event {
|
||
|
|
||
|
alternative(GetEventType())
|
||
|
|
||
|
case(EV_REQUEST_LIFE) {
|
||
|
SetScriptResult(HP_MAX);
|
||
|
}
|
||
|
|
||
|
case(EV_REQUEST_IS_DURABLE_SPELL) {
|
||
|
SetScriptResult(false);
|
||
|
}
|
||
|
|
||
|
case(EV_REQUEST_TIMER) {
|
||
|
SetScriptResult(STAGE_LENGTH);
|
||
|
//SetScriptResult(BOSS_LENGTH+5);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
@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 {
|
||
|
|
||
|
}
|
||
|
|
||
|
// This array contains ONLY FLYING ENEMIES
|
||
|
|
||
|
task groundTask(){
|
||
|
|
||
|
wait(90);
|
||
|
|
||
|
while(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) > BOSS_LENGTH){
|
||
|
|
||
|
WaveGround1();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
WaveGround2();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
WaveGround1A();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
if(GetCommonData("Difficulty", "Standard") != "Novice"){
|
||
|
SetCommonData("Rank", clamp(GetCommonData("Rank", 1)+1, RANK_MIN, RANK_MAX_TRUE));
|
||
|
}
|
||
|
|
||
|
else{}
|
||
|
|
||
|
WaveGround3();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
WaveGround4();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
WaveGround5();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
if(GetCommonData("Rank", 1)+1 >= 7){
|
||
|
|
||
|
WaveGround1A();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
WaveGround6();
|
||
|
wait(max(5, 15-rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
}
|
||
|
|
||
|
SetCommonData("Ground Loops Cleared", GetCommonData("Ground Loops Cleared", 0)+1);
|
||
|
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
task flyingTask(){
|
||
|
|
||
|
wait(30);
|
||
|
|
||
|
while(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) > BOSS_LENGTH){
|
||
|
|
||
|
Wave1();
|
||
|
wait(max(5, 20-4*rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
Wave2();
|
||
|
wait(max(5, 20-4*rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
Wave3();
|
||
|
wait(max(5, 20-4*rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
Wave4();
|
||
|
wait(max(5, 20-4*rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
Wave5();
|
||
|
wait(max(5, 20-4*rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
Wave6();
|
||
|
wait(max(5, 20-4*rank));
|
||
|
if(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) <= BOSS_LENGTH){break;}
|
||
|
|
||
|
SetCommonData("Flying Loops Cleared", GetCommonData("Flying Loops Cleared", 0)+1);
|
||
|
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
task curEnmManage(){
|
||
|
|
||
|
SetCommonData("Flying Loops Cleared", 0);
|
||
|
SetCommonData("Ground Loops Cleared", 0);
|
||
|
|
||
|
RankManagement();
|
||
|
|
||
|
int[] allEnm = [];
|
||
|
|
||
|
while(true){
|
||
|
enmGround = [];
|
||
|
enmFly = [];
|
||
|
allEnm = GetIntersectionRegistedEnemyID();
|
||
|
for each (int enm in ref allEnm){
|
||
|
if(Obj_GetRenderPriorityI(enm) <= 37){enmGround ~= [enm];}
|
||
|
else if(Obj_GetRenderPriorityI(enm) >= 38 && Obj_GetRenderPriorityI(enm) < 41){enmFly ~= [enm];}
|
||
|
else{}
|
||
|
}
|
||
|
wait(10);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
task _BossExplosion(){
|
||
|
|
||
|
float enmX = 0, enmY = 0;
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){
|
||
|
|
||
|
enmX = ObjMove_GetX(bossObj); enmY = ObjMove_GetY(bossObj);
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
//NotifyEventAll(EV_DROP_POINT_ENEMY, [enmX, enmY], timer, maxTimer, minPoint, maxPoint);
|
||
|
|
||
|
DeleteShotAll(TYPE_ALL, TYPE_ITEM);
|
||
|
SetPlayerInvincibilityFrame(300);
|
||
|
ObjSound_Play(bossBoom);
|
||
|
Obj_SetRenderPriorityI(bossObj, 30);
|
||
|
NotifyEvent(GetCommonDataPtr(SYSTEMID_PTR, 0), EV_EXPLODE, [enmX, enmY]);
|
||
|
|
||
|
_ObjShake(bossObj, 190, 60);
|
||
|
|
||
|
loop(30){
|
||
|
//LoadEx(bossBoom, "script/game/resourceLib/bigBoom.ogg", 30 * SFXVol);
|
||
|
ObjSound_Play(bossBoom);
|
||
|
NotifyEvent(GetCommonDataPtr(SYSTEMID_PTR, 0), EV_EXPLODE, [bossX+rand(-240, 240), bossY+rand(-150, 150)]);
|
||
|
wait(6);
|
||
|
}
|
||
|
|
||
|
ObjMove_SetDestAtFrame(bossObj, bossX, STG_HEIGHT+512, 120, LERP_ACCELERATE);
|
||
|
|
||
|
float ang = ObjRender_GetAngleZ(bossObj);
|
||
|
|
||
|
ascent(i in 0..120){
|
||
|
ObjRender_SetAngleZ(bossObj, Interpolate_Accelerate(ang, ang+180, i/120));
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
//wait();
|
||
|
|
||
|
_EndShake(120, 90);
|
||
|
|
||
|
loop(120){
|
||
|
NotifyEvent(GetCommonDataPtr(SYSTEMID_PTR, 0), EV_EXPLODE, [bossX+rand(-240, 240), STG_HEIGHT+rand(0, -150)]);
|
||
|
}
|
||
|
|
||
|
ObjSound_Play(bossBoom);
|
||
|
|
||
|
EndBonus();
|
||
|
|
||
|
//_ScorePopup(float enmX, float enmY, int pointNum, int pivNum);
|
||
|
|
||
|
// NotifyEvent is faster than NotifyEventAll, considering how the item event will be called many times.
|
||
|
|
||
|
}
|
||
|
|
||
|
task EndBonus(){
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){
|
||
|
//WriteLog(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER));
|
||
|
//wait(30);
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
ObjEnemy_SetLife(bossObj, -1);
|
||
|
|
||
|
let timer = ObjEnemyBossScene_GetInfo(objScene, INFO_TIMERF);
|
||
|
//WriteLog(timer);
|
||
|
|
||
|
// Bonus Calculations:
|
||
|
|
||
|
// (Time Remaining + Ground Loops Cleared + Flying Loops Cleared + Average Rank) * 10000
|
||
|
|
||
|
function <void> _CreateBonusText(float x, y, fontSize, int colorBorder, string text){
|
||
|
|
||
|
int objText = CreateTextObject(
|
||
|
|
||
|
x, y, fontSize,
|
||
|
"", "Origami Mommy",
|
||
|
0xFFFFFF, 0xFFFFFF,
|
||
|
colorBorder, 4,
|
||
|
71
|
||
|
|
||
|
);
|
||
|
|
||
|
ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
|
||
|
|
||
|
TTextScroll(objText, text);
|
||
|
|
||
|
}
|
||
|
|
||
|
wait(120);
|
||
|
|
||
|
float rankAvgFinal = 0;
|
||
|
float rankSum = 0;
|
||
|
|
||
|
ascent(i in -1..length(rankAvg)-1){
|
||
|
rankSum += rankAvg[i];
|
||
|
}
|
||
|
|
||
|
rankAvgFinal = rankSum/length(rankAvg);
|
||
|
|
||
|
_CreateBonusText(STG_WIDTH/2, STG_HEIGHT/2-220, 30, 0xCF007A, "LIVES REMAINING: " ~ IntToString(GetPlayerLife()));
|
||
|
_CreateBonusText(STG_WIDTH/2, STG_HEIGHT/2-180, 30, 0x3500CF, "TIME REMAINING: " ~ vtos("5.2f", timer/60));
|
||
|
_CreateBonusText(STG_WIDTH/2, STG_HEIGHT/2-140, 30, 0xCF6100, "ENEMIES DEFEATED: " ~ IntToString(GetCommonDataPtr(GROUNDENM_PTR, 0) + GetCommonDataPtr(FLYINGENM_PTR, 0)));
|
||
|
_CreateBonusText(STG_WIDTH/2, STG_HEIGHT/2-100, 30, 0xCF0000, "AVERAGE RANK LV: " ~ vtos("5.2f", rankAvgFinal));
|
||
|
|
||
|
_CreateBonusText(STG_WIDTH/2, STG_HEIGHT/2, 30, 0xFFA300, "END BONUS:");
|
||
|
|
||
|
wait(120);
|
||
|
|
||
|
float multiplierBonus = (GetPlayerLife() + timer/60 + GetCommonDataPtr(GROUNDENM_PTR, 0)/5 + GetCommonDataPtr(FLYINGENM_PTR, 0)/5 + rankAvgFinal) * 30;
|
||
|
|
||
|
int scoreBonus = trunc ( (multiplierBonus * 100000) / 10 ) * 10;
|
||
|
|
||
|
_CreateBonusText(STG_WIDTH/2, STG_HEIGHT/2+60, 60, 0xFFA300, DigitToCommaArray(scoreBonus));
|
||
|
AddScore(scoreBonus);
|
||
|
|
||
|
wait(60);
|
||
|
|
||
|
if(!IsReplay()){SetCommonData("Run Score", GetScore());}
|
||
|
else{SetCommonData("Run Score", 0);}
|
||
|
|
||
|
Obj_Delete(bossObj);
|
||
|
CloseScript(GetOwnScriptID());
|
||
|
|
||
|
}
|
||
|
|
||
|
task RankManagement(){
|
||
|
|
||
|
//SetCommonData("Rank", 9);
|
||
|
//SetCommonData("Rank", 10);
|
||
|
// Rank increase
|
||
|
let textRank = CreateTextObject(
|
||
|
STG_WIDTH-15, STG_HEIGHT/14, 28,
|
||
|
"RANK:", "Origami Mommy",
|
||
|
0xFFFFFF, 0xFFFFFF,
|
||
|
0xAE22FF, 5,
|
||
|
71
|
||
|
);
|
||
|
|
||
|
ObjText_SetHorizontalAlignment(textRank, ALIGNMENT_RIGHT);
|
||
|
|
||
|
async{
|
||
|
while(true){
|
||
|
rank = trunc(GetCommonData("Rank", 1));
|
||
|
if(rank >= RANK_MAX){ObjText_SetText(textRank, "RANK LV [font sz=45 oc=(193, 0, 99)]MAX");}
|
||
|
else{ObjText_SetText(textRank, "RANK LV [font sz=45 oc=(193, 0, 99)]" ~ IntToString(rank));}
|
||
|
//SetCommonData("Rank", 9);
|
||
|
wait(45);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
while(true){
|
||
|
if(ObjMove_GetY(GetPlayerObjectID()) < GetStgFrameHeight()/6){
|
||
|
ObjRender_SetAlpha(textRank, 60);
|
||
|
}
|
||
|
else{
|
||
|
ObjRender_SetAlpha(textRank, 255);
|
||
|
}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){
|
||
|
rankAvg ~= [rank];
|
||
|
wait(60);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Per frame rank increase. +1 rank per 10 seconds (+0.1 rank per second, +1/600 rank per frame), rank 10 at 100 seconds if no specials, bombs or deaths happen
|
||
|
|
||
|
async{
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0){
|
||
|
SetCommonDataPtr(RANK_PTR, clamp(GetCommonDataPtr(RANK_PTR, 1)+1/600, RANK_MIN, RANK_MAX_TRUE));
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Rank on HUD
|
||
|
|
||
|
async{
|
||
|
let textRank = CreateTextObject(
|
||
|
1500, 660, 48,
|
||
|
"", "Origami Mommy",
|
||
|
0xFF9294, 0xFFFFFF,
|
||
|
0x8F0507, 8,
|
||
|
19
|
||
|
);
|
||
|
|
||
|
ObjText_SetHorizontalAlignment(textRank, ALIGNMENT_CENTER);
|
||
|
|
||
|
let textRankRange = CreateTextObject(
|
||
|
1820, 618, 24,
|
||
|
"", "Unispace",
|
||
|
0xA9FFD0, 0xFFFFFF,
|
||
|
0x8F0507, 2,
|
||
|
19
|
||
|
);
|
||
|
|
||
|
while(true){
|
||
|
ObjText_SetText(textRank, IntToString(rank));
|
||
|
ObjText_SetText(textRankRange, "LV." ~ IntToString(RANK_MIN) ~ "[r][font oy=4 tc=(255, 114, 189)]LV." ~ IntToString(RANK_MAX_TRUE) ~ "[r][font oy=8 tc=(255, 147, 138)]" ~ rtos("00.00", GetCommonData("Rank", 1)));
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
task testTask(){
|
||
|
|
||
|
wait(15);
|
||
|
|
||
|
while(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMER) > 20){
|
||
|
|
||
|
/*
|
||
|
Wave1();
|
||
|
Wave2();
|
||
|
|
||
|
Wave4();
|
||
|
Wave5();
|
||
|
*/
|
||
|
|
||
|
WaveGround6();
|
||
|
|
||
|
wait(15);
|
||
|
|
||
|
SetCommonData("Rank", clamp(GetCommonData("Rank", 1)+1, 1, RANK_MAX));
|
||
|
SetCommonData("Ground Loops Cleared", GetCommonData("Ground Loops Cleared", 0)+1);
|
||
|
SetCommonData("Flying Loops Cleared", GetCommonData("Flying Loops Cleared", 0)+1);
|
||
|
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
///////////// BOSS HANDLING /////////////
|
||
|
|
||
|
task bossFight(){
|
||
|
|
||
|
while(ObjEnemyBossScene_GetInfo(objScene, INFO_TIMERF) > BOSS_LENGTH*60){
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
bossIntro = true;
|
||
|
|
||
|
BossIntro();
|
||
|
BossPhase1();
|
||
|
BossPhase2();
|
||
|
BossPhase3();
|
||
|
|
||
|
// Umbrella waves
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> BossIntro(){
|
||
|
|
||
|
bool bossCurrentlyIntro = true;
|
||
|
|
||
|
async{
|
||
|
int timer = ObjEnemyBossScene_GetInfo(objScene, INFO_TIMERF);
|
||
|
while(bossCurrentlyIntro){
|
||
|
ObjEnemyBossScene_SetSpellTimer(objScene, timer);
|
||
|
SetForbidPlayerShot(true);
|
||
|
SetForbidPlayerSpell(true);
|
||
|
ObjEnemy_SetDamageRate(bossObj, 0, 0);
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
SetForbidPlayerShot(false);
|
||
|
SetForbidPlayerSpell(false);
|
||
|
ObjEnemy_SetDamageRate(bossObj, 0, 0);
|
||
|
|
||
|
}
|
||
|
|
||
|
SetPlayerInvincibilityFrame(180);
|
||
|
DeleteShotAll(TYPE_ALL, TYPE_ITEM);
|
||
|
|
||
|
Obj_SetRenderPriorityI(imgCharacter, 81);
|
||
|
Obj_SetRenderPriorityI(imgTitle, 81);
|
||
|
|
||
|
ObjRender_SetScaleXYZ(imgCharacter, 1);
|
||
|
ObjRender_SetScaleXYZ(imgTitle, 0.5);
|
||
|
|
||
|
ObjRender_SetPosition(imgCharacter, 1920/2, 1080/2, 1);
|
||
|
ObjRender_SetPosition(imgTitle, 1920/2, 1080/2, 1);
|
||
|
|
||
|
ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/4, 30, LERP_DECELERATE);
|
||
|
wait(30);
|
||
|
|
||
|
ascent(i in 0..30){
|
||
|
|
||
|
int a = i;
|
||
|
if(a > 15){a = 15;}
|
||
|
|
||
|
ObjRender_SetX(imgCharacter, FUNC_LERP_DECEL(1920/2, 1920/2 + 240, i/30));
|
||
|
ObjRender_SetX(imgTitle, FUNC_LERP_DECEL(1920/2, 1920/2 - 240, i/30));
|
||
|
|
||
|
ObjRender_SetAlpha(imgCharacter, FUNC_LERP_DECEL(0, 255, a/15));
|
||
|
ObjRender_SetAlpha(imgTitle, FUNC_LERP_DECEL(0, 255, a/15));
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 0..75){
|
||
|
|
||
|
ObjRender_SetX(imgCharacter, FUNC_LERP_LINEAR(1920/2+240, 1920/2+275, i/75));
|
||
|
ObjRender_SetX(imgTitle, FUNC_LERP_LINEAR(1920/2-240, 1920/2-275, i/75));
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 0..30){
|
||
|
|
||
|
int a = i;
|
||
|
if(a > 15){a = 15;}
|
||
|
|
||
|
ObjRender_SetX(imgCharacter, FUNC_LERP_LINEAR(1920/2+275, 1920/2+600, i/30));
|
||
|
ObjRender_SetX(imgTitle, FUNC_LERP_LINEAR(1920/2-275, 1920/2-600, i/30));
|
||
|
|
||
|
ObjRender_SetAlpha(imgCharacter, FUNC_LERP_DECEL(255, 0, a/15));
|
||
|
ObjRender_SetAlpha(imgTitle, FUNC_LERP_DECEL(255, 0, a/15));
|
||
|
|
||
|
yield;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
bossCurrentlyIntro = false;
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> BossPhase1(){
|
||
|
|
||
|
ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/4, 60, LERP_DECELERATE);
|
||
|
wait(10);
|
||
|
|
||
|
_FadeInvincibility(bossObj, 90, 90, 0.25);
|
||
|
|
||
|
// Bird columns moving horizontally, leaving behind 2-way bullet lines
|
||
|
|
||
|
int bulletNum = FUNC_LERP_LINEAR(3, 5, rank/RANK_MAX);
|
||
|
float birdNum = FUNC_LERP_LINEAR(5, 8, rank/RANK_MAX);
|
||
|
float bulletSpd = FUNC_LERP_ACCEL(8, 12, rank/RANK_MAX);
|
||
|
float birdMaxSpd = FUNC_LERP_ACCEL(12, 16, rank/RANK_MAX);
|
||
|
int birdAccelTime = FUNC_LERP_ACCEL(30, 20, rank/RANK_MAX);
|
||
|
int spawnDel = FUNC_LERP_LINEAR(90, 75, rank/RANK_MAX);
|
||
|
|
||
|
// Spiral - use W3 parameters
|
||
|
|
||
|
int linenum = FUNC_LERP_LINEAR(4, 7, rank/RANK_MAX);
|
||
|
int dense = FUNC_LERP_LINEAR(14, 18, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(5, 3, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(10, 13, rank/RANK_MAX);
|
||
|
float angStart = rand(0, 360);
|
||
|
|
||
|
task _SummonBird(float startX, startY){
|
||
|
|
||
|
float angMove = startX < 0 ? 0 : 180;
|
||
|
float destMove = startX < 0 ? STG_WIDTH/13 : 12*STG_WIDTH/13;
|
||
|
|
||
|
int enm = _SmallWitch(
|
||
|
40, birdAccelTime*999,
|
||
|
startX, startY
|
||
|
);
|
||
|
|
||
|
async{
|
||
|
|
||
|
ObjEnemy_SetDamageRate(enm, 0, 0);
|
||
|
ObjMove_SetDestAtFrame(enm, destMove, startY, birdAccelTime, LERP_DECELERATE);
|
||
|
wait(birdAccelTime);
|
||
|
ObjMove_AddPatternA2(enm, 0, NO_CHANGE, NO_CHANGE, birdMaxSpd/birdAccelTime, birdMaxSpd, 0);
|
||
|
|
||
|
}
|
||
|
|
||
|
ObjRender_SetAngleZ(enm, angMove);
|
||
|
|
||
|
wait(birdAccelTime*1.5);
|
||
|
|
||
|
float ang = angMove + rand(-5, 5);
|
||
|
|
||
|
ascent(i in 0..bulletNum)
|
||
|
{
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), FUNC_LERP_LINEAR(bulletSpd/1.4, bulletSpd, i/bulletNum), GetAngleToPlayer(enm), KEV_BALL_PINK, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
|
||
|
//int bullet2 = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), FUNC_LERP_LINEAR(bulletSpd/2, bulletSpd, i/bulletNum), GetAngleToPlayer(enm), KEV_BALL_PINK, 5);
|
||
|
|
||
|
//_BulletRescale(bullet2, 0.75, true, 0.25);
|
||
|
//_Delay(bullet2, 5);
|
||
|
|
||
|
};
|
||
|
|
||
|
ObjEnemy_SetDamageRate(enm, 200, 200);
|
||
|
|
||
|
}
|
||
|
|
||
|
PhaseBonusCalculation(PHASE1_LIMIT, "[font oc=(98, 0, 164) wg=800]Hitchcock Trap");
|
||
|
|
||
|
async{
|
||
|
|
||
|
int i = 180;
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE1_LIMIT){
|
||
|
|
||
|
int shot = CreateFan(bossObj, 1, KEV_LEAF_ORANGE, linenum,
|
||
|
angStart+i*1*360/dense, 0, spd/1.5, spd,
|
||
|
0.75,
|
||
|
0, 0,
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
int shot2 = CreateFan(bossObj, 1, KEV_LEAF_ORANGE, linenum,
|
||
|
angStart+(180+angStart)+i*(-1)*360/dense, 0, spd/1.5, spd,
|
||
|
0.75,
|
||
|
0, 0,
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
|
||
|
Shoot2;
|
||
|
|
||
|
i++;
|
||
|
wait(del);
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
float ang = 180;
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE1_LIMIT){
|
||
|
|
||
|
ObjMove_SetX(bossObj, STG_WIDTH/2 + STG_WIDTH/6 * sin(ang));
|
||
|
ang += 1.5;
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
float offset = rand(-STG_HEIGHT/16, STG_HEIGHT/16);
|
||
|
float y1 = 0 - offset;
|
||
|
float y2 = STG_HEIGHT - offset;
|
||
|
|
||
|
async{
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE1_LIMIT){
|
||
|
|
||
|
ChargeSFX;
|
||
|
// From the left
|
||
|
ascent(i in 0..birdNum){
|
||
|
_SummonBird(-96, FUNC_LERP_LINEAR(y1, y2, i/birdNum));
|
||
|
}
|
||
|
|
||
|
wait(spawnDel);
|
||
|
|
||
|
offset = rand(-STG_HEIGHT/12, STG_HEIGHT/12);
|
||
|
y1 = 0 - offset;
|
||
|
y2 = STG_HEIGHT - offset;
|
||
|
|
||
|
ChargeSFX;
|
||
|
ascent(i in 0..birdNum){
|
||
|
_SummonBird(STG_WIDTH+96, FUNC_LERP_LINEAR(y1, y2, i/birdNum));
|
||
|
}
|
||
|
|
||
|
wait(spawnDel);
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE1_LIMIT){
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
ObjEnemy_SetDamageRate(bossObj, 0, 0);
|
||
|
DeleteShotAll(TYPE_ALL, TYPE_ITEM);
|
||
|
|
||
|
wait(30);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> BossPhase2(){
|
||
|
|
||
|
ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/4, 60, LERP_DECELERATE);
|
||
|
|
||
|
_FadeInvincibility(bossObj, 90, 90, 0.25);
|
||
|
|
||
|
wait(30);
|
||
|
|
||
|
// FISH
|
||
|
|
||
|
int bulletNum = FUNC_LERP_LINEAR(9, 12, rank/RANK_MAX);
|
||
|
float bulletSpd = FUNC_LERP_ACCEL(8, 12, rank/RANK_MAX);
|
||
|
float fishMaxSpd = FUNC_LERP_ACCEL(14, 18, rank/RANK_MAX);
|
||
|
int fishAccelTime = FUNC_LERP_ACCEL(30, 20, rank/RANK_MAX);
|
||
|
int spawnDel1 = FUNC_LERP_LINEAR(10, 6, rank/RANK_MAX);
|
||
|
int spawnDel2 = FUNC_LERP_LINEAR(60, 45, rank/RANK_MAX);
|
||
|
|
||
|
// Bullet lines
|
||
|
|
||
|
int linenum = FUNC_LERP_LINEAR(12, 18, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(4, 2, rank/RANK_MAX);
|
||
|
int del2 = FUNC_LERP_ACCEL(8, 5, rank/RANK_MAX);
|
||
|
int bulletDel = FUNC_LERP_ACCEL(10, 5, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(9, 11, rank/RANK_MAX);
|
||
|
float ang = rand(80, 100);
|
||
|
|
||
|
task _SummonFish(float startX){
|
||
|
|
||
|
float angMove = atan2((-48 - playerY), (startX - playerX))+180;
|
||
|
|
||
|
int enm = _Fish(
|
||
|
39, fishAccelTime*50,
|
||
|
startX, -48
|
||
|
);
|
||
|
|
||
|
ObjEnemy_SetDamageRate(enm, 0, 0);
|
||
|
ObjMove_SetSpeed(enm, fishMaxSpd);
|
||
|
ObjMove_SetAngle(enm, angMove);
|
||
|
ObjRender_SetAngleZ(enm, angMove+90);
|
||
|
|
||
|
float ang = angMove;
|
||
|
|
||
|
Shoot2;
|
||
|
|
||
|
ascent(i in 0..bulletNum)
|
||
|
{
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), 0, ang, KEV_LEAF_LAVENDER, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
|
||
|
ObjMove_AddPatternA2(bullet, fishAccelTime, NO_CHANGE, NO_CHANGE, FUNC_LERP_LINEAR(bulletSpd, bulletSpd*1.5, i/bulletNum)/fishAccelTime, FUNC_LERP_LINEAR(bulletSpd, bulletSpd*1.5, i/bulletNum), 0);
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
};
|
||
|
|
||
|
ObjEnemy_SetDamageRate(enm, 200, 200);
|
||
|
|
||
|
}
|
||
|
|
||
|
PhaseBonusCalculation(PHASE2_LIMIT, "[font oc=(98, 0, 164) wg=800]Fish Out of Water");
|
||
|
|
||
|
async{
|
||
|
|
||
|
float angA = ang;
|
||
|
int i = 0;
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE2_LIMIT){
|
||
|
|
||
|
float val1 = i % 2 == 0 ? -384 : STG_WIDTH + 384;
|
||
|
float val2 = i % 2 == 0 ? STG_WIDTH + 384 : -384;
|
||
|
|
||
|
Shoot1;
|
||
|
|
||
|
ascent(i in 0..linenum){
|
||
|
|
||
|
int bullet = CreateShotA1(
|
||
|
FUNC_LERP_LINEAR(val1, val2, i/linenum), -96,
|
||
|
spd, angA, KEV_BALL_AQUA, 5
|
||
|
);
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE2_LIMIT){
|
||
|
|
||
|
ascent(i in 0..5){
|
||
|
_SummonFish(i * STG_WIDTH/5);
|
||
|
wait(spawnDel1);
|
||
|
}
|
||
|
|
||
|
wait(spawnDel2);
|
||
|
|
||
|
ascent(i in 0..5){
|
||
|
_SummonFish((5-i) * STG_WIDTH/5);
|
||
|
wait(spawnDel1);
|
||
|
}
|
||
|
|
||
|
wait(spawnDel2);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
float offset = rand(-STG_HEIGHT/8, STG_HEIGHT/8);
|
||
|
float y1 = 0 - offset;
|
||
|
float y2 = STG_HEIGHT - offset;
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE2_LIMIT){
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
ObjEnemy_SetDamageRate(bossObj, 0, 0);
|
||
|
DeleteShotAll(TYPE_ALL, TYPE_ITEM);
|
||
|
|
||
|
wait(45);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> BossPhase3(){
|
||
|
|
||
|
ObjMove_SetDestAtFrame(bossObj, STG_WIDTH/2, STG_HEIGHT/5, 60, LERP_DECELERATE);
|
||
|
|
||
|
PhaseBonusCalculation(PHASE3_LIMIT, "[font oc=(98, 0, 164) wg=800]Paving a Rainbow Sky");
|
||
|
|
||
|
_FadeInvincibility(bossObj, 90, 90, 0.25);
|
||
|
|
||
|
wait(30);
|
||
|
|
||
|
float numKilled = 0;
|
||
|
|
||
|
// BIRD
|
||
|
|
||
|
float bulletNum = FUNC_LERP_LINEAR(8, 12, rank/RANK_MAX);
|
||
|
float bulletSpd = FUNC_LERP_ACCEL(6.25, 7.25, rank/RANK_MAX);
|
||
|
float birdWvel = FUNC_LERP_ACCEL(1.2, 2, rank/RANK_MAX);
|
||
|
int bulletDel = FUNC_LERP_LINEAR(10, 5, rank/RANK_MAX);
|
||
|
int bulletWait = FUNC_LERP_LINEAR(45, 35, rank/RANK_MAX);
|
||
|
float birdSpd = FUNC_LERP_ACCEL(9, 11.2, rank/RANK_MAX);
|
||
|
float birdNum = FUNC_LERP_LINEAR(10, 15, rank/RANK_MAX);
|
||
|
int spawnDel = FUNC_LERP_ACCEL(80, 60, rank/RANK_MAX);
|
||
|
|
||
|
// Bullet lines
|
||
|
|
||
|
int linenum = FUNC_LERP_LINEAR(14, 17, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(4, 2, rank/RANK_MAX);
|
||
|
int del2 = FUNC_LERP_ACCEL(8, 5, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(9, 11, rank/RANK_MAX);
|
||
|
float ang = rand(80, 100);
|
||
|
|
||
|
async{
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE3_LIMIT){yield;}
|
||
|
|
||
|
ObjEnemy_SetDamageRate(bossObj, 0, 0);
|
||
|
DeleteShotAll(TYPE_ALL, TYPE_ITEM);
|
||
|
|
||
|
_BossExplosion();
|
||
|
|
||
|
}
|
||
|
|
||
|
task _SummonBirdEx(float startAng, float wvel, int num){
|
||
|
|
||
|
int umbrella = _SmallWitch(
|
||
|
41, bulletDel * bulletNum,
|
||
|
bossX, bossY
|
||
|
);
|
||
|
|
||
|
bool isFinishMove = false;
|
||
|
|
||
|
ObjMove_SetAngle(umbrella, startAng);
|
||
|
ObjRender_SetAngleZ(umbrella, startAng);
|
||
|
|
||
|
ObjMove_SetAngularVelocity(umbrella, wvel);
|
||
|
|
||
|
ObjMove_SetSpeed(umbrella, birdSpd);
|
||
|
|
||
|
ObjMove_AddPatternA2(umbrella, 60, NO_CHANGE, NO_CHANGE, NO_CHANGE, NO_CHANGE, wvel/10);
|
||
|
|
||
|
async{
|
||
|
while(!Obj_IsDeleted(umbrella)){
|
||
|
ObjRender_SetAngleZ(umbrella, ObjMove_GetAngle(umbrella));
|
||
|
yield;
|
||
|
}
|
||
|
numKilled++;
|
||
|
ObjEnemy_SetDamageRate(bossObj, numKilled * 2.5, numKilled * 2.5); // 33 enemies put dmg rate to 100
|
||
|
}
|
||
|
|
||
|
int num2 = 0;
|
||
|
|
||
|
ascent(i in 0..num){
|
||
|
|
||
|
float lerpNum1 = i;
|
||
|
float lerpNum2 = num;
|
||
|
|
||
|
ObjEnemy_SetDamageRate(umbrella, FUNC_LERP_LINEAR(10, 50, lerpNum1/lerpNum2), FUNC_LERP_LINEAR(10, 50, lerpNum1/lerpNum2));
|
||
|
|
||
|
int color = KEV_LEAF_RED + num2;
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(umbrella), ObjMove_GetY(umbrella), 0, wvel < 0 ? ObjMove_GetAngle(umbrella) : ObjMove_GetAngle(umbrella), color, 5);
|
||
|
|
||
|
if(ObjEnemy_GetInfo(bossObj, INFO_LIFE) <= 0 || Obj_IsDeleted(umbrella)){Obj_Delete(bullet);}
|
||
|
else{
|
||
|
_Delay(bullet, 5);
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
BulletAction(bullet, lerpNum1, lerpNum2);
|
||
|
Shoot1;
|
||
|
}
|
||
|
|
||
|
wait(bulletDel);
|
||
|
|
||
|
num2++;
|
||
|
if (num2 > (KEV_BALL_PINK - KEV_BALL_RED)){num2 = 0;}
|
||
|
}
|
||
|
|
||
|
task BulletAction(ID, lerpNum1, lerpNum2){
|
||
|
|
||
|
while(!isFinishMove){yield;}
|
||
|
|
||
|
if(Obj_IsDeleted(ID)){return;}
|
||
|
else{
|
||
|
ObjMove_AddPatternA2(ID, 0, NO_CHANGE, NO_CHANGE, FUNC_LERP_LINEAR(bulletSpd/1.5, bulletSpd, lerpNum1/lerpNum2)/FUNC_LERP_LINEAR(bulletWait, bulletWait/1.5, lerpNum1/lerpNum2), FUNC_LERP_LINEAR(bulletSpd/1.5, bulletSpd, lerpNum1/lerpNum2), 0);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
isFinishMove = true;
|
||
|
|
||
|
ObjEnemy_SetDamageRate(umbrella, 100, 100);
|
||
|
|
||
|
}
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > PHASE3_LIMIT){
|
||
|
|
||
|
float randAng = rand(0, 360);
|
||
|
|
||
|
ascent(i in 0..birdNum){
|
||
|
_SummonBirdEx(i * 360/birdNum + randAng, birdWvel, bulletNum);
|
||
|
}
|
||
|
|
||
|
wait(spawnDel);
|
||
|
|
||
|
randAng = rand(0, 360);
|
||
|
|
||
|
ascent(i in 0..birdNum){
|
||
|
_SummonBirdEx(i * 360/birdNum + randAng, -birdWvel, bulletNum);
|
||
|
}
|
||
|
|
||
|
wait(spawnDel);
|
||
|
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
task PhaseBonusCalculation(int HPthreshold, string spellName){
|
||
|
|
||
|
int curRank = rank;
|
||
|
int scoreBase = 1000000 * curRank;
|
||
|
int scoreBonus = scoreBase * GetCommonDataPtr(POINTER_CHAIN, 1);
|
||
|
int i = 0; // 20 seconds
|
||
|
|
||
|
function _CreateBonusText(float x, y, fontSize, int colorBorder, string text){
|
||
|
|
||
|
let objText = CreateTextObject(
|
||
|
|
||
|
x, y, fontSize,
|
||
|
text, "Unispace",
|
||
|
0xFFFFFF, 0xFFFFFF,
|
||
|
colorBorder, fontSize/10,
|
||
|
71
|
||
|
|
||
|
);
|
||
|
|
||
|
ObjText_SetHorizontalAlignment(objText, ALIGNMENT_RIGHT);
|
||
|
|
||
|
return objText;
|
||
|
|
||
|
}
|
||
|
|
||
|
let scoreText = _CreateBonusText(STG_WIDTH-12, STG_HEIGHT/9+12, 32, 0x000000, "");
|
||
|
|
||
|
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > HPthreshold){
|
||
|
|
||
|
scoreBase = trunc(Interpolate_Smooth(1000000 * curRank, 100000 * curRank, i/1200)/10)*10;
|
||
|
i = min(1200, i+1);
|
||
|
|
||
|
scoreBonus = scoreBase * GetCommonDataPtr(POINTER_CHAIN, 1);
|
||
|
|
||
|
ObjText_SetText(scoreText, spellName ~ "[r]BONUS: " ~ DigitToCommaArray(scoreBase) ~ "[font sz=30] x [font clr][font oc=(255, 134, 81)]" ~ rtos("00.00", GetCommonDataPtr(POINTER_CHAIN, 1)));
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
AddScore(scoreBonus);
|
||
|
|
||
|
async{
|
||
|
|
||
|
ObjText_SetText(scoreText, "[font sz=32 oc=(164, 0, 90)]SCORE BONUS:[r][font sz=50 wg=800 oc=(255, 136, 0)]" ~ DigitToCommaArray(trunc(scoreBonus/10)*10));
|
||
|
|
||
|
ChargeBreakSFX;
|
||
|
|
||
|
wait(60);
|
||
|
|
||
|
Obj_Delete(scoreText);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
///////////// ENEMY HANDLING (NOT BOSS) /////////////
|
||
|
|
||
|
function <void> WaveGround1(){
|
||
|
|
||
|
float speedMove = baseMoveSpeed1L * (1 + MoveSpeedRankMultiplierH * rank);
|
||
|
int invin = FUNC_LERP_DECEL(WG1_invinTimeMax, WG1_invinTimeMin, rank/RANK_MAX);
|
||
|
|
||
|
_SignPlatform1(
|
||
|
34, invin,
|
||
|
STG_WIDTH/4, -128, speedMove
|
||
|
);
|
||
|
|
||
|
wait(invin);
|
||
|
|
||
|
while(length(enmGround) > 1){yield;}
|
||
|
|
||
|
_SignPlatform1(
|
||
|
34, invin,
|
||
|
3*STG_WIDTH/4, -128, speedMove
|
||
|
);
|
||
|
|
||
|
wait(invin);
|
||
|
|
||
|
while(length(enmGround) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> WaveGround1A(){
|
||
|
|
||
|
float speedMove = baseMoveSpeed1L * (1 + MoveSpeedRankMultiplierL * rank);
|
||
|
int invin = FUNC_LERP_DECEL(WG1A_invinTimeMax, WG1A_invinTimeMin, rank/RANK_MAX);
|
||
|
int num = FUNC_LERP_DECEL(WG1A_bulletNumMin, WG1A_bulletNumMax, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_DECEL(WG1A_bulletSpdMin, WG1A_bulletSpdMax, rank/RANK_MAX);
|
||
|
float del = FUNC_LERP_DECEL(WG1A_bulletDelayMin, WG1A_bulletDelayMax, rank/RANK_MAX);
|
||
|
|
||
|
int[] signs1 = _SignPlatform1A(
|
||
|
34, invin,
|
||
|
2*STG_WIDTH/7-64, -128, speedMove
|
||
|
);
|
||
|
|
||
|
for each (int sign in ref signs1){
|
||
|
Atk(sign);
|
||
|
}
|
||
|
|
||
|
int[] signs2 = _SignPlatform1A(
|
||
|
34, invin,
|
||
|
5*STG_WIDTH/7+64, -128, speedMove
|
||
|
);
|
||
|
|
||
|
for each (int sign in ref signs2){
|
||
|
Atk(sign);
|
||
|
}
|
||
|
|
||
|
task Atk(int ID){
|
||
|
|
||
|
async{
|
||
|
while(!Obj_IsDeleted(ID) && ObjMove_GetY(ID) <= STG_HEIGHT - 128 && GetObjectDistance(ID, GetPlayerObjectID()) > popcornHitbox * 2){
|
||
|
|
||
|
CreateFan(
|
||
|
ID, num, KEV_BALL_PINK, 1,
|
||
|
GetAngleToPlayer(ID), 2.25, spd, spd/1.5, 0.75,
|
||
|
ObjMove_GetX(ID), ObjMove_GetY(ID),
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
wait(invin);
|
||
|
|
||
|
while(length(enmGround) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> WaveGround2(){
|
||
|
|
||
|
float speedMove = baseMoveSpeedVL * (1 + MoveSpeedRankMultiplierL * rank);
|
||
|
int invin = FUNC_LERP_DECEL(WG2_invinTimeMax, WG2_invinTimeMin, rank/RANK_MAX);
|
||
|
|
||
|
int del = FUNC_LERP_DECEL(WG2_bulletDelayMax, WG2_bulletDelayMin, rank/RANK_MAX);
|
||
|
int num = FUNC_LERP_DECEL(WG2_bulletNumMin, WG2_bulletNumMax, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_DECEL(WG2_bulletSpdMin, WG2_bulletSpdMax, rank/RANK_MAX);
|
||
|
float space = FUNC_LERP_DECEL(WG2_angRangeMin, WG2_angRangeMax, rank/RANK_MAX);
|
||
|
|
||
|
float aimAng = 0;
|
||
|
|
||
|
task Atk(int ID){
|
||
|
|
||
|
async{
|
||
|
while(!Obj_IsDeleted(ID) && ObjMove_GetY(ID) <= STG_HEIGHT * 6/7 && GetObjectDistance(ID, GetPlayerObjectID()) > popcornHitbox * 3){
|
||
|
|
||
|
float posX = 128 * cos(GetAngleToPlayer(ID));
|
||
|
float posY = 128 * sin(GetAngleToPlayer(ID));
|
||
|
|
||
|
CreateFan(
|
||
|
ID, num, KEV_FIRE_RED, 1,
|
||
|
GetAngleToPlayer(ID), space, spd, spd/1.5, 1,
|
||
|
posX, posY,
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while(!Obj_IsDeleted(ID)){
|
||
|
ObjRender_SetAngleZ(ID, atan2(playerY - ObjMove_GetY(ID), playerX - ObjMove_GetX(ID)));
|
||
|
aimAng = atan2(playerY - ObjMove_GetY(ID), playerX - ObjMove_GetX(ID));
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int[] enmArr = _CreateCannonBush(
|
||
|
35, invin,
|
||
|
2*STG_WIDTH/7, -128, speedMove
|
||
|
);
|
||
|
|
||
|
for each(int enm in ref enmArr){
|
||
|
Atk(enm);
|
||
|
}
|
||
|
|
||
|
wait(invin);
|
||
|
|
||
|
while(length(enmGround) > 0){yield;}
|
||
|
|
||
|
int[] enmArr2 = _CreateCannonBush(
|
||
|
34, invin,
|
||
|
5*STG_WIDTH/7, -128, speedMove
|
||
|
);
|
||
|
|
||
|
for each(int enm in ref enmArr2){
|
||
|
Atk(enm);
|
||
|
}
|
||
|
|
||
|
wait(invin);
|
||
|
|
||
|
while(length(enmGround) > 0){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
// Rybb
|
||
|
|
||
|
function <void> WaveGround3(){
|
||
|
|
||
|
float speedMove = baseMoveSpeedVL * (1 + MoveSpeedRankMultiplierVL * rank);
|
||
|
|
||
|
int dense = FUNC_LERP_DECEL(WG3_spiralDenseMin, WG3_spiralDenseMax, rank/RANK_MAX);
|
||
|
int num = FUNC_LERP_DECEL(WG3_spiralNumMin, WG3_spiralNumMax, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_DECEL(WG3_spiralDelayMax, WG3_spiralDelayMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_DECEL(WG3_spiralSpdMin, WG3_spiralSpdMax, rank/RANK_MAX);
|
||
|
|
||
|
int ship = _CreateRybb(
|
||
|
36, del*3,
|
||
|
playerX, -180, speedMove
|
||
|
);
|
||
|
|
||
|
async{
|
||
|
|
||
|
while(!Obj_IsDeleted(ship)){
|
||
|
|
||
|
if (ObjMove_GetY(ship) <= 0) {ObjEnemy_SetDamageRate(ship, 0, 0);}
|
||
|
else if (ObjMove_GetY(ship) <= FUNC_LERP_LINEAR(180, 60, rank/RANK_MAX)) {ObjEnemy_SetDamageRate(ship, 25, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(ship, 100, 100);}
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
int i = 0;
|
||
|
float startAng = 0;
|
||
|
|
||
|
while(!Obj_IsDeleted(ship)){
|
||
|
|
||
|
int dir = i % 2 == 0 ? 1 : -1;
|
||
|
float startAng = i % 2 == 0 ? rand(-5, 0) : rand(0, 5);
|
||
|
|
||
|
ascent(i in 0..num){
|
||
|
ascent(k in 0..dense){
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(ship), ObjMove_GetY(ship), FUNC_LERP_LINEAR(spd, spd, i/num), startAng + k * 360/dense + dir * i * 4, KEV_BALL_ORANGE, 5+i);
|
||
|
_BulletRescale(bullet, 0.6, true, 0.25);
|
||
|
_Delay(bullet, 5+i*2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Shoot1;
|
||
|
wait(del);
|
||
|
i++;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> WaveGround4(){
|
||
|
|
||
|
int del = FUNC_LERP_DECEL(WG4_bulletDelayMax, WG4_bulletDelayMin, rank/RANK_MAX);
|
||
|
int num = FUNC_LERP_DECEL(WG4_enmNumMin, WG4_enmNumMax, rank/RANK_MAX);
|
||
|
float enmspd = rand(baseMoveSpeedH * (1 + MoveSpeedRankMultiplierL*rank), baseMoveSpeedVH * (1 + MoveSpeedRankMultiplierL*rank));
|
||
|
float spd = FUNC_LERP_DECEL(WG4_bulletSpdMin, WG4_bulletSpdMax, rank/RANK_MAX);
|
||
|
int time = FUNC_LERP_DECEL(WG4_invinTimeMax, WG4_invinTimeMin, rank/RANK_MAX);
|
||
|
float bushspd = baseMoveSpeedVL * (1 + MoveSpeedRankMultiplierVL*rank);
|
||
|
|
||
|
float x = 0, y = 0;
|
||
|
|
||
|
int bussy = _CreateDangerBush(
|
||
|
34, time,
|
||
|
STG_WIDTH/2, -128, bushspd
|
||
|
);
|
||
|
|
||
|
async{
|
||
|
|
||
|
wait(time/2);
|
||
|
|
||
|
while(!Obj_IsDeleted(bussy)){
|
||
|
x = ObjMove_GetX(bussy);
|
||
|
y = ObjMove_GetY(bussy);
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
if(
|
||
|
(y > STG_HEIGHT+64)
|
||
|
)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
// Release bussy busses
|
||
|
|
||
|
loop(num){
|
||
|
|
||
|
int enm = _SmallFairy(
|
||
|
38, time/2,
|
||
|
x, y
|
||
|
);
|
||
|
|
||
|
int debris = _CreateBushRemnant(
|
||
|
35, time/2,
|
||
|
x, y
|
||
|
);
|
||
|
|
||
|
enmPattern(enm);
|
||
|
enmPattern2(debris);
|
||
|
|
||
|
}
|
||
|
|
||
|
task enmPattern(int ID){
|
||
|
|
||
|
float valueX = clamp([rand(-enmspd*1, -enmspd*0.25), rand(enmspd*0.25, enmspd*1)][rand_int(0, 1)], -12, 12);
|
||
|
float valueY = -enmspd * rand(1, 1.5);
|
||
|
|
||
|
ObjMove_AddPatternB2(ID, 0, valueX, valueY, -valueX/45, -valueY/45, valueX/20, -valueY/1.25);
|
||
|
|
||
|
while(!Obj_IsDeleted(ID) && ObjMove_GetY(ID) > 0 && ObjMove_GetY(ID) < STG_HEIGHT * 7/8){
|
||
|
|
||
|
if (ObjMove_GetSpeedY(ID) <= -valueY/24) {ObjEnemy_SetDamageRate(ID, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(ID, 100, 100);}
|
||
|
|
||
|
ObjMove_SetY(ID, clamp(ObjMove_GetY(ID), 0, STG_HEIGHT+99999999));
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(ID), ObjMove_GetY(ID), spd, GetAngleToPlayer(ID), KEV_BALL_LAVENDER, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
Shoot1;
|
||
|
|
||
|
wait(del);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
task enmPattern2(int ID){
|
||
|
|
||
|
float valueX = clamp([rand(-enmspd*1.25, -enmspd*0.75), rand(enmspd*1.25, enmspd*0.75)][rand_int(0, 1)], -12, 12);
|
||
|
float valueY = -enmspd * rand(1, 1.5);
|
||
|
|
||
|
ObjMove_AddPatternB2(ID, 0, valueX, valueY, -valueX/35, -valueY/35, valueX/12.5, -valueY);
|
||
|
//ObjRender_SetAlpha(ID, 160);
|
||
|
|
||
|
while(!Obj_IsDeleted(ID)){
|
||
|
|
||
|
if (ObjMove_GetSpeedY(ID) <= -valueY/24) {ObjEnemy_SetDamageRate(ID, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(ID, 100, 100);}
|
||
|
|
||
|
ObjMove_SetY(ID, clamp(ObjMove_GetY(ID), 0, STG_HEIGHT+99999999));
|
||
|
|
||
|
ObjRender_SetAngleZ(ID, ObjRender_GetAngleZ(ID)+3);
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
wait(time/2);
|
||
|
|
||
|
while(length(enmGround) > 0){yield;}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
function <void> WaveGround5(){
|
||
|
|
||
|
float speedMove = baseMoveSpeedVL * (1 + MoveSpeedRankMultiplierVL * rank) * 0.5;
|
||
|
|
||
|
int num = FUNC_LERP_DECEL(WG5_bulletNumMin, WG5_bulletNumMax, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_DECEL(WG5_bulletDelayMax, WG5_bulletDelayMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_DECEL(WG5_bulletSpdMin, WG5_bulletSpdMax, rank/RANK_MAX);
|
||
|
float[] moveX = [[180, -1.5], [0, 1.5]][GetCommonData("Flying Loops Cleared", 0) % 2];
|
||
|
|
||
|
int ship = _CreateDecker(
|
||
|
37, del*3,
|
||
|
playerX, -180, speedMove
|
||
|
);
|
||
|
|
||
|
async{
|
||
|
if(GetCommonData("Rush", false) == true){WaveGround3();}
|
||
|
else{}
|
||
|
}
|
||
|
|
||
|
async{
|
||
|
|
||
|
while(!Obj_IsDeleted(ship)){
|
||
|
|
||
|
ObjMove_SetSpeedY(ship, speedMove);
|
||
|
ObjMove_SetX(ship, STG_WIDTH/2 + STG_WIDTH/2 * cos(moveX[0]));
|
||
|
|
||
|
if (ObjMove_GetY(ship) <= 0) {ObjEnemy_SetDamageRate(ship, 0, 0);}
|
||
|
else if (ObjMove_GetY(ship) <= FUNC_LERP_LINEAR(180, 60, rank/RANK_MAX)) {ObjEnemy_SetDamageRate(ship, 25, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(ship, 100, 100);}
|
||
|
|
||
|
moveX[0] += moveX[1];
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
int i = 0;
|
||
|
float startAng = 0;
|
||
|
|
||
|
while(!Obj_IsDeleted(ship)){
|
||
|
|
||
|
int x = i % 2 == 0 ? 64 : -64;
|
||
|
|
||
|
ascent(i in 0..num){
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(ship)+x, ObjMove_GetY(ship)+160, FUNC_LERP_LINEAR(spd, spd*1.5, i/num), 90, KEV_LEAF_ORANGE, 5);
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 10);
|
||
|
ObjShot_SetDelayMotionEnable(bullet, true);
|
||
|
}
|
||
|
|
||
|
Shoot1;
|
||
|
wait(del);
|
||
|
i++;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
function <void> WaveGround6(){
|
||
|
|
||
|
SetCommonData("Rush", true);
|
||
|
|
||
|
WaveGround5();
|
||
|
|
||
|
SetCommonData("Rush", false);
|
||
|
|
||
|
}
|
||
|
|
||
|
function Wave1(){
|
||
|
|
||
|
int num = FUNC_LERP_ACCEL(W1_fairyNumMin, W1_fairyNumMax, rank/RANK_MAX);
|
||
|
int decel = FUNC_LERP_ACCEL(W1_decelTimeMax, W1_decelTimeMin, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(W1_bulletDelayMax, W1_bulletDelayMin, rank/RANK_MAX);
|
||
|
int spawndel = FUNC_LERP_ACCEL(W1_spawnDelayMax, W1_spawnDelayMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(W1_bulletSpdMin, W1_bulletSpdMax, rank/RANK_MAX);
|
||
|
float movespd = baseMoveSpeedH * (1 + MoveSpeedRankMultiplierL*rank);
|
||
|
|
||
|
task CreateEnemyA(float startX){
|
||
|
|
||
|
int enm = _SmallFairy(
|
||
|
40, decel+5,
|
||
|
startX, -64
|
||
|
);
|
||
|
|
||
|
ObjMove_AddPatternA2(enm, 0, movespd*1.5, 90, -movespd*1.5/decel, 0, 0);
|
||
|
ObjMove_AddPatternA2(enm, decel*1.5, NO_CHANGE, NO_CHANGE, movespd/decel, movespd, 0);
|
||
|
|
||
|
wait(decel);
|
||
|
|
||
|
while(!Obj_IsDeleted(enm) && ObjMove_GetY(enm) < STG_HEIGHT * 6/7){
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), spd, GetAngleToPlayer(enm), KEV_BALL_LAVENDER, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
Shoot1;
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 1..7){
|
||
|
|
||
|
CreateEnemyA(i * STG_WIDTH/7);
|
||
|
|
||
|
if(i != 7){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
ascent(i in 1..7){
|
||
|
|
||
|
CreateEnemyA((7-i) * STG_WIDTH/7);
|
||
|
|
||
|
if(i != 7){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function Wave2(){
|
||
|
|
||
|
int num = FUNC_LERP_ACCEL(W2_fairyNumMin, W2_fairyNumMax, rank/RANK_MAX);
|
||
|
int bulletnum = FUNC_LERP_ACCEL(W2_bulletLineNumMin, W2_bulletLineNumMax, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(W2_bulletDelayMax, W2_bulletDelayMin, rank/RANK_MAX);
|
||
|
int spawndel = FUNC_LERP_ACCEL(W2_spawnDelayMax, W2_spawnDelayMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(W2_bulletSpdMin, W2_bulletSpdMax, rank/RANK_MAX);
|
||
|
float movespd = baseMoveSpeedM * (1 + MoveSpeedRankMultiplierL*rank);
|
||
|
float range = FUNC_LERP_ACCEL(W2_rangeMin, W2_rangeMax, rank/RANK_MAX);
|
||
|
|
||
|
task CreateEnemyA(float startX, float startY, float angMove){
|
||
|
|
||
|
int enm = _SmallFairy(
|
||
|
40, del, startX, startY
|
||
|
);
|
||
|
|
||
|
ObjMove_AddPatternA1(enm, 0, movespd, angMove);
|
||
|
|
||
|
while(!Obj_IsDeleted(enm) && ObjMove_GetY(enm) < STG_HEIGHT * 6/7){
|
||
|
|
||
|
float ang = rand(-range, range);
|
||
|
|
||
|
ascent(i in 0..bulletnum){
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), FUNC_LERP_LINEAR(spd, spd/1.65, i/bulletnum), 90+ang, KEV_LEAF_LAVENDER, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 1);
|
||
|
_Delay(bullet, 5);
|
||
|
Shoot2;
|
||
|
|
||
|
}
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 1..num){
|
||
|
|
||
|
CreateEnemyA(-128, STG_HEIGHT/8 + i * (STG_HEIGHT/16), 0);
|
||
|
CreateEnemyA(STG_WIDTH + 128, STG_HEIGHT/8 + i * (STG_HEIGHT/16), 180);
|
||
|
|
||
|
if(i != num){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
function Wave3(){
|
||
|
|
||
|
int linenum = FUNC_LERP_LINEAR(W3_bulletLineNumMin, W3_bulletLineNumMax, rank/RANK_MAX);
|
||
|
int dense = FUNC_LERP_LINEAR(W3_bulletDenseMin, W3_bulletDenseMax, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(W3_bulletDelayMax, W3_bulletDelayMin, rank/RANK_MAX);
|
||
|
int zakodel = FUNC_LERP_ACCEL(W3_zakospawnDelayMax, W3_zakospawnDelayMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(W3_bulletSpdMin, W3_bulletSpdMax, rank/RANK_MAX);
|
||
|
float movespd = baseMoveSpeed1L * (1 + MoveSpeedRankMultiplierL*rank);
|
||
|
float zakomovespd = baseMoveSpeedVH * (1 + MoveSpeedRankMultiplierL*rank);
|
||
|
float angmovespd =FUNC_LERP_ACCEL(W3_angleMoveSpdMin, W3_angleMoveSpdMax, rank/RANK_MAX);
|
||
|
float startX = [0, STG_WIDTH][GetCommonData("Flying Loops Cleared", 0) % 2];
|
||
|
float[] moveX = [[180, -angmovespd], [0, angmovespd]][GetCommonData("Flying Loops Cleared", 0) % 2];
|
||
|
float angStart = rand(0, 360);
|
||
|
int i = 0;
|
||
|
|
||
|
int enmLarge = _LargeDancer(
|
||
|
40, 90,
|
||
|
startX, -144
|
||
|
);
|
||
|
|
||
|
async{
|
||
|
|
||
|
while(!Obj_IsDeleted(enmLarge)){
|
||
|
|
||
|
ObjMove_SetSpeedY(enmLarge, movespd);
|
||
|
ObjMove_SetX(enmLarge, STG_WIDTH/2 + STG_WIDTH/2 * cos(moveX[0]));
|
||
|
|
||
|
if (ObjMove_GetY(enmLarge) <= FUNC_LERP_LINEAR(144, 48, rank/RANK_MAX)) {ObjEnemy_SetDamageRate(enmLarge, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(enmLarge, 100, 100);}
|
||
|
|
||
|
moveX[0] += moveX[1];
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(!Obj_IsDeleted(enmLarge)){
|
||
|
|
||
|
int shot = CreateFan(enmLarge, 1, KEV_LEAF_LAVENDER, linenum,
|
||
|
angStart+i*1*360/dense, 0, spd/1.25, spd,
|
||
|
0.75,
|
||
|
0, 0,
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
int shot2 = CreateFan(enmLarge, 1, KEV_LEAF_LAVENDER, linenum,
|
||
|
angStart+(180+angStart)+i*(-1)*360/dense, 0, spd/1.25, spd,
|
||
|
0.75,
|
||
|
0, 0,
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
|
||
|
Shoot2;
|
||
|
|
||
|
i++;
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
// FUCK YOU HERE'S SOME ZAKO
|
||
|
|
||
|
task CreateEnemyA(float startX){
|
||
|
|
||
|
int enm = _SmallFairy(
|
||
|
39, zakomovespd*2,
|
||
|
startX, -64
|
||
|
);
|
||
|
|
||
|
ObjMove_AddPatternA1(enm, 0, zakomovespd*1.5, atan2(playerY - (-64), playerX - startX));
|
||
|
|
||
|
async{
|
||
|
while(!Obj_IsDeleted(enm)){
|
||
|
if (ObjMove_GetY(enm) <= 64) {ObjEnemy_SetDamageRate(enm, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(enm, 400, 400);}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while(!Obj_IsDeleted(enm) && ObjMove_GetY(enm) < STG_HEIGHT * 6/7){
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), spd*1.2, GetAngleToPlayer(enm), KEV_BALL_LAVENDER, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
Shoot1;
|
||
|
|
||
|
wait(del*10);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 1..7){
|
||
|
|
||
|
CreateEnemyA(i * STG_WIDTH/7);
|
||
|
|
||
|
if(i != 7){wait(zakodel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 1..7){
|
||
|
|
||
|
CreateEnemyA((7-i) * STG_WIDTH/7);
|
||
|
|
||
|
if(i != 7){wait(zakodel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function Wave4(){
|
||
|
|
||
|
int del = FUNC_LERP_ACCEL(W4_bulletDelayMax, W4_bulletDelayMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(W4_bulletSpdMin, W4_bulletSpdMax, rank/RANK_MAX);
|
||
|
int spawndel = FUNC_LERP_ACCEL(W4_spawnDelayMax, W4_spawnDelayMin, rank/RANK_MAX);
|
||
|
int invin = FUNC_LERP_ACCEL(W4_invinTimeMax, W4_invinTimeMin, rank/RANK_MAX);
|
||
|
float movespd = baseMoveSpeedH * (1 + MoveSpeedRankMultiplierVL*rank);
|
||
|
|
||
|
task CreateEnemyA(float startX){
|
||
|
|
||
|
int enm = _Oni(
|
||
|
41, invin,
|
||
|
startX, -128
|
||
|
);
|
||
|
|
||
|
ObjMove_AddPatternA1(enm, 0, movespd, 90);
|
||
|
|
||
|
while(!Obj_IsDeleted(enm) && ObjMove_GetY(enm) < STG_HEIGHT * 4/5){
|
||
|
|
||
|
if (ObjMove_GetY(enm) <= 128) {ObjEnemy_SetDamageRate(enm, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(enm, 100, 100);}
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), spd, GetAngleToPlayer(enm), KEV_FIRE_PINK, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 1, true, 1);
|
||
|
_Delay(bullet, 5);
|
||
|
Shoot2;
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 1..6){
|
||
|
|
||
|
CreateEnemyA(1.5*STG_WIDTH/8 + 96);
|
||
|
CreateEnemyA(1.5*STG_WIDTH/8 - 96);
|
||
|
|
||
|
if(i != 6){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
ascent(i in 1..6){
|
||
|
|
||
|
CreateEnemyA(6.5*STG_WIDTH/8 - 96);
|
||
|
CreateEnemyA(6.5*STG_WIDTH/8 + 96);
|
||
|
|
||
|
if(i != 6){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
// Witch
|
||
|
|
||
|
function Wave5(){
|
||
|
|
||
|
float acceltime = FUNC_LERP_ACCEL(W5_accelTimeMax, W5_accelTimeMin, rank/RANK_MAX);
|
||
|
float bulletwait = FUNC_LERP_ACCEL(W5_bulletWaitTimeMax, W5_bulletWaitTimeMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(W5_bulletSpdMin, W5_bulletSpdMax, rank/RANK_MAX);
|
||
|
float angrange = FUNC_LERP_ACCEL(W5_angRangeMin, W5_angRangeMax, rank/RANK_MAX);
|
||
|
float del = FUNC_LERP_ACCEL(W5_bulletDelayMax, W5_bulletDelayMin, rank/RANK_MAX);
|
||
|
float spawndel = FUNC_LERP_ACCEL(W4_spawnDelayMax, W4_spawnDelayMin, rank/RANK_MAX);
|
||
|
float movespd = min(baseMoveSpeedVH * (1 + MoveSpeedRankMultiplierH * rank) * 1.2, 18);
|
||
|
|
||
|
task CreateEnemyA(float startX){
|
||
|
|
||
|
float angMove = atan2(playerY - (-96), playerX - startX);
|
||
|
|
||
|
int enm = _SmallWitch(
|
||
|
40, del*20,
|
||
|
startX, -96
|
||
|
);
|
||
|
|
||
|
ObjMove_AddPatternA1(enm, 0, movespd, angMove);
|
||
|
ObjRender_SetAngleZ(enm, angMove);
|
||
|
|
||
|
while(!Obj_IsDeleted(enm) && ObjMove_GetY(enm) < STG_HEIGHT * 1/2){
|
||
|
|
||
|
if (ObjMove_GetY(enm) <= 128) {ObjEnemy_SetDamageRate(enm, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(enm, 100, 100);}
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enm), ObjMove_GetY(enm), 0, angMove+rand(-angrange, angrange), KEV_LEAF_PINK, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 1);
|
||
|
_Delay(bullet, 5);
|
||
|
|
||
|
ObjMove_AddPatternA2(bullet, bulletwait, NO_CHANGE, NO_CHANGE, spd/acceltime, spd, 0);
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ChargeSFX;
|
||
|
|
||
|
ascent(i in 1..7){
|
||
|
|
||
|
CreateEnemyA(i * STG_WIDTH/7);
|
||
|
|
||
|
if(i != 7){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
ChargeSFX;
|
||
|
|
||
|
ascent(i in 1..7){
|
||
|
|
||
|
CreateEnemyA((7-i) * STG_WIDTH/7);
|
||
|
|
||
|
if(i != 7){wait(spawndel);}
|
||
|
else{}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
function Wave6(){
|
||
|
|
||
|
int dense = FUNC_LERP_LINEAR(W6_spiralDenseMin, W6_spiralDenseMax, rank/RANK_MAX);
|
||
|
int del = FUNC_LERP_ACCEL(W6_bulletDelayMax, W6_bulletDelayMin, rank/RANK_MAX);
|
||
|
int zakodel = FUNC_LERP_ACCEL(W6_zakospawnDelayMax, W6_zakospawnDelayMin, rank/RANK_MAX);
|
||
|
int waittime = FUNC_LERP_ACCEL(W6_bulletWaitTimeMax, W6_bulletWaitTimeMin, rank/RANK_MAX);
|
||
|
float spd = FUNC_LERP_ACCEL(W6_bulletSpdMin, W6_bulletSpdMax, rank/RANK_MAX);
|
||
|
float angoff = FUNC_LERP_ACCEL(W6_spiralAngOffsetMax, W6_spiralAngOffsetMin, rank/RANK_MAX);
|
||
|
float movespd = baseMoveSpeedM * (1 + MoveSpeedRankMultiplierL*rank);
|
||
|
float zakomovespd = baseMoveSpeedVH * (1 + MoveSpeedRankMultiplierL*rank);
|
||
|
float space = FUNC_LERP_ACCEL(W6_angRangeMin, W6_angRangeMax, rank/RANK_MAX);
|
||
|
int bulletnum = FUNC_LERP_LINEAR(W6_bulletNumMin, W6_bulletNumMax, rank/RANK_MAX);
|
||
|
float angStart = rand(0, 360);
|
||
|
int i = 0;
|
||
|
|
||
|
int enmLarge = _LargeWitch(
|
||
|
40, 90,
|
||
|
playerX, -144
|
||
|
);
|
||
|
|
||
|
async{
|
||
|
|
||
|
ObjMove_AddPatternA1(enmLarge, 0, movespd, 90);
|
||
|
|
||
|
while(!Obj_IsDeleted(enmLarge)){
|
||
|
|
||
|
if (ObjMove_GetY(enmLarge) <= FUNC_LERP_LINEAR(144, 48, rank/RANK_MAX)) {ObjEnemy_SetDamageRate(enmLarge, 15, 15);}
|
||
|
else {ObjEnemy_SetDamageRate(enmLarge, 100, 100);}
|
||
|
|
||
|
yield;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
while(!Obj_IsDeleted(enmLarge) && ObjMove_GetY(enmLarge) <= STG_HEIGHT * 7/8){
|
||
|
|
||
|
ascent(i in 0..dense){
|
||
|
|
||
|
int bullet = CreateShotA1(ObjMove_GetX(enmLarge) + 64 * cos(angStart + i * 360/dense), ObjMove_GetY(enmLarge) + 64 * sin(angStart + i * 360/dense), 0, angStart + i * 360/dense, KEV_LEAF_PINK, 5);
|
||
|
|
||
|
_BulletRescale(bullet, 0.75, true, 0.25);
|
||
|
_Delay(bullet, 5);
|
||
|
ObjMove_AddPatternA2(bullet, waittime, NO_CHANGE, NO_CHANGE, spd/waittime, spd, 0);
|
||
|
|
||
|
}
|
||
|
|
||
|
angStart += angoff;
|
||
|
|
||
|
Shoot2;
|
||
|
|
||
|
wait(del);
|
||
|
|
||
|
}
|
||
|
|
||
|
task CreateEnemyA(float startX){
|
||
|
|
||
|
float time = waittime/2;
|
||
|
|
||
|
int enm = _Oni(
|
||
|
39, waittime*1.5,
|
||
|
startX, -64
|
||
|
);
|
||
|
|
||
|
ObjEnemy_SetDamageRate(enm, 0, 0);
|
||
|
ObjMove_SetDestAtFrame(enm, startX, STG_HEIGHT * 1/8, time, LERP_DECELERATE);
|
||
|
|
||
|
wait(time-1);
|
||
|
|
||
|
ObjMove_AddPatternA2(enm, time, NO_CHANGE, 90, zakomovespd/waittime, zakomovespd, 0);
|
||
|
|
||
|
async{
|
||
|
while(!Obj_IsDeleted(enm)){
|
||
|
if (ObjMove_GetY(enm) <= 0) {ObjEnemy_SetDamageRate(enm, 0, 0);}
|
||
|
else {ObjEnemy_SetDamageRate(enm, 200, 200);}
|
||
|
yield;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while(!Obj_IsDeleted(enm) && ObjMove_GetY(enm) < STG_HEIGHT * 6/7){
|
||
|
|
||
|
CreateFan(
|
||
|
enm, bulletnum, KEV_FIRE_PINK, 1,
|
||
|
GetAngleToPlayer(enm), space, spd*1.25, spd*1.25/1.5, 1,
|
||
|
0, 0,
|
||
|
PATTERN_FAN, false
|
||
|
);
|
||
|
|
||
|
wait(del*999);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ascent(i in 1..8){
|
||
|
|
||
|
CreateEnemyA(i * STG_WIDTH/8);
|
||
|
|
||
|
}
|
||
|
|
||
|
wait(waittime/2);
|
||
|
|
||
|
while(length(enmFly) > 1){yield;}
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
task _EndShake(shaketime, intensity){
|
||
|
|
||
|
float baseintensity = intensity;
|
||
|
float shakeno = shaketime;
|
||
|
|
||
|
ascent(i in 0..shakeno){
|
||
|
Set2DCameraFocusX(GetStgFrameWidth/2 + rand(-intensity, intensity));
|
||
|
Set2DCameraFocusY(GetStgFrameHeight/2 + rand(-intensity, intensity));
|
||
|
intensity = Interpolate_Decelerate(0, baseintensity, 1-i/shakeno);
|
||
|
shaketime--;
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
while(shaketime > 0){yield;}
|
||
|
|
||
|
Set2DCameraFocusX(GetStgFrameWidth/2);
|
||
|
Set2DCameraFocusY(GetStgFrameHeight/2);
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
task _ObjShake(objID, shaketime, intensity){
|
||
|
|
||
|
float baseX = ObjMove_GetX(objID);
|
||
|
float baseY = ObjMove_GetY(objID);
|
||
|
float baseintensity = intensity;
|
||
|
float shakeno = shaketime;
|
||
|
|
||
|
ascent(i in 0..shakeno){
|
||
|
ObjMove_SetPosition(objID, baseX + rand(-intensity, intensity), baseY + rand(-intensity, intensity)/2);
|
||
|
intensity = Interpolate_Decelerate(0, baseintensity, 1-i/shakeno);
|
||
|
shaketime--;
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
while(shaketime > 0){yield;}
|
||
|
|
||
|
ObjMove_SetPosition(objID, baseX, baseY);
|
||
|
|
||
|
yield;
|
||
|
}
|
||
|
|
||
|
|