Path: blob/master/SonicMania/Objects/SPZ/Clapperboard.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Clapperboard Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectClapperboard *Clapperboard;1011void Clapperboard_Update(void)12{13RSDK_THIS(Clapperboard);1415StateMachine_Run(self->state);1617self->rotation = self->angle >> 1;18self->stoodPlayers = 0;19StateMachine_Run(self->stateCollide);20}2122void Clapperboard_LateUpdate(void) {}2324void Clapperboard_StaticUpdate(void) {}2526void Clapperboard_Draw(void)27{28RSDK_THIS(Clapperboard);29Vector2 drawPos;3031self->drawFX = FX_ROTATE | FX_FLIP;32RSDK.DrawSprite(&self->clapperTopAnimator, NULL, false);3334self->drawFX = FX_FLIP;35RSDK.DrawSprite(&self->clapperBottomAnimator, NULL, false);3637self->drawFX = FX_NONE;38RSDK.DrawSprite(&self->boardAnimator, NULL, false);3940drawPos.x = self->position.x;41drawPos.y = self->position.y;42if (self->direction == FLIP_X)43drawPos.x -= 0x670000;44else45drawPos.x += 0x10000;46self->numbersAnimator.frameID = self->takeID / 100;47RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);4849drawPos.x += 0xD0000;50self->numbersAnimator.frameID = (self->takeID / 10) % 10;51RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);5253drawPos.x += 0xD0000;54self->numbersAnimator.frameID = self->takeID % 10;55RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);5657drawPos.x += 0x120000;58self->numbersAnimator.frameID = SceneInfo->minutes % 10;59RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);6061drawPos.x += 0x120000;62self->numbersAnimator.frameID = SceneInfo->seconds / 10;63RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);6465drawPos.x += 0xD0000;66self->numbersAnimator.frameID = SceneInfo->seconds % 10;67RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);6869drawPos.x += 0x110000;70self->numbersAnimator.frameID = SceneInfo->milliseconds / 10;71RSDK.DrawSprite(&self->numbersAnimator, &drawPos, false);72}7374void Clapperboard_Create(void *data)75{76RSDK_THIS(Clapperboard);7778RSDK.SetSpriteAnimation(Clapperboard->aniFrames, 0, &self->clapperTopAnimator, true, 0);79RSDK.SetSpriteAnimation(Clapperboard->aniFrames, 0, &self->clapperBottomAnimator, true, 1);80RSDK.SetSpriteAnimation(Clapperboard->aniFrames, 0, &self->boardAnimator, true, 2);81RSDK.SetSpriteAnimation(Clapperboard->aniFrames, 1, &self->numbersAnimator, true, 0);8283if (!SceneInfo->inEditor) {84self->active = ACTIVE_BOUNDS;85self->updateRange.x = 0x800000;86self->updateRange.y = 0x800000;8788if (self->direction == FLIP_NONE) {89self->amplitudeL.x = -0x40000;90self->amplitudeR.x = 0x6C0000;91self->angle = 0x3C0;92self->stateCollide = Clapperboard_Collide_Right;93}94else {95++self->boardAnimator.frameID;96self->amplitudeL.x = -0x6C0000;97self->amplitudeR.x = 0x40000;98self->angle = 0x040;99self->stateCollide = Clapperboard_Collide_Left;100}101102self->amplitudeL.y = -0x40000;103self->amplitudeR.y = -0x40000;104self->state = Clapperboard_State_Idle;105self->visible = true;106self->drawGroup = Zone->objectDrawGroup[0];107}108}109110void Clapperboard_StageLoad(void)111{112if (RSDK.CheckSceneFolder("SPZ1"))113Clapperboard->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Clapperboard.bin", SCOPE_STAGE);114else115Clapperboard->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/Clapperboard.bin", SCOPE_STAGE);116117Clapperboard->sfxWhack = RSDK.GetSfx("Stage/Whack.wav");118}119120void Clapperboard_Collide_Left(void)121{122RSDK_THIS(Clapperboard);123124uint8 negAngle = -(-self->angle >> 2);125126int32 ampL = (self->amplitudeL.y >> 8) * RSDK.Cos256(negAngle) - (self->amplitudeL.x >> 8) * RSDK.Sin256(negAngle);127int32 ampR = (self->amplitudeR.y >> 8) * RSDK.Cos256(negAngle) - (self->amplitudeR.x >> 8) * RSDK.Sin256(negAngle);128129self->hitbox.left = ((self->amplitudeL.y >> 8) * RSDK.Sin256(negAngle) + (self->amplitudeL.x >> 8) * RSDK.Cos256(negAngle)) >> 16;130self->hitbox.right = ((self->amplitudeR.y >> 8) * RSDK.Sin256(negAngle) + (self->amplitudeR.x >> 8) * RSDK.Cos256(negAngle)) >> 16;131132int32 clapStartPos = self->hitbox.right - self->hitbox.left;133self->direction ^= FLIP_X;134bool32 clapped = false;135136foreach_active(Player, player)137{138int32 standPos = self->hitbox.right - CLAMP((player->position.x - self->position.x) >> 16, self->hitbox.left, self->hitbox.right);139int32 top = (ampR >> 16) + ((ampR >> 16) - (ampL >> 16)) * standPos / clapStartPos - (self->clapSpeed & 0xFFFF);140self->hitbox.top = top;141self->hitbox.bottom = top + 24;142if (Player_CheckCollisionPlatform(player, self, &self->hitbox)) {143#if MANIA_USE_PLUS144if (player->state == Player_State_MightyHammerDrop)145player->state = Player_State_Air;146#endif147148player->position.y += (self->clapSpeed + 2) << 16;149if (standPos > (clapStartPos >> 2)) {150self->stoodPlayers |= RSDK.GetEntitySlot(player) + 1;151if (self->state == Clapperboard_State_ClapReboundL152|| (abs(player->groundVel) > 0x80000 && standPos > clapStartPos - (clapStartPos >> 2))) {153player->onGround = false;154player->state = Player_State_Air;155player->velocity.y = -0x40000 - 0x60000 * standPos / clapStartPos;156157int32 anim = player->animator.animationID;158if (anim == ANI_WALK || (anim > ANI_AIR_WALK && anim <= ANI_DASH))159player->animationReserve = player->animator.animationID;160else161player->animationReserve = ANI_WALK;162163RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_DIAGONAL, &player->animator, true, 0);164RSDK.PlaySfx(Clapperboard->sfxWhack, false, 255);165clapped = true;166}167else {168int32 clapSpeed = 16;169if (abs(player->groundVel) < 0xA0000)170clapSpeed = 16 * standPos / clapStartPos;171172if (clapSpeed > self->clapSpeed)173self->clapSpeed = clapSpeed;174}175}176}177}178179self->direction ^= FLIP_X;180if (clapped)181++self->takeID;182}183184void Clapperboard_Collide_Right(void)185{186RSDK_THIS(Clapperboard);187188int32 negAngle = -(-self->angle >> 2);189190int32 ampL = (self->amplitudeL.y >> 8) * RSDK.Cos256(negAngle) - (self->amplitudeL.x >> 8) * RSDK.Sin256(negAngle);191int32 ampR = (self->amplitudeR.y >> 8) * RSDK.Cos256(negAngle) - (self->amplitudeR.x >> 8) * RSDK.Sin256(negAngle);192193self->hitbox.left = (((self->amplitudeL.y >> 8) * RSDK.Sin256(negAngle)) + (self->amplitudeL.x >> 8) * RSDK.Cos256(negAngle)) >> 16;194self->hitbox.right = (((self->amplitudeR.y >> 8) * RSDK.Sin256(negAngle)) + (self->amplitudeR.x >> 8) * RSDK.Cos256(negAngle)) >> 16;195int32 clapStartPos = self->hitbox.right - self->hitbox.left;196bool32 clapped = false;197198foreach_active(Player, player)199{200int32 standPos = CLAMP((player->position.x - self->position.x) >> 16, self->hitbox.left, self->hitbox.right) - self->hitbox.left;201int32 top = (ampL >> 16) + ((ampL >> 16) - (ampR >> 16)) * standPos / clapStartPos - (self->clapSpeed & 0xFFFF);202self->hitbox.top = top;203self->hitbox.bottom = top + 24;204205if (Player_CheckCollisionPlatform(player, self, &self->hitbox)) {206#if MANIA_USE_PLUS207if (player->state == Player_State_MightyHammerDrop)208player->state = Player_State_Air;209#endif210211player->position.y += (self->clapSpeed + 2) << 16;212if (standPos > clapStartPos >> 2) {213self->stoodPlayers |= RSDK.GetEntitySlot(player) + 1;214if (self->state == Clapperboard_State_ClapReboundR215|| (abs(player->groundVel) > 0x80000 && standPos > clapStartPos - (clapStartPos >> 2))) {216player->onGround = false;217player->state = Player_State_Air;218player->velocity.y = -0x40000 - 0x60000 * standPos / clapStartPos;219220int32 anim = player->animator.animationID;221if (anim == ANI_WALK || (anim > ANI_AIR_WALK && anim <= ANI_DASH))222player->animationReserve = player->animator.animationID;223else224player->animationReserve = ANI_WALK;225226RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_DIAGONAL, &player->animator, true, 0);227RSDK.PlaySfx(Clapperboard->sfxWhack, false, 0xFF);228clapped = true;229}230else {231int32 clapSpeed = 16;232if (abs(player->groundVel) < 0xA0000)233clapSpeed = 16 * standPos / clapStartPos;234235if (clapSpeed > self->clapSpeed)236self->clapSpeed = clapSpeed;237}238}239}240}241242if (clapped)243++self->takeID;244}245246void Clapperboard_State_Idle(void)247{248RSDK_THIS(Clapperboard);249250if (self->stoodPlayers > 0)251self->state = self->direction == FLIP_NONE ? Clapperboard_State_ClappingR : Clapperboard_State_ClappingL;252}253254void Clapperboard_State_ClappingL(void)255{256RSDK_THIS(Clapperboard);257258self->angle -= self->clapSpeed;259if (self->angle <= 0x000) {260self->angle = 0x000;261self->state = Clapperboard_State_ClapReboundL;262}263}264265void Clapperboard_State_ClapReboundL(void)266{267RSDK_THIS(Clapperboard);268269self->angle += self->clapSpeed;270if (self->angle >= 0x040) {271self->angle = 0x040;272self->clapSpeed = 0;273self->state = Clapperboard_State_Idle;274}275}276277void Clapperboard_State_ClappingR(void)278{279RSDK_THIS(Clapperboard);280281self->angle += self->clapSpeed;282if (self->angle >= 0x400) {283self->angle = 0x400;284self->state = Clapperboard_State_ClapReboundR;285}286}287288void Clapperboard_State_ClapReboundR(void)289{290RSDK_THIS(Clapperboard);291292self->angle -= self->clapSpeed;293if (self->angle <= 0x3C0) {294self->angle = 0x3C0;295self->clapSpeed = 0;296self->state = Clapperboard_State_Idle;297}298}299300#if GAME_INCLUDE_EDITOR301void Clapperboard_EditorDraw(void)302{303RSDK_THIS(Clapperboard);304305self->boardAnimator.frameID = self->direction == FLIP_NONE ? 2 : 3;306307Clapperboard_Draw();308}309310void Clapperboard_EditorLoad(void)311{312if (RSDK.CheckSceneFolder("SPZ1"))313Clapperboard->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/Clapperboard.bin", SCOPE_STAGE);314else315Clapperboard->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/Clapperboard.bin", SCOPE_STAGE);316317RSDK_ACTIVE_VAR(Clapperboard, direction);318RSDK_ENUM_VAR("Right", FLIP_NONE);319RSDK_ENUM_VAR("Left", FLIP_X);320}321#endif322323void Clapperboard_Serialize(void) { RSDK_EDITABLE_VAR(Clapperboard, VAR_UINT8, direction); }324325326