Path: blob/master/SonicMania/Objects/HCZ/PullChain.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PullChain Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPullChain *PullChain;1011void PullChain_Update(void)12{13RSDK_THIS(PullChain);1415if (!self->decorMode) {16if (self->currentlyActive)17self->currentlyActive = false;1819foreach_active(Player, player)20{21int32 playerID = RSDK.GetEntitySlot(player);2223if (self->grabDelay[playerID] > 0)24self->grabDelay[playerID]--;2526if (!player->sidekick) {27if (((1 << playerID) & self->activePlayers)) {28if (self->chainOffset < 0x100000)29self->chainOffset += 0x8000;3031if (self->chainOffset > 0x100000)32self->chainOffset = 0x100000;3334if (self->chainOffset == 0x100000) {35if (!self->down) {36self->currentlyActive = true;37self->activated = true;38self->toggled = !self->toggled;39}4041self->down = true;42}43}4445self->position.y = self->basePos.y + self->chainOffset;46}4748if (!((1 << playerID) & self->activePlayers)) {49if (!(self->releasedPlayers & (1 << playerID))) {50if (!Current || !((1 << playerID) & Current->activePlayers)) {51int32 x = abs(player->position.x - self->position.x) >> 16;52int32 y = abs((player->position.y - 0x180000) - self->position.y) >> 16;5354if (MathHelpers_SquareRoot(x * x + y * y) <= 8 && player->state != Player_State_Static55&& !self->grabDelay[playerID]) {56self->activePlayers |= 1 << playerID;57self->releasedPlayers |= 1 << playerID;5859RSDK.PlaySfx(Player->sfxGrab, false, 0xFF);6061if (!player->sidekick)62RSDK.PlaySfx(PullChain->sfxPullChain, false, 0xFF);6364RSDK.SetSpriteAnimation(player->aniFrames, ANI_HANG, &player->animator, true, 6);65player->nextGroundState = StateMachine_None;66player->nextAirState = StateMachine_None;67player->velocity.x = 0;68player->velocity.y = 0;69player->state = Player_State_Static;7071// Reset the dunky code inputs if a proper player grabs it72if (!player->sidekick) {73for (int32 i = 0; i < 18; ++i) self->cheatCodeInputs[i] = 0;74}75}76}77}78}7980if ((1 << playerID) & self->activePlayers) {81player->position.x = self->position.x;82player->position.y = self->position.y + 0x1C0000;8384// R.I.P dunkey mode, you are very missed :(85#if GAME_VERSION == VER_10086if (!player->sidekick && PullChain_HandleDunkeyCode(player)) {87HandLauncher->dunkeyMode = true;88RSDK.PlaySfx(Ring->sfxRing, false, 0xFF);89}90#endif9192if (player->jumpPress || player->animator.animationID != ANI_HANG || player->velocity.x || player->velocity.y) {93self->activePlayers &= ~(1 << playerID);94if (player->jumpPress) {95if (self->chainOffset < 0x100000 && !player->sidekick)96RSDK.StopSfx(PullChain->sfxPullChain);9798RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, true, 0);99player->velocity.x = 0;100player->velocity.y = -0x20000;101player->state = Player_State_Air;102}103104self->grabDelay[playerID] = 30;105}106107if ((1 << playerID) & self->activePlayers)108continue;109}110111// Make sure we're far enough away before unsetting this112// This controls if players can grab the hook113if (self->releasedPlayers & (1 << playerID)) {114int32 x = abs(player->position.x - self->position.x);115int32 y = abs(player->position.y - 0x180000 - self->position.y);116if (MathHelpers_SquareRoot((x >> 16) * (x >> 16) + (y >> 16) * (y >> 16)) > 4)117self->releasedPlayers &= ~(1 << playerID);118}119}120121if (!self->activePlayers) {122self->down = false;123124if (self->chainOffset > 0)125self->chainOffset -= 0x8000;126127if (self->chainOffset < 0)128self->chainOffset = 0;129}130}131}132133void PullChain_LateUpdate(void) {}134135void PullChain_StaticUpdate(void) {}136137void PullChain_Draw(void)138{139RSDK_THIS(PullChain);140141RSDK.DrawSprite(&self->hookAnimator, NULL, false);142143Vector2 drawPos = self->position;144for (int32 i = 0; i < self->length; ++i) {145RSDK.DrawSprite(&self->chainAnimator, &drawPos, false);146drawPos.y -= 0x80000;147}148149for (int32 i = 0; i < self->chainOffset; i += 0x80000) {150RSDK.DrawSprite(&self->chainAnimator, &drawPos, false);151drawPos.y -= 0x80000;152}153}154155void PullChain_Create(void *data)156{157RSDK_THIS(PullChain);158159self->active = ACTIVE_BOUNDS;160self->drawGroup = self->decorMode ? Zone->objectDrawGroup[0] : Zone->playerDrawGroup[0];161self->basePos = self->position;162self->visible = true;163self->drawFX = FX_FLIP;164self->updateRange.x = 0x800000;165self->updateRange.y = 0x800000;166167self->hitbox.left = -10;168self->hitbox.top = 3;169self->hitbox.right = 10;170self->hitbox.bottom = 12;171172RSDK.SetSpriteAnimation(PullChain->aniFrames, 0, &self->hookAnimator, true, self->decorMode);173RSDK.SetSpriteAnimation(PullChain->aniFrames, 1, &self->chainAnimator, true, self->decorMode);174}175176void PullChain_StageLoad(void)177{178PullChain->aniFrames = RSDK.LoadSpriteAnimation("HCZ/PullChain.bin", SCOPE_STAGE);179180PullChain->sfxPullChain = RSDK.GetSfx("HCZ/PullChain.wav");181}182183#if GAME_VERSION == VER_100184bool32 PullChain_HandleDunkeyCode(EntityPlayer *player)185{186RSDK_THIS(PullChain);187188if (HandLauncher->dunkeyMode)189return false;190191uint8 buttonMasks = PULLCHAIN_INPUT_NONE;192if (player->left)193buttonMasks = 1;194195if (player->right)196buttonMasks |= 2;197198if (player->up)199buttonMasks |= 4;200201if (player->down)202buttonMasks |= 8;203204if (buttonMasks == self->codeButtonMasks)205return false;206207for (int32 i = 1; i < 18; ++i) self->cheatCodeInputs[i - 1] = self->cheatCodeInputs[i];208209self->cheatCodeInputs[17] = PULLCHAIN_INPUT_NONE;210if (player->left)211self->cheatCodeInputs[17] = PULLCHAIN_INPUT_LEFT;212else if (player->right)213self->cheatCodeInputs[17] = PULLCHAIN_INPUT_RIGHT;214else if (player->up)215self->cheatCodeInputs[17] = PULLCHAIN_INPUT_UP;216else if (player->down)217self->cheatCodeInputs[17] = PULLCHAIN_INPUT_DOWN;218219bool32 activatedCheatCode = true;220for (int32 i = 0; i < 18; ++i) activatedCheatCode &= (self->cheatCodeInputs[i] == PullChain->dunkeyCode[i]);221self->codeButtonMasks = buttonMasks;222223return activatedCheatCode;224}225#endif226227#if GAME_INCLUDE_EDITOR228void PullChain_EditorDraw(void)229{230RSDK_THIS(PullChain);231232self->drawGroup = self->decorMode ? Zone->objectDrawGroup[0] : Zone->playerDrawGroup[0];233RSDK.SetSpriteAnimation(PullChain->aniFrames, 0, &self->hookAnimator, true, self->decorMode);234RSDK.SetSpriteAnimation(PullChain->aniFrames, 1, &self->chainAnimator, true, self->decorMode);235236PullChain_Draw();237}238239void PullChain_EditorLoad(void)240{241PullChain->aniFrames = RSDK.LoadSpriteAnimation("HCZ/PullChain.bin", SCOPE_STAGE);242243RSDK_ACTIVE_VAR(PullChain, type);244RSDK_ENUM_VAR("Normal", PULLCHAIN_NORMAL);245}246#endif247248void PullChain_Serialize(void)249{250RSDK_EDITABLE_VAR(PullChain, VAR_ENUM, type);251RSDK_EDITABLE_VAR(PullChain, VAR_BOOL, walkOnto);252RSDK_EDITABLE_VAR(PullChain, VAR_UINT8, tag);253RSDK_EDITABLE_VAR(PullChain, VAR_UINT32, length);254RSDK_EDITABLE_VAR(PullChain, VAR_BOOL, decorMode);255}256257258