Path: blob/master/SonicMania/Objects/GHZ/DERobot.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: DERobot Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectDERobot *DERobot;1011void DERobot_Update(void)12{13RSDK_THIS(DERobot);14StateMachine_Run(self->state);15}1617void DERobot_LateUpdate(void) {}1819void DERobot_StaticUpdate(void) {}2021void DERobot_Draw(void)22{23RSDK_THIS(DERobot);24StateMachine_Run(self->stateDraw);25}2627void DERobot_Create(void *data)28{29RSDK_THIS(DERobot);30if (!SceneInfo->inEditor) {31if (globals->gameMode < MODE_TIMEATTACK) {32self->drawGroup = Zone->objectDrawGroup[0];33self->updateRange.x = 0x800000;34self->updateRange.y = 0x800000;35int32 slotID = RSDK.GetEntitySlot(self);36if (data)37self->aniID = VOID_TO_INT(data);3839switch (self->aniID) {40case DEROBOT_BODY:41self->active = ACTIVE_BOUNDS;42self->legs[0] = RSDK_GET_ENTITY(slotID - 7, DERobot);43self->legs[1] = RSDK_GET_ENTITY(slotID - 6, DERobot);44self->legs[2] = RSDK_GET_ENTITY(slotID - 5, DERobot);45self->arms[0] = RSDK_GET_ENTITY(slotID - 4, DERobot);46self->arms[1] = RSDK_GET_ENTITY(slotID - 3, DERobot);47self->eggman = RSDK_GET_ENTITY(slotID - 2, Eggman);48self->head = RSDK_GET_ENTITY(slotID - 1, DERobot);49self->legs[3] = RSDK_GET_ENTITY(slotID + 1, DERobot);50self->legs[4] = RSDK_GET_ENTITY(slotID + 2, DERobot);51self->legs[5] = RSDK_GET_ENTITY(slotID + 3, DERobot);52self->shoulderFront = RSDK_GET_ENTITY(slotID + 4, DERobot);53self->arms[2] = RSDK_GET_ENTITY(slotID + 5, DERobot);54self->arms[3] = RSDK_GET_ENTITY(slotID + 6, DERobot);55self->health = 8;56self->state = DERobot_State_SetupArena;57self->stateDraw = DERobot_Draw_Simple;58RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);59break;6061case DEROBOT_HEAD:62self->parent = (Entity *)RSDK_GET_ENTITY(slotID + 1, DERobot);63self->stateDraw = DERobot_Draw_RelativeToParent;64self->drawFX = FX_ROTATE;65self->offset.x = -0x160000;66self->offset.y = -0x240000;67RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);68break;6970case DEROBOT_ARM:71if (self->frameID == 2) {72RSDK.SetSpriteAnimation(DERobot->aniFrames, 5, &self->altAnimator, true, 0);73RSDK.SetSpriteAnimation(DERobot->aniFrames, 4, &self->armAnimator, true, 0);74self->stateDraw = DERobot_Draw_Arm;75self->drawFX = FX_ROTATE;76self->state = DERobot_State_ArmIdle;77}78else if (self->frameID) {79self->stateDraw = DERobot_Draw_Simple;80}81else {82self->parent = (Entity *)RSDK_GET_ENTITY(slotID - 4, DERobot);83self->stateDraw = DERobot_Draw_RelativeToParent;84self->offset.x = -0xC0000;85self->offset.y = -0x100000;86}87RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);88break;8990case DEROBOT_LEG:91if (self->frameID) {92self->stateDraw = DERobot_Draw_Simple;93}94else {95RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->altAnimator, true, 1);96self->stateDraw = DERobot_Draw_FrontLeg;97}9899if (self->frameID > 1)100self->drawFX = FX_ROTATE;101RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);102break;103104case DEROBOT_TARGET_EDGE:105self->active = ACTIVE_NORMAL;106self->visible = true;107self->drawFX = FX_FLIP;108self->drawGroup = Zone->objectDrawGroup[1];109self->velocity.x = 0x20000;110RSDK.SetSpriteAnimation(DERobot->aniFrames, 7, &self->altAnimator, true, 0);111self->state = DERobot_State_Target;112self->stateDraw = DERobot_Draw_Target;113RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);114break;115116case DEROBOT_BOMB:117self->active = ACTIVE_NORMAL;118self->visible = true;119self->state = DERobot_State_BombLaunched;120self->stateDraw = DERobot_Draw_Simple;121RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);122break;123124case DEROBOT_BODY_CUTSCENE:125self->active = ACTIVE_BOUNDS;126self->visible = true;127self->stateDraw = DERobot_Draw_Simple;128self->shoulderFront = RSDK_GET_ENTITY(slotID + 4, DERobot);129self->arms[0] = RSDK_GET_ENTITY(slotID + 1, DERobot);130self->arms[1] = RSDK_GET_ENTITY(slotID + 2, DERobot);131RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);132break;133134default:135self->stateDraw = DERobot_Draw_Simple;136RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);137break;138}139}140else {141destroyEntity(self);142}143}144}145146void DERobot_StageLoad(void)147{148DERobot->aniFrames = RSDK.LoadSpriteAnimation("GHZ/DERobot.bin", SCOPE_STAGE);149150DERobot->hitboxBody.left = -32;151DERobot->hitboxBody.top = -40;152DERobot->hitboxBody.right = 32;153DERobot->hitboxBody.bottom = 32;154155DERobot->hitboxHand.left = -9;156DERobot->hitboxHand.top = -9;157DERobot->hitboxHand.right = 9;158DERobot->hitboxHand.bottom = 9;159160DERobot->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");161DERobot->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");162DERobot->sfxImpact = RSDK.GetSfx("Stage/Impact2.wav");163DERobot->sfxTargeting = RSDK.GetSfx("Stage/Targeting1.wav");164DERobot->sfxLedgeBreak = RSDK.GetSfx("Stage/LedgeBreak.wav");165DERobot->sfxBuzzsaw = RSDK.GetSfx("Stage/Buzzsaw.wav");166DERobot->sfxDrop = RSDK.GetSfx("Stage/Drop.wav");167DERobot->sfxButton2 = RSDK.GetSfx("Stage/Button2.wav");168DERobot->sfxHullClose = RSDK.GetSfx("Stage/HullClose.wav");169170RSDK.SetPaletteEntry(0, 236, 0x282028);171RSDK.SetPaletteEntry(0, 237, 0x383040);172RSDK.SetPaletteEntry(0, 238, 0x484868);173RSDK.SetPaletteEntry(0, 239, 0x587090);174RSDK.SetPaletteEntry(0, 244, 0x000000);175176// Bug Details:177// palette entry 244 is overwritten in GHZ2Cutscene during plus178// this is due to the additional colours in the tileset179// the simple fix to this should be to move DERobot above CutsceneHBH in the scene/stageconfig180// this will allow the CutsceneHBH object to properly store the 0x000000 colour set here when it does its palette swaps181// therefore fixing the orange DERobot bug182// alternatively, have GHZ2Outro_Cutscene_HoleSceneFadeIn call CutsceneHBH_StorePalette to store the updated palette183}184185void DERobot_HandleScreenBounds(void)186{187RSDK_THIS(DERobot);188int32 x = (self->position.x >> 16) - ScreenInfo->center.x + 128;189if (x > Zone->cameraBoundsL[0]) {190Zone->cameraBoundsL[0] = x;191Zone->cameraBoundsR[0] = ScreenInfo->size.x + 96 + x;192Zone->playerBoundsL[0] = Zone->cameraBoundsL[0] << 16;193Zone->playerBoundsR[0] = Zone->cameraBoundsR[0] << 16;194Zone->playerBoundActiveB[0] = 0;195RSDK_GET_ENTITY(SLOT_CAMERA1, Camera)->boundsL = Zone->cameraBoundsL[0];196}197}198199void DERobot_HandleLegMovement(int32 offset)200{201RSDK_THIS(DERobot);202EntityDERobot *knee = self->legs[offset + 0];203EntityDERobot *leg = self->legs[offset + 1];204EntityDERobot *foot = self->legs[offset + 2];205206knee->position.x = 0x440 * RSDK.Sin1024(knee->angle) + self->position.x;207knee->position.y = 0x440 * RSDK.Cos1024(knee->angle) + self->position.y + 0x190000;208leg->position.x = knee->position.x;209leg->position.y = knee->position.y;210leg->angle = MAX(knee->angle >> 2, 0);211leg->rotation = -(leg->angle >> 1);212foot->position.x = 0xA00 * RSDK.Sin1024(leg->angle) + leg->position.x;213foot->position.y = 0xA00 * RSDK.Cos1024(leg->angle) + leg->position.y;214foot->onGround = false;215int32 storeX = foot->position.x;216int32 storeY = foot->position.y;217if (RSDK.ObjectTileGrip(foot, Zone->collisionLayers, CMODE_FLOOR, 0, -0x100000, 0x100000, 32)) {218foot->position.y = storeY;219if (RSDK.ObjectTileGrip(foot, Zone->collisionLayers, CMODE_FLOOR, 0, 0x100000, 0x100000, 32))220foot->rotation = 2 * RSDK.ATan2(32, (foot->position.y >> 16) - (foot->position.y >> 16));221}222foot->position.x = storeX;223foot->position.y = storeY;224if (RSDK.ObjectTileCollision(foot, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x110000, true))225foot->onGround = true;226}227228void DERobot_HandleLegMovement2(int32 offset)229{230RSDK_THIS(DERobot);231EntityDERobot *leg = self->legs[offset + 0];232EntityDERobot *foot = self->legs[offset + 1];233EntityDERobot *knee = self->legs[offset - 1];234leg->position.x = foot->position.x - 0xA00 * RSDK.Sin1024(leg->angle);235leg->position.y = foot->position.y - 0xA00 * RSDK.Cos1024(leg->angle);236leg->angle -= leg->angle >> 3;237leg->rotation -= leg->rotation >> 3;238knee->position.x = leg->position.x;239knee->position.y = leg->position.y;240self->position.x = knee->position.x - 0x440 * RSDK.Sin1024(knee->angle);241self->position.y = knee->position.y - (0x440 * RSDK.Cos1024(knee->angle)) - 0x190000;242}243244void DERobot_HandleArmMovement(int32 offset)245{246RSDK_THIS(DERobot);247EntityDERobot *arm = self->arms[offset + 0];248EntityDERobot *hand = self->arms[offset + 1];249arm->position.x = 0x600 * (RSDK.Sin1024(arm->angle) - 0x200) + self->position.x;250arm->position.y = 0x600 * (RSDK.Cos1024(arm->angle) - 0x300) + self->position.y;251hand->position.x = arm->position.x + 0x600 * RSDK.Cos1024(MIN(arm->angle, 0));252hand->position.y = arm->position.y - 0x600 * RSDK.Sin1024(MIN(arm->angle, 0));253}254255void DERobot_HandleTerrainDestruction(void)256{257RSDK_THIS(DERobot);258int32 tx = (self->position.x + 0xC0000) >> 20;259if (tx > self->destroyedTerrainX) {260self->destroyedTerrainX = tx;261int32 ty = (self->position.y >> 20) - 16;262263int32 spawnX = (tx << 20) + 0x80000;264int32 spawnY = (ty << 20) + 0x80000;265266bool32 playSfx = false;267for (int32 i = 0; i < 32; ++i) {268uint16 tile = RSDK.GetTile(Zone->fgLayer[1], tx, ty);269if (tile != (uint16)-1) {270RSDK.SetTile(Zone->fgLayer[1], tx, ty, -1);271272EntityBreakableWall *wall = CREATE_ENTITY(BreakableWall, INT_TO_VOID(BREAKWALL_TILE_FIXED), spawnX, spawnY);273wall->drawGroup = Zone->objectDrawGroup[1];274wall->visible = true;275wall->tileInfo = tile;276wall->velocity.x = RSDK.Rand(-0x20000, 0x20000);277wall->velocity.y = RSDK.Rand(-0x20000, 0x20000);278wall->drawFX = FX_ROTATE | FX_FLIP;279playSfx = true;280}281++ty;282spawnY += 0x100000;283}284285if (playSfx)286RSDK.PlaySfx(DERobot->sfxLedgeBreak, false, 255);287}288}289290void DERobot_DestroyTerrainFinal(void)291{292RSDK_THIS(DERobot);293294int32 tx = (self->position.x >> 20) - 4;295int32 ty = (self->position.y >> 20) - 16;296297int32 spawnX = (tx << 20) + 0x80000;298for (int32 y = 0; y < 8; ++y) {299int32 spawnY = (ty << 20) + 0x80000;300for (int32 x = 0; x < 32; ++x) {301uint16 tile = RSDK.GetTile(Zone->fgLayer[0], tx, ty);302if (tile != (uint16)-1) {303RSDK.SetTile(Zone->fgLayer[0], tx, ty, -1);304305EntityBreakableWall *wall = CREATE_ENTITY(BreakableWall, INT_TO_VOID(BREAKWALL_TILE_FIXED), spawnX, spawnY);306wall->drawGroup = Zone->objectDrawGroup[1];307wall->visible = true;308wall->tileInfo = tile;309wall->velocity.x = RSDK.Rand(-0x20000, 0x20000);310wall->velocity.y = RSDK.Rand(-0x20000, 0x20000);311wall->drawFX = FX_ROTATE | FX_FLIP;312}313++ty;314spawnY += 0x100000;315}316spawnX += 0x100000;317ty -= 32;318++tx;319}320321tx = (self->position.x >> 20) - 4;322ty = (self->position.y >> 20) - 16;323spawnX = (tx << 20) + 0x80000;324for (int32 y = 0; y < 32; ++y) {325int32 spawnY = (ty << 20) + 0x80000;326for (int32 x = 0; x < 32; ++x) {327uint16 tile = RSDK.GetTile(Zone->fgLayer[1], tx, ty);328if (tile != (uint16)-1) {329RSDK.SetTile(Zone->fgLayer[1], tx, ty, -1);330EntityBreakableWall *wall = CREATE_ENTITY(BreakableWall, INT_TO_VOID(BREAKWALL_TILE_FIXED), spawnX, spawnY);331wall->drawGroup = Zone->objectDrawGroup[1];332wall->visible = true;333wall->tileInfo = tile;334wall->velocity.x = RSDK.Rand(-0x20000, 0x20000);335wall->velocity.y = RSDK.Rand(-0x20000, 0x20000);336wall->drawFX = FX_ROTATE | FX_FLIP;337}338++ty;339spawnY += 0x100000;340}341spawnX += 0x100000;342ty -= 32;343++tx;344}345}346347void DERobot_Hit(void)348{349RSDK_THIS(DERobot);350351if (--self->health <= 0) {352self->timer = 0;353self->state = DERobot_State_Explode;354SceneInfo->timeEnabled = false;355Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);356self->arms[1]->state = DERobot_State_ArmDestroyed;357self->arms[3]->state = DERobot_State_ArmDestroyed;358}359else {360self->invincibilityTimer = 48;361RSDK.PlaySfx(DERobot->sfxHit, false, 255);362if (self->health == 2) {363self->kneeAngleVel = 16;364self->angleVelStart = 0x20000;365self->angleMaxInc = -0x4000;366self->legs[0]->angleVel *= 2;367self->legs[0]->angleInc *= 4;368self->legs[3]->angleVel *= 2;369self->legs[3]->angleInc *= 4;370}371}372}373374void DERobot_Explode(void)375{376RSDK_THIS(DERobot);377378if (!(Zone->timer % 3)) {379RSDK.PlaySfx(DERobot->sfxExplosion, false, 0xFF);380381if ((Zone->timer & 4)) {382int32 x = self->position.x + (RSDK.Rand(-48, 48) << 16);383int32 y = self->position.y + (RSDK.Rand(-48, 48) << 16);384EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y);385explosion->drawGroup = Zone->objectDrawGroup[1];386}387}388}389390void DERobot_CheckPlayerCollisions_Body(void)391{392RSDK_THIS(DERobot);393394if (self->invincibilityTimer > 0) {395self->invincibilityTimer--;396397if ((self->invincibilityTimer & 2)) {398RSDK.SetPaletteEntry(0, 236, 0xC0C0C0);399RSDK.SetPaletteEntry(0, 237, 0xD0D0D0);400RSDK.SetPaletteEntry(0, 238, 0xE0E0E0);401RSDK.SetPaletteEntry(0, 239, 0xF0F0F0);402RSDK.SetPaletteEntry(0, 244, 0xA0A0A0);403}404else {405RSDK.SetPaletteEntry(0, 236, 0x282028);406RSDK.SetPaletteEntry(0, 237, 0x383040);407RSDK.SetPaletteEntry(0, 238, 0x484868);408RSDK.SetPaletteEntry(0, 239, 0x587090);409RSDK.SetPaletteEntry(0, 244, 0x000000);410}411}412413foreach_active(Player, player)414{415if (!self->invincibilityTimer && Player_CheckBadnikTouch(player, self, &DERobot->hitboxBody) && Player_CheckBossHit(player, self)) {416DERobot_Hit();417// DERobot_Hit should already play sfxHit, not sure why its here too418RSDK.PlaySfx(DERobot->sfxHit, false, 255);419player->velocity.x = 0x60000;420}421}422}423424void DERobot_CheckPlayerCollisions_ArmExtend(void)425{426RSDK_THIS(DERobot);427428int32 extend = ((self->armExtend + 22) << 16) >> 8;429430int32 angle = -(self->angle >> 3);431int32 left = (-0xE00 * RSDK.Sin256(angle)) + (0x1600 * RSDK.Cos256(angle));432int32 top = (-0xE00 * RSDK.Cos256(angle)) - (0x1600 * RSDK.Sin256(angle));433int32 right = (-0xE00 * RSDK.Sin256(angle)) + extend * RSDK.Cos256(angle);434int32 bottom = (((-0xE00 * RSDK.Cos256(angle)) - (extend * RSDK.Sin256(angle))) >> 16) - (top >> 16);435436self->hitbox.left = (left >> 16);437self->hitbox.right = (right >> 16);438439foreach_active(Player, player)440{441int32 dist = (player->position.x - self->position.x) >> 16;442if (dist >= left >> 16) {443if (dist > (right >> 16))444dist = (right >> 16);445}446else {447dist = left >> 16;448}449self->hitbox.top = (top >> 16) + bottom * (dist - (left >> 16)) / ((right >> 16) - (left >> 16));450self->hitbox.bottom = self->hitbox.top + 16;451if (Player_CheckCollisionPlatform(player, self, &self->hitbox))452player->position.y += 0x40000;453}454}455456void DERobot_CheckPlayerCollisions_Hand(void)457{458RSDK_THIS(DERobot);459460int32 storeX = self->position.x;461int32 storeY = self->position.y;462463Vector2 pivot;464pivot.x = self->position.x;465pivot.y = self->position.y;466self->position.x += (self->armExtend + 35) << 16;467Zone_RotateOnPivot(&self->position, &pivot, -(self->angle >> 3));468469foreach_active(Player, player)470{471if (Player_CheckCollisionTouch(player, self, &DERobot->hitboxHand)) {472#if MANIA_USE_PLUS473if (!Player_CheckMightyUnspin(player, 0x400, false, &player->uncurlTimer))474#endif475Player_Hurt(player, self);476}477}478479DERobot_HandleTerrainDestruction();480self->position.x = storeX;481self->position.y = storeY;482}483484bool32 DERobot_CheckRubyGrabbed(void)485{486RSDK_THIS(DERobot);487488bool32 grabbedRuby = false;489int32 storeX = self->position.x;490int32 storeY = self->position.y;491492Vector2 pivot;493pivot.x = self->position.x;494pivot.y = self->position.y;495self->position.x += (self->armExtend + 48) << 16;496Zone_RotateOnPivot(&self->position, &pivot, -(self->angle >> 3));497498foreach_active(PhantomRuby, ruby)499{500if (abs(self->position.x - ruby->position.x) < 0x80000) {501if (abs(self->position.y - ruby->position.y) < 0x80000) {502grabbedRuby = true;503ruby->position.x = self->position.x;504ruby->position.y = self->position.y;505ruby->drawGroup = Zone->objectDrawGroup[0];506ruby->state = PhantomRuby_State_RotateToOrigin;507}508}509}510511self->position.x = storeX;512self->position.y = storeY;513return grabbedRuby;514}515516void DERobot_CheckPlayerCollisions_Bomb(void)517{518RSDK_THIS(DERobot);519520foreach_active(Player, player)521{522if (Player_CheckCollisionTouch(player, self, &DERobot->hitboxHand))523Player_Hurt(player, self);524}525}526527void DERobot_Draw_RelativeToParent(void)528{529RSDK_THIS(DERobot);530531self->position.x = self->parent->position.x + self->offset.x;532self->position.y = self->parent->position.y + self->offset.y;533RSDK.DrawSprite(&self->mainAnimator, NULL, false);534}535536void DERobot_Draw_Arm(void)537{538RSDK_THIS(DERobot);539540self->rotation = self->angle >> 2;541RSDK.DrawSprite(&self->mainAnimator, NULL, false);542543if (self->armExtend > 0) {544SpriteFrame *frame = RSDK.GetFrame(DERobot->aniFrames, self->altAnimator.animationID, self->altAnimator.frameID);545frame->width = self->armExtend;546frame->sprX = 4 * (Zone->timer & 3);547RSDK.DrawSprite(&self->altAnimator, NULL, false);548}549550RSDK.GetFrame(DERobot->aniFrames, self->armAnimator.animationID, self->armAnimator.frameID)->pivotX = self->armExtend + 22;551RSDK.DrawSprite(&self->armAnimator, NULL, false);552}553554void DERobot_Draw_Simple(void)555{556RSDK_THIS(DERobot);557558RSDK.DrawSprite(&self->mainAnimator, NULL, false);559}560561void DERobot_Draw_FrontLeg(void)562{563RSDK_THIS(DERobot);564565self->drawFX = FX_NONE;566self->rotation = -(self->angle >> 1);567RSDK.DrawSprite(&self->mainAnimator, NULL, false);568569self->drawFX = FX_ROTATE;570RSDK.DrawSprite(&self->altAnimator, NULL, false);571}572573void DERobot_Draw_Target(void)574{575RSDK_THIS(DERobot);576577Vector2 drawPos;578579self->mainAnimator.frameID = 0;580self->inkEffect = INK_ALPHA;581self->direction = FLIP_NONE;582drawPos.x = self->position.x - self->offset.x;583drawPos.y = self->position.y - self->offset.y;584RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);585586self->direction = FLIP_X;587drawPos.x = self->position.x + self->offset.x;588drawPos.y = self->position.y - self->offset.y;589RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);590591self->mainAnimator.frameID = 1;592self->direction = FLIP_NONE;593drawPos.x = self->position.x - self->offset.x;594drawPos.y = self->position.y + self->offset.y;595RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);596597self->direction = FLIP_X;598drawPos.x = self->position.x + self->offset.x;599drawPos.y = self->position.y + self->offset.y;600RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);601602self->inkEffect = INK_NONE;603self->direction = FLIP_NONE;604RSDK.DrawSprite(&self->altAnimator, NULL, false);605RSDK.DrawSprite(&self->armAnimator, NULL, false);606}607608void DERobot_State_ArmIdle(void)609{610RSDK_THIS(DERobot);611612RSDK.ProcessAnimation(&self->armAnimator);613if (self->armAnimator.speed > 0x40)614self->armAnimator.speed -= 4;615616DERobot_CheckPlayerCollisions_Hand();617}618619void DERobot_State_ArmExtendPrepare(void)620{621RSDK_THIS(DERobot);622623RSDK.ProcessAnimation(&self->armAnimator);624625if (self->armAnimator.speed == 240)626RSDK.PlaySfx(DERobot->sfxBuzzsaw, false, 255);627628if (self->armAnimator.speed >= 0x100)629self->state = DERobot_State_ArmExtending;630else631self->armAnimator.speed += 4;632633DERobot_CheckPlayerCollisions_Hand();634}635636void DERobot_State_ArmExtending(void)637{638RSDK_THIS(DERobot);639640RSDK.ProcessAnimation(&self->altAnimator);641RSDK.ProcessAnimation(&self->armAnimator);642if (self->armExtend < 192)643self->armExtend += 8;644645DERobot_CheckPlayerCollisions_ArmExtend();646DERobot_CheckPlayerCollisions_Hand();647648if (++self->timer == 120) {649self->timer = 0;650self->state = DERobot_State_ArmRetracting;651}652}653654void DERobot_State_ArmRetracting(void)655{656RSDK_THIS(DERobot);657658RSDK.ProcessAnimation(&self->altAnimator);659RSDK.ProcessAnimation(&self->armAnimator);660661if (self->armExtend <= 0) {662self->state = DERobot_State_ArmIdle;663}664else {665DERobot_CheckPlayerCollisions_ArmExtend();666self->armExtend -= 8;667}668669DERobot_CheckPlayerCollisions_Hand();670}671672void DERobot_State_ArmDestroyed(void)673{674RSDK_THIS(DERobot);675676RSDK.ProcessAnimation(&self->altAnimator);677RSDK.ProcessAnimation(&self->armAnimator);678679if (self->armExtend > 0)680self->armExtend -= 8;681}682683void DERobot_Cutscene_ActivateArm(void)684{685RSDK_THIS(DERobot);686RSDK.ProcessAnimation(&self->armAnimator);687688if (self->angle > -96)689self->angle -= 4;690691if (self->armAnimator.speed < 0x80)692self->armAnimator.speed += 4;693694if (self->timer++ == -1)695RSDK.PlaySfx(DERobot->sfxButton2, false, 255);696697if (self->timer == 30) {698self->timer = 0;699self->state = DERobot_Cutscene_ReachForRuby;700RSDK.PlaySfx(DERobot->sfxBuzzsaw, false, 255);701}702}703704void DERobot_Cutscene_ReachForRuby(void)705{706RSDK_THIS(DERobot);707708RSDK.ProcessAnimation(&self->altAnimator);709RSDK.ProcessAnimation(&self->armAnimator);710711if (DERobot_CheckRubyGrabbed() || self->armExtend >= 192)712self->state = DERobot_Cutscene_GrabbedRuby;713else714self->armExtend += 8;715}716717void DERobot_Cutscene_GrabbedRuby(void)718{719RSDK_THIS(DERobot);720721RSDK.ProcessAnimation(&self->altAnimator);722RSDK.ProcessAnimation(&self->armAnimator);723724if (self->armExtend <= 0) {725RSDK.StopSfx(DERobot->sfxBuzzsaw);726self->state = DERobot_Cutscene_ArmDeactivate;727}728else {729self->armExtend -= 8;730DERobot_CheckRubyGrabbed();731}732}733734void DERobot_Cutscene_ArmDeactivate(void)735{736RSDK_THIS(DERobot);737738RSDK.ProcessAnimation(&self->armAnimator);739740if (self->armAnimator.speed)741self->armAnimator.speed--;742}743744void DERobot_State_CloseHeadHatch(void)745{746RSDK_THIS(DERobot);747748self->timer++;749if (self->timer == 30) {750RSDK.PlaySfx(DERobot->sfxButton2, false, 255);751}752753if (self->timer >= 30) {754if (self->rotation >= 0) {755self->timer = 0;756self->state = 0;757self->drawFX = FX_NONE;758RSDK.PlaySfx(DERobot->sfxHullClose, false, 255);759}760else {761self->rotation += 8;762}763}764}765766void DERobot_State_BombLaunched(void)767{768RSDK_THIS(DERobot);769770self->angle += 7;771if (self->angle > 480) {772self->velocity.y += 0x4000;773self->position.x += self->velocity.x;774self->position.y += self->velocity.y;775}776else {777self->velocity.x = self->position.x;778self->position.x = self->offset.x - self->scale.x * RSDK.Cos1024(self->angle);779self->velocity.x = self->position.x - self->velocity.x;780self->velocity.y = self->position.y;781self->position.y = self->offset.y - self->scale.y * RSDK.Sin1024(self->angle);782self->velocity.y = self->position.y - self->velocity.y;783}784785if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xE0000, true))786self->state = DERobot_State_BombLanded;787788DERobot_CheckPlayerCollisions_Bomb();789}790791void DERobot_State_BombLanded(void)792{793RSDK_THIS(DERobot);794795RSDK.ProcessAnimation(&self->mainAnimator);796797if (self->mainAnimator.speed >= 0x80) {798self->visible = false;799self->state = DERobot_State_BombExplode;800EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x, self->position.y - 0x80000);801explosion->drawGroup = Zone->objectDrawGroup[1];802RSDK.PlaySfx(DERobot->sfxExplosion, false, 255);803}804else {805self->mainAnimator.speed++;806}807808DERobot_CheckPlayerCollisions_Bomb();809}810811void DERobot_State_BombExplode(void)812{813RSDK_THIS(DERobot);814815self->position.y -= 0x20000;816817++self->timer;818if (self->timer < 16)819DERobot_CheckPlayerCollisions_Bomb();820821if (!(self->timer & 7)) {822EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x, self->position.y);823explosion->drawGroup = Zone->objectDrawGroup[1];824}825826if (self->timer == 32)827destroyEntity(self);828}829830void DERobot_State_SetupArena(void)831{832RSDK_THIS(DERobot);833834if (++self->timer >= 8) {835self->timer = 0;836837EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);838if (player1->position.y <= self->position.y + 0x200000 && player1->state != Player_State_TubeRoll) {839for (int32 i = 0; i < Player->playerCount; ++i) {840Zone->cameraBoundsL[i] = (self->position.x >> 16) - ScreenInfo->center.x + 128;841Zone->cameraBoundsR[i] = ScreenInfo->center.x + 128 + (self->position.x >> 16);842Zone->cameraBoundsB[i] = self->position.y >> 16;843Zone->playerBoundsB[i] = Zone->cameraBoundsB[i] << 16;844Zone->playerBoundActiveL[i] = true;845Zone->playerBoundActiveR[i] = true;846Zone->playerBoundActiveB[i] = false;847}848self->position.y -= 0x1800000;849self->active = ACTIVE_NORMAL;850self->state = DERobot_State_SetupBoss;851}852}853}854855void DERobot_State_SetupBoss(void)856{857RSDK_THIS(DERobot);858859EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);860861if (self->timer) {862self->timer++;863if (self->timer == 60) {864CREATE_ENTITY(DERobot, INT_TO_VOID(DEROBOT_TARGET_EDGE), self->position.x, 0x3080000);865RSDK.PlaySfx(DERobot->sfxTargeting, false, 255);866Music_TransitionTrack(TRACK_EGGMAN1, 0.0125);867}868869if (self->timer == 160) {870self->timer = 0;871self->visible = true;872self->state = DERobot_State_SurpriseFall;873if (player1->characterID == ID_TAILS)874player1->stateAbility = Player_JumpAbility_Tails;875876EntityDERobot *kneeBack = self->legs[0];877kneeBack->active = ACTIVE_NORMAL;878kneeBack->visible = true;879880EntityDERobot *legBack = self->legs[1];881legBack->active = ACTIVE_NORMAL;882legBack->visible = true;883884EntityDERobot *footBack = self->legs[2];885footBack->active = ACTIVE_NORMAL;886footBack->visible = true;887888EntityDERobot *kneeFront = self->legs[3];889kneeFront->active = ACTIVE_NORMAL;890kneeFront->visible = true;891892EntityDERobot *legFront = self->legs[4];893legFront->active = ACTIVE_NORMAL;894legFront->visible = true;895896EntityDERobot *footFront = self->legs[5];897footFront->active = ACTIVE_NORMAL;898footFront->visible = true;899900EntityDERobot *head = self->head;901head->active = ACTIVE_NORMAL;902head->visible = true;903head->rotation = -128;904905EntityDERobot *shoulder = self->shoulderFront;906shoulder->active = ACTIVE_NORMAL;907shoulder->visible = true;908909EntityDERobot *armBack = self->arms[0];910armBack->active = ACTIVE_NORMAL;911armBack->visible = true;912913EntityDERobot *handBack = self->arms[1];914handBack->active = ACTIVE_NORMAL;915handBack->visible = true;916917EntityDERobot *armFront = self->arms[2];918armFront->active = ACTIVE_NORMAL;919armFront->visible = true;920921EntityDERobot *handFront = self->arms[3];922handFront->active = ACTIVE_NORMAL;923handFront->visible = true;924925EntityEggman *eggman = self->eggman;926RSDK.ResetEntity(eggman, Eggman->classID, self);927eggman->state = Eggman_State_ProcessAnimation;928eggman->animID = 0;929eggman->offset.x = -0x40000;930eggman->offset.y = -0x200000;931}932}933else if (player1->position.x > 0x800000 + self->position.x && player1->onGround) {934RSDK_GET_ENTITY(SLOT_CAMERA1, Camera)->boundsOffset.x = 1;935936++self->timer;937if (player1->characterID == ID_TAILS)938player1->stateAbility = StateMachine_None;939}940941foreach_active(Player, player)942{943if (player->state == Player_State_TubeRoll || player->state == Player_State_TubeAirRoll)944player->state = Player_State_Air;945}946}947948void DERobot_State_Target(void)949{950RSDK_THIS(DERobot);951952RSDK.ProcessAnimation(&self->altAnimator);953RSDK.ProcessAnimation(&self->armAnimator);954955if (self->parent) {956self->position.x = self->parent->position.x;957self->position.y = self->parent->position.y;958}959960self->alpha += 0x20;961self->offset.x -= self->velocity.x;962if (self->offset.x <= 0xC0000) {963self->alpha = 0;964self->offset.x = 0x2C0000;965}966967self->offset.y = self->offset.x;968if (++self->timer == 60)969RSDK.SetSpriteAnimation(DERobot->aniFrames, 8, &self->armAnimator, true, 0);970971if (self->timer == 96) {972self->parent = 0;973foreach_active(DERobot, robot)974{975if (!robot->aniID) {976robot->offset.x = self->position.x;977robot->offset.y = self->position.y;978}979}980}981982if (self->timer == 128)983destroyEntity(self);984}985986void DERobot_State_SurpriseFall(void)987{988RSDK_THIS(DERobot);989990self->velocity.y += 0x3800;991self->position.y += self->velocity.y;992993DERobot_HandleLegMovement(0);994DERobot_HandleLegMovement(3);995996if (self->legs[2]->onGround) {997self->angleVel = -0x10000;998self->state = DERobot_State_FallLand;999RSDK.SetSpriteAnimation(Eggman->aniFrames, 2, &self->eggman->animator, true, 0);1000self->eggman->state = Eggman_State_ProcessThenSet;1001Camera_ShakeScreen(0, 0, 8);1002RSDK.PlaySfx(DERobot->sfxLedgeBreak, false, 255);1003}10041005DERobot_HandleArmMovement(0);1006DERobot_HandleArmMovement(2);1007}10081009void DERobot_State_FallLand(void)1010{1011RSDK_THIS(DERobot);10121013EntityDERobot *kneeBack = self->legs[0];1014EntityDERobot *kneeFront = self->legs[3];10151016kneeBack->angle += self->angleVel >> 12;1017if (kneeBack->angle <= 0) {1018self->angleVel += 2048;1019}1020else {1021kneeBack->angle = 0;1022self->angleVel = 0;1023self->movingSide = 0;1024kneeBack->angleVel = 0x10000;1025kneeBack->angleInc = 0;1026kneeFront->angleVel = 0x10000;1027kneeFront->angleInc = 0;1028self->kneeAngleVel = 8;1029self->angleVelStart = 0x10000;1030self->angleMaxInc = -0x1000;1031RSDK.SetSpriteAnimation(Eggman->aniFrames, 3, &self->eggman->animator, true, 0);1032self->eggman->state = Eggman_State_ProcessThenSet;1033self->head->state = DERobot_State_CloseHeadHatch;1034self->state = DERobot_State_Walk;1035}1036kneeFront->angle = kneeBack->angle;10371038DERobot_HandleLegMovement2(1);1039DERobot_HandleLegMovement2(4);1040DERobot_HandleArmMovement(0);1041DERobot_HandleArmMovement(2);10421043DERobot_CheckPlayerCollisions_Body();1044}10451046void DERobot_State_Walk(void)1047{1048RSDK_THIS(DERobot);10491050int32 id = self->movingSide;10511052EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);1053DERobot_HandleScreenBounds();10541055++self->timer;1056if (self->timer == 240) {1057EntityDERobot *robotPart = CREATE_ENTITY(DERobot, INT_TO_VOID(DEROBOT_TARGET_EDGE), self->position.x, 0x3080000);1058robotPart->parent = (Entity *)player1;1059RSDK.PlaySfx(DERobot->sfxTargeting, false, 0xFF);1060}1061else if (self->timer == 340) {1062self->timer = 0;1063if (self->offset.x - self->position.x <= 0xD00000) {1064self->arms[3]->state = DERobot_State_ArmExtendPrepare;1065self->state = DERobot_State_ArmAttack;1066}1067else {1068EntityDERobot *robotPart = CREATE_ENTITY(DERobot, INT_TO_VOID(DEROBOT_BOMB), self->position.x - 0x360000, self->position.y - 0x60000);1069robotPart->offset.x = (self->offset.x >> 1) + ((self->position.x - 0x360000) >> 1);1070robotPart->offset.y = robotPart->position.y;1071robotPart->scale.y = 0x2000;1072robotPart->scale.x = (self->offset.x - self->position.x + 0x360000) >> 11;1073RSDK.PlaySfx(DERobot->sfxDrop, false, 255);1074}1075}10761077if (self->movingSide == 3) {1078self->arms[0]->angle += (-112 - self->arms[0]->angle) >> 4;1079self->arms[1]->angle += (64 - self->arms[1]->angle) >> 4;1080if (self->timer >= 240 && player1->position.x - self->position.x <= 0xD00000) {1081int32 armAngle =10824 * RSDK.ATan2((player1->position.x - self->arms[3]->position.x) >> 16, (player1->position.y - self->arms[3]->position.y) >> 16);10831084if (armAngle > 0x200)1085armAngle = armAngle - 0x400;10861087armAngle = CLAMP(armAngle, -0x60, 0x80);1088int32 armAngle2 = MIN(self->arms[2]->angle + (-(self->arms[2]->angle + armAngle) >> 3), 0x80);10891090self->arms[2]->angle = armAngle2;1091self->arms[3]->angle += (armAngle - self->arms[3]->angle) >> 3;1092}1093else {1094self->arms[2]->angle += (0x70 - self->arms[2]->angle) >> 4;1095self->arms[3]->angle += (-0x20 - self->arms[3]->angle) >> 4;1096}1097}1098else {1099self->arms[0]->angle += (112 - self->arms[0]->angle) >> 4;1100self->arms[1]->angle += (-32 - self->arms[1]->angle) >> 4;1101if (self->timer >= 240 && player1->position.x - self->position.x <= 0xD00000) {1102int32 armAngle =11034 * RSDK.ATan2((player1->position.x - self->arms[3]->position.x) >> 16, (player1->position.y - self->arms[3]->position.y) >> 16);1104if (armAngle > 0x200)1105armAngle = armAngle - 0x400;1106armAngle = MIN(armAngle, 0x80);11071108int32 armAngle2 = MIN(self->arms[2]->angle + (-(self->arms[2]->angle + armAngle) >> 3), 0x80);11091110self->arms[2]->angle = armAngle2;1111self->arms[3]->angle += (armAngle - self->arms[3]->angle) >> 3;1112}1113else {1114self->arms[2]->angle += (-112 - self->arms[2]->angle) >> 4;1115self->arms[3]->angle += (64 - self->arms[3]->angle) >> 4;1116}1117}11181119DERobot_HandleArmMovement(0);1120DERobot_HandleArmMovement(2);11211122EntityDERobot *knee = self->legs[id];1123EntityDERobot *leg = self->legs[((id + 3) % 6) + 0];1124EntityDERobot *foot = self->legs[((id + 3) % 6) + 2];1125knee->angle -= self->kneeAngleVel;1126DERobot_HandleLegMovement2(id + 1);11271128leg->angle += leg->angleVel >> 12;1129leg->angleVel += leg->angleInc;1130if (leg->angle > 176)1131leg->angleInc = self->angleMaxInc;11321133DERobot_HandleLegMovement((id + 3) % 6);11341135if (foot->onGround && (-knee->angle >> 6) > 0) {1136self->movingSide = (self->movingSide + 3) % 6;1137leg->angleVel = self->angleVelStart;1138leg->angleInc = 0;1139Camera_ShakeScreen(0, 0, 4);1140RSDK.PlaySfx(DERobot->sfxImpact, false, 255);1141if (self->position.x > 0x4D800000) {1142self->health = 1;1143DERobot_Hit();1144foreach_active(CollapsingPlatform, platform) { platform->stoodPos.x = platform->position.x; }1145}1146}11471148DERobot_CheckPlayerCollisions_Body();1149}11501151void DERobot_State_ArmAttack(void)1152{1153RSDK_THIS(DERobot);11541155DERobot_HandleScreenBounds();1156EntityDERobot *armBack = self->arms[0];1157if (self->movingSide == 3) {1158armBack->angle += (-112 - armBack->angle) >> 4;1159self->arms[1]->angle += (64 - self->arms[1]->angle) >> 4;1160}1161else {1162armBack->angle += (112 - armBack->angle) >> 4;1163self->arms[1]->angle += (-32 - self->arms[1]->angle) >> 4;1164}11651166if (self->arms[3]->state == DERobot_State_ArmRetracting)1167self->state = DERobot_State_Walk;11681169DERobot_HandleArmMovement(0);1170DERobot_HandleArmMovement(2);11711172EntityDERobot *knee = self->legs[self->movingSide];1173knee->angle -= self->kneeAngleVel;1174DERobot_HandleLegMovement2(self->movingSide + 1);11751176EntityDERobot *leg = self->legs[((self->movingSide + 3) % 6) + 0];1177EntityDERobot *foot = self->legs[((self->movingSide + 3) % 6) + 2];11781179leg->angle += leg->angleVel >> 12;1180leg->angleVel += leg->angleInc;1181if (leg->angle > 176)1182leg->angleInc = self->angleMaxInc;11831184DERobot_HandleLegMovement((self->movingSide + 3) % 6);11851186if (foot->onGround && (-knee->angle >> 6) > 0) {1187self->movingSide = (self->movingSide + 3) % 6;1188leg->angleVel = self->angleVelStart;1189leg->angleInc = 0;1190Camera_ShakeScreen(0, 0, 4);1191RSDK.PlaySfx(DERobot->sfxImpact, false, 0xFF);1192if (self->position.x > 0x4E000000) {1193self->health = 1;1194DERobot_Hit();1195}1196}11971198DERobot_CheckPlayerCollisions_Body();1199}12001201void DERobot_State_Explode(void)1202{1203RSDK_THIS(DERobot);12041205DERobot_Explode();12061207if (++self->timer == 90) {1208foreach_active(DERobot, robot)1209{1210switch (robot->aniID) {1211case DEROBOT_BODY: break;1212case DEROBOT_HEAD:1213robot->velocity.x = -0x10000;1214robot->velocity.y = -0x40000;1215robot->angleVel = -8;1216robot->drawFX = FX_ROTATE;1217robot->state = DERobot_State_DebrisFall;1218robot->stateDraw = DERobot_Draw_Simple;1219break;12201221case DEROBOT_ARM:1222case DEROBOT_LEG:1223case DEROBOT_SPIKES:1224case DEROBOT_ARM_THREAD:1225case DEROBOT_TARGET_EDGE:1226case DEROBOT_TARGET_CENTER:1227robot->velocity.x = RSDK.Rand(-0x40000, 0x40000);1228robot->velocity.y = RSDK.Rand(-0x40000, -0x10000);1229robot->angleVel = RSDK.Rand(-16, 16);1230robot->drawFX = FX_ROTATE;1231robot->state = DERobot_State_DebrisFall;1232if (robot->stateDraw == DERobot_Draw_RelativeToParent)1233robot->stateDraw = DERobot_Draw_Simple;1234break;1235}1236}12371238RSDK.SetSpriteAnimation(Eggman->aniFrames, 4, &self->eggman->animator, true, 0);1239self->timer = 0;1240self->offset.x = 0;1241self->velocity.y = -0x40000;1242self->state = DERobot_State_ExplodeTerrain;1243RSDK.PlaySfx(DERobot->sfxLedgeBreak, false, 0xFF);1244}1245}12461247void DERobot_State_ExplodeTerrain(void)1248{1249RSDK_THIS(DERobot);12501251DERobot_Explode();12521253self->velocity.y += 0x3800;1254self->position.y += self->velocity.y;12551256if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x280000, true)) {1257DERobot_DestroyTerrainFinal();1258RSDK.PlaySfx(DERobot->sfxLedgeBreak, false, 255);1259self->state = DERobot_State_Finish;1260self->velocity.y = -0x10000 - (self->velocity.y >> 1);1261Camera_ShakeScreen(0, 0, 8);1262}12631264if (self->offset.x < 0x480000)1265self->offset.x += 0x40000;12661267foreach_active(Player, player)1268{1269if (player->position.x < self->offset.x + self->position.x) {1270player->position.x = self->offset.x + self->position.x;1271player->velocity.x = 0x40000;1272player->groundVel = 0x40000;1273}1274}1275}12761277void DERobot_State_Finish(void)1278{1279RSDK_THIS(DERobot);12801281self->velocity.y += 0x2000;1282self->position.y += self->velocity.y;12831284if (++self->timer == 96)1285RSDK.PlaySfx(DERobot->sfxDrop, false, 255);12861287if (self->timer == 180) {1288Music_TransitionTrack(TRACK_STAGE, 0.0125);12891290EntityEggPrison *prison = (EntityEggPrison *)self->eggman;1291RSDK.ResetEntity(prison, EggPrison->classID, INT_TO_VOID(EGGPRISON_FLYING));1292prison->position.x = (ScreenInfo->position.x + ScreenInfo->center.x) << 16;1293prison->checkTileCollisions = true;1294prison->position.y = (ScreenInfo->position.y - 48) << 16;12951296foreach_all(BoundsMarker, marker) { destroyEntity(marker); }1297self->state = DERobot_State_FinishBounds;1298}12991300if (!(Zone->timer & 7)) {1301int32 x = (RSDK.Rand(-48, 48) << 16) + self->position.x;1302int32 y = (RSDK.Rand(-48, 48) << 16) + self->position.y;1303EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), x, y);1304explosion->drawGroup = Zone->objectDrawGroup[1];1305}13061307foreach_active(Player, player)1308{1309if (player->position.x < self->position.x + 0x480000) {1310player->position.x = self->position.x + 0x480000;1311player->velocity.x = 0;1312player->groundVel = 0;1313player->pushing = false;1314}1315}1316}13171318void DERobot_State_DebrisFall(void)1319{1320RSDK_THIS(DERobot);13211322self->velocity.y += 0x3800;1323self->position.x += self->velocity.x;1324self->position.y += self->velocity.y;13251326self->rotation += self->angleVel;13271328if (!RSDK.CheckOnScreen(self, NULL))1329destroyEntity(self);1330}13311332void DERobot_State_FinishBounds(void)1333{1334RSDK_THIS(DERobot);13351336foreach_active(Player, player)1337{1338if (player->position.x < self->position.x + 0x480000) {1339player->position.x = self->position.x + 0x480000;1340player->velocity.x = 0;1341player->groundVel = 0;1342player->pushing = false;1343}13441345if (player->position.x > 0x4E800000) {1346player->position.x = 0x4E800000;1347player->velocity.x = 0;1348player->groundVel = 0;1349player->pushing = false;1350}1351}1352}13531354void DERobot_State_CutsceneExplode(void)1355{1356RSDK_THIS(DERobot);13571358if (!(Zone->timer & 0x3F)) {1359int32 x = (RSDK.Rand(-32, 32) << 16) + self->position.x;1360int32 y = (RSDK.Rand(-32, 32) << 16) + self->position.y;1361EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), x, y);1362explosion->drawGroup = Zone->objectDrawGroup[1];1363}1364}13651366#if GAME_INCLUDE_EDITOR1367void DERobot_EditorDraw(void)1368{1369RSDK_THIS(DERobot);13701371self->drawFX = FX_NONE;1372self->parent = (Entity *)self;13731374switch (self->aniID) {1375case DEROBOT_BODY:1376self->stateDraw = DERobot_Draw_Simple;1377RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);13781379if (showGizmos()) {1380RSDK_DRAWING_OVERLAY(true);1381DrawHelpers_DrawArenaBounds(-WIDE_SCR_XCENTER + 128, -SCREEN_YSIZE, WIDE_SCR_XCENTER + 128, 0, 1 | 0 | 4 | 8, 0x00C0F0);13821383int32 slot = RSDK.GetEntitySlot(self);1384for (int32 i = -7; i < 7; ++i) {1385if (i == 0) // thats this object lol1386continue;13871388EntityDERobot *child = RSDK_GET_ENTITY(slot + i, DERobot);13891390if (child)1391DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xFFFF00, INK_NONE, 0xFF);1392}13931394RSDK_DRAWING_OVERLAY(false);1395}1396break;13971398case DEROBOT_HEAD:1399self->stateDraw = DERobot_Draw_RelativeToParent;1400self->drawFX = FX_ROTATE;1401self->offset.x = -0x160000;1402self->offset.y = -0x240000;1403RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);1404break;14051406case DEROBOT_ARM:1407if (self->frameID == 2) {1408RSDK.SetSpriteAnimation(DERobot->aniFrames, 5, &self->altAnimator, true, 0);1409RSDK.SetSpriteAnimation(DERobot->aniFrames, 4, &self->armAnimator, true, 0);1410self->stateDraw = DERobot_Draw_Arm;1411self->drawFX = FX_ROTATE;1412self->state = DERobot_State_ArmIdle;1413}1414else if (self->frameID) {1415self->stateDraw = DERobot_Draw_Simple;1416}1417else {1418self->stateDraw = DERobot_Draw_RelativeToParent;1419self->offset.x = -0xC0000;1420self->offset.y = -0x100000;1421}1422RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);1423break;14241425case DEROBOT_LEG:1426if (self->frameID) {1427self->stateDraw = DERobot_Draw_Simple;1428}1429else {1430RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->altAnimator, true, 1);1431self->stateDraw = DERobot_Draw_FrontLeg;1432}14331434if (self->frameID > 1)1435self->drawFX = FX_ROTATE;1436RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);1437break;14381439case DEROBOT_TARGET_EDGE:1440self->drawFX = FX_FLIP;1441RSDK.SetSpriteAnimation(DERobot->aniFrames, 7, &self->altAnimator, true, 0);1442self->stateDraw = DERobot_Draw_Target;1443RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);1444break;14451446default:1447self->stateDraw = DERobot_Draw_Simple;1448RSDK.SetSpriteAnimation(DERobot->aniFrames, self->aniID, &self->mainAnimator, true, self->frameID);1449break;1450}14511452StateMachine_Run(self->stateDraw);1453}14541455void DERobot_EditorLoad(void)1456{1457DERobot->aniFrames = RSDK.LoadSpriteAnimation("GHZ/DERobot.bin", SCOPE_STAGE);14581459RSDK_ACTIVE_VAR(DERobot, aniID);1460RSDK_ENUM_VAR("Body", DEROBOT_BODY);1461RSDK_ENUM_VAR("Head", DEROBOT_HEAD);1462RSDK_ENUM_VAR("Arm", DEROBOT_ARM);1463RSDK_ENUM_VAR("Leg", DEROBOT_LEG);1464RSDK_ENUM_VAR("Spikes", DEROBOT_SPIKES);1465RSDK_ENUM_VAR("Arm Thread", DEROBOT_ARM_THREAD);1466RSDK_ENUM_VAR("Target Edge", DEROBOT_TARGET_EDGE);1467RSDK_ENUM_VAR("Target Center", DEROBOT_TARGET_CENTER);1468RSDK_ENUM_VAR("Target Lock", DEROBOT_TARGET_LOCK);1469RSDK_ENUM_VAR("Bomb", DEROBOT_BOMB);1470RSDK_ENUM_VAR("Body (Cutscene)", DEROBOT_BODY_CUTSCENE);1471}1472#endif14731474void DERobot_Serialize(void)1475{1476RSDK_EDITABLE_VAR(DERobot, VAR_ENUM, aniID);1477RSDK_EDITABLE_VAR(DERobot, VAR_ENUM, frameID);1478}147914801481