Path: blob/master/SonicMania/Objects/CPZ/SpeedBooster.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: SpeedBooster Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectSpeedBooster *SpeedBooster;1011void SpeedBooster_Update(void)12{13RSDK_THIS(SpeedBooster);1415StateMachine_Run(self->state);1617for (int32 i = 0; i < PLAYER_COUNT; i++) {18if (self->playerTimer[i])19self->playerTimer[i]--;20}21}2223void SpeedBooster_LateUpdate(void) {}2425void SpeedBooster_StaticUpdate(void) {}2627void SpeedBooster_Draw(void)28{29RSDK_THIS(SpeedBooster);3031RSDK.DrawSprite(&self->animator, &self->drawPos, false);32}3334void SpeedBooster_Create(void *data)35{36RSDK_THIS(SpeedBooster);3738self->visible = true;39if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2"))40self->drawGroup = Zone->playerDrawGroup[0];41else42self->drawGroup = Zone->objectDrawGroup[1];4344self->drawPos = self->position;45self->updateRange.x = 0x400000;46self->updateRange.y = 0x400000;4748if (data) {49self->active = ACTIVE_NORMAL;50self->drawFX = INK_ALPHA;51RSDK.SetSpriteAnimation(SpeedBooster->aniFrames, 1, &self->animator, true, 0);52self->state = SpeedBooster_State_SSZBullet;53}54else {55self->active = ACTIVE_BOUNDS;56if (!self->speed)57self->speed = RSDK.CheckSceneFolder("CPZ") ? 10 : 16;58self->groundVel = self->speed << 16;5960RSDK.SetSpriteAnimation(SpeedBooster->aniFrames, 0, &self->animator, true, 0);61self->state = SpeedBooster_State_SpeedBooster;62}63}6465void SpeedBooster_StageLoad(void)66{67if (RSDK.CheckSceneFolder("CPZ")) {68SpeedBooster->aniFrames = RSDK.LoadSpriteAnimation("CPZ/SpeedBooster.bin", SCOPE_STAGE);6970SpeedBooster->hitbox.left = -16;71SpeedBooster->hitbox.top = -16;72SpeedBooster->hitbox.right = 16;73SpeedBooster->hitbox.bottom = 16;7475SpeedBooster->sfxSpeedBooster = RSDK.GetSfx("Global/Spring.wav");7677SpeedBooster->defaultState = SpeedBooster_State_SpeedBooster;78}79else if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2")) {80if (RSDK.CheckSceneFolder("SSZ1"))81SpeedBooster->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/SpeedBooster.bin", SCOPE_STAGE);82else83SpeedBooster->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/SpeedBooster.bin", SCOPE_STAGE);8485SpeedBooster->hitbox.left = -32;86SpeedBooster->hitbox.top = -16;87SpeedBooster->hitbox.right = 32;88SpeedBooster->hitbox.bottom = 0;8990SpeedBooster->sfxSpeedBooster = RSDK.GetSfx("Stage/SpeedBooster.wav");9192SpeedBooster->defaultState = SpeedBooster_State_SSZFire;93}9495DEBUGMODE_ADD_OBJ(SpeedBooster);96}9798void SpeedBooster_DebugSpawn(void)99{100RSDK_THIS(DebugMode);101102CREATE_ENTITY(SpeedBooster, NULL, self->position.x, self->position.y);103}104105void SpeedBooster_DebugDraw(void)106{107RSDK.SetSpriteAnimation(SpeedBooster->aniFrames, 0, &DebugMode->animator, true, 0);108RSDK.DrawSprite(&DebugMode->animator, NULL, false);109}110111void SpeedBooster_State_SpeedBooster(void)112{113RSDK_THIS(SpeedBooster);114115RSDK.ProcessAnimation(&self->animator);116117SpeedBooster_HandleInteractions();118}119120void SpeedBooster_HandleInteractions(void)121{122RSDK_THIS(SpeedBooster);123124bool32 isSSZ = RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2");125126foreach_active(Player, player)127{128int32 playerID = RSDK.GetEntitySlot(player);129if (self->playerTimer[playerID] || player->animator.animationID == ANI_HURT130|| !Player_CheckCollisionTouch(player, self, &SpeedBooster->hitbox) || !player->onGround) {131self->playerPos[playerID] = player->position.x;132}133else {134self->velocity.x = 2 * (player->position.x < self->position.x) - 1;135self->state = SpeedBooster->defaultState;136self->animator.frameID = 0;137RSDK.PlaySfx(SpeedBooster->sfxSpeedBooster, false, 255);138self->active = ACTIVE_NORMAL;139140bool32 flipFlag = isSSZ ? self->playerPos[playerID] <= self->position.x : !self->direction;141if (flipFlag) {142if (player->groundVel < self->groundVel)143player->groundVel = self->groundVel;144player->direction = FLIP_NONE;145}146else {147if (player->groundVel > -self->groundVel)148player->groundVel = -self->groundVel;149player->direction = FLIP_X;150}151152self->playerTimer[playerID] = 30;153player->controlLock = 16;154player->pushing = false;155player->tileCollisions = TILECOLLISION_DOWN;156if (player->state != Player_State_Roll)157player->state = Player_State_Ground;158self->playerPos[playerID] = player->position.x;159}160}161}162163void SpeedBooster_State_SSZFire(void)164{165RSDK_THIS(SpeedBooster);166167self->velocity.x = 0x55550 * self->velocity.x;168self->drawPos.x = self->position.x;169self->drawPos.y = self->position.y;170171EntitySpeedBooster *child = CREATE_ENTITY(SpeedBooster, INT_TO_VOID(true), self->position.x, self->position.y);172int32 newVel = 0x10000;173child->velocity.y = -0x70000;174if (self->velocity.x > 0)175newVel = -0x10000;176child->velocity.x = newVel;177self->active = ACTIVE_NORMAL;178self->timer = 6;179self->drawPos.x -= self->velocity.x;180if (!--self->timer) {181self->timer = 6;182self->state = SpeedBooster_State_SSZRetract;183}184SpeedBooster_HandleInteractions();185186self->state = SpeedBooster_State_SSZRecoil;187SpeedBooster_HandleInteractions(); // why is this called a second time?188}189190void SpeedBooster_State_SSZRecoil(void)191{192RSDK_THIS(SpeedBooster);193194self->drawPos.x -= self->velocity.x;195if (!--self->timer) {196self->timer = 6;197self->state = SpeedBooster_State_SSZRetract;198}199200SpeedBooster_HandleInteractions();201}202203void SpeedBooster_State_SSZRetract(void)204{205RSDK_THIS(SpeedBooster);206207self->drawPos.x += self->velocity.x;208if (!--self->timer) {209self->active = ACTIVE_BOUNDS;210self->state = SpeedBooster_State_SpeedBooster;211}212213SpeedBooster_HandleInteractions();214}215216void SpeedBooster_State_SSZBullet(void)217{218RSDK_THIS(SpeedBooster);219220self->position.x += self->velocity.x;221self->position.y += self->velocity.y;222self->rotation += 6;223self->velocity.y += 0x3800;224225self->drawPos = self->position;226227if (!RSDK.CheckOnScreen(self, &self->updateRange))228destroyEntity(self);229}230231#if GAME_INCLUDE_EDITOR232void SpeedBooster_EditorDraw(void)233{234RSDK_THIS(SpeedBooster);235236self->visible = true;237self->drawPos = self->position;238self->updateRange.x = 0x400000;239self->updateRange.y = 0x400000;240241self->active = ACTIVE_BOUNDS;242if (!self->speed)243self->speed = RSDK.CheckSceneFolder("CPZ") ? 10 : 16;244self->groundVel = self->speed << 16;245246RSDK.SetSpriteAnimation(SpeedBooster->aniFrames, 0, &self->animator, true, 0);247248SpeedBooster_Draw();249}250251void SpeedBooster_EditorLoad(void)252{253if (RSDK.CheckSceneFolder("CPZ")) {254SpeedBooster->aniFrames = RSDK.LoadSpriteAnimation("CPZ/SpeedBooster.bin", SCOPE_STAGE);255}256else if (RSDK.CheckSceneFolder("SSZ1") || RSDK.CheckSceneFolder("SSZ2")) {257if (RSDK.CheckSceneFolder("SSZ1"))258SpeedBooster->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/SpeedBooster.bin", SCOPE_STAGE);259else260SpeedBooster->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/SpeedBooster.bin", SCOPE_STAGE);261}262263RSDK_ACTIVE_VAR(SpeedBooster, direction);264RSDK_ENUM_VAR("No Flip", FLIP_NONE);265RSDK_ENUM_VAR("Flipped", FLIP_X);266}267#endif268269void SpeedBooster_Serialize(void)270{271RSDK_EDITABLE_VAR(SpeedBooster, VAR_UINT8, direction);272RSDK_EDITABLE_VAR(SpeedBooster, VAR_UINT8, speed);273}274275