Path: blob/master/SonicMania/Objects/PGZ/PSZDoor.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PSZDoor Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPSZDoor *PSZDoor;1011void PSZDoor_Update(void)12{13RSDK_THIS(PSZDoor);1415int32 offsetX = 0;16int32 offsetY = 0;1718int32 speed = 0;19switch (self->open ^ self->orientation) {20case PSZDOOR_ORIENATION_D:21offsetY = -0x10000;22speed = -self->speed;23break;2425case PSZDOOR_ORIENATION_U:26speed = self->speed;27offsetY = 0x10000;28break;2930case PSZDOOR_ORIENATION_L:31speed = self->speed;32offsetX = -0x10000;33break;3435case PSZDOOR_ORIENATION_R:36offsetX = 0x10000;37speed = -self->speed;38break;3940default: break;41}4243int32 startX = self->doorPos.x;44int32 startY = self->doorPos.y;4546if (self->shouldMove) {47if (PSZDoor_GetRemainingDistance() > 0) {48self->doorPos.x += self->speed * (offsetX >> 3);49self->doorPos.y += self->speed * (offsetY >> 3);50self->rotation += speed;51}5253if (PSZDoor_GetRemainingDistance() < 0) {54self->doorPos.x = self->targetPos.x;55self->doorPos.y = self->targetPos.y;56}5758if (self->doorPos.x == self->targetPos.x && self->doorPos.y == self->targetPos.y) {59self->shouldMove = false;60self->open ^= 1;61}62}6364int32 posX = self->doorPos.x - startX;65int32 posY = self->doorPos.y - startY;6667bool32 autoOpen = false;68foreach_active(Player, player)69{70// this was a weird one where apparently it used doorPos directly which is very much undefined behavior lol71// so much so that it breaks as of v5U :]72Vector2 storePos = self->position;73self->position = self->doorPos;74if (Player_CheckCollisionBox(player, self, &PSZDoor->hitboxes[self->doorAnimator.frameID]) == C_TOP) {75if (self->orientation >= PSZDOOR_ORIENATION_L)76player->position.x += posX;77else78player->position.y += posY;79}80self->position = storePos;8182switch (self->automatic) {83default:84case PSZDOOR_AUTO_NONE: break;8586case PSZDOOR_AUTO_LEFT:87if (self->orientation >= PSZDOOR_ORIENATION_L) {88if (player->position.y < self->position.y && abs(player->position.x - self->position.x) < 0x200000)89autoOpen = true;90}91else {92if (player->position.x < self->position.x && abs(player->position.y - self->position.y) < 0x200000)93autoOpen = true;94}95break;9697case PSZDOOR_AUTO_RIGHT:98if (self->orientation >= PSZDOOR_ORIENATION_L) {99if (player->position.y > self->position.y && abs(player->position.x - self->position.x) < 0x200000)100autoOpen = true;101}102else {103if (player->position.x > self->position.x && abs(player->position.y - self->position.y) < 0x200000)104autoOpen = true;105}106break;107}108}109110EntityDoorTrigger *trigger = self->trigger;111if (trigger && ((trigger->classID == DoorTrigger->classID && trigger->bulbAnimator.frameID == 1) || autoOpen)) {112if (self->onScreen)113RSDK.PlaySfx(PSZDoor->sfxOpen, false, 255);114115self->startPos = self->doorPos;116self->trigger = 0;117self->shouldMove = true;118self->targetPos.x = self->doorPos.x + 112 * offsetX;119self->targetPos.y = self->doorPos.y + 112 * offsetY;120}121}122123void PSZDoor_LateUpdate(void) {}124125void PSZDoor_StaticUpdate(void) {}126127void PSZDoor_Draw(void)128{129RSDK_THIS(PSZDoor);130131Vector2 drawPos;132RSDK.DrawSprite(&self->doorAnimator, &self->doorPos, false);133134self->doorAnimator.frameID = 2;135drawPos.x = self->position.x + self->offset.x;136drawPos.y = self->position.y + self->offset.y;137RSDK.DrawSprite(&self->cogAnimator, &drawPos, false);138RSDK.DrawSprite(&self->doorAnimator, &drawPos, false);139140if (self->orientation < PSZDOOR_ORIENATION_L)141drawPos.x -= 2 * self->offset.x;142else143drawPos.y -= 2 * self->offset.y;144145int32 rotation = self->rotation;146self->rotation = 0x100 - rotation;147RSDK.DrawSprite(&self->cogAnimator, &drawPos, false);148RSDK.DrawSprite(&self->doorAnimator, &drawPos, false);149150self->rotation = rotation;151self->doorAnimator.frameID = self->orientation >= PSZDOOR_ORIENATION_L;152}153154void PSZDoor_Create(void *data)155{156RSDK_THIS(PSZDoor);157158if (!self->speed)159self->speed = 8;160161if (!SceneInfo->inEditor) {162self->active = ACTIVE_BOUNDS;163self->visible = true;164self->drawGroup = Zone->objectDrawGroup[0];165self->updateRange.y = 0x800000;166self->updateRange.x = 0x800000;167RSDK.SetSpriteAnimation(PSZDoor->aniFrames, 0, &self->doorAnimator, true, 0);168RSDK.SetSpriteAnimation(PSZDoor->aniFrames, 1, &self->cogAnimator, true, 0);169170self->doorPos = self->position;171self->drawFX = FX_ROTATE;172self->direction = self->orientation & 1;173if (self->orientation < PSZDOOR_ORIENATION_L)174self->direction = 2 * (self->orientation & 1);175else176self->doorAnimator.frameID = 1;177178switch (self->orientation) {179case PSZDOOR_ORIENATION_D:180self->offset.y = -0x380000;181self->offset.x = -0x130000;182183if (self->open)184self->doorPos.y -= 0x700000;185break;186187case PSZDOOR_ORIENATION_U:188self->offset.y = 0x380000;189self->offset.x = -0x130000;190191if (self->open)192self->doorPos.y += 0x700000;193break;194195case PSZDOOR_ORIENATION_L:196self->offset.x = -0x380000;197self->offset.y = -0x130000;198199if (self->open)200self->doorPos.x -= 0x700000;201break;202203case PSZDOOR_ORIENATION_R:204self->offset.x = 0x380000;205self->offset.y = -0x130000;206207if (self->open)208self->doorPos.x += 0x700000;209break;210211default: break;212}213214foreach_all(DoorTrigger, trigger)215{216if (trigger->id == self->id) {217self->updateRange.x += abs(self->position.x - trigger->position.x);218self->updateRange.y += abs(self->position.y - trigger->position.y);219self->trigger = trigger;220}221}222}223}224225void PSZDoor_StageLoad(void)226{227if (RSDK.CheckSceneFolder("PSZ1"))228PSZDoor->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/PSZDoor.bin", SCOPE_STAGE);229230PSZDoor->hitboxes[0].top = -56;231PSZDoor->hitboxes[0].left = -12;232PSZDoor->hitboxes[0].bottom = 56;233PSZDoor->hitboxes[0].right = 12;234235PSZDoor->hitboxes[1].top = -12;236PSZDoor->hitboxes[1].left = -56;237PSZDoor->hitboxes[1].bottom = 12;238PSZDoor->hitboxes[1].right = 56;239240PSZDoor->sfxOpen = RSDK.GetSfx("Stage/Open.wav");241}242243int32 PSZDoor_GetRemainingDistance(void)244{245RSDK_THIS(PSZDoor);246247if (self->shouldMove) {248switch (self->open ^ self->orientation) {249case PSZDOOR_ORIENATION_D: return self->doorPos.y - self->targetPos.y; break;250case PSZDOOR_ORIENATION_U: return self->targetPos.y - self->doorPos.y; break;251case PSZDOOR_ORIENATION_L: return self->doorPos.x - self->targetPos.x; break;252case PSZDOOR_ORIENATION_R: return self->targetPos.x - self->doorPos.x; break;253254default: break;255}256}257258return 0;259}260261#if GAME_INCLUDE_EDITOR262void PSZDoor_EditorDraw(void)263{264RSDK_THIS(PSZDoor);265266self->updateRange.y = 0x800000;267self->updateRange.x = 0x800000;268RSDK.SetSpriteAnimation(PSZDoor->aniFrames, 0, &self->doorAnimator, true, 0);269RSDK.SetSpriteAnimation(PSZDoor->aniFrames, 1, &self->cogAnimator, true, 0);270271self->doorPos = self->position;272self->drawFX = FX_ROTATE;273self->direction = self->orientation & 1;274275if (self->orientation < PSZDOOR_ORIENATION_L)276self->direction = 2 * (self->orientation & 1);277else278self->doorAnimator.frameID = 1;279280switch (self->orientation) {281case PSZDOOR_ORIENATION_D:282self->offset.y = -0x380000;283self->offset.x = -0x130000;284if (self->open)285self->doorPos.y -= 0x700000;286break;287288case PSZDOOR_ORIENATION_U:289self->offset.y = 0x380000;290self->offset.x = -0x130000;291if (self->open)292self->doorPos.y += 0x700000;293break;294295case PSZDOOR_ORIENATION_L:296self->offset.x = -0x380000;297self->offset.y = -0x130000;298if (self->open)299self->doorPos.x -= 0x700000;300break;301302case PSZDOOR_ORIENATION_R:303self->offset.x = 0x380000;304self->offset.y = -0x130000;305if (self->open)306self->doorPos.x += 0x700000;307break;308309default: break;310}311312PSZDoor_Draw();313314if (showGizmos()) {315self->doorPos = self->position;316self->inkEffect = INK_BLEND;317self->open ^= 1;318319switch (self->orientation) {320case PSZDOOR_ORIENATION_D:321self->offset.y = -0x380000;322self->offset.x = -0x130000;323if (self->open)324self->doorPos.y -= 0x700000;325break;326327case PSZDOOR_ORIENATION_U:328self->offset.y = 0x380000;329self->offset.x = -0x130000;330if (self->open)331self->doorPos.y += 0x700000;332break;333334case PSZDOOR_ORIENATION_L:335self->offset.x = -0x380000;336self->offset.y = -0x130000;337if (self->open)338self->doorPos.x -= 0x700000;339break;340341case PSZDOOR_ORIENATION_R:342self->offset.x = 0x380000;343self->offset.y = -0x130000;344if (self->open)345self->doorPos.x += 0x700000;346break;347348default: break;349}350351PSZDoor_Draw();352353self->open ^= 1;354self->inkEffect = INK_NONE;355356self->trigger = NULL;357foreach_all(DoorTrigger, trigger)358{359if (trigger->id == self->id)360self->trigger = trigger;361}362363if (self->trigger) {364DrawHelpers_DrawArrow(self->trigger->position.x, self->trigger->position.y, self->position.x, self->position.y, 0xFFFF00, INK_NONE, 0xFF);365}366}367}368369void PSZDoor_EditorLoad(void)370{371PSZDoor->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/PSZDoor.bin", SCOPE_STAGE);372373RSDK_ACTIVE_VAR(PSZDoor, orientation);374RSDK_ENUM_VAR("Down", PSZDOOR_ORIENATION_D);375RSDK_ENUM_VAR("Up", PSZDOOR_ORIENATION_U);376RSDK_ENUM_VAR("Left", PSZDOOR_ORIENATION_L);377RSDK_ENUM_VAR("Right", PSZDOOR_ORIENATION_R);378379RSDK_ACTIVE_VAR(PSZDoor, automatic);380RSDK_ENUM_VAR("Not Automatic", PSZDOOR_AUTO_NONE);381RSDK_ENUM_VAR("Auto-Open when player is to the left", PSZDOOR_AUTO_LEFT);382RSDK_ENUM_VAR("Auto-Open when player is to the right", PSZDOOR_AUTO_RIGHT);383}384#endif385386void PSZDoor_Serialize(void)387{388RSDK_EDITABLE_VAR(PSZDoor, VAR_UINT8, orientation);389RSDK_EDITABLE_VAR(PSZDoor, VAR_BOOL, open);390RSDK_EDITABLE_VAR(PSZDoor, VAR_ENUM, speed);391RSDK_EDITABLE_VAR(PSZDoor, VAR_UINT8, id);392RSDK_EDITABLE_VAR(PSZDoor, VAR_ENUM, automatic);393}394395396