Path: blob/master/SonicMania/Objects/TMZ/PopOut.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PopOut Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPopOut *PopOut;1011void PopOut_Update(void)12{13RSDK_THIS(PopOut);1415int32 storeDir = self->direction;16int32 storeX = self->position.x;17int32 storeY = self->position.y;1819EntitySpring *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, Spring);20if (child->classID != Spring->classID && child->classID != Spikes->classID)21child = NULL;2223self->direction = FLIP_NONE;24if (!self->manualTrigger) {25self->shouldAppear = false;26foreach_active(Player, player)27{28if (Player_CheckCollisionTouch(player, self, &self->hitboxRange)) {29self->shouldAppear = true;30foreach_break;31}32}33}34else if (PopOut->hasButton) {35foreach_active(Button, button)36{37if (button->tag == self->tag && button->activated)38self->shouldAppear = true;39}40}4142if (self->shouldAppear) {43if (self->timer < self->delay) {44self->timer++;45}46else {47if (self->appearTimer < 8) {48self->appearTimer++;49if (self->childType <= POPOUT_CHILD_SPRING_YELLOW && child && self->appearTimer == 8) {50child->sfxTimer = 0;51child->animator.speed = 0;52child->animator.frameID = 0;53}54}55}56}57else {58self->timer = 0;59if (self->appearTimer > 0) {60self->appearTimer--;61if (self->childType <= POPOUT_CHILD_SPRING_YELLOW && child && self->appearTimer == 7) {62child->sfxTimer = 0;63child->animator.speed = 0;64child->animator.frameID = 0;65}66}67}6869if (child) {70if (self->appearTimer == 8) {71child->active = ACTIVE_BOUNDS;72child->visible = true;73}74else {75child->active = ACTIVE_NEVER;76child->visible = false;77}78}7980self->active = (self->appearTimer <= 0) ? ACTIVE_BOUNDS : ACTIVE_NORMAL;8182self->position.x += -32 * self->appearVelocity.x + 4 * self->appearTimer * self->appearVelocity.x;83self->position.y += -32 * self->appearVelocity.y + 4 * self->appearTimer * self->appearVelocity.y;84foreach_active(Player, playerLoop) { Player_CheckCollisionBox(playerLoop, self, &self->hitboxSolid); }85self->direction = storeDir;86self->position.x = storeX;87self->position.y = storeY;88}8990void PopOut_LateUpdate(void) {}9192void PopOut_StaticUpdate(void) {}9394void PopOut_Draw(void)95{96RSDK_THIS(PopOut);9798int32 dir = self->direction;99int32 storeX = self->position.x;100int32 storeY = self->position.y;101self->position.x = -16 * self->appearVelocity.x + self->position.x + 2 * self->appearTimer * self->appearVelocity.x;102self->position.y = -16 * self->appearVelocity.y + self->position.y + 2 * self->appearTimer * self->appearVelocity.y;103self->rotation = self->orientation << 7;104105if (!self->appearTimer) {106int32 off = 128;107if (!dir)108off = -128;109self->rotation += off;110}111else if (self->appearTimer < 8) {112int32 off = 16;113if (!dir)114off = -16;115self->rotation += (7 - self->appearTimer) * off;116}117118RSDK.DrawSprite(&self->mountAnimator, NULL, false);119120if (self->appearTimer < 8)121RSDK.DrawSprite(&self->childAnimator, NULL, false);122123self->position.x = storeX;124self->position.y = storeY;125self->direction = dir;126self->rotation = 0;127}128129void PopOut_Create(void *data)130{131RSDK_THIS(PopOut);132self->drawFX = FX_ROTATE | FX_FLIP;133134if (!SceneInfo->inEditor) {135self->active = ACTIVE_BOUNDS;136self->drawGroup = Zone->objectDrawGroup[0];137self->startPos.x = self->position.x;138self->startPos.y = self->position.y;139self->visible = true;140self->updateRange.x = 0x800000;141self->updateRange.y = 0x800000;142RSDK.SetSpriteAnimation(PopOut->aniFrames, 0, &self->mountAnimator, true, 0);143144EntitySpring *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, Spring);145if (child->classID != Spring->classID && child->classID != Spikes->classID)146child = NULL;147148if (child->classID == Spring->classID) {149self->childType = (child->type & 1) ? POPOUT_CHILD_SPRING_RED : POPOUT_CHILD_SPRING_YELLOW;150RSDK.SetSpriteAnimation(PopOut->aniFrames, 1, &self->childAnimator, true, self->childType);151}152else {153// Assume its spikes154self->childType = POPOUT_CHILD_SPIKES;155RSDK.SetSpriteAnimation(PopOut->aniFrames, 2, &self->childAnimator, true, 0);156}157PopOut_SetupHitboxes();158159switch (self->orientation + 4 * self->direction) {160case 0:161case 4:162self->appearVelocity.x = 0;163self->appearVelocity.y = -0x10000;164break;165166case 1:167case 5:168self->appearVelocity.y = 0;169self->appearVelocity.x = 0x10000;170break;171172case 2:173case 6:174self->appearVelocity.x = 0;175self->appearVelocity.y = 0x10000;176break;177178default:179case 3:180case 7:181self->appearVelocity.y = 0;182self->appearVelocity.x = -0x10000;183break;184}185}186}187188void PopOut_StageLoad(void)189{190PopOut->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/PopOut.bin", SCOPE_STAGE);191192if (RSDK.FindObject("Button"))193PopOut->hasButton = true;194}195196void PopOut_SetupHitboxes(void)197{198RSDK_THIS(PopOut);199self->hitboxRange.left = 0;200self->hitboxRange.top = 0;201self->hitboxRange.right = 0;202self->hitboxRange.bottom = 0;203204self->hitboxSolid.left = 0;205self->hitboxSolid.top = 0;206self->hitboxSolid.right = 0;207self->hitboxSolid.bottom = 0;208209switch (self->orientation + 4 * self->direction) {210case 0:211self->hitboxRange.right = 80;212self->hitboxRange.top = -64;213self->hitboxRange.bottom = 32;214215self->hitboxSolid.left = -32;216self->hitboxSolid.top = -32;217break;218219case 1:220self->hitboxRange.right = 80;221self->hitboxRange.bottom = 64;222self->hitboxRange.left = -32;223224self->hitboxSolid.top = -32;225self->hitboxSolid.right = 32;226break;227228case 2:229self->hitboxRange.left = -80;230self->hitboxRange.top = -32;231self->hitboxRange.bottom = 64;232233self->hitboxSolid.right = 32;234self->hitboxSolid.bottom = 32;235break;236237case 3:238self->hitboxRange.left = -64;239self->hitboxRange.top = -80;240self->hitboxRange.right = 32;241242self->hitboxSolid.left = -32;243self->hitboxSolid.bottom = 32;244break;245246case 4:247self->hitboxRange.left = -80;248self->hitboxRange.top = -63;249self->hitboxRange.bottom = 32;250251self->hitboxSolid.top = -32;252self->hitboxSolid.right = 32;253break;254255case 5:256self->hitboxRange.top = -80;257self->hitboxRange.right = 64;258self->hitboxRange.left = -32;259260self->hitboxSolid.right = 32;261self->hitboxSolid.bottom = 32;262break;263264case 6:265self->hitboxRange.right = 80;266self->hitboxRange.bottom = 64;267self->hitboxRange.top = -32;268269self->hitboxSolid.left = -32;270self->hitboxSolid.bottom = 32;271break;272273default:274case 7:275self->hitboxRange.right = 80;276self->hitboxRange.bottom = 32;277self->hitboxRange.left = -64;278279self->hitboxSolid.left = -32;280self->hitboxSolid.top = -32;281break;282}283}284285#if GAME_INCLUDE_EDITOR286void PopOut_EditorDraw(void)287{288RSDK_THIS(PopOut);289290PopOut->hasButton = false;291if (RSDK.FindObject("Button"))292PopOut->hasButton = true;293294RSDK.SetSpriteAnimation(PopOut->aniFrames, 0, &self->mountAnimator, true, 0);295296EntitySpring *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, Spring);297if (child->classID != Spring->classID && child->classID != Spikes->classID)298child = NULL;299300if (child && child->classID == Spring->classID) {301self->childType = (child->type & 1) ? POPOUT_CHILD_SPRING_RED : POPOUT_CHILD_SPRING_YELLOW;302RSDK.SetSpriteAnimation(PopOut->aniFrames, 1, &self->childAnimator, true, self->childType);303}304else {305self->childType = POPOUT_CHILD_SPIKES;306RSDK.SetSpriteAnimation(PopOut->aniFrames, 2, &self->childAnimator, true, 0);307}308309self->appearTimer = 0;310self->appearVelocity.x = 0;311self->appearVelocity.y = 0;312313int32 storeX = self->position.x;314int32 storeY = self->position.y;315316PopOut_Draw();317318if (showGizmos()) {319PopOut_SetupHitboxes();320321switch (self->orientation + 4 * self->direction) {322case 0:323case 4:324self->appearVelocity.x = 0;325self->appearVelocity.y = -0x10000;326break;327328case 1:329case 5:330self->appearVelocity.y = 0;331self->appearVelocity.x = 0x10000;332break;333334case 2:335case 6:336self->appearVelocity.x = 0;337self->appearVelocity.y = 0x10000;338break;339340default:341case 3:342case 7:343self->appearVelocity.y = 0;344self->appearVelocity.x = -0x10000;345break;346}347348DrawHelpers_DrawHitboxOutline(self->position.x, self->position.y, &self->hitboxRange, FLIP_NONE, 0xFF0000);349350self->appearTimer = 8;351self->position.x = -16 * self->appearVelocity.x + self->position.x + 2 * self->appearTimer * self->appearVelocity.x;352self->position.y = -16 * self->appearVelocity.y + self->position.y + 2 * self->appearTimer * self->appearVelocity.y;353self->inkEffect = INK_BLEND;354355PopOut_Draw();356357self->inkEffect = INK_NONE;358self->position.x = storeX;359self->position.y = storeY;360361if (self->manualTrigger && PopOut->hasButton) {362EntityButton *taggedButton = NULL;363foreach_all(Button, button)364{365if (button->tag == self->tag) {366taggedButton = button;367foreach_break;368}369}370371if (taggedButton) {372RSDK_DRAWING_OVERLAY(true);373if (taggedButton) {374DrawHelpers_DrawArrow(taggedButton->position.x, taggedButton->position.y, self->position.x, self->position.y, 0xFFFF00, INK_NONE,3750xFF);376}377RSDK_DRAWING_OVERLAY(false);378}379}380}381}382383void PopOut_EditorLoad(void) { PopOut->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/PopOut.bin", SCOPE_STAGE); }384#endif385386void PopOut_Serialize(void)387{388RSDK_EDITABLE_VAR(PopOut, VAR_UINT8, direction);389RSDK_EDITABLE_VAR(PopOut, VAR_UINT8, orientation);390RSDK_EDITABLE_VAR(PopOut, VAR_UINT8, tag);391RSDK_EDITABLE_VAR(PopOut, VAR_BOOL, manualTrigger);392RSDK_EDITABLE_VAR(PopOut, VAR_ENUM, delay);393}394395396