2022-08-21 04:08:54 +00:00
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Remilia Spell 1 (Remilia Card)"]
#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:
- Remilia wait time
- Spiral density
- Spiral angle offset per frame
- Ring density
- Ring (max) speed
- Delays between rings
*/
2022-08-22 10:14:18 +00:00
int[] denseSpiral = [6, 7, 8];
float[] angleoffsetSpiral = [1.618*7, 1.618*6, 1.618*5];
float[] speedSpiral = [8, 9.25, 11];
2022-08-21 04:08:54 +00:00
int[] denseRing = [10, 12, 14];
2022-08-22 10:14:18 +00:00
float[] maxspeedRing = [7.5, 8.5, 10];
int[] deceltimeRing = [20, 25, 32];
int[] acceltimeRing = [60, 50, 40];
2022-08-21 04:08:54 +00:00
// Remilia takes 36 frames. Preferably, pick a number 36 can divide with.
int[] delayRing = [9, 6, 5];
// How much time Remilia takes to charge her attack and you get to GTFO.
2022-08-22 10:14:18 +00:00
int[] waittimeRemi = [80, 70, 60];
2022-08-21 04:08:54 +00:00
string tex = "script/game/resourceLib/Spritesheet_StationJam.png";
2022-08-22 10:14:18 +00:00
//LoadTextureEx(tex, true, false);
2022-08-21 04:08:54 +00:00
// Includes ahoy
#include "script/KevinSystem/Universal_Lib.txt" // The library to include all libraries :sans: :nail_care:
@Initialize {
//SetIntersectionVisualization(true);
SetAutoDeleteObject(true);
2022-08-22 10:14:18 +00:00
LoadTextureEx(tex, true, false);
2022-08-21 04:08:54 +00:00
_InitDifficulty(difficultySelect);
2022-08-22 10:14:18 +00:00
//difficultySelect = 2; // debug
2022-08-21 04:08:54 +00:00
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);
//WriteLog(spellPIV);
WriteLog(ObjEnemyBossScene_GetInfo(objScene, INFO_SPELL_SCORE));
mainTask();
_FadeInvincibility(bossObj, 150, 150, 1);
endingnew();
}
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(4000);
}
case(EV_REQUEST_TIMER) {
SetScriptResult(40);
}
}
@MainLoop {
playerY = GetPlayerY();
playerX = GetPlayerX();
//The player position is ALWAYS UPDATED
bossX = ObjMove_GetX(bossObj);
bossY = ObjMove_GetY(bossObj);
2022-08-22 10:14:18 +00:00
ObjEnemy_SetIntersectionCircleToShot(bossObj, ObjMove_GetX(bossObj), ObjMove_GetY(bossObj), 180);
2022-08-21 04:08:54 +00:00
yield;
}
@Finalize {
}
/*
Remi Spell 1
Remi moves to your current position (takes 36 frames), fires a dense star of stars (lol) that fades away quickly, and waits a set number of frames before repeating. After 3 waves of this, she moves to the middle and shoots a thick spiral of fireballs that requires you to spin around the screen for a bit.
She also leaves behind trails of rings with every dash.
Remilia takes 36 frames to move to you each time. -> delay between rings: 9, 6, 5
Parameters:
- Remilia wait time
- Spiral density
- Spiral speed
- Spiral angle offset per frame
- Ring density
- Ring speed
- Delays between rings
*/
task mainTask {
2022-08-22 10:14:18 +00:00
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 <void> _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);
2022-08-21 04:08:54 +00:00
}
function <void> _VampireChase(){
2022-08-22 10:14:18 +00:00
float chaseX = playerX;
float chaseY = playerY;
2022-08-21 04:08:54 +00:00
2022-08-22 10:14:18 +00:00
ChargeSFX;
2022-08-21 04:08:54 +00:00
2022-08-22 10:14:18 +00:00
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);
2022-08-21 04:08:54 +00:00
2022-08-22 10:14:18 +00:00
loop(36/delayRing){
2022-08-21 04:08:54 +00:00
ascent(i in 0..denseRing[difficultySelect]){
2022-08-22 10:14:18 +00:00
int shot = CreateShotA2(bossX, bossY, maxspeedRing[difficultySelect], ang + 360/denseRing[difficultySelect] * i, -maxspeedRing[difficultySelect]/deceltimeRing[difficultySelect], 0, 0, KEV_AURABALL_RED, 10);
2022-08-21 04:08:54 +00:00
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);
2022-08-22 10:14:18 +00:00
_BulletRescale(shot, 0.6, true, 1);
Shoot2;
2022-08-21 04:08:54 +00:00
}
}
2022-08-22 10:14:18 +00:00
ang += 18;
2022-08-21 04:08:54 +00:00
wait(delayRing);
}
2022-08-22 10:14:18 +00:00
//wait(36);
// BOOM
_FireExplosion(bossObj);
wait(waittimeRemi[difficultySelect]);
}
function <void> 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);
2022-08-21 04:08:54 +00:00
}
task endingnew(){
while(ObjEnemy_GetInfo(bossObj, INFO_LIFE)>0){
yield;
}
_GoToBrazil(objScene, bossObj, 12, 24);
wait(120);
ObjSound_SetVolumeRate(fire2, 20);
CloseScript(GetOwnScriptID);
}