Path: blob/master/SonicMania/Objects/SPZ/HeavyGunner.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: HeavyGunner Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectHeavyGunner *HeavyGunner;1011void HeavyGunner_Update(void)12{13RSDK_THIS(HeavyGunner);1415StateMachine_Run(self->state);16}1718void HeavyGunner_LateUpdate(void) {}1920void HeavyGunner_StaticUpdate(void) {}2122void HeavyGunner_Draw(void)23{24RSDK_THIS(HeavyGunner);2526StateMachine_Run(self->stateDraw);27}2829void HeavyGunner_Create(void *data)30{31RSDK_THIS(HeavyGunner);3233if (!SceneInfo->inEditor) {34if (globals->gameMode < MODE_TIMEATTACK) {35if (data) {36self->type = VOID_TO_INT(data);37self->active = ACTIVE_NORMAL;38self->visible = true;39self->drawGroup = Zone->objectDrawGroup[0] - 1;4041switch (self->type) {42case HEAVYGUNNER_HELI:43RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 6, &self->mainAnimator, true, 0);44RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 14, &self->pilotAnimator, true, 0);45RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 7, &self->frontAnimator, true, 0);46RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 8, &self->tBladeAnimator, true, 0);47RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 9, &self->rBladeAnimator, true, 0);48RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 10, &self->beaconAnimator, true, 0);49RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feetAnimator, true, 0);50RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feet2Animator, true, 2);51RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 0, &self->gunnerAnimator, true, 0);5253self->drawFX = FX_ROTATE;54self->rotation = 0x40;55self->state = HeavyGunner_StateHeli_AwaitPlayer;56self->stateDraw = HeavyGunner_Draw_Heli;57break;5859case HEAVYGUNNER_EGGROBO:60RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 17, &self->feetAnimator, true, 0);61RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 16, &self->mainAnimator, true, RSDK.Rand(0, 4));62self->drawFX = FX_SCALE | FX_ROTATE;63self->state = HeavyGunner_StateEggRobo_Patrolling;64self->stateDraw = HeavyGunner_Draw_EggRobo;65self->scale.x = 0x200;66self->scale.y = 0x200;67self->targetScale = 512;68self->parentOffset = RSDK.Rand(-0x200000, 0x600000);69self->timer = 240;70break;7172case HEAVYGUNNER_GUN:73RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 20, &self->mainAnimator, true, 0);74self->drawFX = FX_ROTATE;75self->rotation = 64;76self->state = HeavyGunner_StateGun_Thrown;77self->stateDraw = HeavyGunner_Draw_Simple;78break;7980case HEAVYGUNNER_MISSILE_F:81case HEAVYGUNNER_MISSILE:82if (self->type == HEAVYGUNNER_MISSILE_F)83RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 29, &self->mainAnimator, true, 0);84else85RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 30, &self->mainAnimator, true, 0);86self->drawFX = FX_SCALE | FX_ROTATE | FX_FLIP;87self->velocity.x = 0x40000;88self->velocity.y = -0x38000;89self->scale.x = 0x100;90self->scale.y = 0x100;91self->rotation = -24;92self->state = HeavyGunner_StateMissile_Launched;93self->stateDraw = HeavyGunner_Draw_Missile;94self->drawGroup = Zone->objectDrawGroup[0];95break;9697case HEAVYGUNNER_ESCAPE_HBH:98RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 5, &self->mainAnimator, true, 0);99self->velocity.x = -0x20000;100self->velocity.y = -0x20000;101self->state = HeavyGunner_StateEscapeHBH_Hover;102self->stateDraw = HeavyGunner_Draw_Simple;103self->drawGroup = Zone->objectDrawGroup[0];104break;105106default: break;107}108}109else {110Zone->autoScrollSpeed = 0;111self->active = ACTIVE_XBOUNDS;112self->updateRange.x = 0x800000;113self->updateRange.y = 0x800000;114self->state = HeavyGunner_StateManager_SetupArena;115}116}117else {118destroyEntity(self);119}120}121}122123void HeavyGunner_StageLoad(void)124{125HeavyGunner->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Boss.bin", SCOPE_STAGE);126127HeavyGunner->sfxFire = RSDK.GetSfx("Stage/CannonFire.wav");128HeavyGunner->sfxJet = RSDK.GetSfx("Stage/RocketJet.wav");129HeavyGunner->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");130HeavyGunner->sfxDestroy = RSDK.GetSfx("Global/Destroy.wav");131HeavyGunner->sfxExplosion2 = RSDK.GetSfx("Stage/Explosion2.wav");132HeavyGunner->sfxExplosion3 = RSDK.GetSfx("Stage/Explosion3.wav");133HeavyGunner->sfxCharge = RSDK.GetSfx("SPZ1/BazookaCharge.wav");134HeavyGunner->sfxThrow = RSDK.GetSfx("SPZ1/BazookaThrow.wav");135HeavyGunner->sfxFlyIn = RSDK.GetSfx("SPZ1/EggRoboFlyIn.wav");136HeavyGunner->sfxWooshIn = RSDK.GetSfx("SPZ1/HeliWooshIn.wav");137HeavyGunner->sfxWooshOut = RSDK.GetSfx("SPZ1/HeliWooshOut.wav");138HeavyGunner->sfxFlip = RSDK.GetSfx("SPZ1/RocketFlip.wav");139HeavyGunner->sfxRumble = RSDK.GetSfx("SPZ1/Rumble.wav");140141Soundboard_LoadSfx("SPZ1/HBHSurprise.wav", true, HeavyGunner_SfxCheck_HBHSurprise, StateMachine_None);142Soundboard_LoadSfx("SPZ1/HeliProp.wav", true, HeavyGunner_SfxCheck_HeliProp, StateMachine_None);143Soundboard_LoadSfx("SPZ1/RocketBurn.wav", true, HeavyGunner_SfxCheck_RocketBurn, StateMachine_None);144145// Absolutely zero clue what these are for146HeavyGunner->unused1 = 0x470000;147HeavyGunner->unused2 = 0x2D0000;148HeavyGunner->unused3 = 0x100000;149HeavyGunner->unused4 = 0x80000;150151HeavyGunner->hitboxMissileF.left = -32;152HeavyGunner->hitboxMissileF.top = -8;153HeavyGunner->hitboxMissileF.right = 32;154HeavyGunner->hitboxMissileF.bottom = 8;155156HeavyGunner->hitboxMissile.left = -16;157HeavyGunner->hitboxMissile.top = -8;158HeavyGunner->hitboxMissile.right = 16;159HeavyGunner->hitboxMissile.bottom = 8;160161HeavyGunner->active = ACTIVE_NEVER;162}163164bool32 HeavyGunner_SfxCheck_HeliProp(void)165{166Vector2 range;167168range.x = 0x800000;169range.y = 0x800000;170bool32 active = false;171172foreach_active(HeavyGunner, gunner)173{174if (RSDK.CheckOnScreen(gunner, &range) && gunner->tBladeAnimator.animationID == 8)175active = true;176}177return active;178}179180bool32 HeavyGunner_SfxCheck_HBHSurprise(void)181{182Vector2 range;183184range.x = 0x800000;185range.y = 0x800000;186bool32 active = false;187188foreach_active(HeavyGunner, gunner)189{190if (RSDK.CheckOnScreen(gunner, &range) && gunner->gunnerAnimator.animationID == 3 && gunner->mainAnimator.animationID != 12)191active = true;192}193194return active;195}196197bool32 HeavyGunner_SfxCheck_RocketBurn(void)198{199Vector2 range;200201range.x = 0x800000;202range.y = 0x800000;203bool32 active = false;204205foreach_active(HeavyGunner, gunner)206{207if (RSDK.CheckOnScreen(gunner, &range) && gunner->exhaustAnimator.animationID == 25)208active = true;209}210return active;211}212213void HeavyGunner_HandleBGWrap(int32 multiplier)214{215TileLayer *background1 = RSDK.GetTileLayer(0);216for (int32 s = 0; s < background1->scrollInfoCount; ++s) {217background1->scrollInfo[s].scrollPos += multiplier * background1->scrollInfo[s].parallaxFactor;218}219220TileLayer *background2 = RSDK.GetTileLayer(1);221for (int32 s = 0; s < background2->scrollInfoCount; ++s) {222background2->scrollInfo[s].scrollPos += multiplier * background2->scrollInfo[s].parallaxFactor;223}224225TileLayer *background3 = RSDK.GetTileLayer(2);226for (int32 s = 0; s < background3->scrollInfoCount; ++s) {227background3->scrollInfo[s].scrollPos += multiplier * background3->scrollInfo[s].parallaxFactor;228}229}230231void HeavyGunner_DestroyAllMissiles(void)232{233RSDK_THIS(HeavyGunner);234235foreach_active(HeavyGunner, gunner)236{237if (gunner != self) {238if (gunner->type == HEAVYGUNNER_MISSILE_F || gunner->type == HEAVYGUNNER_MISSILE) {239RSDK.PlaySfx(HeavyGunner->sfxFlip, false, 0xFF);240gunner->velocity.x = -0x10000;241RSDK.SetSpriteAnimation(-1, 0, &gunner->exhaustAnimator, true, 0);242243gunner->direction = FLIP_NONE;244gunner->rotation = 256;245gunner->state = HeavyGunner_StateMissile_Malfunction;246}247}248}249}250251void HeavyGunner_Draw_Heli(void)252{253RSDK_THIS(HeavyGunner);254Vector2 drawPos;255256drawPos.x = self->position.x + 0x1B0000;257drawPos.y = self->position.y;258259RSDK.DrawSprite(&self->feetAnimator, &drawPos, false);260RSDK.DrawSprite(&self->mainAnimator, NULL, false);261RSDK.DrawSprite(&self->pilotAnimator, NULL, false);262RSDK.DrawSprite(&self->frontAnimator, NULL, false);263RSDK.DrawSprite(&self->tBladeAnimator, NULL, false);264RSDK.DrawSprite(&self->rBladeAnimator, NULL, false);265RSDK.DrawSprite(&self->beaconAnimator, NULL, false);266RSDK.DrawSprite(&self->feet2Animator, NULL, false);267RSDK.DrawSprite(&self->gunnerAnimator, NULL, false);268}269270void HeavyGunner_Draw_EggRobo(void)271{272RSDK_THIS(HeavyGunner);273274RSDK.DrawSprite(&self->feetAnimator, NULL, false);275RSDK.DrawSprite(&self->mainAnimator, NULL, false);276RSDK.DrawSprite(&self->armAnimator, NULL, false);277}278279void HeavyGunner_Draw_Missile(void)280{281RSDK_THIS(HeavyGunner);282283RSDK.DrawSprite(&self->mainAnimator, NULL, false);284RSDK.DrawSprite(&self->exhaustAnimator, NULL, false);285}286287void HeavyGunner_Draw_Simple(void)288{289RSDK_THIS(HeavyGunner);290RSDK.DrawSprite(&self->mainAnimator, NULL, false);291}292293void HeavyGunner_Draw_FadeOut(void)294{295RSDK_THIS(HeavyGunner);296297RSDK.FillScreen(0xF0F0F0, self->timer, self->timer - 128, self->timer - 256);298}299300void HeavyGunner_StateManager_SetupArena(void)301{302RSDK_THIS(HeavyGunner);303304if (++self->timer >= 8) {305EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);306307if (player1->position.x >= self->position.x - 0x1000000) {308HeavyGunner->active = ACTIVE_ALWAYS;309self->timer = 0;310self->active = ACTIVE_NORMAL;311312EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);313self->position.x = camera->position.x - 0x100000;314self->position.y = camera->position.y;315316Zone->playerBoundActiveL[0] = true;317Zone->playerBoundActiveR[0] = true;318HeavyGunner->boundsL = Zone->cameraBoundsL[0];319HeavyGunner->boundsR = Zone->cameraBoundsR[0];320HeavyGunner->boundsT = Zone->cameraBoundsT[0];321HeavyGunner->boundsB = 0xC00;322HeavyGunner->stageWrapActive = true;323324int32 mult = -0x1E00 * ScreenInfo->position.y;325326TileLayer *background1 = RSDK.GetTileLayer(0);327background1->scrollPos += mult;328background1->parallaxFactor = 88;329330TileLayer *background2 = RSDK.GetTileLayer(1);331background2->scrollPos += mult;332background2->parallaxFactor = 88;333334TileLayer *background3 = RSDK.GetTileLayer(2);335background3->scrollPos += mult;336background3->parallaxFactor = 88;337338foreach_active(ParallaxSprite, sprite)339{340sprite->parallaxFactor.y = 0x5800;341sprite->position.y -= mult;342}343344Zone->autoScrollSpeed = player1->velocity.x;345346EntityHeavyGunner *robo1 = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, HeavyGunner);347int32 x = robo1->position.x;348int32 y = robo1->position.y;349RSDK.ResetEntitySlot(SceneInfo->entitySlot + 1, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_EGGROBO));350robo1->position.x = x;351robo1->position.y = y;352robo1->parent = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);353robo1->angle = 0;354RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 22, &robo1->armAnimator, true, 0);355356EntityHeavyGunner *robo2 = RSDK_GET_ENTITY(SceneInfo->entitySlot + 2, HeavyGunner);357x = robo2->position.x;358y = robo2->position.y;359RSDK.ResetEntitySlot(SceneInfo->entitySlot + 2, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_EGGROBO));360robo2->position.x = x;361robo2->position.y = y;362robo2->parent = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);363robo2->angle = 80;364RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 23, &robo2->armAnimator, true, 0);365366EntityHeavyGunner *robo3 = RSDK_GET_ENTITY(SceneInfo->entitySlot + 3, HeavyGunner);367x = robo3->position.x;368y = robo3->position.y;369RSDK.ResetEntitySlot(SceneInfo->entitySlot + 3, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_EGGROBO));370robo3->position.x = x;371robo3->position.y = y;372robo3->parent = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);373robo3->angle = 160;374robo3->timer = 0;375robo3->state = HeavyGunner_StateEggRobo_FlyIn;376RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 19, &robo3->armAnimator, true, 0);377378EntityHeavyGunner *heli = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);379x = heli->position.x;380y = heli->position.y;381RSDK.ResetEntitySlot(SceneInfo->entitySlot + 4, HeavyGunner->classID, INT_TO_VOID(HEAVYGUNNER_HELI));382heli->position.x = x;383heli->position.y = y;384385self->state = HeavyGunner_StateManager_HandleStageWrap;386Music_TransitionTrack(TRACK_HBHBOSS, 0.0125);387}388}389}390391void HeavyGunner_StateManager_HandleStageWrap(void)392{393RSDK_THIS(HeavyGunner);394395self->position.x += Zone->autoScrollSpeed;396397if (HeavyGunner->stageWrapActive) {398if (self->position.x >= 0x49800000) {399HeavyGunner_HandleBGWrap(0x80000);400401foreach_active(HeavyGunner, gunner) { gunner->position.x -= 0x8000000; }402403for (int32 p = 0; p < Player->playerCount; ++p) {404EntityPlayer *player = RSDK_GET_ENTITY(p, Player);405player->position.x -= 0x8000000;406}407408foreach_active(Ring, ring) { ring->position.x -= 0x8000000; }409410foreach_active(ImageTrail, imageTrail)411{412imageTrail->position.x -= 0x8000000;413imageTrail->currentPos.x -= 0x8000000;414for (int32 i = 0; i < IMAGETRAIL_TRACK_COUNT; ++i) imageTrail->statePos[i].x -= 0x8000000;415}416}417418Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;419Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;420Zone->playerBoundsL[0] = Zone->cameraBoundsL[0] << 16;421Zone->playerBoundsR[0] = Zone->cameraBoundsR[0] << 16;422423EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);424camera->boundsL = Zone->cameraBoundsL[0];425camera->boundsR = Zone->cameraBoundsR[0];426427if (self->flyInTimer == 120) {428if (!RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 0x40))429self->position.y += 0x80000;430Zone->cameraBoundsB[0] = (self->position.y >> 16) + 168;431Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - ScreenInfo->size.y;432}433else {434self->flyInTimer++;435}436}437else if (self->position.x < 0x49800000) {438Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x;439Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x;440Zone->playerBoundsL[0] = Zone->cameraBoundsL[0] << 16;441Zone->playerBoundsR[0] = Zone->cameraBoundsR[0] << 16;442443EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);444camera->boundsL = Zone->cameraBoundsL[0];445camera->boundsR = Zone->cameraBoundsR[0];446447if (self->flyInTimer == 120) {448if (!RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 0x40))449self->position.y += 0x80000;450Zone->cameraBoundsB[0] = (self->position.y >> 16) + 168;451Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - ScreenInfo->size.y;452}453else {454self->flyInTimer++;455}456}457else {458Zone->cameraBoundsL[0] = HeavyGunner->boundsL;459Zone->cameraBoundsR[0] = HeavyGunner->boundsR;460Zone->cameraBoundsT[0] = HeavyGunner->boundsT;461Zone->cameraBoundsB[0] = HeavyGunner->boundsB;462Zone->playerBoundActiveR[0] = false;463464for (int32 p = 0; p < Player->playerCount; ++p) {465EntityPlayer *player = RSDK_GET_ENTITY(p, Player);466if (player->stateInput == Player_Input_P1) {467player->stateInput = HeavyGunner_Input_LockedP1;468}469else if (player->stateInput == Player_Input_P2_Player) {470player->stateInput = HeavyGunner_Input_LockedP2;471}472else if (player->stateInput == Player_Input_P2_AI) {473player->stateInput = HeavyGunner_Input_LockedP2_AI;474}475}476477self->state = HeavyGunner_StateManager_HandlePathChange;478}479480if (Zone->autoScrollSpeed > 0x70000) {481Zone->autoScrollSpeed -= 0x2000;482if (Zone->autoScrollSpeed < 0x70000)483Zone->autoScrollSpeed = 0x70000;484}485else if (Zone->autoScrollSpeed < 0x70000) {486Zone->autoScrollSpeed += 0x2000;487if (Zone->autoScrollSpeed > 0x70000)488Zone->autoScrollSpeed = 0x70000;489}490491for (int32 p = 0; p < Player->playerCount; ++p) {492EntityPlayer *player = RSDK_GET_ENTITY(p, Player);493494if (player->groundVel < Zone->autoScrollSpeed - 0x20000)495player->groundVel = Zone->autoScrollSpeed - 0x20000;496497player->direction = FLIP_NONE;498player->topSpeed = Zone->autoScrollSpeed + 0x20000;499500if (player->state == Player_State_KnuxGlideLeft) {501player->timer = 0;502player->animator.frameID = 6;503player->state = Player_State_KnuxGlideRight;504player->abilitySpeed = Zone->autoScrollSpeed - 0x18000;505}506else if (player->state == Player_State_KnuxGlideRight) {507if (player->abilitySpeed < Zone->autoScrollSpeed - 0x18000)508player->abilitySpeed = Zone->autoScrollSpeed - 0x18000;509}510511if (player->groundVel > player->topSpeed)512player->groundVel = player->topSpeed;513}514}515516void HeavyGunner_StateManager_HandlePathChange(void)517{518RSDK_THIS(HeavyGunner);519520EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);521if (camera->position.x <= 0x51800000) {522for (int32 p = 0; p < Player->playerCount; ++p) {523EntityPlayer *player = RSDK_GET_ENTITY(p, Player);524525if (player->onGround) {526if (player->groundVel < 0x80000)527player->groundVel = 0x80000;528}529else if (player->velocity.x < 0x80000) {530player->velocity.x = 0x80000;531}532533player->direction = FLIP_NONE;534535if (player->state == Player_State_KnuxGlideLeft) {536player->timer = 0;537player->animator.frameID = 6;538player->state = Player_State_KnuxGlideRight;539player->abilitySpeed = Zone->autoScrollSpeed;540}541else if (player->state == Player_State_KnuxGlideRight) {542if (player->abilitySpeed < Zone->autoScrollSpeed)543player->abilitySpeed = Zone->autoScrollSpeed;544}545}546}547else {548camera->position.x -= 0x10000000;549self->position.x = camera->position.x - 0x100000;550self->position.y = camera->position.y - 0x800000;551HeavyGunner_HandleBGWrap(0x100000);552553for (int32 p = 0; p < Player->playerCount; ++p) {554EntityPlayer *player = RSDK_GET_ENTITY(p, Player);555player->position.x -= 0x10000000;556if (player->velocity.x > Zone->autoScrollSpeed)557Zone->autoScrollSpeed = player->velocity.x;558}559560foreach_active(Ring, ring) { ring->position.x -= 0x10000000; }561562foreach_active(ImageTrail, imageTrail)563{564imageTrail->position.x -= 0x10000000;565imageTrail->currentPos.x -= 0x10000000;566for (int32 i = 0; i < IMAGETRAIL_TRACK_COUNT; ++i) imageTrail->statePos[i].x -= 0x10000000;567}568569for (int32 p = 0; p < Player->playerCount; ++p) {570EntityPlayer *player = RSDK_GET_ENTITY(p, Player);571572if (player->stateInput == HeavyGunner_Input_LockedP1)573player->stateInput = Player_Input_P1;574else if (player->stateInput == HeavyGunner_Input_LockedP2)575player->stateInput = Player_Input_P2_Player;576else if (player->stateInput == HeavyGunner_Input_LockedP2_AI)577player->stateInput = Player_Input_P2_AI;578}579580Zone->playerBoundActiveR[0] = true;581HeavyGunner->stageWrapActive = true;582self->state = HeavyGunner_StateManager_HandleStageWrap;583584EntityHeavyGunner *heli = RSDK_GET_ENTITY(SceneInfo->entitySlot + 4, HeavyGunner);585heli->position.x = camera->position.x - 0x1200000;586heli->position.y = camera->position.y - 0xC00000;587RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 1, &heli->gunnerAnimator, true, 0);588heli->state = HeavyGunner_StateHeli_AwaitPlayer;589590for (int32 c = 3 - heli->nextRoboID; c > 0; --c) {591EntityHeavyGunner *robo = RSDK_GET_ENTITY(SceneInfo->entitySlot + c, HeavyGunner);592robo->position.x = camera->position.x - 0x200000;593robo->position.y = camera->position.y - 0xC00000;594}595}596}597598void HeavyGunner_Input_LockedP1(void)599{600RSDK_THIS(Player);601602Player_Input_P1();603604if (self->state != Player_State_Static) {605self->up = false;606self->down = false;607self->jumpPress = false;608self->jumpHold = false;609}610}611612void HeavyGunner_Input_LockedP2(void)613{614RSDK_THIS(Player);615616Player_Input_P2_Player();617618self->up = false;619self->down = false;620self->jumpPress = false;621self->jumpHold = false;622623if (self->stateInput == Player_Input_P2_AI)624self->stateInput = HeavyGunner_Input_LockedP2_AI;625}626627void HeavyGunner_Input_LockedP2_AI(void)628{629RSDK_THIS(Player);630Player_Input_P2_AI();631632self->up = false;633self->down = false;634self->jumpPress = false;635self->jumpHold = false;636637if (self->stateInput == Player_Input_P2_Player)638self->stateInput = HeavyGunner_Input_LockedP2;639}640641void HeavyGunner_StateEggRobo_Patrolling(void)642{643RSDK_THIS(HeavyGunner);644EntityHeavyGunner *parent = self->parent;645646RSDK.ProcessAnimation(&self->mainAnimator);647RSDK.ProcessAnimation(&self->feetAnimator);648RSDK.ProcessAnimation(&self->armAnimator);649650int32 angle = RSDK.Sin256(self->angle);651if (self->position.x > parent->position.x)652angle -= 0x40;653654self->position.x += (angle << 9) + Zone->autoScrollSpeed;655self->rotation = (RSDK.Sin256(self->angle) >> 4) - 32;656self->angle = (self->angle + 1) & 0xFF;657658if (self->scale.x < self->targetScale)659self->scale.x += 2;660else if (self->scale.x > self->targetScale)661self->scale.x -= 2;662663self->scale.y = self->scale.x;664if (self->scale.x <= 0x200)665self->drawGroup = Zone->objectDrawGroup[0] - 1;666else667self->drawGroup = Zone->objectDrawGroup[1];668669if (parent->state == HeavyGunner_StateHeli_EscapeMissile)670self->velocity.y = -0x8000;671else672self->velocity.y += ((parent->position.y + self->parentOffset - self->position.y) >> 8) - (self->velocity.y >> 4);673674self->position.y += self->velocity.y;675if (--self->timer <= 0) {676self->timer = RSDK.Rand(120, 240);677678self->parentOffset = RSDK.Rand(-0x200000, 0x600000);679switch (RSDK.Rand(0, 8)) {680case 0:681case 1:682case 2:683case 3:684case 4: self->targetScale = 0x200; break;685686case 5:687case 6: self->targetScale = 0x180; break;688689case 7: self->targetScale = 0x300; break;690691default: break;692}693}694}695696void HeavyGunner_StateEggRobo_FlyIn(void)697{698RSDK_THIS(HeavyGunner);699700if (++self->timer == 120) {701self->position.x = self->parent->position.x - 0x1800000;702self->position.y = self->parent->position.y + 0x800000;703self->scale.x = 0x400;704self->scale.y = 0x400;705self->velocity.x = 0x6A000;706self->drawGroup = Zone->objectDrawGroup[1];707RSDK.PlaySfx(HeavyGunner->sfxFlyIn, false, 0xFF);708self->state = HeavyGunner_StateEggRobo_ThrowGun;709}710}711712void HeavyGunner_StateEggRobo_ThrowGun(void)713{714RSDK_THIS(HeavyGunner);715716RSDK.ProcessAnimation(&self->mainAnimator);717RSDK.ProcessAnimation(&self->feetAnimator);718RSDK.ProcessAnimation(&self->armAnimator);719720self->velocity.x -= 0x1000;721self->position.x += self->velocity.x + Zone->autoScrollSpeed;722self->position.y += self->velocity.y + ((self->parent->position.y - self->position.y + 0x400000) >> 6);723724self->rotation = (self->velocity.x - 0x40000) >> 13;725726if (self->velocity.x < 0 && self->position.x < self->parent->position.x + 0x600000) {727self->drawGroup = Zone->objectDrawGroup[0] - 1;728RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 21, &self->armAnimator, true, 0);729self->state = HeavyGunner_StateEggRobo_ThrownGun;730731EntityHeavyGunner *child = CREATE_ENTITY(HeavyGunner, INT_TO_VOID(HEAVYGUNNER_GUN), self->position.x + 0x80000, self->position.y - 0x80000);732child->velocity.x = -0x34000;733child->velocity.y = -0x80000;734child->parent = self->parent;735RSDK.PlaySfx(HeavyGunner->sfxThrow, false, 0xFF);736}737738if (self->scale.x > 0x200) {739self->scale.x -= 4;740self->scale.y = self->scale.x;741}742}743744void HeavyGunner_StateEggRobo_ThrownGun(void)745{746RSDK_THIS(HeavyGunner);747748RSDK.ProcessAnimation(&self->mainAnimator);749RSDK.ProcessAnimation(&self->feetAnimator);750RSDK.ProcessAnimation(&self->armAnimator);751752self->position.x += Zone->autoScrollSpeed;753self->velocity.y += ((self->parent->position.y - self->position.y + 0x400000) >> 8) - (self->velocity.y >> 4);754self->position.y += self->velocity.y;755756if (self->armAnimator.frameID >= self->armAnimator.frameCount - 1) {757RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 18, &self->armAnimator, true, 0);758self->timer = 0;759self->state = HeavyGunner_StateEggRobo_Patrolling;760}761}762763void HeavyGunner_StateGun_Thrown(void)764{765RSDK_THIS(HeavyGunner);766767EntityHeavyGunner *parent = self->parent;768769self->velocity.y += 0x4000;770self->rotation = (self->rotation - 16) & 0x1FF;771self->position.x += self->velocity.x + Zone->autoScrollSpeed;772self->position.y += self->velocity.y;773774if (self->position.x < parent->position.x - 0x180000)775self->velocity.x = 0;776777if (self->velocity.y > 0 && self->position.y > parent->position.y - 0x200000) {778RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 1, &parent->gunnerAnimator, true, 0);779RSDK.PlaySfx(Player->sfxGrab, false, 255);780self->drawGroup = Zone->hudDrawGroup;781self->state = HeavyGunner_StateGun_Grabbed;782self->timer = 0x200;783self->stateDraw = HeavyGunner_Draw_FadeOut;784}785}786787void HeavyGunner_StateGun_Grabbed(void)788{789RSDK_THIS(HeavyGunner);790791self->timer -= 64;792if (!self->timer)793destroyEntity(self);794}795796void HeavyGunner_StateMissile_Launched(void)797{798RSDK_THIS(HeavyGunner);799800RSDK.ProcessAnimation(&self->mainAnimator);801802self->velocity.x -= 0x1800;803self->velocity.y += 0x3800;804805self->position.x += self->velocity.x + Zone->autoScrollSpeed;806self->position.y += self->velocity.y;807808self->scale.x += ((0x200 - self->scale.x) >> 3);809self->scale.y = self->scale.x;810811if (self->rotation < 0)812self->rotation++;813814if (++self->timer == 32) {815self->scale.x = 0x200;816self->timer = self->missileID + 48;817self->scale.y = 0x200;818RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 26, &self->exhaustAnimator, true, 0);819self->state = HeavyGunner_StateMissile_BlastOff;820RSDK.PlaySfx(HeavyGunner->sfxJet, false, 255);821}822}823824void HeavyGunner_StateMissile_BlastOff(void)825{826RSDK_THIS(HeavyGunner);827828RSDK.ProcessAnimation(&self->mainAnimator);829RSDK.ProcessAnimation(&self->exhaustAnimator);830831if (self->velocity.x < 0x80000)832self->velocity.x += 0x3800;833834self->position.x += self->velocity.x + Zone->autoScrollSpeed;835836if (self->exhaustAnimator.animationID == 26 && self->exhaustAnimator.frameID == self->exhaustAnimator.frameCount - 1)837RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 25, &self->exhaustAnimator, true, 0);838839if (!(Zone->timer & 3)) {840EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x - 0x180000, self->position.y);841explosion->drawGroup = Zone->objectDrawGroup[0] - 1;842explosion->drawFX = FX_ROTATE;843explosion->rotation = 128;844}845846if (--self->timer <= 0) {847self->timer = 0;848self->state = HeavyGunner_StateMissile_FindFloor;849}850}851852void HeavyGunner_StateMissile_FindFloor(void)853{854RSDK_THIS(HeavyGunner);855856self->position.x += Zone->autoScrollSpeed;857self->position.y += 0x20000;858859if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {860self->direction = FLIP_X;861self->velocity.x = self->type == HEAVYGUNNER_MISSILE ? -0x10000 : -0x20000;862self->state = HeavyGunner_StateMissile_AttackPlayer;863}864}865866void HeavyGunner_StateMissile_AttackPlayer(void)867{868RSDK_THIS(HeavyGunner);869870RSDK.ProcessAnimation(&self->mainAnimator);871RSDK.ProcessAnimation(&self->exhaustAnimator);872873self->position.x += self->velocity.x + Zone->autoScrollSpeed;874RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, 64);875876Hitbox *hitbox = self->type == HEAVYGUNNER_MISSILE ? &HeavyGunner->hitboxMissile : &HeavyGunner->hitboxMissileF;877878foreach_active(Player, player)879{880if (Player_CheckBadnikTouch(player, self, hitbox)) {881if (Player_CheckAttacking(player, self) && self->type == HEAVYGUNNER_MISSILE) {882if (player->onGround) {883player->groundVel = Zone->autoScrollSpeed - 0x20000;884}885#if MANIA_USE_PLUS886else if (player->state != Player_State_MightyHammerDrop) {887#endif888player->velocity.y = -player->velocity.y;889if (player->velocity.y > -0x40000)890player->velocity.y = -0x40000;891#if MANIA_USE_PLUS892}893#endif894self->velocity.x = -0x10000;895RSDK.SetSpriteAnimation(-1, 0, &self->exhaustAnimator, true, 0);896self->direction = FLIP_NONE;897self->rotation = 256;898self->state = HeavyGunner_StateMissile_Malfunction;899900RSDK.PlaySfx(HeavyGunner->sfxHit, false, 255);901RSDK.PlaySfx(HeavyGunner->sfxFlip, false, 255);902}903else {904Player_Hurt(player, self);905RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);906907int32 x = RSDK.Cos512(self->rotation) << 11;908int32 y = RSDK.Sin512(self->rotation) << 11;909EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x + x, self->position.y + y);910911RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSS, &debris->animator, true, 0);912debris->velocity.x = self->velocity.x + Zone->autoScrollSpeed;913debris->drawGroup = Zone->objectDrawGroup[0];914debris->timer = 41;915destroyEntity(self);916}917}918}919}920921void HeavyGunner_StateMissile_Malfunction(void)922{923RSDK_THIS(HeavyGunner);924925RSDK.ProcessAnimation(&self->mainAnimator);926927self->position.x += self->velocity.x + Zone->autoScrollSpeed + (RSDK.Cos512(self->rotation) << 8);928self->position.y += (RSDK.Sin512(self->rotation) - 0x200) << 8;929930self->rotation += 0x20;931932if (!(Zone->timer & 3)) {933int32 x = RSDK.Cos512(self->rotation) << 11;934int32 y = RSDK.Sin512(self->rotation) << 11;935CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x - x, self->position.y - y);936}937938if (self->rotation == 0x400) {939EntityHeavyGunner *parent = self->parent;940if (parent->gunnerAnimator.animationID == 3) {941EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x, self->position.y);942RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);943debris->velocity.x = Zone->autoScrollSpeed;944debris->drawGroup = Zone->objectDrawGroup[1];945debris->drawFX = FX_SCALE;946debris->scale.x = 0x300;947debris->scale.y = 0x300;948debris->timer = 52;949--parent->missileID;950destroyEntity(self);951RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);952}953else {954self->state = HeavyGunner_StateMissile_ReturnToSender;955self->rotation = 0;956self->velocity.x = 0;957RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 3, &parent->gunnerAnimator, true, 0);958RSDK.PlaySfx(HeavyGunner->sfxJet, false, 255);959}960}961}962963void HeavyGunner_StateMissile_ReturnToSender(void)964{965RSDK_THIS(HeavyGunner);966EntityHeavyGunner *parent = self->parent;967968RSDK.ProcessAnimation(&self->mainAnimator);969970self->position.x += self->velocity.x + Zone->autoScrollSpeed;971self->position.y += self->velocity.y;972973self->velocity.y += ((parent->position.y - self->position.y) >> 8) - (self->velocity.y >> 4);974975self->velocity.x = CLAMP(self->velocity.x, -0x20000, 0x70000);976977if (self->rotation <= -0x100 || self->direction) {978self->rotation = 0;979self->direction = FLIP_X;980self->velocity.x -= RSDK.Cos512(self->rotation) << 6;981982int32 x = 0, y = 0;983EntityDebris *debris = NULL;984switch (Zone->timer & 3) {985default: break;986987case 0:988x = RSDK.Cos512(self->rotation) << 11;989y = RSDK.Sin512(self->rotation) << 11;990debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x + x, self->position.y + y);991992RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);993debris->velocity.x = (RSDK.Cos512(self->rotation) << 8) + Zone->autoScrollSpeed;994debris->velocity.y = 16 * RSDK.Cos512(self->rotation);995debris->drawGroup = Zone->objectDrawGroup[0];996debris->timer = 41;997break;998999case 2:1000x = 0x600 * RSDK.Cos512(self->rotation);1001y = 0x600 * RSDK.Sin512(self->rotation);1002debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);10031004RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);1005debris->velocity.x = Zone->autoScrollSpeed;1006debris->drawGroup = Zone->objectDrawGroup[1];1007debris->drawFX = FX_SCALE;1008debris->scale.x = RSDK.Rand(0x80, 0x180);1009debris->scale.y = debris->scale.x;1010debris->timer = 52;1011break;1012}10131014if (self->position.x - parent->position.x < TO_FIXED(160)) {1015if (parent->nextRoboID >= 3) {1016parent->velocity.y = 0;1017parent->timer = 0;1018parent->state = HeavyGunner_StateHeli_IncomingMissile;1019self->state = HeavyGunner_StateMissile_AttackGunner;1020}1021else {1022parent->nextRoboID++;1023self->parent = RSDK_GET_ENTITY(RSDK.GetEntitySlot(parent) - parent->nextRoboID, HeavyGunner);1024parent->state = HeavyGunner_StateHeli_EscapeMissile;1025self->state = HeavyGunner_StateMissile_AttackRobo;1026RSDK.PlaySfx(HeavyGunner->sfxWooshOut, false, 255);1027}10281029self->groundVel = 0x100;1030}1031}1032else {1033self->rotation -= 4;1034self->velocity.x += RSDK.Cos512(self->rotation) << 6;10351036int32 x = 0, y = 0;1037EntityDebris *debris = NULL;1038switch (Zone->timer & 3) {1039default: break;10401041case 0:1042x = RSDK.Cos512(self->rotation) << 11;1043y = RSDK.Sin512(self->rotation) << 11;1044debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);10451046RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);1047debris->velocity.x = Zone->autoScrollSpeed - (RSDK.Cos512(self->rotation) << 8);1048debris->velocity.y = -16 * RSDK.Cos512(self->rotation);1049debris->drawGroup = Zone->objectDrawGroup[0];1050debris->timer = 41;1051break;10521053case 2:1054x = 0x600 * RSDK.Cos512(self->rotation);1055y = 0x600 * RSDK.Sin512(self->rotation);1056debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);10571058RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSS, &debris->animator, true, 0);1059debris->velocity.x = Zone->autoScrollSpeed;1060debris->drawGroup = Zone->objectDrawGroup[1];1061debris->drawFX = FX_SCALE;1062debris->scale.x = RSDK.Rand(0x80, 0x180);1063debris->scale.y = debris->scale.x;1064debris->timer = 52;1065break;1066}1067}1068}10691070void HeavyGunner_StateMissile_AttackRobo(void)1071{1072RSDK_THIS(HeavyGunner);10731074EntityHeavyGunner *parent = self->parent;10751076RSDK.ProcessAnimation(&self->mainAnimator);10771078int32 angle = RSDK.ATan2(self->position.x - parent->position.x, self->position.y - parent->position.y);1079self->groundVel += 16;1080self->rotation = 2 * angle;10811082self->velocity.x = self->groundVel * RSDK.Cos512(self->rotation);1083self->velocity.y = self->groundVel * RSDK.Sin512(self->rotation);1084self->position.x += Zone->autoScrollSpeed - self->velocity.x;1085self->position.y -= self->velocity.y;10861087if (self->scale.x >= parent->scale.x) {1088if (self->scale.x > parent->scale.x)1089self->scale.x -= 2;1090}1091else {1092self->scale.x += 2;1093}10941095self->scale.y = self->scale.x;1096self->drawGroup = parent->drawGroup;1097if (Zone->timer & 3) {1098if ((Zone->timer & 3) == 2) {1099int32 x = 0x600 * RSDK.Cos512(self->rotation);1100int32 y = 0x600 * RSDK.Sin512(self->rotation);1101EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);1102RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);1103debris->velocity.x = Zone->autoScrollSpeed;1104debris->drawGroup = Zone->objectDrawGroup[1];1105debris->drawFX = FX_SCALE;1106debris->scale.x = RSDK.Rand(0x80, 0x180);1107debris->scale.y = debris->scale.x;1108debris->timer = 52;1109}1110}1111else {1112int32 x = RSDK.Cos512(self->rotation) << 11;1113int32 y = RSDK.Sin512(self->rotation) << 11;1114EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x + self->position.x, y + self->position.y);1115RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);1116debris->velocity.x = (RSDK.Cos512(self->rotation) << 8) + Zone->autoScrollSpeed;1117debris->velocity.y = 16 * RSDK.Cos512(self->rotation);1118debris->drawGroup = Zone->objectDrawGroup[0];1119debris->timer = 41;1120}11211122int32 rx = (self->position.x - parent->position.x) >> 16;1123int32 ry = (self->position.y - parent->position.y) >> 16;1124if (rx * rx + ry * ry < 0x100) {1125for (int32 i = 0; i < 12; ++i) {1126int32 x = self->position.x + RSDK.Rand(-0xC0000, 0xC0000);1127int32 y = self->position.y + RSDK.Rand(-0xC0000, 0xC0000);1128EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);1129RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 28, &debris->animator, true, i >> 1);1130debris->velocity.x = Zone->autoScrollSpeed + RSDK.Rand(-0x20000, 0x20000);1131debris->velocity.y = RSDK.Rand(-0x20000, 0x20000) - 0x40000;1132debris->gravityStrength = 0x3800;1133debris->scale = parent->scale;1134debris->rotSpeed = RSDK.Rand(-24, 24);1135debris->drawGroup = Zone->objectDrawGroup[0];1136if (i >> 1 < 3)1137debris->drawFX = FX_SCALE | FX_ROTATE;1138}11391140EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, parent->position.x, parent->position.y);1141RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_ENEMY, &debris->animator, true, 0);1142debris->velocity.x = Zone->autoScrollSpeed;1143debris->drawGroup = Zone->objectDrawGroup[1];1144debris->timer = 32;1145HeavyGunner->stageWrapActive = false;11461147int32 plane = RSDK.Rand(0, 2);1148foreach_active(Player, player) { player->collisionPlane = plane; }11491150--parent->parent->missileID;1151destroyEntity(self);1152destroyEntity(parent);1153RSDK.PlaySfx(HeavyGunner->sfxDestroy, false, 255);1154RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);1155HeavyGunner_DestroyAllMissiles();1156}1157}11581159void HeavyGunner_StateMissile_AttackGunner(void)1160{1161RSDK_THIS(HeavyGunner);1162EntityHeavyGunner *parent = self->parent;11631164RSDK.ProcessAnimation(&self->mainAnimator);11651166int32 angle = RSDK.ATan2(self->position.x - parent->position.x, self->position.y - parent->position.y);1167self->groundVel += 16;1168self->rotation = 2 * angle;11691170self->velocity.x = self->groundVel * RSDK.Cos512(self->rotation);1171self->velocity.y = self->groundVel * RSDK.Sin512(self->rotation);1172self->position.x += Zone->autoScrollSpeed - self->velocity.x;1173self->position.y -= self->velocity.y;11741175if (Zone->timer & 3) {1176if ((Zone->timer & 3) == 2) {1177int32 x = 0x600 * RSDK.Cos512(self->rotation);1178int32 y = 0x600 * RSDK.Sin512(self->rotation);1179EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - x, self->position.y - y);1180RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);1181debris->velocity.x = Zone->autoScrollSpeed;1182debris->drawGroup = Zone->objectDrawGroup[1];1183debris->drawFX = FX_SCALE;1184debris->scale.x = RSDK.Rand(0x80, 0x180);1185debris->scale.y = debris->scale.x;1186debris->timer = 52;1187}1188}1189else {1190int32 x = RSDK.Cos512(self->rotation) << 11;1191int32 y = RSDK.Sin512(self->rotation) << 11;1192EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x + self->position.x, y + self->position.y);1193RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSSPUFF, &debris->animator, true, 0);1194debris->velocity.x = (RSDK.Cos512(self->rotation) << 8) + Zone->autoScrollSpeed;1195debris->velocity.y = 16 * RSDK.Cos512(self->rotation);1196debris->drawGroup = Zone->objectDrawGroup[0];1197debris->timer = 41;1198}11991200int32 rx = (self->position.x - parent->position.x) >> 16;1201int32 ry = (self->position.y - parent->position.y) >> 16;1202if (rx * rx + ry * ry < 0x300) {1203for (int32 i = 0; i < 12; ++i) {1204int32 x = self->position.x + RSDK.Rand(0x60000, 0x180000);1205int32 y = self->position.y + RSDK.Rand(-0xC0000, 0xC0000);1206EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, x, y);1207RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 28, &debris->animator, true, i >> 1);1208debris->velocity.x = Zone->autoScrollSpeed + RSDK.Rand(-0x20000, 0x20000);1209debris->velocity.y = RSDK.Rand(-0x20000, 0x20000) - 0x40000;1210debris->gravityStrength = 0x3800;1211debris->rotSpeed = RSDK.Rand(-24, 24);1212debris->drawGroup = Zone->objectDrawGroup[1];1213if (i >> 1 < 3)1214debris->drawFX = FX_ROTATE;1215}12161217EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x, self->position.y - 0x200000);1218RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 13, &debris->animator, true, 0);1219debris->velocity.x = Zone->autoScrollSpeed + RSDK.Rand(-0x20000, 0x20000);1220debris->velocity.y = RSDK.Rand(-0x20000, 0x20000) - 0x40000;1221debris->gravityStrength = 0x3800;1222debris->drawGroup = Zone->objectDrawGroup[1];12231224debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x + 0x60000, self->position.y - 0x40000);1225RSDK.SetSpriteAnimation(Explosion->aniFrames, EXPLOSION_BOSS, &debris->animator, true, 0);1226debris->velocity.x = Zone->autoScrollSpeed;1227debris->drawGroup = Zone->objectDrawGroup[1];1228debris->drawFX = FX_SCALE;1229debris->scale.x = 768;1230debris->scale.y = 768;1231debris->timer = 52;12321233destroyEntity(self);1234RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->mainAnimator, true, 0);1235RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->frontAnimator, true, 1);1236RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->tBladeAnimator, true, 2);1237RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 12, &parent->beaconAnimator, true, 3);1238RSDK.SetSpriteAnimation(-1, 0, &parent->pilotAnimator, true, 0);12391240--parent->missileID;1241parent->state = HeavyGunner_StateHeli_Exploding;1242SceneInfo->timeEnabled = false;1243Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);1244RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);1245self->defeated = true; // ? self was destroyed, this wont do a thing right??1246HeavyGunner_DestroyAllMissiles();1247}1248}12491250void HeavyGunner_StateHeli_AwaitPlayer(void)1251{1252RSDK_THIS(HeavyGunner);12531254if (RSDK_GET_ENTITY(SLOT_PLAYER1, Player)->position.x > self->position.x) {1255self->velocity.x = 0x40000;1256self->velocity.y = 0;1257self->drawFX = FX_ROTATE;1258self->state = HeavyGunner_StateHeli_WooshIn;12591260Camera_ShakeScreen(0, 12, 12);1261RSDK.PlaySfx(HeavyGunner->sfxRumble, false, 255);1262RSDK.PlaySfx(HeavyGunner->sfxWooshIn, false, 255);1263Zone->deathBoundary[0] += 0x8000000;1264}1265}12661267void HeavyGunner_StateHeli_WooshIn(void)1268{1269RSDK_THIS(HeavyGunner);12701271RSDK.ProcessAnimation(&self->mainAnimator);1272RSDK.ProcessAnimation(&self->pilotAnimator);1273RSDK.ProcessAnimation(&self->frontAnimator);1274RSDK.ProcessAnimation(&self->tBladeAnimator);1275RSDK.ProcessAnimation(&self->rBladeAnimator);1276RSDK.ProcessAnimation(&self->beaconAnimator);1277RSDK.ProcessAnimation(&self->feetAnimator);1278RSDK.ProcessAnimation(&self->feet2Animator);1279RSDK.ProcessAnimation(&self->gunnerAnimator);12801281self->position.x += self->velocity.x;1282self->position.x += Zone->autoScrollSpeed;1283self->position.y += 0x10000;12841285self->rotation = (self->velocity.x + 0x40000) >> 13;1286if (self->rotation < 0)1287self->rotation = 0;12881289RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, true);1290if (self->position.x > Zone->playerBoundsL[0] + ((ScreenInfo->center.x - 16) << 16))1291self->state = HeavyGunner_StateHeli_FindFloor;1292}12931294void HeavyGunner_StateHeli_FindFloor(void)1295{1296RSDK_THIS(HeavyGunner);12971298RSDK.ProcessAnimation(&self->mainAnimator);1299RSDK.ProcessAnimation(&self->pilotAnimator);1300RSDK.ProcessAnimation(&self->frontAnimator);1301RSDK.ProcessAnimation(&self->tBladeAnimator);1302RSDK.ProcessAnimation(&self->rBladeAnimator);1303RSDK.ProcessAnimation(&self->beaconAnimator);1304RSDK.ProcessAnimation(&self->feetAnimator);1305RSDK.ProcessAnimation(&self->feet2Animator);1306RSDK.ProcessAnimation(&self->gunnerAnimator);13071308self->velocity.x -= 0x1000;1309self->position.x += self->velocity.x;1310self->position.x += Zone->autoScrollSpeed;1311self->position.y += 0x10000;13121313self->rotation = (self->velocity.x + 0x40000) >> 13;1314if (self->rotation < 0)1315self->rotation = 0;13161317bool32 collided = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, true);1318if (self->velocity.x < 0 && collided && self->position.x < Zone->playerBoundsL[0] + ((ScreenInfo->center.x - 16) << 16)) {1319self->velocity.x = 0;1320self->drawFX = FX_NONE;1321if (self->nextRoboID > 0)1322self->timer = 240;13231324self->state = HeavyGunner_StateHeli_HandleAttacks;1325}1326}13271328void HeavyGunner_StateHeli_HandleAttacks(void)1329{1330RSDK_THIS(HeavyGunner);13311332RSDK.ProcessAnimation(&self->mainAnimator);1333RSDK.ProcessAnimation(&self->pilotAnimator);1334RSDK.ProcessAnimation(&self->frontAnimator);1335RSDK.ProcessAnimation(&self->tBladeAnimator);1336RSDK.ProcessAnimation(&self->rBladeAnimator);1337RSDK.ProcessAnimation(&self->beaconAnimator);1338RSDK.ProcessAnimation(&self->feetAnimator);1339RSDK.ProcessAnimation(&self->feet2Animator);1340RSDK.ProcessAnimation(&self->gunnerAnimator);13411342self->position.x += Zone->autoScrollSpeed;1343RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 64);13441345self->position.y += RSDK.Sin256(self->angle) << 11;1346self->angle = (self->angle + 3) & 0xFF;13471348if (self->gunnerAnimator.animationID == 3)1349self->timer = 0;13501351if (++self->timer == 320) {1352RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 2, &self->gunnerAnimator, true, 0);1353RSDK.PlaySfx(HeavyGunner->sfxCharge, false, 255);1354}13551356if (self->timer == 380) {1357RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 1, &self->gunnerAnimator, true, 0);1358self->timer = 0;1359self->state = HeavyGunner_StateHeli_ShotsFired;1360self->drawFX = FX_ROTATE;1361self->velocity.x = -0x30000;13621363int32 dudID = RSDK.Rand(0, 3);13641365EntityHeavyGunner *child =1366CREATE_ENTITY(HeavyGunner, INT_TO_VOID((dudID == 0) + HEAVYGUNNER_MISSILE_F), self->position.x - 0x200000, self->position.y - 0x100000);1367child->velocity.y -= 0x10000;1368child->parent = self;1369child->missileID = 0;1370++self->missileID;13711372child =1373CREATE_ENTITY(HeavyGunner, INT_TO_VOID((dudID == 1) + HEAVYGUNNER_MISSILE_F), self->position.x - 0x200000, self->position.y - 0x100000);1374child->parent = self;1375child->missileID = 15 * ((dudID != 1) + 1);1376++self->missileID;13771378child =1379CREATE_ENTITY(HeavyGunner, INT_TO_VOID((dudID == 2) + HEAVYGUNNER_MISSILE_F), self->position.x - 0x200000, self->position.y - 0x100000);1380child->velocity.y += 0x10000;1381child->parent = self;1382child->missileID = 30 * ((dudID != 2) + 1);1383++self->missileID;13841385EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, self->position.x - 0x200000, self->position.y - 0x140000);1386RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 27, &debris->animator, true, 0);1387debris->timer = 22;1388debris->drawGroup = Zone->objectDrawGroup[1];1389debris->velocity.x = Zone->autoScrollSpeed;1390RSDK.PlaySfx(HeavyGunner->sfxFire, false, 255);1391}1392}13931394void HeavyGunner_StateHeli_ShotsFired(void)1395{1396RSDK_THIS(HeavyGunner);13971398RSDK.ProcessAnimation(&self->mainAnimator);1399RSDK.ProcessAnimation(&self->pilotAnimator);1400RSDK.ProcessAnimation(&self->frontAnimator);1401RSDK.ProcessAnimation(&self->tBladeAnimator);1402RSDK.ProcessAnimation(&self->rBladeAnimator);1403RSDK.ProcessAnimation(&self->beaconAnimator);1404RSDK.ProcessAnimation(&self->feetAnimator);1405RSDK.ProcessAnimation(&self->feet2Animator);1406RSDK.ProcessAnimation(&self->gunnerAnimator);14071408self->velocity.x += 0x1800;1409self->position.x += self->velocity.x + Zone->autoScrollSpeed;1410self->rotation = self->velocity.x >> 14;14111412RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x800000, 64);14131414self->position.y += RSDK.Sin256(self->angle) << 11;1415self->angle = (self->angle + 3) & 0xFF;14161417if (self->rotation > 0)1418self->rotation = 0;14191420if (self->position.x > Zone->playerBoundsL[0] + ((ScreenInfo->center.x - 16) << 16)) {1421self->velocity.x = 0;1422self->drawFX = FX_NONE;1423self->state = HeavyGunner_StateHeli_HandleAttacks;1424}1425}14261427void HeavyGunner_StateHeli_EscapeMissile(void)1428{1429RSDK_THIS(HeavyGunner);14301431RSDK.ProcessAnimation(&self->mainAnimator);1432RSDK.ProcessAnimation(&self->pilotAnimator);1433RSDK.ProcessAnimation(&self->frontAnimator);1434RSDK.ProcessAnimation(&self->tBladeAnimator);1435RSDK.ProcessAnimation(&self->rBladeAnimator);1436RSDK.ProcessAnimation(&self->beaconAnimator);1437RSDK.ProcessAnimation(&self->feetAnimator);1438RSDK.ProcessAnimation(&self->feet2Animator);1439RSDK.ProcessAnimation(&self->gunnerAnimator);14401441self->position.x += self->velocity.x + Zone->autoScrollSpeed;1442self->position.y += self->velocity.y;1443self->velocity.y -= 0x4000;1444}14451446void HeavyGunner_StateHeli_IncomingMissile(void)1447{1448RSDK_THIS(HeavyGunner);14491450RSDK.ProcessAnimation(&self->mainAnimator);1451RSDK.ProcessAnimation(&self->pilotAnimator);1452RSDK.ProcessAnimation(&self->frontAnimator);1453RSDK.ProcessAnimation(&self->tBladeAnimator);1454RSDK.ProcessAnimation(&self->rBladeAnimator);1455RSDK.ProcessAnimation(&self->beaconAnimator);1456RSDK.ProcessAnimation(&self->feetAnimator);1457RSDK.ProcessAnimation(&self->feet2Animator);14581459self->position.x += self->velocity.x + Zone->autoScrollSpeed;1460self->velocity.x -= 0xE00;14611462if (self->velocity.y < 0x400)1463self->velocity.y += 16;14641465self->position.y += self->velocity.y * RSDK.Sin256(self->angle);1466self->angle = (self->angle + 6) & 0xFF;14671468if (!self->timer) {1469self->timer = 1;1470RSDK.SetSpriteAnimation(-1, 0, &self->gunnerAnimator, true, 0);1471CREATE_ENTITY(HeavyGunner, INT_TO_VOID(HEAVYGUNNER_ESCAPE_HBH), self->position.x - 0x80000, self->position.y - 0x20000);14721473EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x - 0x300000, self->position.y - 0x240000);1474RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 20, &debris->animator, true, 0);1475debris->velocity.y = -0x20000;1476debris->velocity.x = Zone->autoScrollSpeed - 0x20000;1477debris->gravityStrength = 0x3800;1478debris->drawFX = FX_ROTATE;1479debris->rotSpeed = -16;1480debris->drawGroup = Zone->objectDrawGroup[1];1481}1482}14831484void HeavyGunner_StateHeli_Exploding(void)1485{1486RSDK_THIS(HeavyGunner);14871488RSDK.ProcessAnimation(&self->mainAnimator);1489RSDK.ProcessAnimation(&self->rBladeAnimator);1490RSDK.ProcessAnimation(&self->feetAnimator);1491RSDK.ProcessAnimation(&self->feet2Animator);14921493self->position.x += self->velocity.x + Zone->autoScrollSpeed;1494if (self->velocity.x < 0x8000)1495self->velocity.x += 0xE00;14961497self->position.y += self->velocity.y * RSDK.Sin256(self->angle);1498self->angle = (self->angle + 6) & 0xFF;14991500++self->timer;1501if ((self->timer & 7) == 2)1502RSDK.PlaySfx(HeavyGunner->sfxExplosion2, false, 255);15031504if (!(self->timer & 0x1F))1505RSDK.PlaySfx(HeavyGunner->sfxHit, false, 255);15061507if (!(self->timer & 3)) {1508int32 x = self->position.x + RSDK.Rand(-0x300000, 0x300000);1509int32 y = self->position.y + RSDK.Rand(-0x300000, 0x300000);15101511EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(RSDK.Rand(EXPLOSION_BOSS, EXPLOSION_BOSSPUFF + 1)), x, y);1512explosion->drawGroup = Zone->objectDrawGroup[1];1513explosion->drawFX = FX_SCALE;1514explosion->scale.x = RSDK.Rand(0x100, 0x300);1515explosion->scale.y = explosion->scale.x;1516}15171518if (self->timer > 60) {1519self->timer = 0;15201521EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x, self->position.y);1522RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &debris->animator, true, self->feetAnimator.frameID);1523debris->velocity.y = -0x10000;1524debris->velocity.x = Zone->autoScrollSpeed - 0x10000;1525debris->gravityStrength = 0x3800;1526debris->drawGroup = Zone->objectDrawGroup[1];15271528debris = CREATE_ENTITY(Debris, Debris_State_Fall, self->position.x + 0x1B0000, self->position.y);1529RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &debris->animator, true, self->feet2Animator.frameID);1530debris->velocity.y = -0x10000;1531debris->velocity.x = Zone->autoScrollSpeed + 0x10000;1532debris->gravityStrength = 0x3800;1533debris->drawGroup = Zone->objectDrawGroup[0] - 1;1534RSDK.SetSpriteAnimation(-1, 0, &self->feetAnimator, true, 0);1535RSDK.SetSpriteAnimation(-1, 0, &self->feet2Animator, true, 0);1536self->state = HeavyGunner_StateHeli_ExplodeAndFall;1537}1538}15391540void HeavyGunner_StateHeli_ExplodeAndFall(void)1541{1542RSDK_THIS(HeavyGunner);15431544RSDK.ProcessAnimation(&self->mainAnimator);1545RSDK.ProcessAnimation(&self->rBladeAnimator);15461547self->velocity.y += 0x3800;1548self->position.x += self->velocity.x + Zone->autoScrollSpeed;1549self->position.y += self->velocity.y;15501551if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x200000, true))1552self->velocity.y = -(self->velocity.y >> 1);15531554self->timer++;1555if ((self->timer & 7) == 2)1556RSDK.PlaySfx(HeavyGunner->sfxExplosion2, false, 255);15571558if (!(self->timer & 0x1F))1559RSDK.PlaySfx(HeavyGunner->sfxHit, false, 255);15601561if (!(self->timer & 3)) {1562int32 x = self->position.x + RSDK.Rand(-0x300000, 0x300000);1563int32 y = self->position.y + RSDK.Rand(-0x300000, 0x300000);1564EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(RSDK.Rand(EXPLOSION_BOSS, EXPLOSION_BOSSPUFF + 1)), x, y);15651566explosion->drawGroup = Zone->objectDrawGroup[1];1567explosion->drawFX = FX_SCALE;1568explosion->scale.x = RSDK.Rand(0x100, 0x200);1569explosion->scale.y = explosion->scale.x;1570}15711572if (self->timer > 200) {1573self->drawGroup = Zone->hudDrawGroup;1574self->state = HeavyGunner_StateHeli_FadeOutDestroy;1575self->timer = 768;1576self->stateDraw = HeavyGunner_Draw_FadeOut;15771578Music_TransitionTrack(TRACK_STAGE, 0.0125);1579RSDK.PlaySfx(HeavyGunner->sfxExplosion3, false, 255);15801581EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);1582camera->position.x = 0x57C00000;1583if (camera->position.y <= 0x6600000) {1584camera->position.y = 0x2EC0000;1585if (camera->position.y > 0x3800000)1586camera->position.y = 0x5EC0000;1587}1588else {1589camera->position.y = 0x8EC0000;1590}15911592foreach_active(Player, player)1593{1594player->position.x = 0x57C00000;1595player->position.y = camera->position.y;1596}15971598foreach_all(SignPost, signPost)1599{1600signPost->position.y = camera->position.y;1601Zone->cameraBoundsL[0] = (signPost->position.x >> 16) - 512;1602RSDK.ObjectTileGrip(signPost, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x180000, 0x40);1603}16041605Zone->autoScrollSpeed = 0;1606Zone->cameraBoundsR[0] = HeavyGunner->boundsR;1607Zone->playerBoundActiveR[0] = false;1608destroyEntitySlot(SceneInfo->entitySlot - 4);1609}1610}16111612void HeavyGunner_StateEscapeHBH_Hover(void)1613{1614RSDK_THIS(HeavyGunner);16151616RSDK.ProcessAnimation(&self->mainAnimator);16171618self->velocity.y += 0x3800;1619self->position.x += self->velocity.x + Zone->autoScrollSpeed;1620self->position.y += self->velocity.y;16211622if (++self->timer == 30) {1623self->timer = 0;1624RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 4, &self->mainAnimator, true, 0);1625self->state = HeavyGunner_StateEscapeHBH_FlyAway;1626RSDK.PlaySfx(HeavyGunner->sfxJet, false, 0xFF);1627}1628}16291630void HeavyGunner_StateEscapeHBH_FlyAway(void)1631{1632RSDK_THIS(HeavyGunner);16331634RSDK.ProcessAnimation(&self->mainAnimator);16351636self->velocity.y -= 0x6000;1637self->position.x += self->velocity.x + Zone->autoScrollSpeed;1638self->position.y += self->velocity.y;1639if (++self->timer == 60)1640destroyEntity(self);1641}16421643void HeavyGunner_StateHeli_FadeOutDestroy(void)1644{1645RSDK_THIS(HeavyGunner);16461647self->timer -= 8;1648if (!self->timer)1649destroyEntity(self);1650}16511652#if GAME_INCLUDE_EDITOR1653void HeavyGunner_EditorDraw(void)1654{1655RSDK_THIS(HeavyGunner);16561657RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 6, &self->mainAnimator, true, 0);1658RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 14, &self->pilotAnimator, true, 0);1659RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 7, &self->frontAnimator, true, 0);1660RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 8, &self->tBladeAnimator, true, 0);1661RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 9, &self->rBladeAnimator, true, 0);1662RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 10, &self->beaconAnimator, true, 0);1663RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feetAnimator, true, 0);1664RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 11, &self->feet2Animator, true, 2);1665RSDK.SetSpriteAnimation(HeavyGunner->aniFrames, 0, &self->gunnerAnimator, true, 0);1666self->drawFX = FX_ROTATE;1667self->rotation = 0x40;16681669HeavyGunner_Draw_Heli();16701671if (showGizmos()) {1672RSDK_DRAWING_OVERLAY(true);16731674for (int32 i = 0; i < 4; ++i) {1675EntityHeavyGunner *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1 + i, HeavyGunner);16761677if (child)1678DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xE0E0E0, INK_NONE, 0xFF);1679}16801681RSDK_DRAWING_OVERLAY(false);1682}1683}16841685void HeavyGunner_EditorLoad(void) { HeavyGunner->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Boss.bin", SCOPE_STAGE); }1686#endif16871688void HeavyGunner_Serialize(void) {}168916901691