Path: blob/master/SonicMania/Objects/LRZ/HeavyKing.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: HeavyKing Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectHeavyKing *HeavyKing;1011void HeavyKing_Update(void)12{13RSDK_THIS(HeavyKing);1415RSDK.ProcessAnimation(&self->bodyAnimator);16RSDK.ProcessAnimation(&self->scepterAnimator);1718if (self->invincibilityTimer > 0)19self->invincibilityTimer--;2021StateMachine_Run(self->state);22}2324void HeavyKing_LateUpdate(void) {}2526void HeavyKing_StaticUpdate(void) {}2728void HeavyKing_Draw(void)29{30RSDK_THIS(HeavyKing);3132if (self->invincibilityTimer & 1) {33RSDK.CopyPalette(2, 16, 0, 16, 16);34RSDK.CopyPalette(2, 192, 0, 192, 16);3536RSDK.DrawSprite(&self->bodyAnimator, NULL, false);37RSDK.DrawSprite(&self->scepterAnimator, NULL, false);38RSDK.DrawSprite(&self->electricityAnimator, NULL, false);3940RSDK.CopyPalette(1, 16, 0, 16, 16);41RSDK.CopyPalette(1, 192, 0, 192, 16);42}43else {44RSDK.DrawSprite(&self->bodyAnimator, NULL, false);45RSDK.DrawSprite(&self->scepterAnimator, NULL, false);46RSDK.DrawSprite(&self->electricityAnimator, NULL, false);47}48}4950void HeavyKing_Create(void *data)51{52RSDK_THIS(HeavyKing);5354if (!SceneInfo->inEditor) {55if (globals->gameMode == MODE_TIMEATTACK) {56destroyEntity(self);57}58else {59self->drawGroup = Zone->objectDrawGroup[0];60self->drawFX = FX_FLIP;61self->active = ACTIVE_BOUNDS;62self->updateRange.x = 0xC00000;63self->updateRange.y = 0x800000;64self->health = 8;65self->state = HeavyKing_State_SetupArena;6667RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 7, &self->bodyAnimator, true, 0);68RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 16, &self->scepterAnimator, true, 0);69}70}71}7273void HeavyKing_StageLoad(void)74{75HeavyKing->aniFrames = RSDK.LoadSpriteAnimation("LRZ3/HeavyKing.bin", SCOPE_STAGE);76HeavyKing->cutsceneFrames = RSDK.LoadSpriteAnimation("Players/KnuxCutsceneHPZ.bin", SCOPE_STAGE);7778HeavyKing->attackPatternPos = 0;7980HeavyKing->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");81HeavyKing->sfxImpact2 = RSDK.GetSfx("Stage/Impact2.wav");82HeavyKing->sfxImpact5 = RSDK.GetSfx("Stage/Impact5.wav");83HeavyKing->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");84HeavyKing->sfxFreeze = RSDK.GetSfx("PSZ/Freeze.wav");85HeavyKing->sfxCharge = RSDK.GetSfx("LRZ/KingCharge.wav");86HeavyKing->sfxImpact6 = RSDK.GetSfx("Stage/Impact6.wav");87HeavyKing->sfxRodPlant = RSDK.GetSfx("LRZ/RodPlant.wav");88HeavyKing->sfxRodShine = RSDK.GetSfx("LRZ/RodShine.wav");89HeavyKing->sfxElecOn = RSDK.GetSfx("LRZ/ElecOn.wav");90HeavyKing->sfxTwinCharge = RSDK.GetSfx("LRZ/TwinCharge.wav");9192HeavyKing->hitboxBody.left = -24;93HeavyKing->hitboxBody.top = 40;94HeavyKing->hitboxBody.right = 24;95HeavyKing->hitboxBody.bottom = 44;9697HeavyKing->hitboxBoss.left = -20;98HeavyKing->hitboxBoss.top = 20;99HeavyKing->hitboxBoss.right = 20;100HeavyKing->hitboxBoss.bottom = 16;101102HeavyKing->hitboxCharging.left = -32;103HeavyKing->hitboxCharging.top = -40;104HeavyKing->hitboxCharging.right = 32;105HeavyKing->hitboxCharging.bottom = 40;106}107108void HeavyKing_CheckPlayerCollisions(void)109{110RSDK_THIS(HeavyKing);111112foreach_active(Player, player)113{114if (!self->invincibilityTimer && Player_CheckBadnikTouch(player, self, &HeavyKing->hitboxBoss) && Player_CheckBossHit(player, self)) {115HeavyKing_Hit();116}117}118}119120void HeavyKing_CheckPlayerCollisions_Charging(void)121{122RSDK_THIS(HeavyKing);123124foreach_active(Player, player)125{126if (!self->invincibilityTimer && Player_CheckCollisionTouch(player, self, &HeavyKing->hitboxCharging)) {127Player_ElementHurt(player, self, SHIELD_LIGHTNING);128}129}130}131132void HeavyKing_Hit(void)133{134RSDK_THIS(HeavyKing);135136if (--self->health <= 0) {137RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 6, &self->bodyAnimator, false, 0);138RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 15, &self->scepterAnimator, false, 0);139140self->state = HeavyKing_State_Destroyed;141self->velocity.y = -0x40000;142self->onGround = false;143self->timer = 0;144RSDK.StopSfx(HeavyKing->sfxTwinCharge);145146foreach_active(KingAttack, attack) { destroyEntity(attack); }147148SceneInfo->timeEnabled = false;149Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);150}151else {152if (self->bodyAnimator.animationID == 5) {153self->invincibilityTimer = 48;154}155else {156self->invincibilityTimer = 96;157self->stateStore = self->state;158self->storedBodyAnimator = self->bodyAnimator;159self->storedScepterAnimator = self->scepterAnimator;160161RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 6, &self->bodyAnimator, false, 0);162RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 15, &self->scepterAnimator, false, 0);163self->state = HeavyKing_State_HitRecoil;164}165166RSDK.PlaySfx(HeavyKing->sfxHit, false, 255);167}168}169170void HeavyKing_Explode(void)171{172RSDK_THIS(HeavyKing);173174if (!(Zone->timer & 7)) {175RSDK.PlaySfx(HeavyKing->sfxExplosion, false, 255);176177if (!(Zone->timer & 0xF)) {178int32 x = self->position.x + RSDK.Rand(-0x180000, 0x180000);179int32 y = self->position.y + RSDK.Rand(-0x180000, 0x180000);180CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y)->drawGroup = Zone->objectDrawGroup[1];181}182}183}184185void HeavyKing_HandleClawMovement(void)186{187RSDK_THIS(HeavyKing);188189EntityKingClaw *claw = self->claw;190191if (claw) {192self->position = claw->position;193194if (self->direction == FLIP_NONE)195self->position.x += 0x300000;196else197self->position.x -= 0x300000;198self->position.y += 0x9C0000;199}200}201202void HeavyKing_HandleAnimators(void)203{204RSDK_THIS(HeavyKing);205206self->bodyAnimator.speed = 0;207self->scepterAnimator.speed = 0;208209if (self->velocity.y >= 0) {210if (self->velocity.y <= 0x10000) {211self->bodyAnimator.frameID = 7;212self->scepterAnimator.frameID = 7;213}214else {215self->bodyAnimator.frameID = 8;216self->scepterAnimator.frameID = 8;217}218}219else if (self->velocity.y >= -0x10000) {220self->bodyAnimator.frameID = 6;221self->scepterAnimator.frameID = 6;222}223else {224self->bodyAnimator.frameID = 5;225self->scepterAnimator.frameID = 5;226}227}228229void HeavyKing_HandleHoverMovement(void)230{231RSDK_THIS(HeavyKing);232233EntityPlayer *player = Player_GetNearestPlayerX();234235int32 bounds = HeavyKing->boundsL;236if (player->position.x >= bounds) {237bounds = player->position.x;238if (player->position.x > HeavyKing->boundsR)239bounds = HeavyKing->boundsR;240}241242int32 angle = RSDK.ATan2((bounds - self->position.x) >> 16, (player->position.y - self->position.y) >> 16);243int32 rot = 2 * angle;244245if (abs(rot) >= abs(rot - 0x200)) {246if (abs(rot - 0x200) < abs(rot + 0x200))247self->rotation += ((rot - 0x200) >> 5);248else249self->rotation += ((rot + 0x200) >> 5);250}251else {252if (abs(rot) < abs(rot + 0x200))253self->rotation += (rot >> 5);254else255self->rotation += ((rot + 0x200) >> 5);256}257258self->rotation &= 0x1FF;259260int32 rx = (self->position.x - HeavyKing->boundsM) >> 16;261self->velocity.x = CLAMP(self->velocity.x + (8 * RSDK.Cos512(self->rotation)), -0x20000, 0x20000);262self->position.x += self->velocity.x;263self->originPos.y = HeavyKing->startY + 96 * abs(rx * rx);264self->direction = self->position.x <= player->position.x;265}266267void HeavyKing_FindTargetEmerald(void)268{269RSDK_THIS(HeavyKing);270271EntityHPZEmerald *targetEmerald = NULL;272int32 emeraldDist = 0x7FFFFFFF;273274if (self->onGround) {275if (self->direction == FLIP_X) {276foreach_active(HPZEmerald, emerald)277{278if (emerald->type != HPZEMERALD_MASTER) {279int32 dist = emerald->position.x - self->position.x;280if (dist < emeraldDist && dist >= 0 && self->targetEmerald != emerald) {281emeraldDist = dist;282targetEmerald = emerald;283}284}285}286}287else {288foreach_active(HPZEmerald, emerald)289{290if (emerald->type != HPZEMERALD_MASTER) {291int32 dist = self->position.x - emerald->position.x;292if (dist < emeraldDist && dist >= 0 && self->targetEmerald != emerald) {293emeraldDist = dist;294targetEmerald = emerald;295}296}297}298}299300if (targetEmerald)301self->targetEmerald = targetEmerald;302else303self->direction ^= FLIP_X;304}305else {306foreach_active(HPZEmerald, emerald)307{308if (emerald->type != HPZEMERALD_MASTER) {309int32 dist = abs(self->position.x - emerald->position.x);310if (dist < emeraldDist) {311emeraldDist = dist;312targetEmerald = emerald;313}314}315}316317if (targetEmerald)318self->targetEmerald = targetEmerald;319}320}321322void HeavyKing_StartLeap(int32 startFrame)323{324RSDK_THIS(HeavyKing);325326RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 3, &self->bodyAnimator, true, startFrame);327RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 12, &self->scepterAnimator, true, startFrame);328329if (RSDK.GetEntityCount(KingAttack->classID, true)) {330HeavyKing_FindTargetEmerald();331self->velocity.x = (self->targetEmerald->position.x - self->position.x) / 40;332EntityPlayer *player = Player_GetNearestPlayer();333334foreach_active(KingAttack, attack)335{336if (attack->state == KingAttack_State_Orbiting) {337int32 angle = RSDK.ATan2((player->position.x - attack->position.x) >> 16, (player->position.y - attack->position.y) >> 16);338attack->targetVelocity.x = 0x600 * RSDK.Cos256(angle);339attack->targetVelocity.y = 0x600 * RSDK.Sin256(angle);340attack->drawGroup = Zone->objectDrawGroup[0];341attack->state = KingAttack_State_OrbitLaunched;342RSDK.PlaySfx(KingAttack->sfxElecPulse, false, 255);343foreach_break;344}345}346}347else {348self->attacksRemaining = 0;349if (self->position.x - HeavyKing->boundsM > 0)350self->velocity.x = -0x30000;351else352self->velocity.x = 0x30000;353}354355self->velocity.y = -0x60000;356self->onGround = false;357self->state = HeavyKing_State_Leaping;358}359360void HeavyKing_HandleAttackFinish(void)361{362RSDK_THIS(HeavyKing);363364HeavyKing_FindTargetEmerald();365366self->velocity.x = 0;367self->velocity.y = 0;368self->onGround = false;369self->state = HeavyKing_State_JumpToTargetEmerald;370371RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 3, &self->bodyAnimator, false, 6);372RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 12, &self->scepterAnimator, false, 6);373}374375void HeavyKing_CreateSpinRayFX(void)376{377RSDK_THIS(HeavyKing);378379EntityFXSpinRay *ray = NULL;380if (self->direction) {381ray = CREATE_ENTITY(FXSpinRay, NULL, self->position.x - 0x240000, self->position.y - 0x300000);382ray->offsetPos.x = -0x240000;383}384else {385ray = CREATE_ENTITY(FXSpinRay, NULL, self->position.x + 0x240000, self->position.y - 0x300000);386ray->offsetPos.x = 0x240000;387}388389ray->parent = (Entity *)self;390ray->offsetPos.y = -0x300000;391}392393void HeavyKing_CreateExpandRingFX(void)394{395RSDK_THIS(HeavyKing);396397EntityFXExpandRing *expandRing = CREATE_ENTITY(FXExpandRing, NULL, self->position.x + 0x240000, self->position.y - 0x300000);398expandRing->parent = (Entity *)self;399expandRing->drawFX = FX_FLIP;400expandRing->posOffset.x = 0x240000;401expandRing->posOffset.y = -0x300000;402}403404void HeavyKing_CreateLaser(void)405{406RSDK_THIS(HeavyKing);407408EntityKingAttack *attack = CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_LASER), self->position.x, HeavyKing->spinRaySpawnPos);409attack->parent = (Entity *)self;410411if (self->direction) {412attack->position.x -= 0xC00000;413attack->velocity.x = 0x100000;414}415else {416attack->position.x += 0xC00000;417attack->velocity.x = -0x100000;418}419}420421void HeavyKing_CreateExpandRing(void)422{423RSDK_THIS(HeavyKing);424425for (int32 angle = 0; angle < 1020; angle += 170) {426EntityKingAttack *attack = CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_ORBIT), self->position.x, self->position.y);427attack->angle = angle;428attack->parent = (Entity *)self;429}430}431432void HeavyKing_State_SetupArena(void)433{434RSDK_THIS(HeavyKing);435436if (++self->timer >= 8) {437self->timer = 0;438439foreach_active(KingClaw, claw) { self->claw = claw; }440441EntityKingClaw *kingClaw = self->claw;442if (kingClaw) {443HeavyKing->boundsL = kingClaw->position.x - 0xA00000;444HeavyKing->boundsM = kingClaw->position.x;445HeavyKing->boundsR = kingClaw->position.x + 0x600000;446447Zone->playerBoundActiveL[0] = true;448Zone->playerBoundActiveR[0] = true;449Zone->cameraBoundsL[0] = (kingClaw->position.x >> 16) - 320;450Zone->cameraBoundsR[0] = (kingClaw->position.x >> 16) + 320;451Zone->cameraBoundsT[0] = (kingClaw->position.y >> 16);452453HeavyKing->spinRaySpawnPos = kingClaw->position.y + 0x2400000;454self->active = ACTIVE_NORMAL;455HeavyKing_HandleClawMovement();456self->state = HeavyKing_State_HandleCutsceneSetup;457}458}459}460461void HeavyKing_State_HandleCutsceneSetup(void)462{463RSDK_THIS(HeavyKing);464465EntityKingClaw *claw = self->claw;466467EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);468if (player1->position.x > self->position.x - 0x1800000) {469CutsceneSeq_LockPlayerControl(player1);470471player1->stateInput = StateMachine_None;472player1->jumpPress = false;473player1->jumpHold = false;474player1->right = true;475player1->pushing = false;476player1->state = Player_State_Ground;477478#if GAME_VERSION != VER_100479Player->disableP2KeyCheck = true;480#endif481482if (player1->velocity.x > 0x20000) {483player1->groundVel = 0x20000;484player1->velocity.x = 0x20000;485}486}487488if (player1->position.x > self->position.x - 0xE00000) {489player1->groundVel = 0;490player1->velocity.x = 0;491player1->right = false;492player1->state = Player_State_Static;493494RSDK.SetSpriteAnimation(player1->aniFrames, ANI_LOOK_UP, &player1->animator, false, 0);495496EntityPlayer *player2 = RSDK_GET_ENTITY(SLOT_PLAYER2, Player);497if (player2->classID == Player->classID) {498player2->groundVel = 0;499player2->velocity.x = 0;500player2->direction = FLIP_NONE;501CutsceneSeq_LockPlayerControl(player2);502player2->stateInput = StateMachine_None;503player2->up = true;504}505506Music_TransitionTrack(TRACK_HBHMISCHIEF, 0.0125);507claw->state = KingClaw_State_EnterClaw;508self->visible = true;509self->state = HeavyKing_StateCutscene_PlayerLookUp;510511Camera_ShakeScreen(0, 6, 6);512RSDK.PlaySfx(HeavyKing->sfxImpact6, false, 255);513}514}515516void HeavyKing_StateCutscene_PlayerLookUp(void)517{518RSDK_THIS(HeavyKing);519520EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);521522++self->timer;523if (player1->animator.frameID == 5)524player1->animator.speed = 0;525526if (self->timer == 30) {527self->timer = 0;528foreach_all(HPZEmerald, emerald)529{530emerald->active = ACTIVE_NORMAL;531if (emerald->type == HPZEMERALD_MASTER) {532self->masterEmerald = emerald;533Camera_SetupLerp(CAMERA_LERP_SIN1024_2, 0, emerald->position.x - 0x500000, emerald->position.y - 0x800000, 3);534}535}536537self->state = HeavyKing_StateCutscene_EnterKing;538}539540HeavyKing_HandleClawMovement();541}542543void HeavyKing_StateCutscene_EnterKing(void)544{545RSDK_THIS(HeavyKing);546547if (++self->timer == 180) {548self->timer = 0;549EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);550Camera_SetupLerp(CAMERA_LERP_SIN512, 0, camera->position.x, camera->startLerpPos.y, 4);551self->state = HeavyKing_StateCutscene_ReturnCamToPlayer;552553EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);554#if MANIA_USE_PLUS555if (player1->characterID == ID_KNUCKLES)556#endif557RSDK.SetSpriteAnimation(player1->aniFrames, ANI_IDLE, &player1->animator, false, 0);558}559560HeavyKing_HandleClawMovement();561}562563void HeavyKing_StateCutscene_ReturnCamToPlayer(void)564{565RSDK_THIS(HeavyKing);566567if (!RSDK_GET_ENTITY(SLOT_CAMERA1, Camera)->state) {568EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);569570#if MANIA_USE_PLUS571if (player1->characterID == ID_KNUCKLES) {572#endif573RSDK.SetSpriteAnimation(HeavyKing->cutsceneFrames, 0, &player1->animator, false, 0);574CREATE_ENTITY(ThoughtBubble, NULL, player1->position.x - 0x300000, player1->position.y - 0x500000);575#if MANIA_USE_PLUS576}577#endif578579self->state = HeavyKing_StateCutscene_GrabMasterEmerald;580}581582HeavyKing_HandleClawMovement();583}584585void HeavyKing_StateCutscene_GrabMasterEmerald(void)586{587RSDK_THIS(HeavyKing);588589EntityKingClaw *claw = self->claw;590591HeavyKing_HandleClawMovement();592593if (++self->timer == 180)594claw->state = KingClaw_State_Grab;595596if (self->timer == 240) {597self->timer = 0;598Camera_ShakeScreen(0, 6, 6);599RSDK.PlaySfx(HeavyKing->sfxImpact6, false, 255);600601EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);602#if MANIA_USE_PLUS603if (player1->characterID == ID_KNUCKLES)604#endif605RSDK.SetSpriteAnimation(HeavyKing->cutsceneFrames, 1, &player1->animator, false, 0);606607self->state = HeavyKing_StateCutscene_FinishThinking;608}609}610611void HeavyKing_StateCutscene_FinishThinking(void)612{613RSDK_THIS(HeavyKing);614615HeavyKing_HandleClawMovement();616617EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);618619#if MANIA_USE_PLUS620if (player1->characterID == ID_KNUCKLES) {621#endif622if (player1->animator.frameID == player1->animator.frameCount - 1) {623RSDK.SetSpriteAnimation(HeavyKing->cutsceneFrames, 2, &player1->animator, false, 0);624self->state = HeavyKing_StateCutscene_GetHigherGround;625}626#if MANIA_USE_PLUS627}628else {629self->state = HeavyKing_StateCutscene_GetHigherGround;630}631#endif632}633634void HeavyKing_StateCutscene_GetHigherGround(void)635{636RSDK_THIS(HeavyKing);637638EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);639EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);640641HeavyKing_HandleClawMovement();642643if (player1->onGround)644player1->groundVel = 0;645646switch (++self->timer) {647case 30:648#if MANIA_USE_PLUS649if (player1->characterID == ID_KNUCKLES)650#endif651RSDK.SetSpriteAnimation(HeavyKing->cutsceneFrames, 4, &player1->animator, false, 0);652break;653654case 90:655RSDK.PlaySfx(Player->sfxJump, false, 255);656RSDK.SetSpriteAnimation(player1->aniFrames, ANI_JUMP, &player1->animator, false, 0);657player1->velocity.x = 0x2C000;658player1->velocity.y = -0x50000;659player1->applyJumpCap = false;660player1->onGround = false;661player1->state = Player_State_Air;662break;663664case 124:665RSDK.PlaySfx(Player->sfxJump, false, 255);666RSDK.SetSpriteAnimation(player1->aniFrames, ANI_JUMP, &player1->animator, false, 0);667668player1->velocity.x = -0x1C000;669player1->velocity.y = -0x66000;670player1->applyJumpCap = false;671player1->onGround = false;672player1->state = Player_State_Air;673674Camera_SetupLerp(CAMERA_LERP_SIN512, 0, camera->startLerpPos.x, camera->startLerpPos.y + 0x200000, 4);675break;676677default:678if (self->timer > 144 && player1->onGround) {679#if MANIA_USE_PLUS680if (player1->characterID == ID_KNUCKLES)681#endif682RSDK.SetSpriteAnimation(HeavyKing->cutsceneFrames, 3, &player1->animator, false, 0);683#if MANIA_USE_PLUS684else685RSDK.SetSpriteAnimation(player1->aniFrames, ANI_IDLE, &player1->animator, false, 0);686#endif687player1->position.y -= player1->jumpOffset;688player1->state = Player_State_Static;689player1->nextGroundState = StateMachine_None;690self->timer = 0;691self->state = HeavyKing_StateCutscene_Complaining;692}693break;694}695}696697void HeavyKing_StateCutscene_Complaining(void)698{699RSDK_THIS(HeavyKing);700701EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);702703HeavyKing_HandleClawMovement();704705if (++self->timer == 90) {706self->timer = 0;707player1->down = true;708player1->state = Player_State_Ground;709self->state = HeavyKing_StateCutscene_ChargeSpindash;710}711}712713void HeavyKing_StateCutscene_ChargeSpindash(void)714{715RSDK_THIS(HeavyKing);716717EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);718719HeavyKing_HandleClawMovement();720721self->timer++;722player1->jumpPress = self->timer > 24 && !(self->timer & 7);723724if (self->timer == 56) {725self->timer = 0;726player1->down = false;727self->state = HeavyKing_StateCutscene_AttackClaw;728Music_TransitionTrack(TRACK_EGGMAN2, 0.0125);729}730}731732void HeavyKing_StateCutscene_AttackClaw(void)733{734RSDK_THIS(HeavyKing);735736EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);737738HeavyKing_HandleClawMovement();739740if (++self->timer == 2) {741player1->jumpPress = true;742player1->jumpHold = true;743player1->scrollDelay = 160;744745if (self->masterEmerald)746Camera_SetupLerp(CAMERA_LERP_SIN1024_2, 0, self->masterEmerald->position.x, self->masterEmerald->position.y + 0x300000, 4);747}748else {749player1->jumpPress = false;750}751752if (self->timer == 14) {753self->timer = 0;754self->velocity.y = -0x20000;755self->velocity.x = 0x10000;756self->state = HeavyKing_StateCutscene_AttackRebound;757758RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 6, &self->bodyAnimator, false, 0);759RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 15, &self->scepterAnimator, false, 0);760761player1->velocity.x = -0x24000;762player1->velocity.y = -0x20000;763764EntityKingClaw *claw = self->claw;765claw->state = KingClaw_State_Swinging;766claw->timer = 128;767if (claw->masterEmerald)768claw->masterEmerald->onGround = false;769770RSDK.PlaySfx(HeavyKing->sfxImpact5, false, 255);771}772}773774void HeavyKing_StateCutscene_AttackRebound(void)775{776RSDK_THIS(HeavyKing);777778self->velocity.y += 0x3800;779self->position.x += self->velocity.x;780self->position.y += self->velocity.y;781782EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);783if (player1->onGround)784player1->groundVel = 0;785786if (++self->timer == 24) {787RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 3, &self->bodyAnimator, false, 6);788RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 12, &self->scepterAnimator, false, 6);789}790791if (self->onGround) {792RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 4, &self->bodyAnimator, false, 0);793RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 13, &self->scepterAnimator, false, 0);794HeavyKing_StartLeap(0);795796#if GAME_VERSION != VER_100797Player->disableP2KeyCheck = false;798#endif799player1->stateInput = Player_Input_P1;800801EntityPlayer *player2 = RSDK_GET_ENTITY(SLOT_PLAYER2, Player);802if (player2->classID == Player->classID) {803CutsceneSeq_LockPlayerControl(player2);804player2->stateInput = Player_Input_P2_AI;805}806}807}808809void HeavyKing_State_JumpToTargetEmerald(void)810{811RSDK_THIS(HeavyKing);812813HeavyKing_HandleAnimators();814815if (self->onGround) {816HeavyKing_StartLeap(4);817818if (!self->attacksRemaining) {819EntityHPZEmerald *masterEmerald = self->masterEmerald;820if (abs(self->position.x - HeavyKing->boundsM) < 0x100000) {821masterEmerald->solid = true;822self->state = HeavyKing_State_LeapToMasterEmerald;823}824}825}826else {827EntityHPZEmerald *targetEmerald = self->targetEmerald;828if (targetEmerald)829self->position.x += (targetEmerald->position.x - self->position.x) >> 3;830831self->velocity.y += 0x3800;832self->position.y += self->velocity.y;833}834835HeavyKing_CheckPlayerCollisions();836}837838void HeavyKing_State_Leaping(void)839{840RSDK_THIS(HeavyKing);841842if (self->bodyAnimator.frameID >= 5) {843HeavyKing_HandleAnimators();844845RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, HeavyKing->hitboxBody.bottom >> 15, true);846847if (!self->onGround) {848int32 vel = self->velocity.y;849self->velocity.y += 0x3800;850if (self->velocity.y >= 0 && vel < 0)851HeavyKing_FindTargetEmerald();852853self->position.x += self->velocity.x;854855EntityHPZEmerald *targetEmerald = self->targetEmerald;856if (self->velocity.y > 0) {857if (self->velocity.x <= 0) {858if (self->velocity.x < 0) {859if (self->position.x < targetEmerald->position.x) {860self->velocity.x = 0;861self->position.x = targetEmerald->position.x;862}863}864}865else {866if (self->position.x > targetEmerald->position.x) {867self->velocity.x = 0;868self->position.x = targetEmerald->position.x;869}870}871}872873self->position.y += self->velocity.y;874}875else {876HeavyKing_StartLeap(4);877878if (!self->attacksRemaining) {879EntityHPZEmerald *masterEmerald = self->masterEmerald;880if (abs(self->position.x - HeavyKing->boundsM) >= 0x200000) {881self->direction = self->position.x < masterEmerald->position.x;882}883else {884masterEmerald->solid = true;885self->state = HeavyKing_State_LeapToMasterEmerald;886}887}888}889}890891HeavyKing_CheckPlayerCollisions();892}893894void HeavyKing_State_LeapToMasterEmerald(void)895{896RSDK_THIS(HeavyKing);897898if (self->bodyAnimator.frameID >= 5) {899HeavyKing_HandleAnimators();900901EntityHPZEmerald *masterEmerald = self->masterEmerald;902903if (!self->onGround) {904self->velocity.y += 0x3800;905self->position.y += self->velocity.y;906self->position.x += (masterEmerald->position.x - self->position.x) >> 2;907}908else {909masterEmerald->solid = false;910RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 4, &self->bodyAnimator, false, 0);911RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 13, &self->scepterAnimator, false, 0);912913foreach_active(KingAttack, attack)914{915if (attack->state == KingAttack_State_Orbiting)916destroyEntity(attack);917}918919self->state = HeavyKing_State_LandedOnMasterEmerald;920}921}922923HeavyKing_CheckPlayerCollisions();924}925926void HeavyKing_State_LandedOnMasterEmerald(void)927{928RSDK_THIS(HeavyKing);929930if (self->bodyAnimator.frameID == self->bodyAnimator.frameCount - 1) {931RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 1, &self->bodyAnimator, false, 0);932RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 10, &self->scepterAnimator, false, 0);933self->state = HeavyKing_State_ChargeStart;934}935936HeavyKing_CheckPlayerCollisions();937}938939void HeavyKing_State_ChargeStart(void)940{941RSDK_THIS(HeavyKing);942943if (self->scepterAnimator.frameID == 7 && self->scepterAnimator.timer == 1)944RSDK.PlaySfx(HeavyKing->sfxRodPlant, false, 255);945946if (self->bodyAnimator.frameID == 12) {947RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 18, &self->electricityAnimator, false, 0);948self->state = HeavyKing_State_Charging;949self->attacksRemaining = (self->health >= 2) + 1;950}951952HeavyKing_CheckPlayerCollisions();953}954955void HeavyKing_State_Charging(void)956{957RSDK_THIS(HeavyKing);958959RSDK.ProcessAnimation(&self->electricityAnimator);960++self->timer;961962EntityHPZEmerald *masterEmerald = self->masterEmerald;963masterEmerald->alpha = 0x80 + (RSDK.Sin256(8 * self->timer) >> 1);964965if (self->timer == 176) {966self->timer = 0;967masterEmerald->alpha = 0;968RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 2, &self->bodyAnimator, false, 0);969RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 11, &self->scepterAnimator, false, 0);970RSDK.SetSpriteAnimation(-1, 0, &self->electricityAnimator, false, 0);971self->state = HeavyKing_State_ChargeStop;972}973974if (!(self->timer & 7))975RSDK.PlaySfx(HeavyKing->sfxCharge, false, 0xFF);976977HeavyKing_CheckPlayerCollisions_Charging();978}979980void HeavyKing_State_ChargeStop(void)981{982RSDK_THIS(HeavyKing);983984if (self->bodyAnimator.frameID == self->bodyAnimator.frameCount - 1) {985RSDK.Rand(0, 3);986RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 3, &self->bodyAnimator, false, 0);987RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 12, &self->scepterAnimator, false, 0);988self->state = HeavyKing_State_PrepareHover;989}990991HeavyKing_CheckPlayerCollisions();992}993994void HeavyKing_State_PrepareHover(void)995{996RSDK_THIS(HeavyKing);997998if (self->bodyAnimator.frameID == 5) {999self->position.y -= 0x60000;1000self->originPos = self->position;1001self->velocity.x = 0;1002self->velocity.y = -0x10000;10031004RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 5, &self->bodyAnimator, false, 0);1005RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 14, &self->scepterAnimator, false, 0);10061007self->targetEmerald = NULL;1008self->onGround = false;1009self->state = HeavyKing_State_StartHovering;1010}10111012HeavyKing_CheckPlayerCollisions();1013}10141015void HeavyKing_State_StartHovering(void)1016{1017RSDK_THIS(HeavyKing);10181019self->velocity.y -= 0x800;1020self->originPos.y += self->velocity.y;1021BadnikHelpers_Oscillate(self->originPos.y, 2, 11);10221023if (++self->timer == 24) {1024HeavyKing->startY = self->originPos.y;1025self->timer = 0;1026self->timer = 0;1027self->state = HeavyKing_State_Hovering;1028}10291030HeavyKing_CheckPlayerCollisions();1031}10321033void HeavyKing_State_Hovering(void)1034{1035RSDK_THIS(HeavyKing);10361037HeavyKing_HandleHoverMovement();1038BadnikHelpers_Oscillate(self->originPos.y, 2, 11);10391040if (++self->timer == 120) {1041self->timer = 0;10421043self->curAttack = HeavyKing->attackPattern[HeavyKing->attackPatternPos++];1044HeavyKing->attackPatternPos &= 0x1F;10451046if (self->attacksRemaining > 0)1047self->attacksRemaining--;10481049switch (self->curAttack) {1050case 0:1051HeavyKing_CreateSpinRayFX();1052RSDK.PlaySfx(HeavyKing->sfxRodShine, false, 255);1053self->state = HeavyKing_State_LaserAttack;1054break;10551056case 1:1057HeavyKing_CreateExpandRingFX();1058RSDK.PlaySfx(HeavyKing->sfxElecOn, false, 255);1059self->state = HeavyKing_State_ExpandRingAttack;1060break;10611062case 2:1063--self->attacksRemaining;1064CREATE_ENTITY(KingAttack, INT_TO_VOID(KINGATTACK_LARGEBULLET), self->position.x, self->position.y)->parent = (Entity *)self;1065RSDK.PlaySfx(HeavyKing->sfxTwinCharge, false, 255);1066self->state = HeavyKing_State_TwinChargeAttack;1067break;1068}1069}10701071HeavyKing_CheckPlayerCollisions();1072}10731074void HeavyKing_State_LaserAttack(void)1075{1076RSDK_THIS(HeavyKing);10771078BadnikHelpers_Oscillate(self->originPos.y, 2, 11);10791080if (++self->timer == 60)1081HeavyKing_CreateLaser();10821083if (self->timer == 120) {1084self->timer = 0;1085if (self->attacksRemaining <= 0)1086HeavyKing_HandleAttackFinish();1087else1088self->state = HeavyKing_State_Hovering;1089}10901091HeavyKing_CheckPlayerCollisions();1092}10931094void HeavyKing_State_ExpandRingAttack(void)1095{1096RSDK_THIS(HeavyKing);10971098HeavyKing_HandleHoverMovement();10991100BadnikHelpers_Oscillate(self->originPos.y, 2, 11);11011102if (++self->timer == 16)1103HeavyKing_CreateExpandRing();11041105if (self->timer == 128) {1106self->timer = 0;1107HeavyKing_HandleAttackFinish();1108}11091110HeavyKing_CheckPlayerCollisions();1111}11121113void HeavyKing_State_TwinChargeAttack(void)1114{1115RSDK_THIS(HeavyKing);11161117BadnikHelpers_Oscillate(self->originPos.y, 2, 11);11181119if (!RSDK.GetEntityCount(KingAttack->classID, true))1120HeavyKing_HandleAttackFinish();11211122HeavyKing_CheckPlayerCollisions();1123}11241125void HeavyKing_State_HitRecoil(void)1126{1127RSDK_THIS(HeavyKing);11281129if (self->invincibilityTimer == 48) {1130self->bodyAnimator = self->storedBodyAnimator;1131self->scepterAnimator = self->storedScepterAnimator;1132self->state = self->stateStore;1133}1134}11351136void HeavyKing_State_Destroyed(void)1137{1138RSDK_THIS(HeavyKing);11391140HeavyKing_Explode();11411142RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, HeavyKing->hitboxBody.bottom >> 15, true);11431144if (!self->onGround) {1145self->velocity.y += 0x3800;1146self->position.y += self->velocity.y;1147}11481149if (++self->timer == 60)1150RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 17, &self->scepterAnimator, false, 0);11511152if (self->timer == 72) {1153RSDK.PlaySfx(HeavyKing->sfxFreeze, false, 255);1154int32 centerX = self->position.x - 0x280000;1155if (self->direction == FLIP_NONE)1156centerX = self->position.x + 0x280000;11571158for (int32 i = 0; i < 6; ++i) {1159int32 y = (self->position.y - 0x300000) + RSDK.Rand(-0x40000, 0x40000);1160int32 x = centerX + RSDK.Rand(-0x40000, 0x40000);1161EntityDebris *debris = CREATE_ENTITY(Debris, NULL, x, y);11621163debris->state = Debris_State_Fall;1164debris->gravityStrength = 0x3800;1165debris->velocity.x = RSDK.Rand(0, 0x20000);1166if (debris->position.x < centerX)1167debris->velocity.x = -debris->velocity.x;11681169debris->velocity.y = RSDK.Rand(-0x40000, -0x10000);1170debris->drawFX = FX_FLIP;1171debris->direction = i & 3;1172debris->drawGroup = Zone->objectDrawGroup[1];1173debris->timer = 120;11741175RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 19, &debris->animator, true, RSDK.Rand(0, 3));1176}1177}11781179if (self->timer == 120) {1180EntityKingClaw *claw = self->claw;1181self->bodyAnimator.speed = 0;1182self->scepterAnimator.speed = 0;1183self->timer = 0;1184self->state = HeavyKing_State_Escape;1185if (self->direction == FLIP_NONE)1186claw->position.x = self->position.x - 0x300000;1187else1188claw->position.x = self->position.x + 0x300000;11891190claw->state = KingClaw_State_LowerClaw;1191claw->velocity.y = 0x10000;1192claw->forceHighdrawGroup = true;1193claw->targetY = self->position.y - 0xA00000;1194claw->position.y = claw->targetY - 0xE00000;1195claw->drawGroup = Zone->objectDrawGroup[1];1196self->drawGroup = Zone->objectDrawGroup[1];1197KingClaw->active = ACTIVE_NEVER;1198}1199}12001201void HeavyKing_State_Escape(void)1202{1203RSDK_THIS(HeavyKing);12041205if (!(Zone->timer & 0x1F)) {1206int32 x = self->position.x + RSDK.Rand(-0x180000, 0x180000);1207int32 y = self->position.y + RSDK.Rand(-0x180000, 0x180000);1208CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), x, y)->drawGroup = Zone->objectDrawGroup[1];1209}12101211if ((Zone->timer & 0xF) == 4) {1212int32 x = self->position.x - 0x2C0000;1213if (self->direction == FLIP_NONE)1214x = self->position.x + 0x2C0000;12151216CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), x, self->position.y - 0x300000)->drawGroup = Zone->objectDrawGroup[1];1217}12181219EntityKingClaw *claw = self->claw;1220if (!claw->state) {1221claw->state = KingClaw_State_RaiseClaw;1222RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 7, &self->bodyAnimator, true, 0);1223RSDK.SetSpriteAnimation(-1, 0, &self->scepterAnimator, true, 0);1224self->state = HeavyKing_State_Finish;1225}1226}12271228void HeavyKing_State_Finish(void)1229{1230RSDK_THIS(HeavyKing);12311232HeavyKing_HandleClawMovement();12331234if (!RSDK.CheckOnScreen(self, &self->updateRange)) {1235Music_TransitionTrack(TRACK_STAGE, 0.0125);1236Zone->cameraBoundsR[0] += 1024;1237destroyEntity(self->claw);1238destroyEntity(self);1239}1240}12411242#if GAME_INCLUDE_EDITOR1243void HeavyKing_EditorDraw(void)1244{1245RSDK_THIS(HeavyKing);12461247RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 7, &self->bodyAnimator, true, 0);1248RSDK.SetSpriteAnimation(HeavyKing->aniFrames, 16, &self->scepterAnimator, true, 0);12491250HeavyKing_Draw();12511252if (showGizmos()) {1253RSDK_DRAWING_OVERLAY(true);12541255DrawHelpers_DrawArenaBounds(-320, -SCREEN_YSIZE, 320, SCREEN_YCENTER, 1 | 2 | 4 | 0, 0x00C0F0);12561257RSDK_DRAWING_OVERLAY(false);1258}1259}12601261void HeavyKing_EditorLoad(void) { HeavyKing->aniFrames = RSDK.LoadSpriteAnimation("LRZ3/HeavyKing.bin", SCOPE_STAGE); }1262#endif12631264void HeavyKing_Serialize(void) {}126512661267