Path: blob/master/SonicMania/Objects/Global/EggPrison.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: EggPrison Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectEggPrison *EggPrison;1011void EggPrison_Update(void)12{13RSDK_THIS(EggPrison);1415StateMachine_Run(self->state);1617if (self->type == EGGPRISON_FLYING) {18RSDK.ProcessAnimation(&self->propellerAnimator);1920EggPrison_HandleMovement();2122if (!self->notSolid) {23foreach_active(Player, player)24{25if (Player_CheckCollisionBox(player, self, &self->hitboxSolid) == C_TOP) {26player->position.x += self->velocity.x;27player->position.y += TO_FIXED(1);28}2930if (self->state == EggPrison_State_Idle) {31if (Player_CheckCollisionBox(player, self, &self->hitboxButton) == C_BOTTOM) {32self->velocity.x = 0;33self->active = ACTIVE_NORMAL;34self->state = EggPrison_State_Opened;35self->buttonPos = -TO_FIXED(8);36}37else {38if (!Player_CheckCollisionTouch(player, self, &self->hitboxButtonTrigger)) {39if (self->buttonPos < 0)40self->buttonPos += TO_FIXED(1);41}42else {43Hitbox *playerHitbox = Player_GetHitbox(player);44self->buttonPos = TO_FIXED(playerHitbox->top - 48) - self->position.y + player->position.y;45self->buttonPos = CLAMP(self->buttonPos, -TO_FIXED(8), 0);46self->buttonPos &= 0xFFFF0000;47}48}49}50else {51Player_CheckCollisionBox(player, self, &self->hitboxButton);52}53}54}55}56else {57if (!self->notSolid) {58foreach_active(Player, player)59{60Player_CheckCollisionBox(player, self, &self->hitboxSolid);6162if (self->state == EggPrison_State_Idle) {63if (Player_CheckCollisionBox(player, self, &self->hitboxButton) == C_TOP) {64self->buttonPos = TO_FIXED(8);6566if (self->type < EGGPRISON_DUD)67SceneInfo->timeEnabled = false;6869if (self->type == EGGPRISON_SPRING) {70int32 anim = player->animator.animationID;71if (anim == ANI_WALK || (anim > ANI_AIR_WALK && anim <= ANI_DASH))72player->animationReserve = player->animator.animationID;73else74player->animationReserve = ANI_WALK;75player->state = Player_State_Air;76player->onGround = false;77player->velocity.y = -TO_FIXED(10);78RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_TWIRL, &player->animator, true, 0);79RSDK.PlaySfx(EggPrison->sfxSpring, false, 255);80}81else {82self->active = ACTIVE_NORMAL;83self->state = EggPrison_State_Opened;84}85}86else {87if (Player_CheckCollisionTouch(player, self, &self->hitboxButtonTrigger)) {88Hitbox *playerHitbox = Player_GetHitbox(player);8990self->buttonPos = TO_FIXED(playerHitbox->bottom + 48) - self->position.y + player->position.y;91self->buttonPos = CLAMP(self->buttonPos, 0, TO_FIXED(8));92self->buttonPos &= 0xFFFF0000;93}94else if (self->buttonPos > 0)95self->buttonPos -= TO_FIXED(1);96}97}98else {99Player_CheckCollisionBox(player, self, &self->hitboxButton);100}101}102}103}104}105106void EggPrison_LateUpdate(void) {}107108void EggPrison_StaticUpdate(void) {}109110void EggPrison_Draw(void)111{112RSDK_THIS(EggPrison);113114Vector2 drawPos;115if (self->type == EGGPRISON_FLYING) {116self->direction = FLIP_Y;117drawPos.x = self->position.x;118drawPos.y = self->position.y + self->buttonPos;119RSDK.DrawSprite(&self->buttonAnimator, &drawPos, false);120121self->direction = FLIP_NONE;122RSDK.DrawSprite(&self->capsuleAnimator, NULL, false);123RSDK.DrawSprite(&self->panelAnimator, NULL, false);124RSDK.DrawSprite(&self->propellerAnimator, NULL, false);125126self->direction = FLIP_X;127RSDK.DrawSprite(&self->propellerAnimator, NULL, false);128129self->direction = FLIP_NONE;130}131else {132drawPos.x = self->position.x;133drawPos.y = self->position.y + self->buttonPos;134RSDK.DrawSprite(&self->buttonAnimator, &drawPos, false);135RSDK.DrawSprite(&self->capsuleAnimator, NULL, false);136RSDK.DrawSprite(&self->panelAnimator, NULL, false);137}138}139140void EggPrison_Create(void *data)141{142RSDK_THIS(EggPrison);143144if (globals->gameMode < MODE_TIMEATTACK || self->type >= EGGPRISON_FLYING) {145self->drawFX = FX_FLIP;146147if (!SceneInfo->inEditor) {148if (data)149self->type = VOID_TO_INT(data);150151if (self->type == EGGPRISON_FLYING) {152RSDK.SetSpriteAnimation(EggPrison->aniFrames, 0, &self->capsuleAnimator, true, 1);153RSDK.SetSpriteAnimation(EggPrison->aniFrames, 1, &self->buttonAnimator, true, 0);154RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &self->panelAnimator, true, 1);155RSDK.SetSpriteAnimation(EggPrison->aniFrames, 3, &self->propellerAnimator, true, 0);156157self->hitboxButton.left = -16;158self->hitboxButton.top = 24;159self->hitboxButton.right = 16;160self->hitboxButton.bottom = 38;161162self->hitboxButtonTrigger.left = -15;163self->hitboxButtonTrigger.top = 24;164self->hitboxButtonTrigger.right = 15;165self->hitboxButtonTrigger.bottom = 48;166167self->velocity.x = 0x10000;168self->velocity.y = 0x4000;169}170else {171RSDK.SetSpriteAnimation(EggPrison->aniFrames, 0, &self->capsuleAnimator, true, 0);172RSDK.SetSpriteAnimation(EggPrison->aniFrames, 1, &self->buttonAnimator, true, 0);173RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &self->panelAnimator, true, 0);174175self->hitboxButton.left = -16;176self->hitboxButton.top = -38;177self->hitboxButton.right = 16;178self->hitboxButton.bottom = -24;179180self->hitboxButtonTrigger.left = -15;181self->hitboxButtonTrigger.top = -48;182self->hitboxButtonTrigger.right = 15;183self->hitboxButtonTrigger.top = -24;184}185self->hitboxSolid.left = -32;186self->hitboxSolid.top = -24;187self->hitboxSolid.right = 32;188self->hitboxSolid.bottom = 32;189190self->state = EggPrison_State_Init;191self->active = ACTIVE_BOUNDS;192self->updateRange.x = TO_FIXED(128);193self->updateRange.y = TO_FIXED(128);194self->visible = true;195self->drawGroup = Zone->objectDrawGroup[0];196}197}198else {199destroyEntity(self);200}201}202203void EggPrison_StageLoad(void)204{205EggPrison->aniFrames = RSDK.LoadSpriteAnimation("Global/EggPrison.bin", SCOPE_STAGE);206207EggPrison->sfxDestroy = RSDK.GetSfx("Global/Destroy.wav");208EggPrison->sfxSpring = RSDK.GetSfx("Global/Spring.wav");209}210211void EggPrison_HandleMovement(void)212{213RSDK_THIS(EggPrison);214215bool32 hitFloor = false;216if (self->checkTileCollisions) {217if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, -TO_FIXED(48), TO_FIXED(144), false)218|| RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, TO_FIXED(48), TO_FIXED(144), false)) {219self->originY -= self->velocity.y;220hitFloor = true;221}222}223224if (!hitFloor) {225if (self->originY < (ScreenInfo->position.y + 64) << 16)226self->originY += self->velocity.y;227}228229if (self->state != EggPrison_State_FlyOffScreen) {230if (self->velocity.x > 0) {231if (self->position.x <= TO_FIXED(ScreenInfo->position.x + ScreenInfo->size.x - 48)) {232if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, TO_FIXED(64), 0, true))233self->velocity.x = -self->velocity.x;234}235else {236self->velocity.x = -self->velocity.x;237}238}239else if (self->position.x < TO_FIXED(ScreenInfo->position.x + 48)) {240self->velocity.x = -self->velocity.x;241}242else {243if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, -TO_FIXED(64), 0, true))244self->velocity.x = -self->velocity.x;245}246}247248self->position.x += self->velocity.x;249self->position.y = BadnikHelpers_Oscillate(self->originY, 4, 10);250}251252void EggPrison_State_Opened(void)253{254RSDK_THIS(EggPrison);255256RSDK.SetSpriteAnimation(-1, 0, &self->panelAnimator, true, 0);257self->state = EggPrison_State_Explode;258259switch (self->type) {260default:261case EGGPRISON_NORMAL:262case EGGPRISON_FLYING:263case EGGPRISON_DUD:264case EGGPRISON_SPRING:265for (int32 a = 0; a < 10; ++a) {266int32 x = self->position.x + TO_FIXED((RSDK.Rand(0, 48) & -4) - 24);267int32 y = self->position.y + TO_FIXED(4);268EntityAnimals *animals = CREATE_ENTITY(Animals, INT_TO_VOID(Animals->animalTypes[a & 1] + 1), x, y);269270animals->timer = 4 * a;271animals->state = Animals_State_Placed;272animals->behaviour = ANIMAL_BEHAVE_FOLLOW;273animals->direction = (a ^ (a >> 1)) & 1;274}275break;276277case EGGPRISON_RINGS: {278int32 angle = 0x90;279for (int32 r = 0; r < 6; ++r) {280int32 x = self->position.x + TO_FIXED((RSDK.Rand(0, 48) & -4) - 24);281int32 y = self->position.y;282EntityRing *ring = CREATE_ENTITY(Ring, self, x, y);283284ring->velocity.x = RSDK.Cos256(angle) << 9;285ring->velocity.y = RSDK.Sin256(angle) << 9;286ring->animator.speed = 512;287ring->collisionPlane = 0;288ring->inkEffect = INK_ALPHA;289if (angle != 176)290angle += 8;291else292angle = 0xD0;293ring->alpha = 0x100;294ring->state = Ring_State_Lost;295ring->stateDraw = Ring_Draw_Normal;296}297break;298}299300case EGGPRISON_TRAP: {301EntityTechnosqueek *technosqueek = CREATE_ENTITY(Technosqueek, NULL, self->position.x - TO_FIXED(8), self->position.y);302technosqueek->velocity.x = -TO_FIXED(3);303technosqueek->velocity.y = -TO_FIXED(4);304technosqueek->active = ACTIVE_NORMAL;305technosqueek->state = Technosqueek_State_Fall;306307technosqueek = CREATE_ENTITY(Technosqueek, NULL, self->position.x + TO_FIXED(8), self->position.y);308technosqueek->velocity.x = TO_FIXED(3);309technosqueek->velocity.y = -TO_FIXED(4);310technosqueek->active = ACTIVE_NORMAL;311technosqueek->direction = FLIP_X;312technosqueek->state = Technosqueek_State_Fall;313314EntityBlaster *blaster = CREATE_ENTITY(Blaster, NULL, self->position.x - TO_FIXED(24), self->position.y);315blaster->velocity.x = -TO_FIXED(3);316blaster->velocity.y = -TO_FIXED(3);317blaster->active = ACTIVE_NORMAL;318blaster->state = Blaster_State_Fall;319320blaster = CREATE_ENTITY(Blaster, NULL, self->position.x + TO_FIXED(24), self->position.y);321blaster->velocity.x = TO_FIXED(3);322blaster->velocity.y = -TO_FIXED(3);323blaster->active = ACTIVE_NORMAL;324blaster->direction = FLIP_X;325blaster->state = Blaster_State_Fall;326break;327}328}329330EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - TO_FIXED(22), self->position.y);331RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &debris->animator, true, 2);332debris->velocity.x = -TO_FIXED(2);333debris->velocity.y = -TO_FIXED(2);334debris->gravityStrength = 0x3800;335debris->rotSpeed = -4;336debris->drawFX = FX_ROTATE;337debris->drawGroup = Zone->objectDrawGroup[1];338debris->updateRange.x = TO_FIXED(128);339debris->updateRange.y = TO_FIXED(128);340341debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);342RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &debris->animator, true, 3);343debris->velocity.x = TO_FIXED(0);344debris->velocity.y = -TO_FIXED(3);345debris->gravityStrength = 0x3800;346debris->rotSpeed = 8;347debris->drawFX = FX_ROTATE;348debris->drawGroup = Zone->objectDrawGroup[1];349debris->updateRange.x = TO_FIXED(128);350debris->updateRange.y = TO_FIXED(128);351352debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + TO_FIXED(22), self->position.y);353RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &debris->animator, true, 4);354debris->velocity.x = TO_FIXED(2);355debris->velocity.y = -TO_FIXED(2);356debris->gravityStrength = 0x3800;357debris->rotSpeed = 4;358debris->drawFX = FX_ROTATE;359debris->drawGroup = Zone->objectDrawGroup[1];360debris->updateRange.x = TO_FIXED(128);361debris->updateRange.y = TO_FIXED(128);362}363364void EggPrison_State_Init(void)365{366RSDK_THIS(EggPrison);367368self->originY = self->position.y;369self->state = EggPrison_State_Idle;370}371372void EggPrison_State_Idle(void)373{374RSDK_THIS(EggPrison);375376for (int32 p = 0; p < Player->playerCount && self->type < EGGPRISON_DUD; ++p) {377EntityPlayer *player = RSDK_GET_ENTITY(p, Player);378if (!player->sidekick) {379if (abs(self->position.x - player->position.x) < TO_FIXED(256)) {380if (abs(self->position.y - player->position.y) < TO_FIXED(256) && self->position.x - (Zone->cameraBoundsR[p] << 16) < TO_FIXED(256)) {381Zone->playerBoundActiveL[p] = true;382Zone->playerBoundActiveR[p] = true;383384if (self->type == EGGPRISON_NORMAL) {385Zone->cameraBoundsL[p] = FROM_FIXED(self->position.x) - ScreenInfo[p].center.x;386Zone->cameraBoundsR[p] = FROM_FIXED(self->position.x) + ScreenInfo[p].center.x;387}388}389}390}391}392}393394void EggPrison_State_Explode(void)395{396RSDK_THIS(EggPrison);397398if (!(self->timer % 3)) {399int32 x = self->position.x + (RSDK.Rand(-24, 24) << 16);400int32 y = self->position.y + (RSDK.Rand(-24, 24) << 16);401EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(2 * (RSDK.Rand(0, 256) > 192) + EXPLOSION_ENEMY), x, y);402explosion->drawGroup = Zone->objectDrawGroup[1];403RSDK.PlaySfx(EggPrison->sfxDestroy, false, 255);404}405406if (++self->timer == 20) {407self->timer = 0;408if (self->type < EGGPRISON_DUD) {409self->state = EggPrison_State_SetupActClear;410Music_FadeOut(0.025);411}412else {413self->state = StateMachine_None;414}415}416}417418void EggPrison_State_SetupActClear(void)419{420RSDK_THIS(EggPrison);421422if (++self->timer == 60) {423self->timer = 0;424self->state = StateMachine_None;425Zone->shouldRecoverPlayers = false;426Music_PlayTrack(TRACK_ACTCLEAR);427RSDK.ResetEntitySlot(SLOT_ACTCLEAR, ActClear->classID, NULL);428}429}430431void EggPrison_State_FlyOffScreen(void)432{433RSDK_THIS(EggPrison);434435if (self->velocity.x > -TO_FIXED(3))436self->velocity.x -= 0x1000;437438if (!RSDK.CheckOnScreen(self, NULL))439destroyEntity(self);440}441442#if GAME_INCLUDE_EDITOR443void EggPrison_EditorDraw(void)444{445RSDK_THIS(EggPrison);446447Vector2 drawPos;448if (self->type == EGGPRISON_FLYING) {449RSDK.SetSpriteAnimation(EggPrison->aniFrames, 0, &self->capsuleAnimator, true, 1);450RSDK.SetSpriteAnimation(EggPrison->aniFrames, 1, &self->buttonAnimator, true, 0);451RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &self->panelAnimator, true, 1);452RSDK.SetSpriteAnimation(EggPrison->aniFrames, 3, &self->propellerAnimator, true, 0);453454self->direction = FLIP_Y;455drawPos.x = self->position.x;456drawPos.y = self->position.y + self->buttonPos;457RSDK.DrawSprite(&self->buttonAnimator, &drawPos, false);458459self->direction = FLIP_NONE;460RSDK.DrawSprite(&self->capsuleAnimator, NULL, false);461RSDK.DrawSprite(&self->panelAnimator, NULL, false);462RSDK.DrawSprite(&self->propellerAnimator, NULL, false);463464self->direction = FLIP_X;465RSDK.DrawSprite(&self->propellerAnimator, NULL, false);466467self->direction = FLIP_NONE;468}469else {470RSDK.SetSpriteAnimation(EggPrison->aniFrames, 0, &self->capsuleAnimator, true, 0);471RSDK.SetSpriteAnimation(EggPrison->aniFrames, 1, &self->buttonAnimator, true, 0);472RSDK.SetSpriteAnimation(EggPrison->aniFrames, 2, &self->panelAnimator, true, 0);473474drawPos.x = self->position.x;475drawPos.y = self->position.y + self->buttonPos;476RSDK.DrawSprite(&self->buttonAnimator, &drawPos, false);477RSDK.DrawSprite(&self->capsuleAnimator, NULL, false);478RSDK.DrawSprite(&self->panelAnimator, NULL, false);479}480}481482void EggPrison_EditorLoad(void)483{484EggPrison->aniFrames = RSDK.LoadSpriteAnimation("Global/EggPrison.bin", SCOPE_STAGE);485486RSDK_ACTIVE_VAR(EggPrison, type);487RSDK_ENUM_VAR("Normal", EGGPRISON_NORMAL);488RSDK_ENUM_VAR("Flying", EGGPRISON_FLYING);489RSDK_ENUM_VAR("Dud", EGGPRISON_DUD);490RSDK_ENUM_VAR("Rings", EGGPRISON_RINGS);491RSDK_ENUM_VAR("Trap", EGGPRISON_TRAP);492RSDK_ENUM_VAR("Spring", EGGPRISON_SPRING);493}494#endif495496void EggPrison_Serialize(void) { RSDK_EDITABLE_VAR(EggPrison, VAR_ENUM, type); }497498499