Path: blob/master/SonicMania/Objects/CPZ/Springboard.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Springboard Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectSpringboard *Springboard;1011void Springboard_Update(void)12{13RSDK_THIS(Springboard);1415RSDK.ProcessAnimation(&self->animator);1617// bounceDelay is unused, but if it was used, it'd prolly be "if (!--self->bounceDelay) {" around this foreach loop.18// source: it was exactly like that in S2 '1319foreach_active(Player, playerPtr)20{21if (playerPtr->velocity.y >= 0 && ((1 << RSDK.GetEntitySlot(playerPtr)) & self->activePlayers)) {22int32 pos = CLAMP((playerPtr->position.x - self->position.x + 0x1C0000) >> 17, 0, 28);2324if ((self->direction & FLIP_X))25pos = 28 - pos;2627if (pos >= 8) {28if (self->animator.frameID == 3)29RSDK.SetSpriteAnimation(Springboard->aniFrames, 0, &self->animator, true, 0);3031if (self->animator.frameID == 2) {32int32 anim = playerPtr->animator.animationID;33if (anim == ANI_WALK || (anim > ANI_AIR_WALK && anim <= ANI_DASH))34playerPtr->animationReserve = playerPtr->animator.animationID;35else36playerPtr->animationReserve = ANI_WALK;3738playerPtr->state = Player_State_Air;39playerPtr->onGround = false;40playerPtr->tileCollisions = TILECOLLISION_DOWN;41RSDK.SetSpriteAnimation(playerPtr->aniFrames, ANI_SPRING_CS, &playerPtr->animator, true, 1);42playerPtr->groundVel = playerPtr->velocity.x;43playerPtr->velocity.y = Springboard->springPower[MIN(2 * pos - 16, 39)] - playerPtr->gravityStrength - self->force;44playerPtr->applyJumpCap = false;4546RSDK.PlaySfx(Springboard->sfxSpring, false, 0xFF);47}48}49}50}5152foreach_active(Player, player)53{54int32 playerID = RSDK.GetEntitySlot(player);5556int32 playerGndVel = player->groundVel;57int32 playerVelX = player->velocity.x;58int32 springPos = CLAMP((player->position.x - self->position.x + 0x1C0000) >> 17, 0, 27);59bool32 bounced = false;6061if (!self->direction) {62int32 hitboxTop = 0;6364if (self->animator.frameID <= 2)65hitboxTop = Springboard->heightsFlat[springPos];66else if (self->animator.frameID == 3)67hitboxTop = Springboard->heightsReady[springPos];6869Hitbox hitbox;70hitbox.left = -28;71hitbox.top = -hitboxTop;72hitbox.right = 28;73hitbox.bottom = 8;7475uint8 collision = 0;76if (!((1 << playerID) & self->activePlayers))77bounced = collision = Player_CheckCollisionBox(player, self, &hitbox);78else79bounced = collision = Player_CheckCollisionPlatform(player, self, &hitbox);8081bounced = collision == C_TOP;82switch (collision) {83case C_LEFT:84player->groundVel = playerGndVel;85player->velocity.x = playerVelX;86// [Fallthrough]87case C_NONE:88case C_RIGHT:89case C_BOTTOM:90if (player->velocity.y >= 0 && ((1 << playerID) & self->activePlayers)) {91Hitbox *playerHitbox = Player_GetHitbox(player);92player->position.y = self->position.y - (playerHitbox->bottom << 16) - (hitboxTop << 16);9394if (!bounced)95bounced = player->position.x > self->position.x;96}97break;9899case C_TOP:100#if MANIA_USE_PLUS101if (player->state == Player_State_MightyHammerDrop)102player->state = Player_State_Air;103#endif104break;105106default: break;107}108109player->flailing = false;110}111else if (self->direction == FLIP_X) {112int32 pos = abs(springPos - 27);113int32 hitboxTop = 0;114115if (self->animator.frameID <= 2)116hitboxTop = Springboard->heightsFlat[pos];117else if (self->animator.frameID == 3)118hitboxTop = Springboard->heightsReady[pos];119120Hitbox hitbox;121hitbox.left = -28;122hitbox.top = -hitboxTop;123hitbox.right = 28;124hitbox.bottom = 8;125126uint8 collision = 0;127if (!((1 << playerID) & self->activePlayers))128collision = Player_CheckCollisionBox(player, self, &hitbox);129else130collision = Player_CheckCollisionPlatform(player, self, &hitbox);131132bounced = collision == C_TOP;133switch (collision) {134case C_NONE:135case C_LEFT:136case C_BOTTOM: break;137138case C_TOP:139#if MANIA_USE_PLUS140if (player->state == Player_State_MightyHammerDrop) {141player->state = Player_State_Air;142}143#endif144break;145146case C_RIGHT:147player->groundVel = playerGndVel;148player->velocity.x = playerVelX;149break;150151default: break;152}153154if (player->velocity.y >= 0 && ((1 << playerID) & self->activePlayers)) {155Hitbox *playerHitbox = Player_GetHitbox(player);156player->position.y = self->position.y - (playerHitbox->bottom << 16) - (hitboxTop << 16);157if (!bounced)158bounced = player->position.x < self->position.x;159}160161player->flailing = false;162}163164if (bounced) {165self->activePlayers |= (1 << playerID);166if (springPos >= 8 && !self->bounceDelay)167self->bounceDelay = 6;168}169else {170self->activePlayers &= ~(1 << playerID);171}172}173}174175void Springboard_LateUpdate(void) {}176177void Springboard_StaticUpdate(void) {}178179void Springboard_Draw(void)180{181RSDK_THIS(Springboard);182183RSDK.DrawSprite(&self->animator, NULL, false);184}185186void Springboard_Create(void *data)187{188RSDK_THIS(Springboard);189190self->visible = true;191self->drawGroup = Zone->objectDrawGroup[0];192self->drawFX |= FX_FLIP;193self->active = ACTIVE_BOUNDS;194self->updateRange.x = 0x400000;195self->updateRange.y = 0x400000;196197if (!SceneInfo->inEditor) {198self->force = (self->force + 8) << 15;199RSDK.SetSpriteAnimation(Springboard->aniFrames, 0, &self->animator, true, 3);200}201}202203void Springboard_StageLoad(void)204{205Springboard->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Springboard.bin", SCOPE_STAGE);206207Springboard->sfxSpring = RSDK.GetSfx("Global/Spring.wav");208209DEBUGMODE_ADD_OBJ(Springboard);210}211212void Springboard_DebugSpawn(void)213{214RSDK_THIS(DebugMode);215216CREATE_ENTITY(Springboard, NULL, self->position.x, self->position.y);217}218void Springboard_DebugDraw(void)219{220RSDK.SetSpriteAnimation(Springboard->aniFrames, 1, &DebugMode->animator, true, 0);221RSDK.DrawSprite(&DebugMode->animator, NULL, false);222}223224#if GAME_INCLUDE_EDITOR225void Springboard_EditorDraw(void)226{227RSDK_THIS(Springboard);228RSDK.SetSpriteAnimation(Springboard->aniFrames, 0, &self->animator, false, 3);229230Springboard_Draw();231}232233void Springboard_EditorLoad(void)234{235Springboard->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Springboard.bin", SCOPE_STAGE);236237RSDK_ACTIVE_VAR(Springboard, direction);238RSDK_ENUM_VAR("Right", FLIP_NONE);239RSDK_ENUM_VAR("Left", FLIP_X);240}241#endif242243void Springboard_Serialize(void)244{245RSDK_EDITABLE_VAR(Springboard, VAR_UINT8, direction);246RSDK_EDITABLE_VAR(Springboard, VAR_ENUM, force);247}248249250