Path: blob/master/SonicMania/Objects/OOZ/MegaOctus.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: MegaOctus Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectMegaOctus *MegaOctus;1011void MegaOctus_Update(void)12{13RSDK_THIS(MegaOctus);1415StateMachine_Run(self->state);16}1718void MegaOctus_LateUpdate(void) {}1920void MegaOctus_StaticUpdate(void)21{22foreach_active(MegaOctus, boss)23{24if (boss->type == MEGAOCTUS_ARM)25RSDK.AddDrawListRef(Zone->objectDrawGroup[0], RSDK.GetEntitySlot(boss));26}27}2829void MegaOctus_Draw(void)30{31RSDK_THIS(MegaOctus);3233StateMachine_Run(self->stateDraw);34}3536void MegaOctus_Create(void *data)37{38RSDK_THIS(MegaOctus);3940self->drawFX = FX_FLIP;41if (!SceneInfo->inEditor) {42if (globals->gameMode < MODE_TIMEATTACK) {43self->active = ACTIVE_BOUNDS;44if (data)45self->type = VOID_TO_INT(data);4647switch (self->type) {48case MEGAOCTUS_BODY:49self->visible = false;50self->drawGroup = Zone->objectDrawGroup[0];5152RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 0, &self->animator, true, 0);53RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 1, &MegaOctus->eggmanAnimator, true, 0);54RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 1, &MegaOctus->noseAnimator, true, 5);55RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 2, &MegaOctus->boltsAnimator, true, 5);56RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 0, &MegaOctus->hatchBaseAnimator, true, 0);57RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 1, &MegaOctus->hatchOpenAnimator, true, 0);5859self->hitbox.left = -33;60self->hitbox.top = -37;61self->hitbox.right = 33;62self->hitbox.bottom = 6;6364self->origin.x = self->position.x + 0x800000;65self->origin.y = self->position.y;6667self->updateRange.x = 0x800000;68self->updateRange.y = 0x800000;69MegaOctus->bossEntity = self;70MegaOctus->turnPos = 0;71self->state = MegaOctus_State_SetupBounds;72self->stateDraw = MegaOctus_Draw_Body;73break;7475case MEGAOCTUS_UNUSED1: break;7677case MEGAOCTUS_HARPOON:78self->active = ACTIVE_NORMAL;79self->visible = true;80self->drawGroup = Zone->objectDrawGroup[0];8182self->hitbox.left = -8;83self->hitbox.top = -8;84self->hitbox.right = 8;85self->hitbox.bottom = 8;8687self->origin = self->position;88self->updateRange.x = 0x800000;89self->updateRange.y = 0x800000;90self->angle = 0;91self->rotation = 0;9293RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 3, &self->animator, true, 1);94break;9596case MEGAOCTUS_CANNON:97self->active = ACTIVE_NORMAL;98self->visible = true;99self->updateRange.x = 0x800000;100self->updateRange.y = 0x800000;101self->drawGroup = Zone->objectDrawGroup[0] + 1;102103self->hitbox.left = -8;104self->hitbox.top = -8;105self->hitbox.right = 8;106self->hitbox.bottom = 8;107108self->targetPos = self->position.y - 0x700000;109self->origin = self->position;110self->lastAttackHeight = 0x100;111self->shotCount = 3;112113RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 3, &self->animator, true, 1);114RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 4, &self->altAnimator, true, 3);115116self->velocity.y = -0x10000;117self->state = MegaOctus_StateCannon_RiseUp;118self->stateDraw = MegaOctus_Draw_Cannon;119break;120121case MEGAOCTUS_ORB:122self->active = ACTIVE_NORMAL;123self->visible = true;124self->updateRange.x = 0x800000;125self->updateRange.y = 0x800000;126self->drawGroup = Zone->objectDrawGroup[0] + 1;127128self->hitbox.left = -16;129self->hitbox.top = -16;130self->hitbox.right = 16;131self->hitbox.bottom = 16;132133self->targetPos = self->position.y - 0x1000000;134self->origin = self->position;135136RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 3, &self->animator, true, 1);137RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 5, &self->altAnimator, true, 0);138139self->velocity.y = -0x18000;140self->state = MegaOctus_StateOrb_Wait;141self->stateDraw = MegaOctus_Draw_Orb;142break;143144case MEGAOCTUS_ARM:145self->active = ACTIVE_NORMAL;146self->visible = true;147self->updateRange.x = 0x800000;148self->drawGroup = Zone->objectDrawGroup[0] + 1;149150self->hitbox.left = -8;151self->hitbox.top = -8;152self->hitbox.right = 8;153self->hitbox.bottom = 8;154155self->origin = self->position;156self->updateRange.y = 0x800000;157self->angle = 0;158self->rotation = 0;159160RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 3, &self->animator, true, 1);161162self->state = MegaOctus_StateArm_WrapAroundPlatform;163self->stateDraw = MegaOctus_Draw_Arm_WrapAroundPlatformBase;164break;165166case MEGAOCTUS_LASER:167self->active = ACTIVE_NORMAL;168self->visible = true;169self->drawGroup = Zone->objectDrawGroup[0];170171self->hitbox.left = -16;172self->hitbox.top = -1;173self->hitbox.right = 16;174self->hitbox.bottom = 1;175176self->updateRange.x = 0x800000;177self->updateRange.y = 0x800000;178179RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 7, &self->animator, true, 0);180181self->state = MegaOctus_State_Laser;182self->stateDraw = MegaOctus_Draw_Laser;183break;184185case MEGAOCTUS_ORBSHOT:186self->active = ACTIVE_NORMAL;187self->visible = true;188self->drawGroup = Zone->objectDrawGroup[0];189190self->hitbox.left = -3;191self->hitbox.top = -3;192self->hitbox.right = 3;193self->hitbox.bottom = 3;194195self->updateRange.x = 0x400000;196self->updateRange.y = 0x400000;197198RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 6, &self->animator, true, 0);199200self->state = MegaOctus_State_Shot;201self->stateDraw = MegaOctus_Draw_OrbShot;202break;203204case MEGAOCTUS_UNUSED8: break;205206case MEGAOCTUS_LASERFIRE:207self->active = ACTIVE_NORMAL;208self->visible = true;209self->drawGroup = Zone->objectDrawGroup[0];210211self->hitbox.left = -8;212self->hitbox.top = -4;213self->hitbox.right = 8;214self->hitbox.bottom = 0;215216self->updateRange.x = 0x800000;217self->updateRange.y = 0x800000;218219RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 8, &self->animator, true, 0);220221self->state = MegaOctus_State_LaserFire;222self->stateDraw = MegaOctus_Draw_Laser;223break;224225default: break;226}227}228else {229MegaOctus->bossEntity = NULL;230destroyEntity(self);231}232}233}234235void MegaOctus_StageLoad(void)236{237MegaOctus->active = ACTIVE_ALWAYS;238MegaOctus->bossEntity = NULL;239240MegaOctus->aniFrames = RSDK.LoadSpriteAnimation("OOZ/MegaOctus.bin", SCOPE_STAGE);241MegaOctus->eggmanFrames = RSDK.LoadSpriteAnimation("Eggman/EggmanOOZ.bin", SCOPE_STAGE);242MegaOctus->hatchFrames = RSDK.LoadSpriteAnimation("OOZ/Hatch.bin", SCOPE_STAGE);243244MegaOctus->hitbox.left = -16;245MegaOctus->hitbox.top = 22;246MegaOctus->hitbox.right = 16;247MegaOctus->hitbox.bottom = 30;248249MegaOctus->spawnHarpoon = false;250MegaOctus->orbHealth[0] = 4;251MegaOctus->orbHealth[1] = 4;252MegaOctus->defeated = false;253254MegaOctus->sfxBossHit = RSDK.GetSfx("Stage/BossHit.wav");255MegaOctus->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");256MegaOctus->sfxLaser = RSDK.GetSfx("OOZ/OOZLaser.wav");257MegaOctus->sfxBullet = RSDK.GetSfx("OOZ/OOZBullet.wav");258MegaOctus->sfxHarpoon = RSDK.GetSfx("OOZ/Harpoon.wav");259MegaOctus->sfxSurface = RSDK.GetSfx("OOZ/OOZSurface.wav");260MegaOctus->sfxLaserSplash = RSDK.GetSfx("OOZ/LaserSplash.wav");261}262263void MegaOctus_CheckPlayerCollisions_Body(void)264{265RSDK_THIS(MegaOctus);266267if (self->invincibilityTimer)268self->invincibilityTimer--;269270foreach_active(Player, player)271{272int32 playerRadius = 0x100000;273274EntityShield *shield = RSDK_GET_ENTITY(Player->playerCount + RSDK.GetEntitySlot(player), Shield);275if (shield->classID == Shield->classID && shield->state == Shield_State_Insta)276playerRadius = 0x160000;277278if (RSDK.CheckObjectCollisionTouchCircle(self, 0x300000, player, playerRadius)) {279int32 angle = RSDK.ATan2(player->position.x - self->position.x, player->position.y - self->position.y);280281player->velocity.x += 80 * RSDK.Cos256(angle);282if (self->invincibilityTimer || !Player_CheckBossHit(player, self)) {283player->velocity.y -= 80 * abs(RSDK.Sin256(angle));284}285else {286MegaOctus_Hit();287}288}289}290}291292void MegaOctus_HandleEggmanAnim(void)293{294RSDK_THIS(MegaOctus);295296switch (MegaOctus->eggmanAnimator.animationID) {297case 0:298case 1:299if (MegaOctus->eggmanAnimator.frameID >= MegaOctus->eggmanAnimator.frameCount - 1) {300if (self->invincibilityTimer) {301RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 3, &MegaOctus->eggmanAnimator, true, 0);302}303else {304bool32 laughing = false;305foreach_active(Player, player)306{307if (player->state == Player_State_Hurt || player->state == Player_State_Death)308laughing = true;309}310311if (laughing)312RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 4, &MegaOctus->eggmanAnimator, true, 0);313}314}315break;316317case 2:318case 4:319if (self->invincibilityTimer) {320RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 3, &MegaOctus->eggmanAnimator, true, 0);321}322else {323bool32 laughing = false;324foreach_active(Player, player)325{326if (player->state == Player_State_Hurt || player->state == Player_State_Death)327laughing = true;328}329330if (MegaOctus->eggmanAnimator.frameID >= MegaOctus->eggmanAnimator.frameCount - 1) {331if (!laughing) {332uint8 anim = self->state == MegaOctus_State_CloseHatch ? 2 : 0;333RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, anim, &MegaOctus->eggmanAnimator, true, 0);334}335else {336RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 4, &MegaOctus->eggmanAnimator, true, 8);337}338}339}340break;341342case 3:343if (!self->invincibilityTimer) {344if (MegaOctus->eggmanAnimator.frameID >= MegaOctus->eggmanAnimator.frameCount - 1) {345uint8 anim = self->state == MegaOctus_State_CloseHatch ? 2 : 0;346RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, anim, &MegaOctus->eggmanAnimator, true, 0);347}348}349break;350351default: break;352}353}354355void MegaOctus_Hit(void)356{357RSDK_THIS(MegaOctus);358359if (self->health)360self->health--;361362if (self->health) {363RSDK.PlaySfx(MegaOctus->sfxBossHit, false, 255);364self->invincibilityTimer = 30;365MegaOctus->spawnHarpoon = true;366}367else {368SceneInfo->timeEnabled = false;369Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);370RSDK.PlaySfx(MegaOctus->sfxExplosion, false, 255);371self->invincibilityTimer = 120;372RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 5, &MegaOctus->eggmanAnimator, true, 0);373MegaOctus->defeated = true;374self->state = MegaOctus_State_Destroyed;375}376}377378void MegaOctus_Explode(void)379{380RSDK_THIS(MegaOctus);381382if (!(Zone->timer % 3)) {383RSDK.PlaySfx(MegaOctus->sfxExplosion, false, 255);384385if (Zone->timer & 4) {386int32 x = self->position.x + (RSDK.Rand(-48, 48) << 16);387int32 y = self->position.y + (RSDK.Rand(-48, 48) << 16);388EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y);389explosion->drawGroup = Zone->objectDrawGroup[1] + 2;390}391}392}393394void MegaOctus_HandleDirectionChange(void)395{396RSDK_THIS(MegaOctus);397398EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);399400if (abs(player1->position.x - self->position.x) < 0x200000) {401if (self->orbID > 10)402self->orbID--;403else if (self->orbID < 10)404self->orbID++;405}406else {407if (player1->position.x < self->position.x) {408if (self->orbID)409self->orbID--;410}411else {412if (self->orbID < 20)413self->orbID++;414}415}416417self->direction = self->orbID < 10;418MegaOctus->noseAnimator.frameID = self->orbID >> 1;419MegaOctus->boltsAnimator.frameID = self->orbID >> 1;420MegaOctus->turnPos = MegaOctus->turnOffsets[MegaOctus->noseAnimator.frameID];421}422423void MegaOctus_State_SetupBounds(void)424{425RSDK_THIS(MegaOctus);426427if (++self->timer >= 2) {428self->timer = 0;429430Zone->playerBoundActiveR[0] = true;431Zone->playerBoundActiveB[0] = false;432Zone->cameraBoundsR[0] = (self->position.x >> 16) + 448;433Zone->cameraBoundsB[0] = (self->position.y >> 16) + 96;434Zone->deathBoundary[0] = Zone->cameraBoundsB[0] << 16;435#if MANIA_USE_PLUS436Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - 384;437#endif438439self->position.y += 0xC00000;440self->active = ACTIVE_NORMAL;441self->visible = true;442self->state = MegaOctus_State_SetupArena;443}444}445446void MegaOctus_State_SetupArena(void)447{448RSDK_THIS(MegaOctus);449450Zone->playerBoundActiveL[0] = true;451Zone->cameraBoundsL[0] = ScreenInfo->position.x;452453if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x > self->origin.x) {454RSDK.GetTileLayer(Zone->fgLayer[0])->drawGroup[0] = 2;455Zone->playerBoundActiveL[0] = true;456Zone->cameraBoundsL[0] = (self->position.x >> 16) - 192;457458Music_TransitionTrack(TRACK_EGGMAN1, 0.0075);459460OOZSetup->useSmogEffect = false;461self->velocity.y = -0x40000;462self->health = 8;463self->timer = 60;464465EntityMegaOctus *arm = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ARM), self->position.x + 0x800000, self->origin.y + 0x400000);466arm->direction = self->direction;467arm->angle = 128;468469arm = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ARM), self->position.x - 0x800000, self->origin.y + 0x400000);470arm->direction = self->direction;471arm->angle = 128;472473self->state = MegaOctus_State_None;474}475}476477void MegaOctus_State_None(void)478{479// :3480}481482void MegaOctus_State_EnterMegaOctus(void)483{484RSDK_THIS(MegaOctus);485486self->position.y += self->velocity.y;487self->velocity.y += MANIA_USE_PLUS ? 0x3800 : 0x6000;488489if (self->velocity.y >= 0x10000) {490self->state = MegaOctus_State_OpenHatchAndLaugh;491self->velocity.y = 0;492}493494MegaOctus_CheckPlayerCollisions_Body();495}496497void MegaOctus_State_OpenHatchAndLaugh(void)498{499RSDK_THIS(MegaOctus);500501RSDK.ProcessAnimation(&MegaOctus->hatchOpenAnimator);502RSDK.ProcessAnimation(&MegaOctus->eggmanAnimator);503504MegaOctus_HandleEggmanAnim();505MegaOctus_HandleDirectionChange();506MegaOctus_CheckPlayerCollisions_Body();507508if (--self->timer <= 0) {509self->timer = 60;510511RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 2, &MegaOctus->hatchOpenAnimator, true, 0);512if (MegaOctus->eggmanAnimator.animationID < 2)513RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 2, &MegaOctus->eggmanAnimator, true, 0);514515self->state = MegaOctus_State_CloseHatch;516}517}518519void MegaOctus_State_CloseHatch(void)520{521RSDK_THIS(MegaOctus);522523RSDK.ProcessAnimation(&MegaOctus->hatchOpenAnimator);524RSDK.ProcessAnimation(&MegaOctus->eggmanAnimator);525526MegaOctus_HandleEggmanAnim();527528MegaOctus->eggmanVelocity += 0x4800;529MegaOctus->eggmanOffset += MegaOctus->eggmanVelocity;530531MegaOctus_HandleDirectionChange();532MegaOctus_CheckPlayerCollisions_Body();533534if (--self->timer <= 0)535self->state = MegaOctus_State_DiveIntoOil;536}537538void MegaOctus_State_DiveIntoOil(void)539{540RSDK_THIS(MegaOctus);541542self->position.y += self->velocity.y;543self->velocity.y += MANIA_USE_PLUS ? 0x3800 : 0x6000;544545if (self->position.y >= self->origin.y + 0xC00000) {546self->position.y = self->origin.y + 0xC00000;547548self->state = MegaOctus_State_SpawnWeapons;549self->timer = MegaOctus->spawnHarpoon ? 480 : 240;550}551552MegaOctus_CheckPlayerCollisions_Body();553}554555void MegaOctus_State_SpawnWeapons(void)556{557RSDK_THIS(MegaOctus);558559if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x <= self->origin.x)560self->position.x = self->origin.x - 0x800000;561else562self->position.x = self->origin.x + 0x800000;563564if (--self->timer == 240) {565MegaOctus->spawnHarpoon = false;566EntityMegaOctus *harpoon = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_HARPOON), self->position.x, self->origin.y + 0x300000);567harpoon->direction = self->direction;568RSDK.PlaySfx(MegaOctus->sfxHarpoon, false, 255);569570if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x <= self->position.x) {571harpoon->origin.x -= 0x800000;572harpoon->state = MegaOctus_State_HarpoonLeft;573harpoon->stateDraw = MegaOctus_Draw_HarpoonLeft;574}575else {576harpoon->origin.x += 0x800000;577harpoon->state = MegaOctus_State_HarpoonRight;578harpoon->stateDraw = MegaOctus_Draw_HarpoonRight;579}580}581else if (self->timer <= 0) {582self->timer = 480;583CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_CANNON), self->position.x, self->origin.y + 0x400000)->direction = self->direction;584self->state = MegaOctus_State_CannonThenSpawnOrbs;585}586587MegaOctus_CheckPlayerCollisions_Body();588}589590void MegaOctus_State_CannonThenSpawnOrbs(void)591{592RSDK_THIS(MegaOctus);593594MegaOctus_HandleDirectionChange();595596EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);597if (player1->position.x <= self->origin.x)598self->position.x = self->origin.x - 0x800000;599else600self->position.x = self->origin.x + 0x800000;601602MegaOctus_CheckPlayerCollisions_Body();603604if (--self->timer <= 0) {605EntityMegaOctus *arm = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ARM), self->position.x + 0x800000, self->origin.y + 0x400000);606arm->direction = self->direction;607arm->angle = 128;608609arm = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ARM), self->position.x - 0x800000, self->origin.y + 0x400000);610arm->direction = self->direction;611arm->angle = 128;612613if (MegaOctus->orbHealth[0] > 0) {614EntityMegaOctus *orb = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ORB), self->position.x + 0x380000, self->origin.y + 0x780000);615orb->direction = self->direction;616orb->health = MegaOctus->orbHealth[0];617orb->orbID = 0;618orb->velocity.x = self->position.x > self->origin.x ? 0 : 136;619}620621if (MegaOctus->orbHealth[1] > 0) {622EntityMegaOctus *orb = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ORB), self->position.x - 0x380000, self->origin.y + 0x780000);623orb->direction = self->direction;624orb->health = MegaOctus->orbHealth[1];625orb->orbID = 1;626orb->angle = 0x100;627orb->velocity.x = self->position.x > self->origin.x ? -136 : 0;628}629630self->timer = 120;631self->state = MegaOctus_State_None;632}633}634635void MegaOctus_State_Destroyed(void)636{637RSDK_THIS(MegaOctus);638639RSDK.ProcessAnimation(&MegaOctus->hatchOpenAnimator);640RSDK.ProcessAnimation(&MegaOctus->eggmanAnimator);641642if (MegaOctus->eggmanVelocity > 0) {643MegaOctus->eggmanVelocity += 0x4800;644MegaOctus->eggmanOffset += MegaOctus->eggmanVelocity;645}646647MegaOctus_Explode();648649if (--self->invincibilityTimer <= 0) {650if (!MegaOctus->eggmanVelocity)651RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 2, &MegaOctus->hatchOpenAnimator, true, 0);652653Music_TransitionTrack(TRACK_STAGE, 0.0125);654self->timer = 0;655self->state = MegaOctus_State_Finish;656}657}658659void MegaOctus_State_Finish(void)660{661RSDK_THIS(MegaOctus);662663RSDK.ProcessAnimation(&MegaOctus->hatchOpenAnimator);664RSDK.ProcessAnimation(&MegaOctus->eggmanAnimator);665666MegaOctus->eggmanVelocity += 0x4800;667MegaOctus->eggmanOffset += MegaOctus->eggmanVelocity;668669self->position.y += 0x10000;670671if (!(Zone->timer & 7)) {672int32 x = self->position.x + (RSDK.Rand(-48, 48) << 16);673int32 y = self->position.y + (RSDK.Rand(-48, 48) << 16);674EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), x, y);675explosion->drawGroup = self->drawGroup;676}677678if (++self->timer > 120) {679bool32 isFinished = true;680foreach_active(MegaOctus, boss)681{682if (boss->type == MEGAOCTUS_ARM) {683isFinished = false;684foreach_break;685}686}687688if (isFinished) {689Zone->cameraBoundsR[0] += WIDE_SCR_XSIZE;690destroyEntity(self);691}692}693}694695void MegaOctus_Draw_Body(void)696{697RSDK_THIS(MegaOctus);698699int32 turnPos = abs(MegaOctus->turnPos) / 96;700if (self->invincibilityTimer & 1)701RSDK.SetPaletteEntry(0, 128, 0xE0E0E0);702703Vector2 drawPos = self->position;704drawPos.y -= 0x320000;705RSDK.DrawSprite(&MegaOctus->hatchOpenAnimator, &drawPos, false);706707Vector2 eggmanPos = drawPos;708eggmanPos.y += MegaOctus->eggmanOffset;709RSDK.DrawSprite(&MegaOctus->eggmanAnimator, &eggmanPos, false);710711self->animator.frameID = 0;712RSDK.DrawSprite(&self->animator, NULL, false);713RSDK.DrawSprite(&MegaOctus->hatchBaseAnimator, &drawPos, false);714715if (MegaOctus->turnPos < 0) {716self->drawFX |= FX_SCALE;717self->scale.y = 0x200;718self->scale.x = 0x200 - (turnPos << 9 >> 15);719}720drawPos = self->position;721drawPos.x += turnPos - 0x10000 + MegaOctus->turnPos + 16 * (turnPos - 0x10000);722self->animator.frameID = 1;723RSDK.DrawSprite(&self->animator, &drawPos, false);724725drawPos.x += turnPos * (MegaOctus->turnPos >> 18);726self->animator.frameID = 2;727RSDK.DrawSprite(&self->animator, &drawPos, false);728729drawPos.x -= turnPos * (MegaOctus->turnPos >> 18);730self->drawFX &= ~FX_SCALE;731if (MegaOctus->turnPos > 0) {732self->drawFX |= FX_SCALE;733self->scale.y = 0x200;734self->scale.x = 0x200 - (turnPos << 9 >> 15);735}736737drawPos.x += 34 * (0x10000 - turnPos);738self->animator.frameID = 1;739RSDK.DrawSprite(&self->animator, &drawPos, false);740741drawPos.x += turnPos * (MegaOctus->turnPos >> 18);742self->animator.frameID = 2;743RSDK.DrawSprite(&self->animator, &drawPos, false);744745drawPos.x -= turnPos * (MegaOctus->turnPos >> 18);746self->drawFX = FX_FLIP;747RSDK.DrawSprite(&MegaOctus->boltsAnimator, NULL, false);748RSDK.DrawSprite(&MegaOctus->noseAnimator, NULL, false);749750self->animator.frameID = 6;751RSDK.DrawSprite(&self->animator, NULL, false);752RSDK.SetPaletteEntry(0, 128, 0x0000);753}754755void MegaOctus_CheckPlayerCollisions_Harpoon(void)756{757RSDK_THIS(MegaOctus);758759self->position.x = 0x3400 * RSDK.Sin512(self->angle) + self->origin.x;760self->position.y = 0x3400 * RSDK.Cos512(self->angle) + self->origin.y;761762foreach_active(Player, player)763{764if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {765#if MANIA_USE_PLUS766if (!Player_CheckMightyUnspin(player, 0x300, 2, &player->uncurlTimer))767#endif768Player_Hurt(player, self);769}770}771}772773void MegaOctus_State_HarpoonLeft(void)774{775RSDK_THIS(MegaOctus);776777self->angle = (self->angle + 3) & 0x1FF;778self->shotCount += 12;779780MegaOctus_CheckPlayerCollisions_Harpoon();781782if (self->angle == 1)783destroyEntity(self);784}785786void MegaOctus_State_HarpoonRight(void)787{788RSDK_THIS(MegaOctus);789790self->angle = (self->angle - 3) & 0x1FF;791self->shotCount -= 12;792793MegaOctus_CheckPlayerCollisions_Harpoon();794795if (self->angle == 2)796destroyEntity(self);797}798799void MegaOctus_Draw_HarpoonLeft(void)800{801RSDK_THIS(MegaOctus);802803self->animator.frameID = 1;804int32 angle = (self->angle - 108) & 0x1FF;805for (int32 i = 0; i < 9; ++i) {806self->position.x = 0x3400 * RSDK.Sin512(angle) + self->origin.x;807self->position.y = 0x3400 * RSDK.Cos512(angle) + self->origin.y;808RSDK.DrawSprite(&self->animator, NULL, false);809angle = (angle + 12) & 0x1FF;810}811812self->drawFX |= FX_ROTATE;813self->direction = FLIP_NONE;814self->rotation = (-0x100 - self->angle) & 0x1FF;815self->animator.frameID = 0;816RSDK.DrawSprite(&self->animator, NULL, false);817818self->drawFX &= ~FX_ROTATE;819}820821void MegaOctus_Draw_HarpoonRight(void)822{823RSDK_THIS(MegaOctus);824825self->animator.frameID = 1;826int32 angle = (self->angle + 108) & 0x1FF;827for (int32 i = 0; i < 9; ++i) {828self->position.x = 0x3400 * RSDK.Sin512(angle) + self->origin.x;829self->position.y = 0x3400 * RSDK.Cos512(angle) + self->origin.y;830RSDK.DrawSprite(&self->animator, NULL, false);831angle = (angle - 12) & 0x1FF;832}833834self->drawFX |= FX_ROTATE;835self->direction = FLIP_X;836self->rotation = (-0x100 - self->angle) & 0x1FF;837self->animator.frameID = 0;838RSDK.DrawSprite(&self->animator, NULL, false);839840self->drawFX &= ~FX_ROTATE;841}842843void MegaOctus_CheckPlayerCollisions_Cannon(void)844{845RSDK_THIS(MegaOctus);846847Vector2 storePos = self->position;848849foreach_active(Player, player)850{851self->position.x = (RSDK.Cos512(self->angle) << 10) + storePos.x;852self->position.y = (RSDK.Sin512(self->angle) << 8) + storePos.y;853854if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {855self->position = storePos;856857#if MANIA_USE_PLUS858if (!Player_CheckMightyUnspin(player, 0x300, 2, &player->uncurlTimer))859#endif860Player_Hurt(player, self);861}862}863864self->position = storePos;865}866867void MegaOctus_StateCannon_RiseUp(void)868{869RSDK_THIS(MegaOctus);870871self->position.y += self->velocity.y;872self->angle = (self->angle + 6) & 0x1FF;873874RSDK.ProcessAnimation(&self->altAnimator);875876self->direction = RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x >= self->position.x;877if (self->position.y <= self->targetPos) {878self->shotCount = MANIA_USE_PLUS ? 2 : 3;879self->timer = 128;880self->lastAttackHeight = 0x100;881self->state = MegaOctus_StateCannon_Idle;882}883884MegaOctus_CheckPlayerCollisions_Cannon();885}886887void MegaOctus_StateCannon_Idle(void)888{889RSDK_THIS(MegaOctus);890891self->angle = (self->angle + 6) & 0x1FF;892RSDK.ProcessAnimation(&self->altAnimator);893894self->direction = RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x >= self->position.x;895896if (--self->timer <= 0) {897if (self->shotCount <= 0) {898self->velocity.y = 0x10000;899self->state = MegaOctus_StateCannon_SinkDown;900}901else {902int32 attackHeight = self->lastAttackHeight;903while (attackHeight == self->lastAttackHeight) attackHeight = RSDK.Rand(0, 4);904905self->lastAttackHeight = attackHeight;906self->targetPos = MegaOctus->cannonHeights[attackHeight] + self->origin.y;907self->state = MegaOctus_StateCannon_FireLaser;908self->velocity.y = self->targetPos < self->position.y ? -0x8000 : 0x8000;909}910}911912MegaOctus_CheckPlayerCollisions_Cannon();913}914915void MegaOctus_StateCannon_FireLaser(void)916{917RSDK_THIS(MegaOctus);918919self->position.y += self->velocity.y;920self->angle = (self->angle + 6) & 0x1FF;921922RSDK.ProcessAnimation(&self->altAnimator);923924self->direction = RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x >= self->position.x;925926if ((self->velocity.y < 0 && self->position.y <= self->targetPos) || (self->velocity.y >= 0 && self->position.y >= self->targetPos)) {927self->position.y = self->targetPos;928RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 4, &self->altAnimator, true, 0);929RSDK.PlaySfx(MegaOctus->sfxLaser, false, 255);930931--self->shotCount;932self->timer = 40;933int32 x = (RSDK.Cos512(self->angle) << 10) + self->position.x;934int32 y = (RSDK.Sin512(self->angle) << 9) + self->position.y;935EntityMegaOctus *child = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_LASER), x, y);936child->direction = self->direction;937child->velocity.x = self->direction ? 0x40000 : -0x40000;938child->position.x += child->velocity.x;939child->parent = (Entity *)self;940child->timer = 11;941self->state = MegaOctus_StateCannon_Idle;942}943MegaOctus_CheckPlayerCollisions_Cannon();944}945946void MegaOctus_StateCannon_SinkDown(void)947{948RSDK_THIS(MegaOctus);949950self->angle = (self->angle + 6) & 0x1FF;951RSDK.ProcessAnimation(&self->altAnimator);952953self->direction = RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x >= self->position.x;954955self->position.y += self->velocity.y;956957MegaOctus_CheckPlayerCollisions_Cannon();958959if (self->position.y > self->origin.y)960destroyEntity(self);961}962void MegaOctus_Draw_Cannon(void)963{964RSDK_THIS(MegaOctus);965966int32 angle = self->angle;967int32 y = self->position.y + 0x780000;968969Vector2 drawPos;970for (int32 i = 0; i < 8; ++i) {971drawPos.x = (RSDK.Cos512(angle) << 10) + self->position.x;972drawPos.y = (RSDK.Sin512(angle) << 8) + y;973RSDK.DrawSprite(&self->animator, &drawPos, false);974975angle = (angle + 64) & 0x1FF;976y -= 0xF0000;977}978979drawPos.x = (RSDK.Cos512(angle) << 10) + self->position.x;980drawPos.y = (RSDK.Sin512(angle) << 8) + y;981RSDK.DrawSprite(&self->altAnimator, &drawPos, false);982}983984void MegaOctus_CheckPlayerCollisions_Orb(void)985{986RSDK_THIS(MegaOctus);987988Vector2 storePos = self->position;989990if (self->invincibilityTimer) {991self->invincibilityTimer--;992}993else {994foreach_active(Player, player)995{996self->position.x = (RSDK.Cos512(self->angle) << 10) + storePos.x;997self->position.y = (RSDK.Sin512(self->angle) << 8) + storePos.y;998if (Player_CheckBadnikTouch(player, self, &self->hitbox) && Player_CheckBossHit(player, self)) {999self->position = storePos;10001001--self->health;1002--MegaOctus->orbHealth[self->orbID];10031004if (self->health) {1005RSDK.PlaySfx(MegaOctus->sfxBossHit, false, 255);1006self->invincibilityTimer = 30;1007}1008else {1009RSDK.PlaySfx(MegaOctus->sfxExplosion, false, 255);1010self->invincibilityTimer = 60;1011self->state = MegaOctus_StateOrb_Destroyed;1012}1013}1014}1015}10161017self->position = storePos;1018}10191020void MegaOctus_StateOrb_Wait(void)1021{1022RSDK_THIS(MegaOctus);10231024self->position.y += self->velocity.y;10251026self->angle = (self->angle + 6) & 0x1FF;1027RSDK.ProcessAnimation(&self->altAnimator);10281029if (MegaOctus->defeated) {1030self->invincibilityTimer = 60;1031self->state = MegaOctus_StateOrb_Destroyed;1032}10331034if (self->position.y <= self->targetPos) {1035self->timer = 60;1036self->state = MegaOctus_StateOrb_FireShot;1037}10381039MegaOctus_CheckPlayerCollisions_Orb();1040}10411042void MegaOctus_StateOrb_FireShot(void)1043{1044RSDK_THIS(MegaOctus);10451046self->angle = (self->angle + 6) & 0x1FF;1047RSDK.ProcessAnimation(&self->altAnimator);10481049if (MegaOctus->defeated) {1050self->invincibilityTimer = 60;1051self->state = MegaOctus_StateOrb_Destroyed;1052}10531054#if MANIA_USE_PLUS1055if (self->shotCount > 0)1056self->position.x += self->velocity.x * RSDK.Sin1024(++self->orbMoveAngle);1057#endif10581059if (--self->timer <= 0) {1060++self->shotCount;10611062int32 x = (RSDK.Cos512(self->angle) << 10) + self->position.x;1063int32 y = (RSDK.Sin512(self->angle) << 9) + self->position.y;10641065int32 angle = 0;1066#if MANIA_USE_PLUS1067if (MegaOctus->bossEntity->position.x <= x)1068angle = -3 * self->shotCount;1069else1070angle = 3 * self->shotCount;1071angle *= 4;10721073EntityMegaOctus *shot = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ORBSHOT), x, y);1074shot->velocity.x = 0x300 * RSDK.Sin256(angle);1075shot->velocity.y = 0x300 * RSDK.Cos256(angle);1076#else1077EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);1078angle = RSDK.ATan2(player1->position.x - x, player1->position.y - y);10791080EntityMegaOctus *shot = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ORBSHOT), x, y);1081shot->velocity.x = 0x300 * RSDK.Cos256(angle);1082shot->velocity.y = 0x300 * RSDK.Sin256(angle);1083#endif10841085RSDK.PlaySfx(MegaOctus->sfxBullet, false, 255);1086if (self->shotCount >= 4) {1087self->velocity.y = 0x10000;1088self->state = MegaOctus_StateOrb_Idle;1089}1090else {1091self->timer = 60;1092}1093}10941095MegaOctus_CheckPlayerCollisions_Orb();1096}10971098void MegaOctus_StateOrb_Idle(void)1099{1100RSDK_THIS(MegaOctus);11011102self->angle = (self->angle + 6) & 0x1FF;1103RSDK.ProcessAnimation(&self->altAnimator);11041105if (MegaOctus->defeated) {1106self->invincibilityTimer = 60;1107self->state = MegaOctus_StateOrb_Destroyed;1108}11091110self->position.y += self->velocity.y;1111MegaOctus_CheckPlayerCollisions_Orb();11121113if (self->position.y > self->origin.y)1114destroyEntity(self);1115}11161117void MegaOctus_StateOrb_Destroyed(void)1118{1119RSDK_THIS(MegaOctus);11201121if (!(Zone->timer % 3)) {1122RSDK.PlaySfx(MegaOctus->sfxExplosion, false, 255);11231124if (Zone->timer & 4) {1125int32 x = self->position.x + (RSDK.Cos512(self->angle) << 10) + (RSDK.Rand(-16, 16) << 16);1126int32 y = self->position.y + (RSDK.Sin512(self->angle) << 9) + (RSDK.Rand(-16, 16) << 16);1127EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + 2), x, y);1128explosion->drawGroup = Zone->objectDrawGroup[1] + 2;1129}1130}11311132if (--self->invincibilityTimer <= 0) {1133int32 angle = self->angle;1134int32 y = self->position.y + 0xF80000;11351136EntityDebris *debris = NULL;1137for (int32 i = 0; i < 16; ++i) {1138debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + (RSDK.Cos512(angle) << 10), y + (RSDK.Sin512(angle) << 8));1139RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 3, &debris->animator, true, 1);1140debris->velocity.x = RSDK.Rand(-6, 6) << 15;1141debris->velocity.y = RSDK.Rand(-10, -6) << 15;1142debris->gravityStrength = 0x3800;1143debris->drawGroup = Zone->objectDrawGroup[0] + 1;1144debris->updateRange.x = 0x400000;1145debris->updateRange.y = 0x400000;11461147angle = (angle + 0x40) & 0x1FF;1148y -= 0xF0000;1149}11501151debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + (RSDK.Cos512(angle) << 10), y + (RSDK.Sin512(angle) << 8));1152RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 9, &debris->animator, true, 0);1153debris->velocity.x = -0x20000;1154debris->velocity.y = -0x40000;1155debris->gravityStrength = 0x3800;1156debris->drawGroup = Zone->objectDrawGroup[0] + 1;1157debris->updateRange.x = 0x400000;1158debris->updateRange.y = 0x400000;11591160debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + (RSDK.Cos512(angle) << 10), y + (RSDK.Sin512(angle) << 8));1161RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 9, &debris->animator, true, 1);1162debris->velocity.x = 0x20000;1163debris->velocity.y = -0x40000;1164debris->gravityStrength = 0x3800;1165debris->drawGroup = Zone->objectDrawGroup[0] + 1;1166debris->updateRange.x = 0x400000;1167debris->updateRange.y = 0x400000;11681169debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + (RSDK.Cos512(angle) << 10), y + (RSDK.Sin512(angle) << 8));1170RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 9, &debris->animator, true, 2);1171debris->velocity.x = -0x10000;1172debris->velocity.y = -0x20000;1173debris->gravityStrength = 0x3800;1174debris->drawGroup = Zone->objectDrawGroup[0] + 1;1175debris->updateRange.x = 0x400000;1176debris->updateRange.y = 0x400000;11771178debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + (RSDK.Cos512(angle) << 10), y + (RSDK.Sin512(angle) << 8));1179RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 9, &debris->animator, true, 3);1180debris->velocity.x = 0x10000;1181debris->velocity.y = -0x20000;1182debris->gravityStrength = 0x3800;1183debris->drawGroup = Zone->objectDrawGroup[0] + 1;1184debris->updateRange.x = 0x400000;1185debris->updateRange.y = 0x400000;11861187destroyEntity(self);1188}1189}11901191void MegaOctus_Draw_Orb(void)1192{1193RSDK_THIS(MegaOctus);11941195int32 angle = self->angle;1196int32 y = self->position.y + 0xF80000;11971198if (self->invincibilityTimer & 1)1199RSDK.SetPaletteEntry(0, 128, 0xE0E0E0);12001201Vector2 drawPos;1202for (int32 i = 0; i < 16; ++i) {1203drawPos.x = (RSDK.Cos512(angle) << 10) + self->position.x;1204drawPos.y = (RSDK.Sin512(angle) << 8) + y;1205RSDK.DrawSprite(&self->animator, &drawPos, false);12061207angle = (angle + 0x40) & 0x1FF;1208y -= 0xF0000;1209}12101211drawPos.x = (RSDK.Cos512(angle) << 10) + self->position.x;1212drawPos.y = (RSDK.Sin512(angle) << 8) + y;1213RSDK.DrawSprite(&self->altAnimator, &drawPos, false);12141215RSDK.SetPaletteEntry(0, 128, 0x000000);1216}12171218void MegaOctus_StateArm_WrapAroundPlatform(void)1219{1220RSDK_THIS(MegaOctus);12211222self->angle += 4;12231224self->position.y -= 0xC000;1225self->shotCount += 0xC000;1226self->position.x = 0x1400 * RSDK.Cos256(self->angle) + self->origin.x;12271228if (self->shotCount >= 0x4B0000) {1229if (!self->targetPos) {1230// Create another arm to grab the other platform1231self->targetPos = 1;1232EntityMegaOctus *arm = CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_ARM), self->position.x, self->position.y + 0x40000);1233arm->direction = self->direction;1234arm->state = MegaOctus_StateArm_GrabPlatform;1235arm->stateDraw = MegaOctus_Draw_Arm_WrapAroundPlatformTop;1236}12371238if (self->shotCount >= 0x71A000) {1239self->timer = 30;1240self->state = MegaOctus_StateArm_GrabbedPlatform;1241}1242}1243}12441245void MegaOctus_StateArm_GrabPlatform(void)1246{1247RSDK_THIS(MegaOctus);12481249self->position.x += 0xC000;1250self->shotCount += 0xC000;12511252self->position.y = BadnikHelpers_Oscillate(self->origin.y, -4, 12);12531254if (self->shotCount >= 0x270000) {1255foreach_active(TilePlatform, platform)1256{1257if (RSDK.CheckObjectCollisionTouchBox(self, &self->hitbox, platform, &platform->hitbox)) {1258self->parent = (Entity *)platform;1259#if MANIA_USE_PLUS1260self->tilePlatY = platform->position.y;1261#endif1262RSDK.CopyTileLayer(Zone->fgLayer[0], (platform->position.x >> 20) - 4, (platform->position.y >> 20) - 2, Zone->moveLayer, 10, 1, 8,12635);1264}1265}12661267int32 slot = RSDK.GetEntitySlot(MegaOctus->bossEntity) + 4;12681269EntityCollapsingPlatform *collapsingPlatform = RSDK_GET_ENTITY(slot, CollapsingPlatform);1270collapsingPlatform->collapseDelay = 24;1271collapsingPlatform->stoodPos.x = self->position.x;12721273collapsingPlatform = RSDK_GET_ENTITY(slot + 1, CollapsingPlatform);1274collapsingPlatform->collapseDelay = 24;1275collapsingPlatform->stoodPos.x = self->position.x;12761277self->timer = 30;1278self->state = MegaOctus_StateArm_GrabbedPlatform;1279}1280}12811282void MegaOctus_StateArm_GrabbedPlatform(void)1283{1284RSDK_THIS(MegaOctus);12851286if (--self->timer <= 0) {1287#if !MANIA_USE_PLUS1288foreach_active(Player, player)1289{1290if (abs(player->position.x - player->position.x) < 0x400000 && player->groundedStore) {1291player->state = Player_State_Air;1292player->velocity.y = -0x10000;1293player->onGround = false;1294}1295}1296#endif12971298self->state = MegaOctus_StateArm_PullPlatformDown;1299}1300}13011302void MegaOctus_StateArm_PullPlatformDown(void)1303{1304RSDK_THIS(MegaOctus);13051306EntityTilePlatform *parent = (EntityTilePlatform *)self->parent;13071308self->origin.y += 0x60000;1309self->position.y += 0x60000;13101311if (parent) {1312#if MANIA_USE_PLUS1313parent->state = MegaOctus_TilePlatformState_RiseOuttaOil;1314parent->velocity.y = 0x60000;1315if (parent->drawPos.y - self->tilePlatY > 0x480000)1316parent->stateCollide = Platform_Collision_None;1317#else1318parent->drawPos.y += 0x60000;1319parent->centerPos.y += 0x60000;1320#endif1321}13221323if (++self->timer >= 32) {1324EntityMegaOctus *boss = MegaOctus->bossEntity;1325boss->velocity.y = MANIA_USE_PLUS ? -0x8F400 : -0xB8000;1326boss->state = MegaOctus_State_EnterMegaOctus;13271328MegaOctus->eggmanOffset = 0;1329MegaOctus->eggmanVelocity = 0;1330RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 1, &MegaOctus->eggmanAnimator, true, 0);1331RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 1, &MegaOctus->hatchOpenAnimator, true, 0);1332RSDK.PlaySfx(MegaOctus->sfxSurface, false, 255);13331334if (parent) {1335self->timer = 384;1336self->state = MegaOctus_StateArm_RisePlatformUp;1337#if MANIA_USE_PLUS1338parent->state = StateMachine_None;1339parent->position.y = self->tilePlatY + (self->timer << 15);1340#endif1341}1342else {1343destroyEntity(self);1344}1345}1346}13471348void MegaOctus_StateArm_RisePlatformUp(void)1349{1350RSDK_THIS(MegaOctus);13511352EntityTilePlatform *parent = (EntityTilePlatform *)self->parent;13531354#if MANIA_USE_PLUS1355if (parent) {1356parent->state = MegaOctus_TilePlatformState_RiseOuttaOil;1357parent->timer = 4;1358parent->velocity.y = -0x8000;13591360if (parent->drawPos.y > self->tilePlatY)1361--self->timer;1362else1363self->timer = 0;13641365if (parent->drawPos.y - self->tilePlatY < 0x480000)1366parent->stateCollide = Platform_Collision_Tiles;1367}1368#else1369parent->drawPos.y -= 0x8000;1370parent->centerPos.y -= 0x8000;1371--self->timer;1372#endif13731374if (self->timer <= 0) {1375#if MANIA_USE_PLUS1376if (parent) {1377parent->state = StateMachine_None;1378parent->drawPos.y = self->tilePlatY;1379parent->velocity.y = 0;1380}1381#endif13821383RSDK.CopyTileLayer(Zone->fgLayer[0], (parent->position.x >> 20) - 4, (parent->position.y >> 20) - 2, Zone->moveLayer, 1, 1, 8, 5);1384destroyEntity(self);1385}1386}13871388void MegaOctus_Draw_Arm_WrapAroundPlatformBase(void)1389{1390RSDK_THIS(MegaOctus);13911392int32 pos = 0xA0000;1393Vector2 drawPos = self->position;1394uint8 angle = self->angle;13951396for (int32 i = self->shotCount; i > 0; i -= 0x6000) {1397pos += 0x6000;1398if (pos >= 0x60000) {1399if (i < 0x400000) {1400if ((SceneInfo->currentDrawGroup == Zone->objectDrawGroup[0] + 1 && angle < 0x80)1401|| (SceneInfo->currentDrawGroup == Zone->objectDrawGroup[0] && angle >= 0x80))1402RSDK.DrawSprite(&self->animator, &drawPos, false);1403}1404angle -= 0x20;1405drawPos.y += 0x60000;1406drawPos.x = 0x1400 * RSDK.Cos256(angle) + self->origin.x;1407pos -= 0x60000;1408}1409}1410}14111412void MegaOctus_Draw_Arm_WrapAroundPlatformTop(void)1413{1414RSDK_THIS(MegaOctus);14151416int32 pos = 0xA0000;1417Vector2 drawPos = self->position;1418int32 count = (self->shotCount - 1) / 0x6000 + 1;14191420int32 angle = self->angle;1421uint8 checkAngle = self->angle - 0x40;1422for (int32 i = 0; i < count; ++i) {1423pos += 0x6000;1424if (pos >= 0x60000) {1425if ((SceneInfo->currentDrawGroup == Zone->objectDrawGroup[0] + 1 && checkAngle < 0x80)1426|| (SceneInfo->currentDrawGroup == Zone->objectDrawGroup[0] && checkAngle >= 0x80))1427RSDK.DrawSprite(&self->animator, &drawPos, false);1428checkAngle += 0x20;1429angle += 0x20;1430drawPos.x -= 0x60000;1431drawPos.y = (RSDK.Sin256(angle) << 12) + self->origin.y;1432pos -= 0x60000;1433}1434}1435}14361437void MegaOctus_State_Laser(void)1438{1439RSDK_THIS(MegaOctus);14401441RSDK.ProcessAnimation(&self->animator);14421443self->position.x += self->velocity.x;14441445if (self->timer > 0) {1446self->timer--;1447self->position.y = (RSDK.Sin512(self->parent->angle) << 9) + self->parent->position.y;1448}14491450foreach_active(Player, player)1451{1452if (Player_CheckCollisionTouch(player, self, &self->hitbox))1453Player_Hurt(player, self);1454}14551456if (self->onScreen == 1) {1457if (RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0, 8)) {1458if (self->shotCount != self->position.x >> 20) {1459self->shotCount = self->position.x >> 20;1460RSDK.PlaySfx(MegaOctus->sfxLaserSplash, false, 255);1461CREATE_ENTITY(MegaOctus, INT_TO_VOID(MEGAOCTUS_LASERFIRE), (self->position.x & 0xFFF00000) + 0x80000, self->position.y);1462}1463}1464}14651466if (!RSDK.CheckOnScreen(self, &self->updateRange))1467destroyEntity(self);1468}14691470void MegaOctus_State_LaserFire(void)1471{1472RSDK_THIS(MegaOctus);14731474RSDK.ProcessAnimation(&self->animator);14751476foreach_active(Player, player)1477{1478if (Player_CheckCollisionTouch(player, self, &self->hitbox))1479Player_Hurt(player, self);1480}14811482if (self->animator.frameID == self->animator.frameCount - 1)1483destroyEntity(self);1484}14851486void MegaOctus_Draw_Laser(void)1487{1488RSDK_THIS(MegaOctus);14891490RSDK.DrawSprite(&self->animator, NULL, false);1491}14921493void MegaOctus_State_Shot(void)1494{1495RSDK_THIS(MegaOctus);14961497if (MegaOctus->defeated || !RSDK.CheckOnScreen(self, &self->updateRange)) {1498destroyEntity(self);1499}1500else {1501RSDK.ProcessAnimation(&self->animator);15021503self->position.x += self->velocity.x;1504self->position.y += self->velocity.y;15051506foreach_active(Player, player)1507{1508if (Player_CheckCollisionTouch(player, self, &self->hitbox))1509Player_ProjectileHurt(player, self);1510}1511}1512}15131514void MegaOctus_Draw_OrbShot(void)1515{1516RSDK_THIS(MegaOctus);15171518RSDK.DrawSprite(&self->animator, NULL, false);1519}15201521#if MANIA_USE_PLUS1522void MegaOctus_TilePlatformState_RiseOuttaOil(void)1523{1524EntityTilePlatform *self = RSDK_GET_ENTITY(SceneInfo->entitySlot, TilePlatform);15251526if (self->velocity.y <= 0x10000) {1527foreach_active(Player, player)1528{1529if ((1 << player->playerID) & self->stoodPlayers) {1530if (player->state == OOZSetup_PlayerState_OilPool) {1531player->state = Player_State_Ground;1532OOZSetup->activePlayers &= ~(1 << player->playerID);1533}1534}1535}1536}1537else {1538foreach_active(Player, player)1539{1540if ((1 << player->playerID) & self->stoodPlayers) {1541if (player->state != OOZSetup_PlayerState_OilPool)1542player->velocity.y = self->velocity.y >> 1;15431544player->onGround = false;1545self->stoodPlayers &= ~(1 << player->playerID);1546}1547}1548}15491550self->drawPos.y += self->velocity.y;1551}1552#endif15531554#if GAME_INCLUDE_EDITOR1555void MegaOctus_EditorDraw(void)1556{1557RSDK_THIS(MegaOctus);15581559RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 0, &self->animator, false, 0);1560RSDK.SetSpriteAnimation(MegaOctus->eggmanFrames, 1, &MegaOctus->eggmanAnimator, false, 0);1561RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 1, &MegaOctus->noseAnimator, false, 5);1562RSDK.SetSpriteAnimation(MegaOctus->aniFrames, 2, &MegaOctus->boltsAnimator, false, 5);1563RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 0, &MegaOctus->hatchBaseAnimator, false, 0);1564RSDK.SetSpriteAnimation(MegaOctus->hatchFrames, 1, &MegaOctus->hatchOpenAnimator, false, 0);15651566MegaOctus_Draw_Body();15671568if (showGizmos()) {1569int32 slot = RSDK.GetEntitySlot(self);15701571RSDK_DRAWING_OVERLAY(true);15721573#if MANIA_USE_PLUS1574DrawHelpers_DrawArenaBounds(-192, -384, 448, 96, 1 | 2 | 4 | 8, 0x00C0F0);1575#else1576DrawHelpers_DrawArenaBounds(-192, -384, 448, 96, 1 | 0 | 4 | 8, 0x00C0F0);1577#endif15781579// Tile Platforms1580for (int32 p = 1; p < 4; ++p) {1581EntityTilePlatform *platform = RSDK_GET_ENTITY(slot + p, TilePlatform);1582if (!platform)1583continue;15841585DrawHelpers_DrawArrow(self->position.x, self->position.y, platform->position.x, platform->position.y, 0xFFFF00, INK_NONE, 0xFF);1586}15871588// Collapsing Platforms1589for (int32 p = 4; p < 6; ++p) {1590EntityCollapsingPlatform *platform = RSDK_GET_ENTITY(slot + p, CollapsingPlatform);1591if (!platform)1592continue;15931594DrawHelpers_DrawArrow(self->position.x, self->position.y, platform->position.x, platform->position.y, 0xFFFF00, INK_NONE, 0xFF);1595}1596RSDK_DRAWING_OVERLAY(false);1597}1598}15991600void MegaOctus_EditorLoad(void)1601{1602MegaOctus->aniFrames = RSDK.LoadSpriteAnimation("OOZ/MegaOctus.bin", SCOPE_STAGE);1603MegaOctus->eggmanFrames = RSDK.LoadSpriteAnimation("Eggman/EggmanOOZ.bin", SCOPE_STAGE);1604MegaOctus->hatchFrames = RSDK.LoadSpriteAnimation("OOZ/Hatch.bin", SCOPE_STAGE);1605}1606#endif16071608void MegaOctus_Serialize(void) {}160916101611