Path: blob/master/SonicMania/Objects/MSZ/CollapsingSand.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: CollapsingSand Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectCollapsingSand *CollapsingSand;1011void CollapsingSand_Update(void)12{13RSDK_THIS(CollapsingSand);1415self->visible = DebugMode->debugActive;1617StateMachine_Run(self->state);18}1920void CollapsingSand_LateUpdate(void) {}2122void CollapsingSand_StaticUpdate(void) {}2324void CollapsingSand_Draw(void)25{26RSDK_THIS(CollapsingSand);27Vector2 drawPos;2829// Draw Outline30drawPos.x = self->position.x - (self->size.x >> 1);31drawPos.y = self->position.y - (self->size.y >> 1);32RSDK.DrawLine(drawPos.x - 0x10000, drawPos.y - 0x10000, drawPos.x + self->size.x, drawPos.y - 0x10000, 0xE0E0E0, 0, INK_NONE, false);33RSDK.DrawLine(drawPos.x - 0x10000, self->size.y + drawPos.y, drawPos.x + self->size.x, self->size.y + drawPos.y, 0xE0E0E0, 0, INK_NONE, false);34RSDK.DrawLine(drawPos.x - 0x10000, drawPos.y - 0x10000, drawPos.x - 0x10000, drawPos.y + self->size.y, 0xE0E0E0, 0, INK_NONE, false);35RSDK.DrawLine(drawPos.x + self->size.x, drawPos.y - 0x10000, drawPos.x + self->size.x, drawPos.y + self->size.y, 0xE0E0E0, 0, INK_NONE, false);3637// Draw Corners38self->direction = FLIP_NONE;39RSDK.DrawSprite(&CollapsingSand->animator, &drawPos, false);4041drawPos.x += self->size.x;42self->direction = FLIP_X;43RSDK.DrawSprite(&CollapsingSand->animator, &drawPos, false);4445drawPos.y += self->size.y;46self->direction = FLIP_XY;47RSDK.DrawSprite(&CollapsingSand->animator, &drawPos, false);4849drawPos.x -= self->size.x;50self->direction = FLIP_Y;51RSDK.DrawSprite(&CollapsingSand->animator, &drawPos, false);52}5354void CollapsingSand_Create(void *data)55{56RSDK_THIS(CollapsingSand);5758self->visible = true;59self->drawGroup = Zone->objectDrawGroup[0];60self->drawFX |= FX_FLIP;61self->position.x &= 0xFFF80000;62self->position.y &= 0xFFF80000;6364if (!SceneInfo->inEditor) {65self->active = ACTIVE_BOUNDS;66self->updateRange.x = 0x800000;67self->updateRange.y = 0x800000;68self->hitbox.left = -(self->size.x >> 17);69self->hitbox.top = -48 - (self->size.y >> 17);70self->hitbox.right = self->size.x >> 17;71self->hitbox.bottom = self->size.y >> 17;72self->state = CollapsingSand_State_CheckPlayerCollisions;73}74}7576void CollapsingSand_StageLoad(void)77{78CollapsingSand->aniFrames = RSDK.LoadSpriteAnimation("MSZ/SandCollapse.bin", SCOPE_STAGE);79RSDK.SetSpriteAnimation(CollapsingSand->aniFrames, 0, &CollapsingSand->animator, true, 0);8081CollapsingSand->sfxSandFall = RSDK.GetSfx("MSZ/SandFall.wav");82}8384void CollapsingSand_State_CheckPlayerCollisions(void)85{86RSDK_THIS(CollapsingSand);8788foreach_active(Player, player)89{90if (Player_CheckCollisionTouch(player, self, &self->hitbox) && player->onGround && player->collisionMode) {91self->state = CollapsingSand_State_CollapseDelay;92self->collapseLeft = player->position.x <= self->position.x;93foreach_break;94}95}96}9798void CollapsingSand_State_CollapseDelay(void)99{100RSDK_THIS(CollapsingSand);101102if (self->collapseTimer >= self->delay) {103self->collapseDuration.x = self->size.x >> 20;104self->collapseDuration.y = self->size.y >> 20;105self->collapseTimer = 0;106107if (!self->collapseLeft) {108self->state = CollapsingSand_State_CollapseRight;109self->tilePos.x = ((self->size.x >> 1) + self->position.x - 0x80000) >> 20;110}111else {112self->state = CollapsingSand_State_CollapseLeft;113self->tilePos.x = (self->position.x - (self->size.x >> 1) + 0x80000) >> 20;114}115RSDK.PlaySfx(CollapsingSand->sfxSandFall, false, 255);116117self->tilePos.y = ((self->size.y >> 1) + self->position.y - 0x80000) >> 20;118self->tileEndPos.x = self->tilePos.x;119self->tileEndPos.y = (self->position.y - (self->size.y >> 1) + 0x80000) >> 20;120}121else {122self->collapseTimer++;123}124}125126void CollapsingSand_State_CollapseLeft(void)127{128RSDK_THIS(CollapsingSand);129130if (self->collapseTimer) {131self->collapseTimer = (self->collapseTimer + 1) & 3;132}133else {134if (self->collapseDuration.x > 0 || self->collapseDuration.y > 0) {135int32 tx = self->tilePos.x;136int32 ty = self->tilePos.y;137138for (int32 x = (tx << 20) + 0x80000, y = (ty << 20) + 0x80000; tx >= self->tileEndPos.x && ty >= self->tileEndPos.y; --tx, --ty) {139bool32 spawnSand = false;140141uint16 tile = RSDK.GetTile(Zone->fgLayer[0], tx, ty);142if ((tile & 0x3FF) >= 446 && (tile & 0x3FF) <= 554) {143RSDK.SetTile(Zone->fgLayer[0], tx, ty, -1);144spawnSand = true;145}146147tile = RSDK.GetTile(Zone->fgLayer[1], tx, ty);148if ((tile & 0x3FF) >= 446 && (tile & 0x3FF) <= 554) {149RSDK.SetTile(Zone->fgLayer[1], tx, ty, -1);150spawnSand = true;151}152153if (spawnSand) {154EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);155RSDK.SetSpriteAnimation(CollapsingSand->aniFrames, 0, &debris->animator, true, 0);156debris->drawGroup = Zone->objectDrawGroup[1];157debris->timer = 44;158if (self->collapseDuration.x > 0) {159// Replace ground tile with a flat one160if (ty == self->tilePos.y)161RSDK.SetTile(Zone->fgLayer[0], tx, ty, (168 + (self->collapseDuration.x & 1)) | 0b1111000000000000);162}163}164165x -= 0x100000;166y -= 0x100000;167}168169if (self->collapseDuration.x > 0) {170++self->tilePos.x;171--self->collapseDuration.x;172}173else {174--self->tilePos.y;175--self->collapseDuration.y;176}177self->collapseTimer = (self->collapseTimer + 1) & 3;178}179else {180foreach_all(ItemBox, itembox)181{182if (abs(itembox->position.x - self->position.x) < self->size.x >> 1) {183if (abs(itembox->position.y - self->position.y >= 0) < self->size.y >> 1 && itembox->state == ItemBox_State_Idle)184itembox->state = ItemBox_State_Falling;185}186}187188destroyEntity(self);189}190}191}192193void CollapsingSand_State_CollapseRight(void)194{195RSDK_THIS(CollapsingSand);196197if (self->collapseTimer) {198self->collapseTimer = (self->collapseTimer + 1) & 3;199}200else {201if (self->collapseDuration.x > 0 || self->collapseDuration.y > 0) {202int32 tx = self->tilePos.x;203int32 ty = self->tilePos.y;204205for (int32 x = (tx << 20) + 0x80000, y = (ty << 20) + 0x80000; tx <= self->tileEndPos.x && ty >= self->tileEndPos.y; ++tx, --ty) {206bool32 spawnSand = false;207208uint16 tile = RSDK.GetTile(Zone->fgLayer[0], tx, ty);209if ((tile & 0x3FF) >= 446 && (tile & 0x3FF) <= 554) {210RSDK.SetTile(Zone->fgLayer[0], tx, ty, -1);211spawnSand = true;212}213214tile = RSDK.GetTile(Zone->fgLayer[1], tx, ty);215if ((tile & 0x3FF) >= 446 && (tile & 0x3FF) <= 554) {216RSDK.SetTile(Zone->fgLayer[1], tx, ty, -1);217spawnSand = true;218}219220if (spawnSand) {221EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);222RSDK.SetSpriteAnimation(CollapsingSand->aniFrames, 0, &debris->animator, true, 0);223debris->drawGroup = Zone->objectDrawGroup[1];224debris->timer = 44;225if (self->collapseDuration.x > 0) {226// Replace ground tile with a flat one227if (ty == self->tilePos.y)228RSDK.SetTile(Zone->fgLayer[0], tx, ty, (169 - (self->collapseDuration.x & 1)) | 0b1111000000000000);229}230}231232x += 0x100000;233y -= 0x100000;234}235236if (self->collapseDuration.x > 0) {237--self->tilePos.x;238--self->collapseDuration.x;239}240else {241--self->tilePos.y;242--self->collapseDuration.y;243}244245self->collapseTimer = (self->collapseTimer + 1) & 3;246}247else {248foreach_all(ItemBox, itembox)249{250if (abs(itembox->position.x - self->position.x) < self->size.x >> 1) {251if (abs(itembox->position.y - self->position.y >= 0) < self->size.y >> 1 && itembox->state == ItemBox_State_Idle)252itembox->state = ItemBox_State_Falling;253}254}255destroyEntity(self);256}257}258}259260#if GAME_INCLUDE_EDITOR261void CollapsingSand_EditorDraw(void) { CollapsingSand_Draw(); }262263void CollapsingSand_EditorLoad(void)264{265CollapsingSand->aniFrames = RSDK.LoadSpriteAnimation("MSZ/SandCollapse.bin", SCOPE_STAGE);266RSDK.SetSpriteAnimation(CollapsingSand->aniFrames, 0, &CollapsingSand->animator, true, 0);267}268#endif269270void CollapsingSand_Serialize(void)271{272RSDK_EDITABLE_VAR(CollapsingSand, VAR_VECTOR2, size);273RSDK_EDITABLE_VAR(CollapsingSand, VAR_ENUM, delay);274}275276277