Path: blob/master/SonicMania/Objects/Common/PlatformControl.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PlatformControl Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPlatformControl *PlatformControl;1011void PlatformControl_Update(void)12{13RSDK_THIS(PlatformControl);1415self->active = ACTIVE_NORMAL;1617int32 startNodeSlot = RSDK.GetEntitySlot(self) + 1;18int32 platformSlot = startNodeSlot + self->nodeCount;1920if (self->isActive) {21for (int32 c = 0; c < self->childCount; ++c) {22EntityPlatform *platform = RSDK_GET_ENTITY(platformSlot, Platform);23EntityPlatformNode *node = RSDK_GET_ENTITY(platform->speed, PlatformNode);2425int32 finishDir = 0;26if (platform->velocity.x <= 0) {27if (platform->drawPos.x <= node->position.x)28finishDir = 1;29}30else {31if (platform->drawPos.x >= node->position.x)32finishDir = 1;33}3435if (platform->velocity.y <= 0) {36if (platform->drawPos.y <= node->position.y)37finishDir |= 2;38}39else {40if (platform->drawPos.y >= node->position.y)41finishDir |= 2;42}4344if (finishDir == (1 | 2)) {45platform->timer = node->nodeFlag;4647if (platform->direction < 4) {48int32 nodeID = ++platform->speed - startNodeSlot;49if (nodeID >= self->nodeCount) {50switch (self->type) {51case PLATFORMCONTROL_CIRCUIT: platform->speed = startNodeSlot; break;5253case PLATFORMCONTROL_REVERSE:54--platform->speed;55platform->direction = platform->direction ^ 4;56break;5758case PLATFORMCONTROL_TELEPORT: {59Entity *startNode = RSDK_GET_ENTITY_GEN(startNodeSlot);60platform->drawPos.x = startNode->position.x;61platform->drawPos.y = startNode->position.y;62platform->speed = startNodeSlot + 1;63break;64}6566case PLATFORMCONTROL_STOP: self->speed = 0; break;67}68}69}70else {71int32 nodeID = --platform->speed - startNodeSlot;72if (nodeID < 0) {73switch (self->type) {74default:75case PLATFORMCONTROL_STOP: break;7677case PLATFORMCONTROL_CIRCUIT: platform->speed = startNodeSlot + (self->nodeCount - 1); break;7879case PLATFORMCONTROL_REVERSE:80platform->direction = platform->direction ^ 4;81platform->speed = platform->speed + 1;82break;8384case PLATFORMCONTROL_TELEPORT: {85Entity *startNode = RSDK_GET_ENTITY_GEN(startNodeSlot + self->nodeCount - 1);86platform->drawPos.x = startNode->position.x;87platform->drawPos.y = startNode->position.y;88platform->speed = startNodeSlot + (self->nodeCount - 2);89break;90}91}92}93}9495PlatformControl_ManagePlatformVelocity(platform, RSDK_GET_ENTITY(platform->speed, PlatformNode));96}9798platformSlot += platform->childCount + 1;99}100}101else {102EntityButton *button = self->taggedButton;103104if (button && button->currentlyActive)105self->setActive = true;106107if (self->setActive) {108for (int32 c = 0; c < self->childCount; ++c) {109EntityPlatform *platform = RSDK_GET_ENTITY(platformSlot, Platform);110if (platform->state == Platform_State_PathStop)111platform->state = Platform_State_Path;112113if (platform->state == Platform_State_PathReact) {114self->setActive = false;115return;116}117118platform->speed += startNodeSlot;119platform->active = ACTIVE_NORMAL;120PlatformControl_ManagePlatformVelocity(platform, RSDK_GET_ENTITY(platform->speed, PlatformNode));121platformSlot += platform->childCount + 1;122}123124self->isActive = true;125}126}127128if (!RSDK.CheckOnScreen(self, NULL)) {129self->active = ACTIVE_BOUNDS;130131int32 slot = startNodeSlot + self->nodeCount;132for (int32 c = 0; c < self->childCount; ++c) {133EntityPlatform *platform = RSDK_GET_ENTITY(slot, Platform);134if (platform->state == Platform_State_Path) {135platform->speed -= startNodeSlot;136platform->state = Platform_State_PathStop;137platform->active = ACTIVE_BOUNDS;138}139slot += platform->childCount + 1;140}141142self->isActive = false;143}144}145146void PlatformControl_LateUpdate(void) {}147148void PlatformControl_StaticUpdate(void) {}149150void PlatformControl_Draw(void) {}151152void PlatformControl_Create(void *data)153{154RSDK_THIS(PlatformControl);155156if (!SceneInfo->inEditor) {157self->active = ACTIVE_BOUNDS;158159int32 id = RSDK.GetEntitySlot(self) + 1;160for (int32 i = 0; i < self->nodeCount; ++i) {161Entity *node = RSDK_GET_ENTITY_GEN(id++);162163if (abs(node->position.x - self->position.x) > self->updateRange.x)164self->updateRange.x = abs(node->position.x - self->position.x);165166if (abs(node->position.y - self->position.y) > self->updateRange.y)167self->updateRange.y = abs(node->position.y - self->position.y);168}169170if (!self->speed)171self->speed = 4;172173self->updateRange.x += TO_FIXED(128);174self->updateRange.y += TO_FIXED(128);175176self->taggedButton = NULL;177EntityButton *taggedButton = RSDK_GET_ENTITY(RSDK.GetEntitySlot(self) - 1, Button);178if (self->buttonTag > 0) {179bool32 foundButton = false;180if (Button) {181foreach_all(Button, button)182{183if (button->tag == self->buttonTag) {184taggedButton = button;185foundButton = true;186foreach_break;187}188}189}190191if (SDashWheel && !foundButton) {192foreach_all(SDashWheel, wheel)193{194if (wheel->tag == self->buttonTag) {195taggedButton = (EntityButton *)wheel;196foundButton = true;197foreach_break;198}199}200}201202if (PullChain && !taggedButton) {203foreach_all(PullChain, chain)204{205if (chain->tag == self->buttonTag) {206taggedButton = (EntityButton *)chain;207foundButton = true;208foreach_break;209}210}211}212}213214if (taggedButton) {215if ((Button && taggedButton->classID == Button->classID) || (SDashWheel && taggedButton->classID == SDashWheel->classID)216|| (PullChain && taggedButton->classID == PullChain->classID)) {217self->taggedButton = taggedButton;218if (self->updateRange.x < TO_FIXED(128) + abs(self->position.x - taggedButton->position.x))219self->updateRange.x = TO_FIXED(128) + abs(self->position.x - taggedButton->position.x);220221if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - taggedButton->position.y))222self->updateRange.y = TO_FIXED(128) + abs(self->position.y - taggedButton->position.y);223}224}225}226}227228void PlatformControl_StageLoad(void) {}229230void PlatformControl_ManagePlatformVelocity(EntityPlatform *platform, EntityPlatformNode *node)231{232RSDK_THIS(PlatformControl);233234int32 distX = abs((node->position.x - platform->drawPos.x) >> 16);235int32 distY = abs((node->position.y - platform->drawPos.y) >> 16);236237if (distY >= distX) {238if (distY)239platform->velocity.x = self->speed * (((distX << 16) / distY) >> 2);240else241platform->velocity.x = 0;242243platform->velocity.y = self->speed << 14;244}245else {246platform->velocity.x = self->speed << 14;247248if (distX)249platform->velocity.y = self->speed * (((distY << 16) / distX) >> 2);250else251platform->velocity.y = 0;252}253254if (node->position.x < platform->drawPos.x)255platform->velocity.x = -platform->velocity.x;256if (node->position.y < platform->drawPos.y)257platform->velocity.y = -platform->velocity.y;258}259260#if GAME_INCLUDE_EDITOR261void PlatformControl_EditorDraw(void)262{263RSDK_THIS(PlatformControl);264265if (HUD) {266Animator animator;267RSDK.SetSpriteAnimation(HUD->aniFrames, 0, &animator, false, 7);268RSDK.DrawSprite(&animator, NULL, false);269}270271self->updateRange.x = TO_FIXED(128);272self->updateRange.y = TO_FIXED(128);273274if (showGizmos()) {275self->taggedButton = NULL;276EntityButton *taggedButton = RSDK_GET_ENTITY(RSDK.GetEntitySlot(self) - 1, Button);277if (self->buttonTag > 0) {278bool32 foundButton = false;279if (Button) {280foreach_all(Button, button)281{282if (button->tag == self->buttonTag) {283taggedButton = button;284foundButton = true;285foreach_break;286}287}288}289290if (SDashWheel && !foundButton) {291foreach_all(SDashWheel, wheel)292{293if (wheel->tag == self->buttonTag) {294taggedButton = (EntityButton *)wheel;295foundButton = true;296foreach_break;297}298}299}300301if (PullChain && !taggedButton) {302foreach_all(PullChain, chain)303{304if (chain->tag == self->buttonTag) {305taggedButton = (EntityButton *)chain;306foundButton = true;307foreach_break;308}309}310}311}312313if (taggedButton) {314if ((Button && taggedButton->classID == Button->classID) || (SDashWheel && taggedButton->classID == SDashWheel->classID)315|| (PullChain && taggedButton->classID == PullChain->classID)) {316self->taggedButton = taggedButton;317if (self->updateRange.x < TO_FIXED(128) + abs(self->position.x - taggedButton->position.x))318self->updateRange.x = TO_FIXED(128) + abs(self->position.x - taggedButton->position.x);319320if (self->updateRange.y < TO_FIXED(128) + abs(self->position.y - taggedButton->position.y))321self->updateRange.y = TO_FIXED(128) + abs(self->position.y - taggedButton->position.y);322}323}324325RSDK_DRAWING_OVERLAY(true);326if (self->taggedButton) {327DrawHelpers_DrawArrow(self->taggedButton->position.x, self->taggedButton->position.y, self->position.x, self->position.y, 0xFFFF00,328INK_NONE, 0xFF);329}330331int32 startNodeSlot = RSDK.GetEntitySlot(self) + 1;332333/*EntityPlatformNode *lastNode = RSDK_GET_ENTITY(startNodeSlot, PlatformNode);334for (int32 n = 1; n < self->nodeCount; ++n) {335EntityPlatformNode *node = RSDK_GET_ENTITY(startNodeSlot + n, PlatformNode);336337if (lastNode && node) {338DrawHelpers_DrawArrow(lastNode->position.x, lastNode->position.y, node->position.x, node->position.y, 0xFF0000, INK_NONE, 0xFF);339}340lastNode = node;341}342343if (lastNode) {344EntityPlatformNode *node = RSDK_GET_ENTITY(startNodeSlot, PlatformNode);345if (node && self->type != PLATFORMCONTROL_STOP) {346DrawHelpers_DrawArrow(lastNode->position.x, lastNode->position.y, node->position.x, node->position.y, 0xFF0000, INK_NONE, 0xFF);347}348}*/349350int32 platformSlot = startNodeSlot + self->nodeCount;351for (int32 c = 0; c < self->childCount; ++c) {352EntityPlatform *platform = RSDK_GET_ENTITY(platformSlot, Platform);353platformSlot++;354355if (platform) {356platformSlot += platform->childCount;357DrawHelpers_DrawArrow(self->position.x, self->position.y, platform->position.x, platform->position.y, 0xFFFFFF, INK_NONE, 0xFF);358}359}360361RSDK_DRAWING_OVERLAY(false);362}363}364365void PlatformControl_EditorLoad(void)366{367368RSDK_ACTIVE_VAR(PlatformControl, type);369RSDK_ENUM_VAR("Circuit", PLATFORMCONTROL_CIRCUIT);370RSDK_ENUM_VAR("Reverse", PLATFORMCONTROL_REVERSE);371RSDK_ENUM_VAR("Teleport", PLATFORMCONTROL_TELEPORT);372RSDK_ENUM_VAR("Stop", PLATFORMCONTROL_STOP);373}374#endif375376void PlatformControl_Serialize(void)377{378RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, nodeCount);379RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, childCount);380RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, speed);381RSDK_EDITABLE_VAR(PlatformControl, VAR_BOOL, setActive);382RSDK_EDITABLE_VAR(PlatformControl, VAR_UINT8, type);383RSDK_EDITABLE_VAR(PlatformControl, VAR_ENUM, buttonTag);384}385386387