#TouhouDanmakufu[Single] #ScriptVersion[3] #Title["the fruit of your labors, part 1"] #Text["ayyy lmao"] // Declaring variables // Boss positions + Boss graphic + Shot sheet let bossObj; let bossX = 0; //These are important let bossY = 0; //Animation frames let aniframe = 0; let aniframe2 = 0; let imgBoss = "script/basic4/sprite/enm_yuyuko.png"; let angleO = 90; let wintery = "script/basic4/sprite/cardbg3.png"; let sakura = "script/basic4/sprite/cardbg4.png"; let spellSFX = "script/basic4/sounds/cardstart.wav"; let bossdefeatSFX = "script/basic4/sounds/bossdie.wav"; #include "script/default_system/Default_ShotConst.txt" // Shot sheet goes here, include DOES NOT include semicolon #include "script/default_system/Default_Effect.txt" // Hell @Initialize { // Auto-delete objects when script ends SetAutoDeleteObject(true); // Define a bossObj is boss, register into script bossObj = ObjEnemy_Create(OBJ_ENEMY_BOSS); ObjEnemy_Regist(bossObj); // Start position OUTSIDE playing bounds ObjMove_SetPosition(bossObj,192,-100); // Moving boss to x, y location at speed ObjMove_SetDestAtSpeed(bossObj,192,120,4); // Load sounds LoadSound(spellSFX); LoadSound(bossdefeatSFX); //Play sounds PlaySE(spellSFX); mainTask; } @Event { // Setting boss timer and life alternative(GetEventType()) case(EV_REQUEST_LIFE) { SetScriptResult(2500); } case(EV_REQUEST_TIMER) { SetScriptResult(30); } case(EV_REQUEST_SPELL_SCORE) { SetScriptResult(2500000); } } //MainLoop - everything always happens, all the time @MainLoop { bossX = ObjMove_GetX(bossObj); bossY = ObjMove_GetY(bossObj); //The boss position is ALWAYS UPDATED // Collision for the shots and player ObjEnemy_SetIntersectionCircleToShot(bossObj, bossX, bossY, 36); ObjEnemy_SetIntersectionCircleToShot(bossObj, bossX, bossY, 18); yield; // yielding mainloop tells the script to "look for other tasks" to perform } @Finalize { } //Creating functions for simplicity function wait(w) {loop(w) {yield;}} task mainTask { renderBoss; render; BossMove; ending; shotyeet; } // NEW : BACKGROUNDS AND SPELL OVERLAYS // Note : textures are objects task render { let scrollTex = 0; // BG let bgObj = ObjPrim_Create(OBJ_SPRITE_2D); // NOTE : Obj_SetRenderPriorityI DIFFERENT FROM Obj_SetRenderPriority Obj_SetRenderPriorityI(bgObj,20); ObjPrim_SetTexture(bgObj,wintery); ObjSprite2D_SetSourceRect(bgObj,0,0,512,512); ObjSprite2D_SetDestRect(bgObj,0,0,GetStgFrameWidth,GetStgFrameHeight); // SPELL BG let spellObj = ObjPrim_Create(OBJ_SPRITE_2D); // RENDER PRIORITY NOTICE : OVERLAY ABOVE BG Obj_SetRenderPriorityI(spellObj,21); ObjPrim_SetTexture(spellObj,sakura); ObjRender_SetBlendType(spellObj,BLEND_ADD_ARGB); // Blending option : ADDITIVE + Alpha + RGB (opacity + glow) ObjRender_SetAlpha(spellObj,240); ObjSprite2D_SetSourceRect(spellObj,0,0,1024,1024); ObjSprite2D_SetDestRect(spellObj,0,0,GetStgFrameWidth,GetStgFrameHeight); // Scroll overlay while boss is alive while(!Obj_IsDeleted(bossObj)){ ObjSprite2D_SetSourceRect(spellObj,0-scrollTex,0-scrollTex,1024-scrollTex,1024-scrollTex); scrollTex+=1; yield; } Obj_Delete(spellObj); } task fire { let playerdir; let newdir; playerdir = GetAngleToPlayer(bossObj); CreateShotA1(bossX,bossY,5,playerdir+10,55,5); CreateShotA1(bossX,bossY,5,playerdir+5,55,5); CreateShotA1(bossX,bossY,5,playerdir,55,5); CreateShotA1(bossX,bossY,5,playerdir-5,55,5); CreateShotA1(bossX,bossY,5,playerdir-10,55,5); newdir = playerdir-15; wait(5); loop(40){ CreateShotA1(bossX,bossY,5,newdir+10,55,5); CreateShotA1(bossX,bossY,5,newdir+5,55,5); CreateShotA1(bossX,bossY,5,newdir,55,5); CreateShotA1(bossX,bossY,5,newdir-5,55,5); CreateShotA1(bossX,bossY,5,newdir-10,55,5); newdir = newdir-15; wait(5); } } task renderBoss { // Declare local variables, used for this task only let dir; let speed; // Moved from @Initialize // Giving the bossObj a "texture" ObjPrim_SetTexture(bossObj, imgBoss); // Which part to render -> remember to base this on the sprite itself ObjSprite2D_SetSourceRect(bossObj,0,0,128,128); // Moving our boss around from "true centre" ObjSprite2D_SetDestCenter(bossObj); // Scaling the boss sprite ObjRender_SetScaleXYZ(bossObj,1.2,1.2,0); // While the boss is not defeated yet while (!Obj_IsDeleted(bossObj)){ // "!" mark means "OPPOSITE of whatever comes next, meaning overall : While boss is NOT DELETED" // Update boss speed/direction dir = ObjMove_GetAngle(bossObj); speed = ObjMove_GetSpeed(bossObj); // Actual code for animation handling // Idle animation if(speed == 0){ ObjRender_SetAngleXYZ(bossObj,0,0,0); // if (aniframe....) -> IF the aniframe is this value, SHOW this sprite image if (aniframe < 15){ObjSprite2D_SetSourceRect(bossObj,0,0,128,128);} if (aniframe >= 15 && aniframe < 30){ObjSprite2D_SetSourceRect(bossObj,0,128,128,256);} if (aniframe >= 30 && aniframe < 45){ObjSprite2D_SetSourceRect(bossObj,0,256,128,384);} if (aniframe >= 45){ObjSprite2D_SetSourceRect(bossObj,128,128,256,256);} } // Left/Right animation else if (cos(dir)<0){ aniframe2=0; aniframe2+=2; if(aniframe2 > 60){aniframe2 = 15;} ObjRender_SetAngleXYZ(bossObj,0,0,0); if (aniframe2 < 15){ObjSprite2D_SetSourceRect(bossObj,256,0,384,128);} if (aniframe2 >= 15){ObjSprite2D_SetSourceRect(bossObj,256,128,384,256);} } else if (cos(dir)>0){ aniframe2=0; aniframe2+=2; if(aniframe2 > 60){aniframe2 = 15;} ObjRender_SetAngleXYZ(bossObj,0,0,0); if (aniframe2 < 15){ObjSprite2D_SetSourceRect(bossObj,256,256,384,384);} if (aniframe2 >= 15){ObjSprite2D_SetSourceRect(bossObj,256,384,384,512);} } //Counting aniframe - ++ = up 1 per frame aniframe+=2; //Resetting aniframe if over predefined value if(aniframe > 60){aniframe = 0;} // These two code lines above will ensure the idle loop. yield; } } task BossMove{ wait(60); fire; wait(250); loop{ while(ObjEnemy_GetInfo(bossObj,INFO_LIFE)<=0){return;} ObjMove_SetDestAtSpeed(bossObj,rand(10,280),bossY,3); wait(30); fire; wait(250); yield; } } task ending{ // While the boss is still alive, keep yielding (script works normally) while(ObjEnemy_GetInfo(bossObj,INFO_LIFE)>0){ yield; } DeleteShotAll(TYPE_ALL,TYPE_ITEM); PlaySE(bossdefeatSFX); TExplosionA(bossX,bossY,10,0.5); wait(120); PlaySE(bossdefeatSFX); Obj_Delete(bossObj); TExplosionA(bossX,bossY,10,0.5); wait(120); CloseScript(GetOwnScriptID); } // I SPENT TWO DAYS TO FIGURE THIS OUT LMAO task shotyeet{ while(ObjEnemy_GetInfo(bossObj,INFO_LIFE)>0){ yield; } loop{ DeleteShotAll(TYPE_ALL,TYPE_ITEM); yield; } }