Path: blob/master/SonicMania/Objects/MSZ/HeavyMystic.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: HeavyMystic Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectHeavyMystic *HeavyMystic;1011void HeavyMystic_Update(void)12{13RSDK_THIS(HeavyMystic);1415if (self->invincibilityTimer > 0)16self->invincibilityTimer--;1718if (self->particleFXTimer) {19self->particleFXTimer--;20HeavyMystic_HandleParticleFX();21}2223StateMachine_Run(self->state);2425self->position.x += TornadoPath->moveVel.x;26self->position.y += TornadoPath->moveVel.y;27}2829void HeavyMystic_LateUpdate(void) {}3031void HeavyMystic_StaticUpdate(void)32{33foreach_active(HeavyMystic, mysticBox)34{35if (mysticBox->type == MYSTIC_BOX) {36RSDK.AddDrawListRef(Zone->objectDrawGroup[1], RSDK.GetEntitySlot(mysticBox));37}38}39}4041void HeavyMystic_Draw(void)42{43RSDK_THIS(HeavyMystic);4445if (self->stateDraw) {46StateMachine_Run(self->stateDraw);47}48else {49if (self->invincibilityTimer & 1)50RSDK.SetPaletteEntry(0, 158, 0xE0E0E0);5152RSDK.DrawSprite(&self->animator, NULL, false);5354RSDK.SetPaletteEntry(0, 158, 0x000000);55}56}5758void HeavyMystic_Create(void *data)59{60RSDK_THIS(HeavyMystic);6162if (!SceneInfo->inEditor) {63if (globals->gameMode < MODE_TIMEATTACK) {64self->updateRange.x = 0x800000;65self->updateRange.y = 0x800000;6667if (data)68self->type = VOID_TO_INT(data);6970switch (self->type) {71case MYSTIC_MISCHIEF:72self->active = ACTIVE_BOUNDS;73self->visible = false;74self->drawGroup = Zone->objectDrawGroup[0] + 2;75self->drawFX = FX_FLIP;76self->health = 6;7778RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);7980self->state = HeavyMystic_StateMischief_Setup;81break;8283case MYSTIC_BOSS:84if (globals->gameMode >= MODE_TIMEATTACK) {85destroyEntity(self);86}87else {88self->active = ACTIVE_BOUNDS;89self->visible = false;90self->drawGroup = Zone->objectDrawGroup[0] + 1;91self->drawFX = FX_FLIP;9293self->hitbox.left = -22;94self->hitbox.top = -22;95self->hitbox.right = 22;96self->hitbox.bottom = 22;9798self->health = 8;99HeavyMystic->curtainLinePos = 0xD00000;100101RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);102self->state = HeavyMystic_StateBoss_SetupArena;103}104break;105106case MYSTIC_BOX:107if (globals->gameMode >= MODE_TIMEATTACK) {108destroyEntity(self);109}110else {111self->scale.x = 0x200;112self->scale.y = 0x200;113self->active = ACTIVE_BOUNDS;114self->visible = true;115self->drawGroup = Zone->objectDrawGroup[0];116self->targetPos = self->position;117self->drawFX = FX_SCALE | FX_ROTATE | FX_FLIP;118119RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 10, &self->animator, true, 0);120self->state = HeavyMystic_StateBox_AwaitCurtainRise;121self->stateDraw = HeavyMystic_Draw_BoxOpened;122}123break;124125case MYSTIC_CORK:126self->active = ACTIVE_NORMAL;127self->visible = true;128self->drawGroup = Zone->objectDrawGroup[0];129self->drawFX = FX_FLIP;130131RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 4, &self->animator, true, 0);132self->state = HeavyMystic_StateCork_Fired;133134self->hitbox.left = -3;135self->hitbox.top = -3;136self->hitbox.right = 3;137self->hitbox.bottom = 3;138break;139140case MYSTIC_BOMB:141self->active = ACTIVE_NORMAL;142self->visible = true;143self->drawGroup = Zone->objectDrawGroup[0];144self->drawFX = FX_FLIP;145146RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 11, &self->animator, true, 0);147self->state = HeavyMystic_State_Bomb;148149self->hitbox.left = -8;150self->hitbox.top = -8;151self->hitbox.right = 8;152self->hitbox.bottom = 8;153break;154155case MYSTIC_DEBRIS:156self->active = ACTIVE_NORMAL;157self->visible = true;158self->drawGroup = Zone->objectDrawGroup[0];159self->drawFX = FX_FLIP;160161RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 16, &self->animator, true, 0);162self->state = HeavyMystic_State_BarkDebris;163164self->hitbox.left = -8;165self->hitbox.top = -8;166self->hitbox.right = 8;167self->hitbox.bottom = 8;168break;169170default: break;171}172}173else {174destroyEntity(self);175}176}177}178179void HeavyMystic_StageLoad(void)180{181HeavyMystic->aniFrames = RSDK.LoadSpriteAnimation("MSZ/HeavyMystic.bin", SCOPE_STAGE);182HeavyMystic->roguesFrames = RSDK.LoadSpriteAnimation("MSZ/Rogues.bin", SCOPE_STAGE);183184HeavyMystic->active = ACTIVE_ALWAYS;185HeavyMystic->curtainLinePos = 0;186187HeavyMystic->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");188HeavyMystic->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");189HeavyMystic->sfxMagicBox = RSDK.GetSfx("MSZ/MagicBox.wav");190HeavyMystic->sfxClack = RSDK.GetSfx("Stage/Clack.wav");191HeavyMystic->sfxImpact = RSDK.GetSfx("Stage/Impact3.wav");192HeavyMystic->sfxPowerDown = RSDK.GetSfx("Stage/PowerDown.wav");193HeavyMystic->sfxPon = RSDK.GetSfx("Stage/Pon.wav");194HeavyMystic->sfxDrop = RSDK.GetSfx("Stage/Drop.wav");195HeavyMystic->sfxImpact2 = RSDK.GetSfx("Stage/Impact3.wav");196HeavyMystic->sfxAssemble = RSDK.GetSfx("Stage/Assemble.wav");197HeavyMystic->sfxPoof = RSDK.GetSfx("MSZ/MysticPoof.wav");198HeavyMystic->sfxTwinkle = RSDK.GetSfx("MSZ/MysticTwinkle.wav");199HeavyMystic->sfxHat = RSDK.GetSfx("MSZ/MysticHat.wav");200HeavyMystic->sfxHatNode = RSDK.GetSfx("MSZ/MysticHatNode.wav");201HeavyMystic->sfxBleeps = RSDK.GetSfx("MSZ/MysticBleeps.wav");202HeavyMystic->sfxAppear1 = RSDK.GetSfx("MSZ/MysticAppearAct1.wav");203HeavyMystic->sfxTransform = RSDK.GetSfx("MSZ/MysticTransform.wav");204}205206void HeavyMystic_SpawnParticleFX(int32 x, int32 y)207{208int32 velX = RSDK.Rand(-0xC000, 0xC000);209int32 velY = RSDK.Rand(-0xC000, 0xC000);210211EntityDebris *particles = CREATE_ENTITY(Debris, Debris_State_Move, x, y);212particles->drawGroup = Zone->objectDrawGroup[0];213particles->drawFX = FX_FLIP;214particles->direction = RSDK.Rand(0, 4);215particles->velocity.x = velX;216particles->velocity.y = velY;217particles->inkEffect = INK_SUB;218particles->alpha = 0xE0;219RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, RSDK.Rand(0, 2) + 5, &particles->animator, true, 0);220particles->timer = 3 * particles->animator.frameCount;221222particles = CREATE_ENTITY(Debris, Debris_State_Move, x, y);223particles->velocity.x = velX;224particles->velocity.y = velY;225particles->drawGroup = Zone->objectDrawGroup[0];226particles->inkEffect = INK_ADD;227particles->alpha = 0xFF;228RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, RSDK.Rand(0, 2) + 7, &particles->animator, true, 0);229particles->timer = 3 * particles->animator.frameCount;230}231232void HeavyMystic_HandleParticleFX(void)233{234RSDK_THIS(HeavyMystic);235236if (!(Zone->timer & 7)) {237HeavyMystic_SpawnParticleFX(self->position.x + RSDK.Rand(-0x200000, -0x100000), self->position.y + RSDK.Rand(-0x100000, 0));238HeavyMystic_SpawnParticleFX(self->position.x + RSDK.Rand(0x100000, 0x200000), self->position.y + RSDK.Rand(-0x100000, 0));239}240}241242void HeavyMystic_CheckPlayerCollisions(void)243{244RSDK_THIS(HeavyMystic);245246if (!self->particleFXTimer && !self->invincibilityTimer) {247foreach_active(Player, player)248{249if (Player_CheckBadnikTouch(player, self, &self->hitbox) && Player_CheckBossHit(player, self)) {250HeavyMystic_Hit();251foreach_break;252}253}254}255}256257void HeavyMystic_Hit(void)258{259RSDK_THIS(HeavyMystic);260261--self->health;262--self->rogueHealth;263264if (self->health <= 0) {265RSDK.PlaySfx(HeavyMystic->sfxExplosion, false, 255);266self->timer = 120;267SceneInfo->timeEnabled = false;268Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);269self->state = HeavyMystic_StateBoss_Destroyed;270}271else {272self->timer -= 30;273self->invincibilityTimer = 48;274RSDK.PlaySfx(HeavyMystic->sfxHit, false, 255);275}276}277278void HeavyMystic_CheckPlayerCollisions_Fang(void)279{280RSDK_THIS(HeavyMystic);281282if (!self->particleFXTimer) {283if (self->invincibilityTimer > 0)284self->invincibilityTimer--;285286foreach_active(Player, player)287{288if (!self->invincibilityTimer && Player_CheckBadnikTouch(player, self, &self->hitbox) && Player_CheckBossHit(player, self)) {289RSDK.PlaySfx(HeavyMystic->sfxImpact, false, 255);290self->velocity.x = player->position.x < self->position.x ? 0x20000 : -0x20000;291self->velocity.y = -0x40000;292RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 3, &self->animator, true, 0);293self->state = HeavyMystic_StateBoss_RogueHit;294}295}296}297}298299void HeavyMystic_CheckPlayerCollisions_Bark(void)300{301RSDK_THIS(HeavyMystic);302303if (!self->particleFXTimer) {304if (self->invincibilityTimer > 0)305self->invincibilityTimer--;306307foreach_active(Player, player)308{309if (!self->invincibilityTimer && Player_CheckBadnikTouch(player, self, &self->hitbox)) {310#if MANIA_USE_PLUS311312if (self->animator.animationID == ANI_SKID_TURN313&& ((self->direction == FLIP_NONE && player->position.x > self->position.x)314|| (self->direction == FLIP_X && player->position.x < self->position.x))) {315if (!Player_CheckMightyUnspin(player, 0x600, false, &player->uncurlTimer))316Player_Hurt(player, self);317}318else319#endif320if (Player_CheckBossHit(player, self)) {321322RSDK.PlaySfx(HeavyMystic->sfxImpact, false, 255);323324self->velocity.x = player->position.x < self->position.x ? 0x20000 : -0x20000;325self->velocity.y = -0x40000;326RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 15, &self->animator, true, 0);327self->state = HeavyMystic_StateBoss_RogueHit;328}329}330}331}332}333334void HeavyMystic_CheckPlayerCollisions_Bean(void)335{336RSDK_THIS(HeavyMystic);337338if (!self->particleFXTimer) {339340if (self->invincibilityTimer > 0)341self->invincibilityTimer--;342343foreach_active(Player, player)344{345if (!self->invincibilityTimer && Player_CheckBadnikTouch(player, self, &self->hitbox) && Player_CheckBossHit(player, self)) {346RSDK.PlaySfx(HeavyMystic->sfxImpact, false, 255);347348self->velocity.x = player->position.x < self->position.x ? 0x20000 : -0x20000;349self->velocity.y = -0x40000;350RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 9, &self->animator, true, 0);351self->state = HeavyMystic_StateBoss_RogueHit;352}353}354}355}356357void HeavyMystic_Explode(void)358{359RSDK_THIS(HeavyMystic);360361if (!(Zone->timer & 3)) {362RSDK.PlaySfx(UberCaterkiller->sfxExplosion2, false, 255);363364if (!(Zone->timer & 7)) {365int32 x = self->position.x + (RSDK.Rand(-19, 20) << 16);366int32 y = self->position.y + (RSDK.Rand(-24, 25) << 16);367EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y);368explosion->drawGroup = Zone->objectDrawGroup[1] + 2;369}370}371}372373void HeavyMystic_Scanline_Curtains(ScanlineInfo *scanlines)374{375int32 curtainPos = HeavyMystic->curtainLinePos;376int32 moveY = (0x1100000 - curtainPos) >> 6;377int32 max = MAX(curtainPos - 0x400000, 0x100000);378379int32 posY = (ScreenInfo->position.y + 207) << 16;380if (curtainPos > max) {381int32 scanlineID = HeavyMystic->curtainLinePos >> 16;382383for (int32 i = 0; i < ((curtainPos - max - 1) >> 16) + 1; ++i) {384scanlines[scanlineID--].position.y = posY;385posY -= moveY;386}387}388389for (int32 i = HeavyMystic->curtainLinePos >> 16; i < 208; ++i) {390scanlines[i].position.y = 0x6200000;391}392}393394void HeavyMystic_StateMischief_Setup(void)395{396RSDK_THIS(HeavyMystic);397398RSDK.ProcessAnimation(&self->animator);399400if (++self->timer >= 8) {401self->velocity.x = 0x20000;402403// I'd prolly put a position check here too, its not hard to: go into the special stage, then not hit the starpost, doing so causes a softlock404if (StarPost->postIDs[0])405HeavyMystic->curtainLinePos = 1;406407self->targetPos = self->position;408self->position.y += 0xC00000;409self->visible = true;410self->timer = 120;411self->state = HeavyMystic_StateMischief_EnterMystic;412}413}414415void HeavyMystic_StateBoss_SetupArena(void)416{417RSDK_THIS(HeavyMystic);418if (++self->timer >= 8) {419self->timer = 0;420421HeavyMystic->boundsL = (Zone->cameraBoundsL[0] + 64) << 16;422HeavyMystic->boundsR = (Zone->cameraBoundsR[0] - 64) << 16;423HeavyMystic->boundsM = self->position.x;424HeavyMystic->boundsT = (Zone->cameraBoundsT[0] + 48) << 16;425HeavyMystic->boundsB = (Zone->cameraBoundsB[0] - 8) << 16;426427self->state = HeavyMystic_StateBoss_AwaitPlayer;428}429}430431void HeavyMystic_StateBoss_AwaitPlayer(void)432{433RSDK_THIS(HeavyMystic);434435if (self->timer) {436if (++self->timer == 120) {437Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - ScreenInfo->size.y;438MSZSetup_SetBGScrollOrigin(self->position.x + 0x4000000, 0);439440self->position.y += 0x500000;441self->targetPos = self->position;442self->timer = 0;443self->inkEffect = INK_ALPHA;444self->visible = true;445446self->state = HeavyMystic_StateBoss_BeginShow;447RSDK.GetTileLayer(Zone->fgLayer[1])->scanlineCallback = HeavyMystic_Scanline_Curtains;448449foreach_active(MSZSpotlight, spotlight) { spotlight->state = MSZSpotlight_State_Appear; }450}451}452else {453if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.y > self->position.y) {454Music_TransitionTrack(TRACK_HBHBOSS, 0.0125);455456Zone->playerBoundActiveL[0] = true;457Zone->playerBoundActiveR[0] = true;458459Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;460Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;461Zone->cameraBoundsB[0] = (self->position.y >> 16) + 256;462463++self->timer;464self->active = ACTIVE_NORMAL;465}466}467}468469void HeavyMystic_StateMischief_EnterMystic(void)470{471RSDK_THIS(HeavyMystic);472473RSDK.ProcessAnimation(&self->animator);474HeavyMystic_HandleParticleFX();475476if (self->timer > 0) {477self->timer--;478}479else {480self->velocity.y -= 0x1800;481self->position.x += self->velocity.x;482self->position.y += self->velocity.y;483}484485if (self->timer == 50)486RSDK.PlaySfx(HeavyMystic->sfxAppear1, false, 255);487488if (self->position.y <= self->targetPos.y)489self->state = HeavyMystic_StateMischief_HandleAppearArc;490}491492void HeavyMystic_StateMischief_HandleAppearArc(void)493{494RSDK_THIS(HeavyMystic);495496RSDK.ProcessAnimation(&self->animator);497498HeavyMystic_HandleParticleFX();499500self->velocity.y += 0x3800;501self->position.x += self->velocity.x;502self->position.y += self->velocity.y;503504if (self->position.y >= self->targetPos.y) {505self->velocity.x = 0;506self->velocity.y = 0;507self->position.y = self->targetPos.y;508509RSDK.PlaySfx(HeavyMystic->sfxBleeps, false, 255);510self->state = HeavyMystic_StateMischief_MoveIntoPlace;511}512}513514void HeavyMystic_StateBoss_BeginShow(void)515{516RSDK_THIS(HeavyMystic);517518if (self->alpha > 0xC0)519HeavyMystic_HandleParticleFX();520521#if MANIA_USE_PLUS522if (SceneInfo->filter & FILTER_ENCORE) {523if (self->timer < 256) {524self->timer += 3;525RSDK.SetLimitedFade(0, 1, 5, self->timer, 128, 255);526}527}528#endif529530if (HeavyMystic->curtainLinePos <= 0x100000) {531self->timer = 0;532self->inkEffect = INK_NONE;533self->state = HeavyMystic_StateBoss_AwaitBoxOpened;534}535else {536HeavyMystic->curtainLinePos -= 0x20000;537}538}539540void HeavyMystic_StateMischief_Idle(void)541{542RSDK_THIS(HeavyMystic);543544RSDK.ProcessAnimation(&self->animator);545546self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);547548HeavyMystic_HandleParticleFX();549HeavyMystic_HandleParticleFX();550}551552void HeavyMystic_StateMischief_MoveIntoPlace(void)553{554RSDK_THIS(HeavyMystic);555556RSDK.ProcessAnimation(&self->animator);557self->position.x += 0x8000;558559self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);560561HeavyMystic_HandleParticleFX();562HeavyMystic_HandleParticleFX();563564if (++self->timer == 90) {565self->timer = 0;566RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 1, &self->animator, true, 0);567RSDK.PlaySfx(HeavyMystic->sfxHat, false, 255);568self->state = HeavyMystic_StateMischief_GoodDay;569}570}571572void HeavyMystic_StateMischief_FinishedMagicTrick(void)573{574RSDK_THIS(HeavyMystic);575576self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);577578RSDK.ProcessAnimation(&self->animator);579580HeavyMystic_HandleParticleFX();581HeavyMystic_HandleParticleFX();582583if (++self->timer == 60) {584self->timer = 0;585586RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 3, &self->animator, true, 0);587RSDK.PlaySfx(HeavyMystic->sfxTransform, false, 255);588self->state = HeavyMystic_StateMischief_Disappear;589}590}591592void HeavyMystic_StateMischief_PrepareMagicTrick(void)593{594RSDK_THIS(HeavyMystic);595596self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);597598RSDK.ProcessAnimation(&self->animator);599600HeavyMystic_HandleParticleFX();601HeavyMystic_HandleParticleFX();602603if (++self->timer == 60) {604if (RSDK.CheckSceneFolder("MSZCutscene")) {605self->state = HeavyMystic_StateMischief_Idle;606}607else {608self->timer = 0;609RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 2, &self->animator, true, 0);610RSDK.PlaySfx(HeavyMystic->sfxHat, false, 255);611self->state = HeavyMystic_StateMischief_ConjureHatterkiller;612}613}614}615616void HeavyMystic_StateMischief_GoodDay(void)617{618RSDK_THIS(HeavyMystic);619620self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);621622RSDK.ProcessAnimation(&self->animator);623624HeavyMystic_HandleParticleFX();625626if (self->animator.frameID == self->animator.frameCount - 1) {627RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);628self->state = HeavyMystic_StateMischief_PrepareMagicTrick;629}630}631632void HeavyMystic_StateMischief_ConjureHatterkiller(void)633{634RSDK_THIS(HeavyMystic);635636self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);637638RSDK.ProcessAnimation(&self->animator);639640HeavyMystic_HandleParticleFX();641642if (self->animator.frameID == 8 && !self->timer) {643RSDK.PlaySfx(HeavyMystic->sfxHatNode, false, 255);644CREATE_ENTITY(Hatterkiller, INT_TO_VOID(RSDK.Rand(-0x20000, 0x20000)), self->position.x + 0x320000, self->position.y);645self->timer = 1;646}647648if (self->animator.frameID == self->animator.frameCount - 1) {649self->timer = 0;650RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);651self->state = HeavyMystic_StateMischief_FinishedMagicTrick;652}653}654655void HeavyMystic_StateMischief_Disappear(void)656{657RSDK_THIS(HeavyMystic);658659RSDK.ProcessAnimation(&self->animator);660661HeavyMystic_HandleParticleFX();662663if (self->animator.frameID == self->animator.frameCount - 1) {664if (!HeavyMystic->curtainLinePos) {665HeavyMystic->curtainLinePos = 1;666667CREATE_ENTITY(Vultron, INT_TO_VOID(VULTRON_TARGET), self->position.x, self->position.y);668CREATE_ENTITY(Vultron, INT_TO_VOID(VULTRON_TARGET), self->position.x, self->position.y);669}670671RSDK.PlaySfx(HeavyMystic->sfxPoof, false, 255);672CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];673674destroyEntity(self);675}676}677678void HeavyMystic_StateBoss_Destroyed(void)679{680RSDK_THIS(HeavyMystic);681682RSDK.ProcessAnimation(&self->animator);683684HeavyMystic_Explode();685686if (--self->timer <= 0) {687self->velocity.y = 0;688RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);689self->state = HeavyMystic_StateBoss_Finish;690}691}692693void HeavyMystic_StateBoss_Finish(void)694{695RSDK_THIS(HeavyMystic);696697RSDK.ProcessAnimation(&self->animator);698699HeavyMystic_HandleParticleFX();700701self->position.y += self->velocity.y;702self->velocity.y -= 0x3800;703704if (!RSDK.CheckOnScreen(self, &self->updateRange)) {705Music_TransitionTrack(TRACK_STAGE, 0.0125);706self->state = HeavyMystic_StateBoss_CloseCurtains;707}708}709710void HeavyMystic_StateBoss_CloseCurtains(void)711{712RSDK_THIS(HeavyMystic);713714#if MANIA_USE_PLUS715if (SceneInfo->filter & FILTER_ENCORE) {716if (self->timer < 256) {717self->timer += 3;718RSDK.SetLimitedFade(0, 5, 1, self->timer, 128, 255);719}720}721#endif722723if (HeavyMystic->curtainLinePos >= 0xD00000) {724HeavyMystic->curtainLinePos = 0xD00000;725726RSDK.GetTileLayer(Zone->fgLayer[1])->scanlineCallback = StateMachine_None;727Zone->cameraBoundsR[0] += WIDE_SCR_XSIZE * 2;728destroyEntity(self);729}730else {731HeavyMystic->curtainLinePos += 0x20000;732}733}734735void HeavyMystic_StateBoss_AwaitBoxOpened(void) {}736737void HeavyMystic_StateBoss_EnterMystic(void)738{739RSDK_THIS(HeavyMystic);740741RSDK.ProcessAnimation(&self->animator);742743self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);744745HeavyMystic_HandleParticleFX();746HeavyMystic_HandleParticleFX();747748if (++self->timer == 45) {749self->timer = 0;750RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 1, &self->animator, true, 0);751self->state = HeavyMystic_StateBoss_GoodDay;752}753}754755void HeavyMystic_StateBoss_GoodDay(void)756{757RSDK_THIS(HeavyMystic);758759self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);760761RSDK.ProcessAnimation(&self->animator);762763HeavyMystic_HandleParticleFX();764765if (self->animator.frameID == self->animator.frameCount - 8)766RSDK.PlaySfx(HeavyMystic->sfxHat, false, 255);767768if (self->animator.frameID == self->animator.frameCount - 1) {769RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);770self->state = HeavyMystic_StateBoss_BoxCloseDelay;771}772}773774void HeavyMystic_StateBoss_BoxCloseDelay(void)775{776RSDK_THIS(HeavyMystic);777778RSDK.ProcessAnimation(&self->animator);779780HeavyMystic_HandleParticleFX();781782self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);783784if (self->angle == 192) {785foreach_active(HeavyMystic, boss)786{787if (boss->type == MYSTIC_BOX)788boss->state = HeavyMystic_StateBox_CloseDoors;789}790791RSDK.PlaySfx(HeavyMystic->sfxClack, false, 255);792self->state = HeavyMystic_StateBoss_AwaitBoxClosing;793}794}795796void HeavyMystic_StateBoss_AwaitBoxClosing(void)797{798RSDK_THIS(HeavyMystic);799800RSDK.ProcessAnimation(&self->animator);801802HeavyMystic_HandleParticleFX();803804self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);805806if (self->angle == 252)807self->state = HeavyMystic_StateBoss_AwaitBoxClosed;808}809810void HeavyMystic_StateBoss_AwaitBoxClosed(void)811{812RSDK_THIS(HeavyMystic);813814if (++self->timer == 60) {815self->timer = 0;816self->visible = false;817818foreach_active(HeavyMystic, boss)819{820if (boss->type == MYSTIC_BOX)821boss->state = HeavyMystic_StateBox_Transforming;822}823824self->state = HeavyMystic_StateBoss_Transforming;825}826}827828void HeavyMystic_StateBoss_Transforming(void)829{830RSDK_THIS(HeavyMystic);831832foreach_active(HeavyMystic, boss)833{834if (boss->type == MYSTIC_BOX && boss->state == HeavyMystic_StateBox_ShowContents) {835self->position = boss->position;836boss->position = boss->targetPos;837self->visible = true;838self->state = HeavyMystic_StateBoss_ShowRogue;839}840}841}842843void HeavyMystic_StateBoss_ShowRogue(void)844{845RSDK_THIS(HeavyMystic);846847self->velocity.x = 0;848self->velocity.y = 0;849self->rogueHealth = 2;850RSDK.PlaySfx(HeavyMystic->sfxTwinkle, false, 255);851852self->velocity.y = -0x40000;853self->particleFXTimer = 75;854switch (self->rogueID) {855case 0: // Fang856case 3: // Fang857RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 2, &self->animator, true, 4);858self->state = HeavyMystic_StateBoss_FangHop;859self->attackID = 8;860break;861862case 1: // Bean863RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 6, &self->animator, true, 3);864self->state = HeavyMystic_StateBoss_BeanJump;865break;866867case 2: // Bark868RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 13, &self->animator, true, 3);869self->state = HeavyMystic_StateBoss_BarkJump;870break;871872default: break;873}874}875876void HeavyMystic_StateBoss_MysticReveal(void)877{878RSDK_THIS(HeavyMystic);879880RSDK.ProcessAnimation(&self->animator);881882self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);883884HeavyMystic_CheckPlayerCollisions();885if (--self->timer <= 0) {886foreach_active(HeavyMystic, boss)887{888if (boss->type == MYSTIC_BOX) {889self->targetPos = boss->position;890}891}892893if (self->rogueHealth > 0) {894RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 3, &self->animator, true, 0);895self->state = HeavyMystic_StateBoss_TransformBackIntoRogue;896}897else {898RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);899self->state = HeavyMystic_StateBoss_MoveToBoxY;900}901}902}903904void HeavyMystic_StateBoss_MoveToBoxY(void)905{906RSDK_THIS(HeavyMystic);907908RSDK.ProcessAnimation(&self->animator);909910HeavyMystic_HandleParticleFX();911912if (self->position.x != self->targetPos.x) {913if (self->position.x <= self->targetPos.x) {914self->position.x += self->velocity.x;915916if (self->position.x > self->targetPos.x)917self->position.x = self->targetPos.x;918else if (self->velocity.x < 0x30000)919self->velocity.x += 0x3800;920}921else {922self->position.x += self->velocity.x;923924if (self->position.x < self->targetPos.x)925self->position.x = self->targetPos.x;926else if (self->velocity.x > -0x30000)927self->velocity.x -= 0x3800;928}929}930931if (self->position.y <= self->targetPos.y) {932self->position.y = self->targetPos.y;933self->angle = 0x80;934935if (self->position.x == self->targetPos.x) {936++self->rogueID;937self->state = HeavyMystic_StateBoss_BoxCloseDelay;938}939else {940self->state = HeavyMystic_StateBoss_MoveToBoxX;941}942}943else {944self->position.y += self->velocity.y;945946if (self->velocity.y > -0x20000)947self->velocity.y -= 0x2000;948}949}950951void HeavyMystic_StateBoss_MoveToBoxX(void)952{953RSDK_THIS(HeavyMystic);954955RSDK.ProcessAnimation(&self->animator);956957HeavyMystic_HandleParticleFX();958959self->position.y = BadnikHelpers_Oscillate(self->targetPos.y, 4, 11);960961if (self->position.x == self->targetPos.x) {962++self->rogueID;963964self->position.y = self->targetPos.y;965self->state = HeavyMystic_StateBoss_BoxCloseDelay;966}967else if (self->position.x > self->targetPos.x) {968self->position.x += self->velocity.x;969970if (self->position.x >= self->targetPos.x) {971if (self->velocity.x > -0x30000)972self->velocity.x -= 0x3800;973}974else975self->position.x = self->targetPos.x;976}977else {978self->position.x += self->velocity.x;979980if (self->position.x > self->targetPos.x)981self->position.x = self->targetPos.x;982else if (self->velocity.x < 0x30000)983self->velocity.x += 0x3800;984}985}986987void HeavyMystic_StateBoss_TransformBackIntoRogue(void)988{989RSDK_THIS(HeavyMystic);990991RSDK.ProcessAnimation(&self->animator);992993HeavyMystic_HandleParticleFX();994995if (self->animator.frameID == self->animator.frameCount - 5)996RSDK.PlaySfx(HeavyMystic->sfxTransform, false, 255);997998if (self->animator.frameID == self->animator.frameCount - 1) {999CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];1000self->velocity.x = 0;1001self->velocity.y = -0x20000;1002RSDK.PlaySfx(HeavyMystic->sfxPoof, false, 255);10031004self->velocity.y = -0x40000;1005self->particleFXTimer = 75;1006switch (self->rogueID) {1007case 0:1008case 3:1009RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 2, &self->animator, true, 4);1010self->state = HeavyMystic_StateBoss_FangHop;1011self->attackID = 8;1012break;10131014case 1:1015RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 6, &self->animator, true, 3);1016self->state = HeavyMystic_StateBoss_BeanJump;1017break;10181019case 2:1020RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 13, &self->animator, true, 3);1021self->state = HeavyMystic_StateBoss_BarkJump;1022break;10231024default: break;1025}1026}1027}10281029void HeavyMystic_StateBoss_FangIdle(void)1030{1031RSDK_THIS(HeavyMystic);10321033EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);10341035RSDK.ProcessAnimation(&self->animator);10361037self->direction = player1->position.x < self->position.x;10381039if (!--self->timer) {1040RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 1, &self->animator, true, 0);1041self->state = HeavyMystic_StateBoss_FangTell;1042}10431044HeavyMystic_CheckPlayerCollisions_Fang();1045}10461047void HeavyMystic_StateBoss_FangTell(void)1048{1049RSDK_THIS(HeavyMystic);10501051RSDK.ProcessAnimation(&self->animator);10521053if (self->animator.frameID == self->animator.frameCount - 1) {1054self->velocity.x = RSDK.Rand(0, 2) != 0 ? -0x10000 : 0x10000;1055self->velocity.y = -0x50000;1056self->attackID = 8;1057RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 2, &self->animator, true, 0);1058self->state = HeavyMystic_StateBoss_FangHop;1059}10601061HeavyMystic_CheckPlayerCollisions_Fang();1062}10631064void HeavyMystic_StateBoss_FangHop(void)1065{1066RSDK_THIS(HeavyMystic);10671068EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);10691070self->direction = player1->position.x < self->position.x;10711072self->position.x += self->velocity.x;1073self->position.y += self->velocity.y;1074self->velocity.y += 0x3800;10751076if (self->velocity.x >= 0) {1077if (self->position.x > (ScreenInfo->position.x + ScreenInfo->size.x - 16) << 16)1078self->velocity.x = -self->velocity.x;1079}1080else {1081if (self->position.x < (ScreenInfo->position.x + 16) << 16)1082self->velocity.x = -self->velocity.x;1083}10841085RSDK.ProcessAnimation(&self->animator);10861087if (self->velocity.y > 0 && RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x140000, true)) {1088if (--self->attackID > 0) {1089self->velocity.y = -0x50000;1090self->velocity.x = RSDK.Rand(0, 2) != 0 ? -0x10000 : 0x10000;1091RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 2, &self->animator, true, 0);1092self->state = HeavyMystic_StateBoss_FangHop;1093}1094else {1095self->timer = 15;1096self->velocity.x = 0;1097self->velocity.y = 0;1098RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 0, &self->animator, true, 0);1099self->state = HeavyMystic_StateBoss_FangIdle;1100}1101}11021103if (self->attackID && !(Zone->timer & 0x3F)) {1104RSDK.PlaySfx(HeavyMystic->sfxPon, false, 255);1105EntityHeavyMystic *cork = CREATE_ENTITY(HeavyMystic, INT_TO_VOID(MYSTIC_CORK), self->position.x, self->position.y - 0x40000);1106if (self->direction == FLIP_NONE) {1107cork->position.x += 0x180000;1108cork->velocity.x = 0x20000;1109cork->direction = self->direction;1110}1111else {1112cork->position.x -= 0x180000;1113cork->velocity.x = -0x20000;1114cork->direction = self->direction;1115}1116}11171118HeavyMystic_CheckPlayerCollisions_Fang();1119}11201121void HeavyMystic_StateBoss_RogueHit(void)1122{1123RSDK_THIS(HeavyMystic);11241125self->position.x += self->velocity.x;1126self->position.y += self->velocity.y;1127self->velocity.y += 0x3800;11281129if (self->velocity.x >= 0) {1130if (self->position.x > (ScreenInfo->position.x + ScreenInfo->size.x - 16) << 16)1131self->velocity.x = 0;1132}1133else {1134if (self->position.x < (ScreenInfo->position.x + 16) << 16)1135self->velocity.x = 0;1136}11371138self->visible ^= true;1139RSDK.ProcessAnimation(&self->animator);11401141if (self->velocity.y > 0) {1142if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x240000, true)) {1143RSDK.PlaySfx(HeavyMystic->sfxPowerDown, false, 255);1144CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];1145self->direction ^= FLIP_X;1146self->timer = 90;1147self->attackID = 0;1148self->visible = true;1149self->targetPos.y = self->position.y;1150self->velocity.x = 0;1151self->velocity.y = 0;1152RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 4, &self->animator, true, 0);1153self->state = HeavyMystic_StateBoss_MysticReveal;1154}1155}1156}11571158void HeavyMystic_StateBoss_BarkIdle(void)1159{1160RSDK_THIS(HeavyMystic);1161EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);11621163RSDK.ProcessAnimation(&self->animator);11641165self->direction = player1->position.x < self->position.x;11661167if (!--self->timer) {1168self->velocity.x = RSDK.Rand(0, 2) != 0 ? -0x10000 : 0x10000;1169self->velocity.y = -0x40000;11701171if (self->attackID == 1) {1172self->timer = 240;1173RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 14, &self->animator, true, 0);1174self->state = HeavyMystic_StateBoss_BarkPounding;1175}1176else {1177self->attackID = 1;1178RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 13, &self->animator, true, 0);1179self->state = HeavyMystic_StateBoss_BarkJump;1180}1181}11821183HeavyMystic_CheckPlayerCollisions_Bark();1184}11851186void HeavyMystic_StateBoss_BarkPounding(void)1187{1188RSDK_THIS(HeavyMystic);11891190RSDK.ProcessAnimation(&self->animator);11911192// check when bark's hand hits the grounds1193if (self->animator.frameID == 3 || self->animator.frameID == 10) {1194if (self->attackID != self->animator.frameID)1195RSDK.PlaySfx(HeavyMystic->sfxImpact2, false, 255);1196self->attackID = self->animator.frameID;1197}11981199if (--self->timer <= 0) {1200self->attackID = 0;1201self->timer = 15;1202self->velocity.x = 0;1203self->velocity.y = 0;1204RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 12, &self->animator, true, 0);1205self->state = HeavyMystic_StateBoss_BarkIdle;1206}12071208if (self->attackID != 1) {1209if (!(Zone->timer & 3))1210Camera_ShakeScreen(0, 0, 2);12111212if (!(Zone->timer & 0xF)) {1213int32 x = ScreenInfo->position.x + 16 + 32 * RSDK.Rand(0, ScreenInfo->size.x >> 5);1214EntityHeavyMystic *debris = CREATE_ENTITY(HeavyMystic, INT_TO_VOID(MYSTIC_DEBRIS), x << 16, (ScreenInfo->position.y - 16) << 16);1215debris->animator.frameID = RSDK.Rand(0, 6);1216}1217}12181219HeavyMystic_CheckPlayerCollisions_Bark();1220}12211222void HeavyMystic_StateBoss_BarkJump(void)1223{1224RSDK_THIS(HeavyMystic);1225EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);12261227self->direction = player1->position.x < self->position.x;12281229self->position.x += self->velocity.x;1230self->position.y += self->velocity.y;1231self->velocity.y += 0x3800;12321233if (self->velocity.x >= 0) {1234if (self->position.x > (ScreenInfo->position.x + ScreenInfo->size.x - 16) << 16)1235self->velocity.x = -self->velocity.x;1236}1237else {1238if (self->position.x < (ScreenInfo->position.x + 16) << 16)1239self->velocity.x = -self->velocity.x;1240}12411242RSDK.ProcessAnimation(&self->animator);12431244if (self->velocity.y > 0 && RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x200000, true)) {1245self->timer = 15;1246RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 12, &self->animator, true, 0);1247self->state = HeavyMystic_StateBoss_BarkIdle;1248}12491250HeavyMystic_CheckPlayerCollisions_Bark();1251}12521253void HeavyMystic_StateBoss_BeanIdle(void)1254{1255RSDK_THIS(HeavyMystic);1256EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);12571258self->direction = player1->position.x < self->position.x;12591260RSDK.ProcessAnimation(&self->animator);12611262if (!--self->timer) {1263self->velocity.x = RSDK.Rand(0, 2) != 0 ? -0x20000 : 0x20000;1264self->velocity.y = -0x68000;12651266if (self->attackID == 1) {1267RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 8, &self->animator, true, 0);1268self->state = HeavyMystic_StateBoss_BeanBomb1Throw;1269}1270else {1271self->attackID = 1;1272RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 6, &self->animator, true, 0);1273self->state = HeavyMystic_StateBoss_BeanJump;1274}1275}12761277HeavyMystic_CheckPlayerCollisions_Bean();1278}12791280void HeavyMystic_StateBoss_BeanBomb1Throw(void)1281{1282RSDK_THIS(HeavyMystic);12831284RSDK.ProcessAnimation(&self->animator);12851286if (self->attackID == 1 && self->animator.frameID == 3) {1287self->attackID = 2;1288RSDK.PlaySfx(HeavyMystic->sfxDrop, false, 255);12891290EntityHeavyMystic *bomb = CREATE_ENTITY(HeavyMystic, INT_TO_VOID(MYSTIC_BOMB), self->position.x, self->position.y + 0x130000);1291if (self->direction) {1292bomb->position.x += 0xB0000;1293bomb->velocity.x = -0x40000;1294}1295else {1296bomb->position.x -= 0xB0000;1297bomb->velocity.x = 0x40000;1298}12991300bomb->velocity.y = -0x40000;1301bomb->direction = self->direction;1302}13031304if (self->animator.frameID == self->animator.frameCount - 1) {1305self->attackID = 1;1306RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 7, &self->animator, true, 0);1307self->state = HeavyMystic_StateBoss_BeanBomb2Throw;1308}13091310HeavyMystic_CheckPlayerCollisions_Bean();1311}13121313void HeavyMystic_StateBoss_BeanBomb2Throw(void)1314{1315RSDK_THIS(HeavyMystic);13161317RSDK.ProcessAnimation(&self->animator);13181319if (self->attackID == 1 && self->animator.frameID == 2) {1320self->attackID = 2;1321RSDK.PlaySfx(HeavyMystic->sfxDrop, false, 255);13221323EntityHeavyMystic *bomb = CREATE_ENTITY(HeavyMystic, INT_TO_VOID(MYSTIC_BOMB), self->position.x, self->position.y - 0x130000);1324if (self->direction) {1325bomb->position.x += 0xB0000;1326bomb->velocity.x = -0x40000;1327}1328else {1329bomb->position.x -= 0xB0000;1330bomb->velocity.x = 0x40000;1331}13321333bomb->velocity.y = -0x40000;1334bomb->direction = self->direction;1335}13361337if (self->animator.frameID == self->animator.frameCount - 1) {1338self->attackID = 0;1339self->timer = 5;1340self->velocity.x = 0;1341self->velocity.y = 0;1342RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 5, &self->animator, true, 0);1343self->state = HeavyMystic_StateBoss_BeanIdle;1344}13451346HeavyMystic_CheckPlayerCollisions_Bean();1347}13481349void HeavyMystic_StateBoss_BeanJump(void)1350{1351RSDK_THIS(HeavyMystic);1352EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);13531354self->direction = player1->position.x < self->position.x;13551356self->position.x += self->velocity.x;1357self->position.y += self->velocity.y;1358self->velocity.y += 0x3800;13591360if (self->velocity.x >= 0) {1361if (self->position.x > (ScreenInfo->position.x + ScreenInfo->size.x - 16) << 16)1362self->velocity.x = -self->velocity.x;1363}1364else {1365if (self->position.x < (ScreenInfo->position.x + 16) << 16)1366self->velocity.x = -self->velocity.x;1367}13681369RSDK.ProcessAnimation(&self->animator);13701371if (self->velocity.y > 0 && RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x140000, true) == true) {1372if (--self->attackID <= 0) {1373self->attackID = 1;1374self->timer = 15;1375self->velocity.x = 0;1376self->velocity.y = 0;1377RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 5, &self->animator, true, 0);1378self->state = HeavyMystic_StateBoss_BeanIdle;1379}1380else {1381self->velocity.y = -0x50000;1382self->velocity.x = RSDK.Rand(0, 2) != 0 ? -0x10000 : 0x10000;1383RSDK.SetSpriteAnimation(HeavyMystic->roguesFrames, 6, &self->animator, true, 0);1384}1385}13861387HeavyMystic_CheckPlayerCollisions_Bean();1388}13891390void HeavyMystic_StateCork_Fired(void)1391{1392RSDK_THIS(HeavyMystic);13931394RSDK.ProcessAnimation(&self->animator);13951396self->position.x += self->velocity.x;13971398foreach_active(Player, player)1399{1400if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {1401#if MANIA_USE_PLUS1402if (Player_CheckMightyShellHit(player, self, -0x300, -0x400))1403self->state = HeavyMystic_StateCork_MightyRebound;1404else1405#endif1406Player_Hurt(player, self);14071408RSDK.PlaySfx(HeavyMystic->sfxExplosion, false, 255);1409CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1] + 2;1410destroyEntity(self);1411foreach_break;1412}1413}14141415if (!RSDK.CheckOnScreen(self, &self->updateRange))1416destroyEntity(self);1417}14181419#if MANIA_USE_PLUS1420void HeavyMystic_StateCork_MightyRebound(void)1421{1422RSDK_THIS(HeavyMystic);14231424self->visible ^= true;14251426RSDK.ProcessAnimation(&self->animator);14271428self->position.x += self->velocity.x;1429self->position.y += self->velocity.y;1430self->velocity.y += 0x3800;14311432if (!RSDK.CheckOnScreen(self, &self->updateRange))1433destroyEntity(self);1434}1435#endif14361437void HeavyMystic_State_Bomb(void)1438{1439RSDK_THIS(HeavyMystic);14401441RSDK.ProcessAnimation(&self->animator);14421443self->position.x += self->velocity.x;1444self->position.y += self->velocity.y;1445self->velocity.y += 0x3800;14461447foreach_active(Player, player)1448{1449if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {1450#if MANIA_USE_PLUS1451if (!Player_CheckMightyUnspin(player, 0x300, false, &player->uncurlTimer))1452#endif1453Player_Hurt(player, self);1454RSDK.PlaySfx(HeavyMystic->sfxExplosion, false, 255);1455CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1] + 2;1456destroyEntity(self);1457foreach_break;1458}1459}14601461if (!RSDK.CheckOnScreen(self, &self->updateRange))1462destroyEntity(self);1463}14641465void HeavyMystic_State_BarkDebris(void)1466{1467RSDK_THIS(HeavyMystic);14681469RSDK.ProcessAnimation(&self->animator);14701471self->position.y += self->velocity.y;1472self->velocity.y += 0x1800;14731474foreach_active(Player, player)1475{1476if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {1477#if MANIA_USE_PLUS1478if (!Player_CheckMightyUnspin(player, 0x300, false, &player->uncurlTimer))1479#endif1480Player_Hurt(player, self);1481}1482}14831484if (!RSDK.CheckOnScreen(self, &self->updateRange))1485destroyEntity(self);1486}14871488void HeavyMystic_StateBox_AwaitCurtainRise(void)1489{1490RSDK_THIS(HeavyMystic);14911492self->timer = 2;1493if (HeavyMystic->curtainLinePos <= 0x100000) {1494self->state = HeavyMystic_StateBox_Idle;1495self->stateDraw = HeavyMystic_Draw_BoxTransforming;1496}1497}14981499void HeavyMystic_StateBox_Idle(void) {}15001501void HeavyMystic_StateBox_CloseDoors(void)1502{1503RSDK_THIS(HeavyMystic);15041505self->scale.x -= 0x20;1506if (self->scale.x <= 0) {1507if (self->timer == 2) {1508foreach_active(HeavyMystic, boss)1509{1510if (boss->state == HeavyMystic_StateBoss_AwaitBoxOpened)1511boss->state = HeavyMystic_StateBoss_EnterMystic;1512}15131514self->timer = 1;1515self->stateDraw = HeavyMystic_Draw_BoxOpened;1516self->state = HeavyMystic_StateBox_OpenDoors;1517}1518else {1519self->timer = 2;1520self->stateDraw = HeavyMystic_Draw_BoxTransforming;1521self->state = HeavyMystic_StateBox_OpenDoors;1522}1523}1524}15251526void HeavyMystic_StateBox_OpenDoors(void)1527{1528RSDK_THIS(HeavyMystic);15291530self->scale.x += 0x20;1531if (self->scale.x >= 0x200)1532self->state = HeavyMystic_StateBox_Idle;1533}15341535void HeavyMystic_StateBox_Transforming(void)1536{1537RSDK_THIS(HeavyMystic);15381539if (!(Zone->timer & 7)) {1540RSDK.PlaySfx(HeavyMystic->sfxMagicBox, false, 255);1541int32 x = self->position.x + (RSDK.Rand(-24, 25) << 16);1542int32 y = self->position.y + (RSDK.Rand(-24, 25) << 16);1543CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), x, y)->drawGroup = Zone->objectDrawGroup[1] + 2;1544}15451546self->scale.x = 0x200 + RSDK.Cos256(self->angle + 0x40);1547self->scale.y = 0x200 + RSDK.Sin256(self->angle);15481549if (self->angle == 0x300) {1550RSDK.StopSfx(HeavyMystic->sfxMagicBox);1551RSDK.PlaySfx(HeavyMystic->sfxPowerDown, false, 255);1552self->angle = 0;1553self->timer = 0;1554self->state = HeavyMystic_StateBox_TransformFinish;1555self->stateDraw = HeavyMystic_Draw_BoxClosed;1556}1557else {1558self->angle += 8;1559}1560}15611562void HeavyMystic_StateBox_TransformFinish(void)1563{1564RSDK_THIS(HeavyMystic);15651566if (++self->timer > 30) {1567RSDK.PlaySfx(HeavyMystic->sfxDrop, false, 255);1568self->state = HeavyMystic_StateBox_Dropping;1569}1570}15711572void HeavyMystic_StateBox_Dropping(void)1573{1574RSDK_THIS(HeavyMystic);15751576self->position.y += self->velocity.y;1577self->velocity.y += 0x2800;15781579if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x280000, true)) {1580Camera_ShakeScreen(0, 0, 6);1581RSDK.PlaySfx(HeavyMystic->sfxImpact2, false, 255);1582RSDK.PlaySfx(HeavyMystic->sfxExplosion, false, 255);15831584EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);1585debris->drawGroup = Zone->objectDrawGroup[0];1586debris->drawFX = FX_FLIP;1587debris->direction = FLIP_NONE;1588debris->velocity.y = -0x40000;1589debris->gravityStrength = 0x2800;1590RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 10, &debris->animator, true, 0);1591debris->animator.frameID = 0;15921593debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x280000, self->position.y);1594debris->drawGroup = Zone->objectDrawGroup[1];1595debris->drawFX = FX_FLIP;1596debris->direction = FLIP_NONE;1597debris->velocity.x = -0x20000;1598debris->velocity.y = -0x40000;1599debris->gravityStrength = 0x2800;1600RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 10, &debris->animator, true, 0);1601debris->animator.frameID = 2;16021603debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x280000, self->position.y);1604debris->drawGroup = Zone->objectDrawGroup[1];1605debris->drawFX = FX_FLIP;1606debris->direction = FLIP_X;1607debris->velocity.x = 0x20000;1608debris->velocity.y = -0x40000;1609debris->gravityStrength = 0x2800;1610RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 10, &debris->animator, true, 0);1611debris->animator.frameID = 2;16121613self->timer = 0;1614self->visible = false;1615self->velocity.y = 0;1616self->state = HeavyMystic_StateBox_ShowContents;1617}1618}16191620void HeavyMystic_StateBox_ShowContents(void)1621{1622RSDK_THIS(HeavyMystic);16231624if (++self->timer > 96) {1625CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1] + 2;1626self->visible = true;1627self->scale.x = 0;1628self->scale.y = 0;1629RSDK.PlaySfx(HeavyMystic->sfxAssemble, false, 255);1630self->stateDraw = HeavyMystic_Draw_BoxClosed;1631self->state = HeavyMystic_StateBox_Reappear;1632}1633}16341635void HeavyMystic_StateBox_Reappear(void)1636{1637RSDK_THIS(HeavyMystic);16381639if (self->scale.x < 0x200) {1640self->scale.y += 8;1641self->scale.x = self->scale.y;1642self->rotation -= 8;1643}1644else {1645if (self->rotation & 0x1FF) {1646self->rotation -= 8;1647}1648else {1649RSDK.PlaySfx(HeavyMystic->sfxClack, false, 255);1650self->timer = 2;1651self->stateDraw = HeavyMystic_Draw_BoxTransforming;1652self->state = HeavyMystic_StateBox_CloseDoors;1653}16541655self->rotation &= 0x1FF;1656}1657}16581659void HeavyMystic_Draw_BoxOpened(void)1660{1661RSDK_THIS(HeavyMystic);16621663if (SceneInfo->currentDrawGroup == self->drawGroup) {1664self->drawFX = FX_NONE;1665self->animator.frameID = 0;1666RSDK.DrawSprite(&self->animator, NULL, false);16671668Vector2 drawPos;1669drawPos.x = self->position.x - 0x280000;1670drawPos.y = self->position.y;1671self->animator.frameID = self->timer;1672self->drawFX = FX_SCALE | FX_ROTATE | FX_FLIP;1673RSDK.DrawSprite(&self->animator, &drawPos, false);16741675drawPos.x += 0x500000;1676self->direction = FLIP_X;1677RSDK.DrawSprite(&self->animator, &drawPos, false);16781679self->direction = FLIP_NONE;1680}1681}16821683void HeavyMystic_Draw_BoxTransforming(void)1684{1685RSDK_THIS(HeavyMystic);16861687if (SceneInfo->currentDrawGroup == self->drawGroup) {1688self->drawFX = FX_NONE;1689if (self->state != HeavyMystic_StateBox_Transforming) {1690self->animator.frameID = 0;1691RSDK.DrawSprite(&self->animator, NULL, false);1692}1693}1694else {1695Vector2 drawPos;16961697drawPos.x = self->position.x - 0x280000;1698drawPos.y = self->position.y;1699self->animator.frameID = self->timer;1700self->drawFX = FX_SCALE | FX_ROTATE | FX_FLIP;1701if (self->state == HeavyMystic_StateBox_Transforming)1702drawPos.x += 0x1400 * (0x200 - self->scale.x);1703RSDK.DrawSprite(&self->animator, &drawPos, false);17041705self->direction = FLIP_X;1706drawPos.x = self->position.x + 0x280000;1707if (self->state == HeavyMystic_StateBox_Transforming)1708drawPos.x += 0x1400 * (self->scale.x - 0x200);1709RSDK.DrawSprite(&self->animator, &drawPos, false);1710self->direction = FLIP_NONE;1711}1712}17131714void HeavyMystic_Draw_BoxClosed(void)1715{1716RSDK_THIS(HeavyMystic);17171718if (SceneInfo->currentDrawGroup == self->drawGroup) {1719self->drawFX = FX_SCALE | FX_ROTATE;1720self->animator.frameID = 3;1721RSDK.DrawSprite(&self->animator, NULL, false);1722}1723}17241725#if GAME_INCLUDE_EDITOR1726void HeavyMystic_EditorDraw(void)1727{1728RSDK_THIS(HeavyMystic);17291730switch (self->type) {1731case MYSTIC_MISCHIEF:1732self->drawFX = FX_FLIP;1733RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);1734break;17351736case MYSTIC_BOSS:1737self->drawFX = FX_FLIP;1738RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 0, &self->animator, true, 0);17391740if (showGizmos()) {1741RSDK_DRAWING_OVERLAY(true);17421743DrawHelpers_DrawArenaBounds(-WIDE_SCR_XCENTER, (256 - SCREEN_YSIZE), WIDE_SCR_XCENTER, 256, 1 | 2 | 4 | 8, 0x00C0F0);17441745RSDK_DRAWING_OVERLAY(false);1746}1747break;17481749case MYSTIC_BOX:1750self->drawFX = FX_SCALE | FX_ROTATE | FX_FLIP;1751RSDK.SetSpriteAnimation(HeavyMystic->aniFrames, 10, &self->animator, true, 0);1752break;17531754default: break;1755}17561757RSDK.DrawSprite(&self->animator, NULL, false);1758}17591760void HeavyMystic_EditorLoad(void)1761{1762HeavyMystic->aniFrames = RSDK.LoadSpriteAnimation("MSZ/HeavyMystic.bin", SCOPE_STAGE);1763HeavyMystic->roguesFrames = RSDK.LoadSpriteAnimation("MSZ/Rogues.bin", SCOPE_STAGE);17641765RSDK_ACTIVE_VAR(HeavyMystic, type);1766RSDK_ENUM_VAR("Mischief", MYSTIC_MISCHIEF);1767RSDK_ENUM_VAR("Boss", MYSTIC_BOSS);1768RSDK_ENUM_VAR("Box", MYSTIC_BOX);1769// RSDK_ENUM_VAR("Cork", MYSTIC_CORK);1770// RSDK_ENUM_VAR("Bomb", MYSTIC_BOMB);1771// RSDK_ENUM_VAR("Debris", MYSTIC_DEBRIS);1772}1773#endif17741775void HeavyMystic_Serialize(void) { RSDK_EDITABLE_VAR(HeavyMystic, VAR_ENUM, type); }177617771778