Path: blob/master/SonicMania/Objects/CPZ/StickyPlatform.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: StickyPlatform Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectStickyPlatform *StickyPlatform;1011void StickyPlatform_Update(void)12{13RSDK_THIS(StickyPlatform);1415self->active = ACTIVE_NORMAL;16StateMachine_Run(self->state);1718self->position.x = self->amplitude.x * RSDK.Cos1024(self->angle) + self->centerPos.x;19self->position.y = self->amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.y;2021StickyPlatform_Interact();2223RSDK.ProcessAnimation(&self->animator);2425int32 anim = self->animator.animationID % 3;26if (anim) {27if (anim == 2 && self->animator.frameID == self->animator.frameCount - 1) {28RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1), &self->animator, false, 0);29self->animator.speed = 0;30}31}32else if (self->animator.frameID == self->animator.frameCount - 3) {33RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1) + 1, &self->animator, false, 0);34}3536if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->centerPos, &self->updateRange)) {37self->position = self->centerPos;38self->angle = 0;39self->activePlayers = 0;40self->state = self->oscillate ? StickyPlatform_State_Oscillating : StickyPlatform_State_HandleMovement;41}42}4344void StickyPlatform_LateUpdate(void) {}4546void StickyPlatform_StaticUpdate(void) {}4748void StickyPlatform_Draw(void)49{50RSDK_THIS(StickyPlatform);5152RSDK.DrawSprite(&self->animator, NULL, false);53}5455void StickyPlatform_Create(void *data)56{57RSDK_THIS(StickyPlatform);5859self->drawFX = FX_FLIP;60if (!SceneInfo->inEditor) {61self->visible = true;62self->active = ACTIVE_BOUNDS;63self->drawGroup = Zone->objectDrawGroup[1] - 2;64self->updateRange.x = 0x800000;65self->updateRange.y = 0x800000;6667RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, self->type > STICKYPLATFORM_DOWN ? 3 : 0, &self->animator, true, 0);68switch (self->type) {69case STICKYPLATFORM_UP:70self->direction = FLIP_NONE;71self->rotation = 0;7273self->hitbox.left = -16;74self->hitbox.top = -16;75self->hitbox.right = 16;76self->hitbox.bottom = 8;77break;7879case STICKYPLATFORM_DOWN:80self->direction = FLIP_Y;81self->rotation = 0x80;8283self->hitbox.left = -16;84self->hitbox.top = -8;85self->hitbox.right = 16;86self->hitbox.bottom = 16;87break;8889case STICKYPLATFORM_RIGHT:90self->direction = FLIP_NONE;91self->rotation = 0x40;9293self->hitbox.left = -8;94self->hitbox.top = -16;95self->hitbox.right = 16;96self->hitbox.bottom = 16;97break;9899case STICKYPLATFORM_LEFT:100self->direction = FLIP_X;101self->rotation = 0xC0;102103self->hitbox.left = -16;104self->hitbox.top = -16;105self->hitbox.right = 8;106self->hitbox.bottom = 16;107break;108109default: break;110}111112self->animator.speed = 0;113114self->centerPos.x = self->position.x;115self->centerPos.y = self->position.y;116self->position.x += self->amplitude.x;117self->position.y += self->amplitude.y;118self->amplitude.x >>= 10;119self->amplitude.y >>= 10;120121if (!self->speed)122self->speed = 4;123124self->state = self->oscillate ? StickyPlatform_State_Oscillating : StickyPlatform_State_HandleMovement;125}126}127128void StickyPlatform_StageLoad(void)129{130StickyPlatform->aniFrames = RSDK.LoadSpriteAnimation("CPZ/StickyPlatform.bin", SCOPE_STAGE);131132StickyPlatform->sfxLand = RSDK.GetSfx("Puyo/Land.wav");133}134135void StickyPlatform_Interact(void)136{137RSDK_THIS(StickyPlatform);138139if (Player->playerCount > 0) {140for (int32 i = 0; i < Player->playerCount; i++) {141EntityPlayer *player = RSDK_GET_ENTITY(i, Player);142143if (Player_CheckValidState(player) && player->interaction) {144if (((1 << i) & self->activePlayers)) {145if (player->state == Player_State_Static) {146if (player->jumpPress) {147player->angle = self->rotation;148player->groundVel = 0;149Player_Action_Jump(player);150151player->velocity.x = (320 * player->velocity.x) >> 8;152player->velocity.y = (320 * player->velocity.y) >> 8;153self->activePlayers &= ~(1 << i);154self->playerTimer[i] = 16;155RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1) + 2, &self->animator, false, 0);156}157else {158Hitbox *playerHitbox = Player_GetHitbox(player);159160uint16 animID = 0;161switch (self->type) {162case STICKYPLATFORM_UP:163player->position.x = self->position.x;164player->position.y = self->position.y - (playerHitbox->bottom << 16);165animID = 10;166break;167168case STICKYPLATFORM_DOWN:169player->position.x = self->position.x;170player->position.y = self->position.y - (playerHitbox->top << 16);171animID = 10;172break;173174case STICKYPLATFORM_RIGHT:175player->position.y = self->position.y;176player->position.x = self->position.x + ((8 - playerHitbox->left) << 16);177player->direction = FLIP_NONE;178animID = 36;179break;180181case STICKYPLATFORM_LEFT:182player->position.y = self->position.y;183player->position.x = self->position.x - ((playerHitbox->right + 8) << 16);184player->direction = FLIP_X;185animID = 36;186break;187188default: break;189}190RSDK.SetSpriteAnimation(player->aniFrames, animID, &player->animator, false, 0);191}192}193else {194self->activePlayers &= ~(1 << i);195}196}197else {198if (!Player_CheckCollisionTouch(player, self, &self->hitbox) || self->playerTimer[i]) {199if (self->playerTimer[i])200self->playerTimer[i]--;201continue;202}203204self->activePlayers |= 1 << i;205RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, 3 * (self->type >> 1), &self->animator, true, 0);206self->animator.speed = 1;207player->state = Player_State_Static;208player->velocity.x = 0;209player->velocity.y = 0;210player->groundVel = 0;211player->rotation = 0;212213RSDK.PlaySfx(StickyPlatform->sfxLand, false, 255);214}215}216}217}218}219220void StickyPlatform_State_HandleMovement(void)221{222RSDK_THIS(StickyPlatform);223224if (self->angle) {225if (!self->activePlayers)226self->state = StickyPlatform_State_MoveBackForth;227}228else if (self->activePlayers > 0) {229self->state = StickyPlatform_State_MoveBack;230}231}232233void StickyPlatform_State_MoveBack(void)234{235RSDK_THIS(StickyPlatform);236237self->angle += self->speed;238if (self->angle >= 0x200) {239self->angle = 0x200;240self->state = StickyPlatform_State_HandleMovement;241}242}243244void StickyPlatform_State_MoveBackForth(void)245{246RSDK_THIS(StickyPlatform);247248self->angle += self->speed;249if (self->angle >= 0x400) {250self->angle = 0;251self->state = StickyPlatform_State_HandleMovement;252}253}254255void StickyPlatform_State_Oscillating(void)256{257RSDK_THIS(StickyPlatform);258259self->angle = (self->angle + self->speed) & 0x3FF;260}261262#if GAME_INCLUDE_EDITOR263void StickyPlatform_EditorDraw(void)264{265RSDK_THIS(StickyPlatform);266267self->updateRange.x = 0x800000;268self->updateRange.y = 0x800000;269270RSDK.SetSpriteAnimation(StickyPlatform->aniFrames, self->type > STICKYPLATFORM_DOWN ? 3 : 0, &self->animator, true, 0);271switch (self->type) {272case STICKYPLATFORM_UP: self->direction = FLIP_NONE; break;273case STICKYPLATFORM_DOWN: self->direction = FLIP_Y; break;274case STICKYPLATFORM_RIGHT: self->direction = FLIP_NONE; break;275case STICKYPLATFORM_LEFT: self->direction = FLIP_X; break;276default: break;277}278279StickyPlatform_Draw();280281if (showGizmos()) {282RSDK_DRAWING_OVERLAY(true);283284self->centerPos = self->position;285Vector2 amplitude;286amplitude.x = self->amplitude.x >> 10;287amplitude.y = self->amplitude.y >> 10;288289self->inkEffect = INK_BLEND;290291// start pos292self->position.x = amplitude.x * RSDK.Cos1024(self->angle) + self->centerPos.x;293self->position.y = amplitude.y * RSDK.Cos1024(self->angle) + self->centerPos.y;294StickyPlatform_Draw();295296// right max297self->position.x = amplitude.x * RSDK.Cos1024(0x000) + self->centerPos.x;298self->position.y = amplitude.y * RSDK.Cos1024(0x000) + self->centerPos.y;299Vector2 drawPos = self->position;300StickyPlatform_Draw();301302// left max303self->position.x = amplitude.x * RSDK.Cos1024(0x200) + self->centerPos.x;304self->position.y = amplitude.y * RSDK.Cos1024(0x200) + self->centerPos.y;305StickyPlatform_Draw();306307DrawHelpers_DrawArrow(drawPos.x, drawPos.y, self->position.x, self->position.y, 0x00FF00, INK_NONE, 0xFF);308DrawHelpers_DrawArrow(self->position.x, self->position.y, drawPos.x, drawPos.y, 0x00FF00, INK_NONE, 0xFF);309310self->inkEffect = INK_NONE;311312self->position = self->centerPos;313RSDK_DRAWING_OVERLAY(false);314}315}316317void StickyPlatform_EditorLoad(void)318{319StickyPlatform->aniFrames = RSDK.LoadSpriteAnimation("CPZ/StickyPlatform.bin", SCOPE_STAGE);320321RSDK_ACTIVE_VAR(StickyPlatform, type);322RSDK_ENUM_VAR("Up", STICKYPLATFORM_UP);323RSDK_ENUM_VAR("Down", STICKYPLATFORM_DOWN);324RSDK_ENUM_VAR("Right", STICKYPLATFORM_RIGHT);325RSDK_ENUM_VAR("Left", STICKYPLATFORM_LEFT);326}327#endif328329void StickyPlatform_Serialize(void)330{331RSDK_EDITABLE_VAR(StickyPlatform, VAR_ENUM, type);332RSDK_EDITABLE_VAR(StickyPlatform, VAR_VECTOR2, amplitude);333RSDK_EDITABLE_VAR(StickyPlatform, VAR_ENUM, speed);334RSDK_EDITABLE_VAR(StickyPlatform, VAR_BOOL, oscillate);335}336337