Path: blob/master/SonicMania/Objects/SPZ/PathInverter.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PathInverter Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPathInverter *PathInverter;1011void PathInverter_Update(void)12{13RSDK_THIS(PathInverter);1415StateMachine_Run(self->state);16}1718void PathInverter_LateUpdate(void) {}1920void PathInverter_StaticUpdate(void) {}2122void PathInverter_Draw(void)23{24RSDK_THIS(PathInverter);2526RSDK.DrawSprite(&self->animator, NULL, false);27}2829void PathInverter_Create(void *data)30{31RSDK_THIS(PathInverter);3233RSDK.SetSpriteAnimation(PathInverter->aniFrames, self->type, &self->animator, true, 0);3435if (!SceneInfo->inEditor) {36self->active = ACTIVE_BOUNDS;37Hitbox *hitbox = RSDK.GetHitbox(&self->animator, 0);38self->size.x = hitbox->right;39self->size.y = hitbox->bottom;40self->size2x.x = 2 * self->size.x;41self->size2x.y = 2 * self->size.y;42self->updateRange.x = 0x800000;43self->updateRange.y = 0x800000;44self->visible = true;45self->drawGroup = Zone->objectDrawGroup[0];4647switch (self->type) {48default: break;49case PATHINVERTER_H: self->state = PathInverter_State_Horizontal; break;50case PATHINVERTER_V: self->state = PathInverter_State_Vertical; break;51}52}53}5455void PathInverter_StageLoad(void)56{57if (RSDK.CheckSceneFolder("SPZ2"))58PathInverter->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/PathInverter.bin", SCOPE_STAGE);59}6061void PathInverter_HandlePathSwitch(EntityPlayer *player)62{63RSDK_THIS(PathInverter);6465if (!self->playerPtrs[player->playerID]) {66Hitbox *playerHitbox = Player_GetHitbox(player);6768if (player->position.y > self->position.y == player->position.x > self->position.x)69self->playerFlipFlags[player->playerID] = (self->size.y + playerHitbox->bottom) << 7;70else71self->playerFlipFlags[player->playerID] = -((self->size.y << 7) + (playerHitbox->bottom << 7));7273if (player->collisionMode == CMODE_ROOF)74player->direction ^= FLIP_X;7576self->playerPtrs[player->playerID] = player;77player->tileCollisions = TILECOLLISION_NONE;78player->velocity.x = player->groundVel * RSDK.Cos256(player->angle) >> 8;79player->velocity.y = player->groundVel * RSDK.Sin256(player->angle) >> 8;80self->groundVelStore[player->playerID] = player->groundVel;8182int32 topSpeed = player->state == Player_State_Roll ? 0xC0000 : 0x80000;83player->velocity.x = CLAMP(player->velocity.x, -topSpeed, topSpeed);8485player->state = Player_State_Static;86player->nextAirState = StateMachine_None;87player->nextGroundState = StateMachine_None;88}8990int32 pos = self->size.x + ((self->position.x - player->position.x) >> 16);91int32 frameAngle = 4 * (3 * pos) / self->size2x.x;92int32 angle = (pos << 8) / self->size2x.x;93if (player->animator.animationID != ANI_JUMP || !player->groundedStore) {94int32 frame = 12 - frameAngle;95if (player->collisionMode != CMODE_ROOF * (self->playerFlipFlags[player->playerID] >= 0))96frame = frameAngle;9798if (frame >= 0)99frame %= 24;100else101frame += 24;102103if (player->collisionMode)104player->direction &= ~FLIP_Y;105else106player->direction |= FLIP_Y;107108RSDK.SetSpriteAnimation(player->aniFrames, ANI_SPRING_CS, &player->animator, true, frame);109}110111player->onGround = true;112player->position.y = self->playerFlipFlags[player->playerID] * RSDK.Cos512(angle) + self->position.y;113}114void PathInverter_State_Horizontal(void)115{116RSDK_THIS(PathInverter);117118foreach_active(Player, player)119{120if (player->collisionMode == CMODE_FLOOR || player->collisionMode == CMODE_ROOF) {121if (abs(self->position.x - player->position.x) >> 16 >= self->size.x122|| abs(self->position.y - player->position.y) >> 16 >= self->size.y + 32) {123int32 playerID = player->playerID;124125if (self->playerPtrs[playerID]) {126self->playerPtrs[playerID] = NULL;127128player->groundVel = self->groundVelStore[player->playerID];129player->groundVel = -player->groundVel;130player->velocity.x = -player->velocity.x;131if (player->collisionMode == CMODE_ROOF)132player->direction ^= FLIP_X;133134player->collisionMode = (player->collisionMode - 2) & 3;135player->angle = (player->angle + 0x80) & 0xFF;136player->controlLock = 30;137138if (player->animator.animationID == ANI_JUMP) {139player->state = Player_State_Roll;140}141else {142player->direction &= FLIP_X;143player->direction ^= FLIP_X;144player->state = Player_State_Ground;145RSDK.SetSpriteAnimation(player->aniFrames, ANI_JOG, &player->animator, false, 0);146player->rotation = player->angle << 1;147}148149player->tileCollisions = TILECOLLISION_DOWN;150}151}152else if (player->state == Player_State_Static) {153PathInverter_HandlePathSwitch(player);154}155else {156if (!player->onGround) {157if (self->playerPtrs[player->playerID])158PathInverter_HandlePathSwitch(player);159}160else {161if (abs(player->groundVel) < 0x40000) {162if (self->playerPtrs[player->playerID])163PathInverter_HandlePathSwitch(player);164}165else {166bool32 noInteractions = false;167if (player->velocity.x <= 0)168noInteractions = player->position.x <= self->position.x + 0x80000;169else170noInteractions = player->position.x >= self->position.x - 0x80000;171172if (noInteractions)173self->playerPtrs[player->playerID] = NULL;174else175PathInverter_HandlePathSwitch(player);176}177}178}179}180}181}182void PathInverter_State_Vertical(void)183{184// Nothing !185}186187#if GAME_INCLUDE_EDITOR188void PathInverter_EditorDraw(void)189{190RSDK_THIS(PathInverter);191RSDK.SetSpriteAnimation(PathInverter->aniFrames, self->type, &self->animator, true, 0);192193PathInverter_Draw();194}195196void PathInverter_EditorLoad(void)197{198PathInverter->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/PathInverter.bin", SCOPE_STAGE);199200RSDK_ACTIVE_VAR(PathInverter, type);201RSDK_ENUM_VAR("Horizontal", PATHINVERTER_H);202RSDK_ENUM_VAR("Vertical (Unused)", PATHINVERTER_V);203}204#endif205206void PathInverter_Serialize(void) { RSDK_EDITABLE_VAR(PathInverter, VAR_UINT8, type); }207208209