Path: blob/master/SonicMania/Objects/TMZ/MetalArm.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: MetalArm Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectMetalArm *MetalArm;1011void MetalArm_Update(void)12{13RSDK_THIS(MetalArm);1415self->moveOffset.x = -self->armPosition.x;16self->moveOffset.y = -self->armPosition.y;1718int32 timerA = MIN(self->durationA, self->moveTimer);19int32 interpolateA = ((self->endAngleA - self->startAngleA) << 16) / self->durationA;20self->armAngle.x = (self->startAngleA << 16) + interpolateA * timerA;2122int32 timerB = MIN(self->durationB, self->moveTimer);23int32 interpolateB = ((self->endAngleB - self->startAngleB) << 16) / self->durationB;24self->armAngle.y = (self->startAngleB << 16) + interpolateB * timerB;2526self->armPosition = MetalArm_GetArmPosition();27self->armPosition.x &= 0xFFFF0000;28self->armPosition.y &= 0xFFFF0000;2930self->position.x = self->armPosition.x;31self->position.y = self->armPosition.y;32self->moveOffset.x += self->position.x;33self->moveOffset.y += self->position.y;3435MetalArm_CheckPlayerCollisions();3637self->position.x = self->startPos.x;38self->position.y = self->startPos.y;3940StateMachine_Run(self->state);41}4243void MetalArm_LateUpdate(void) {}4445void MetalArm_StaticUpdate(void) {}4647void MetalArm_Draw(void)48{49RSDK_THIS(MetalArm);5051self->rotation = 0;52RSDK.DrawSprite(&self->baseAnimator, NULL, false);5354int32 x = 0x2400 * RSDK.Cos512((self->armAngle.x >> 16)) + self->position.x;55int32 y = 0x2400 * RSDK.Sin512((self->armAngle.x >> 16)) + self->position.y;5657Vector2 drawPos = MetalArm_GetArmPosition();58self->position.x = x;59self->position.y = y;60self->position.x &= 0xFFFF0000;61self->position.y &= 0xFFFF0000;62self->rotation = (self->armAngle.x + self->armAngle.y) >> 16;63RSDK.DrawSprite(&self->armBAnimator, NULL, false);6465self->position.x = self->startPos.x;66self->position.y = self->startPos.y;67self->position.x &= 0xFFFF0000;68self->position.y &= 0xFFFF0000;69self->rotation = (self->armAngle.x >> 16);70RSDK.DrawSprite(&self->armAAnimator, NULL, false);7172self->rotation = 0;73self->position = drawPos;74self->position.x &= 0xFFFF0000;75self->position.y &= 0xFFFF0000;76RSDK.DrawSprite(&self->platformAnimator, &drawPos, false);7778self->position.x = self->startPos.x;79self->position.y = self->startPos.y;80}8182void MetalArm_Create(void *data)83{84RSDK_THIS(MetalArm);8586self->active = ACTIVE_BOUNDS;87self->drawGroup = Zone->objectDrawGroup[1];88self->startPos.x = self->position.x;89self->startPos.y = self->position.y;90self->visible = true;91self->drawFX = FX_ROTATE | FX_FLIP;92self->updateRange.x = 0x1000000;93self->updateRange.y = 0x1000000;9495if (!self->durationA)96self->durationA = 60;9798if (!self->durationB)99self->durationB = 40;100101if (!self->holdDuration)102self->holdDuration = 60;103104self->hitbox.left = -56;105self->hitbox.top = -27;106self->hitbox.right = 56;107self->hitbox.bottom = -7;108109RSDK.SetSpriteAnimation(MetalArm->aniFrames, 0, &self->baseAnimator, true, 0);110RSDK.SetSpriteAnimation(MetalArm->aniFrames, 1, &self->armAAnimator, true, 0);111RSDK.SetSpriteAnimation(MetalArm->aniFrames, 2, &self->armBAnimator, true, 0);112RSDK.SetSpriteAnimation(MetalArm->aniFrames, 3, &self->platformAnimator, true, 0);113114self->armAngle.x = self->startAngleA << 16;115self->armAngle.y = self->startAngleB << 16;116self->moveTimer = 0;117self->armPosition = MetalArm_GetArmPosition();118self->state = MetalArm_State_Idle;119}120121void MetalArm_StageLoad(void)122{123MetalArm->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/MetalArm.bin", SCOPE_STAGE);124125Soundboard_LoadSfx("TMZ1/MetalArm.wav", true, MetalArm_SfxCheck_MetalArm, StateMachine_None);126}127128bool32 MetalArm_SfxCheck_MetalArm(void)129{130int32 activeCount = 0;131132foreach_active(MetalArm, arm)133{134if (arm->state == MetalArm_State_MoveToHold || arm->state == MetalArm_State_MoveToStart)135++activeCount;136}137138return activeCount > 0;139}140141Vector2 MetalArm_GetArmPosition(void)142{143RSDK_THIS(MetalArm);144145int32 x = 0x2400 * RSDK.Cos512((self->armAngle.x >> 16)) + self->position.x;146int32 y = 0x2400 * RSDK.Sin512((self->armAngle.x >> 16)) + self->position.y;147148Vector2 armPos;149armPos.x = x + 0x3800 * RSDK.Cos512((self->armAngle.x + self->armAngle.y) >> 16);150armPos.y = y + 0x3800 * RSDK.Sin512((self->armAngle.x + self->armAngle.y) >> 16);151152return armPos;153}154155void MetalArm_CheckPlayerCollisions(void)156{157RSDK_THIS(MetalArm);158159foreach_active(Player, player)160{161int32 playerID = RSDK.GetEntitySlot(player);162163if ((1 << playerID) & self->stoodPlayers) {164player->position.x += self->moveOffset.x;165player->position.y += self->moveOffset.y;166player->position.y += 0x10000;167}168169if (!Player_CheckCollisionPlatform(player, self, &self->hitbox))170self->stoodPlayers &= ~(1 << playerID);171else172self->stoodPlayers |= 1 << playerID;173}174}175176void MetalArm_State_Idle(void)177{178RSDK_THIS(MetalArm);179180if ((self->stoodPlayers & 1)) {181self->moveTimer = 0;182self->holdTimer = 0;183self->active = ACTIVE_NORMAL;184self->state = MetalArm_State_MoveToHold;185}186}187188void MetalArm_State_MoveToHold(void)189{190RSDK_THIS(MetalArm);191192if (self->moveTimer >= MAX(self->durationA, self->durationB)) {193self->holdTimer = 0;194self->state = MetalArm_State_Holding;195}196else {197self->moveTimer++;198}199}200201void MetalArm_State_Holding(void)202{203RSDK_THIS(MetalArm);204205if (self->stoodPlayers & 1) {206self->holdTimer = 0;207}208else {209if (self->holdTimer >= self->holdDuration) {210self->state = MetalArm_State_MoveToStart;211}212else {213self->holdTimer++;214}215}216}217218void MetalArm_State_MoveToStart(void)219{220RSDK_THIS(MetalArm);221222if (self->moveTimer <= 0) {223self->state = MetalArm_State_Idle;224self->active = ACTIVE_BOUNDS;225}226else {227self->moveTimer--;228}229}230231#if GAME_INCLUDE_EDITOR232void MetalArm_EditorDraw(void)233{234RSDK_THIS(MetalArm);235236MetalArm_Create(NULL);237238self->startPos.x = self->position.x;239self->startPos.y = self->position.y;240self->armAngle.x = self->startAngleA << 16;241self->armAngle.y = self->startAngleB << 16;242self->armPosition = MetalArm_GetArmPosition();243244MetalArm_Draw();245}246247void MetalArm_EditorLoad(void) { MetalArm->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/MetalArm.bin", SCOPE_STAGE); }248#endif249250void MetalArm_Serialize(void)251{252RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, startAngleA);253RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, startAngleB);254RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, endAngleA);255RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, endAngleB);256RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, durationA);257RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, durationB);258RSDK_EDITABLE_VAR(MetalArm, VAR_INT32, holdDuration);259}260261262