Path: blob/master/SonicMania/Objects/HCZ/TwistingSlide.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: TwistingSlide Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectTwistingSlide *TwistingSlide;1011void TwistingSlide_Update(void)12{13RSDK_THIS(TwistingSlide);14foreach_active(Player, player)15{16int32 playerID = RSDK.GetEntitySlot(player);1718int32 storeX = player->position.x;19int32 storeY = player->position.y;2021if (player->state != Player_State_Static)22self->activePlayers &= ~(1 << playerID);2324if (!Player_CheckCollisionTouch(player, self, &self->hitboxSlide) || (player->position.y < self->minY) || player->position.y > self->maxY) {25self->activePlayers &= ~(1 << playerID);26}27else if (self->direction) {28switch (self->type) {29case TWISTINGSLIDE_START:30if (player->state == Player_State_Static) {31if (!((1 << playerID) & self->activePlayers)) {32self->playerAngles[playerID] = (player->position.y - self->position.y + 0x4A0000) >> 16;33self->activePlayers |= 1 << playerID;34}3536int32 angle = 221 * self->playerAngles[playerID];37if (221 * self->playerAngles[playerID] >= 0x3FC0)38angle = 170 * self->playerAngles[playerID];3940player->position.x = 0x2800 * RSDK.Cos256((angle >> 8) + 0xC0) + self->position.x;41player->position.y = self->position.y + ((self->playerAngles[playerID] - 74) << 16);4243if (player->groundVel > 0 && Player_CheckCollisionTouch(player, self, &self->hitboxSlideStart)) {44self->activePlayers &= ~(1 << playerID);45player->state = Player_State_Roll;46player->collisionMode = CMODE_ROOF;47player->tileCollisions = TILECOLLISION_DOWN;48player->angle = 144;49}50}51else if (!((1 << playerID) & self->activePlayers) && player->onGround && player->groundVel < 0) {52if (Player_CheckCollisionTouch(player, self, &self->hitboxSlideStart)) {53player->tileCollisions = TILECOLLISION_NONE;54player->state = Player_State_Static;55player->velocity.x = 0;56player->velocity.y = 0;57RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);58self->playerAngles[playerID] = (player->position.y - self->position.y + 0x4A0000) >> 16;59self->activePlayers |= (1 << playerID);60}61}62break;6364case TWISTINGSLIDE_STRIP:65if (player->state == Player_State_Static) {66if (!((1 << playerID) & self->activePlayers)) {67self->playerAngles[playerID] = (0xC00000 + player->position.y - self->position.y) >> 16;68self->activePlayers |= 1 << playerID;69}70player->position.x = 0x800000 + self->position.x - 0xAA00 * self->playerAngles[playerID];71player->position.y = self->position.y + ((self->playerAngles[playerID] - 0xC0) << 16);72}73break;7475case TWISTINGSLIDE_TWIST:76if (player->state == Player_State_Static) {77if (!((1 << playerID) & self->activePlayers)) {78self->playerAngles[playerID] = (0xC00000 + player->position.y - self->position.y) >> 16;79self->activePlayers |= 1 << playerID;80}81player->position.x = self->position.x + 0x2800 * RSDK.Cos256(((170 * self->playerAngles[playerID]) >> 8) + 0x40);82player->position.y = self->position.y + ((self->playerAngles[playerID] - 0xC0) << 16);83}84break;8586case TWISTINGSLIDE_END:87if (player->state == Player_State_Static) {88if (!((1 << playerID) & self->activePlayers)) {89self->playerAngles[playerID] = (player->position.y + (self->endLen << 15) - self->position.y) >> 16;90self->activePlayers |= 1 << playerID;91}92player->position.x = self->position.x + ((self->endLen / 3) << 16) - 0xAA00 * self->playerAngles[playerID];93player->position.y = self->position.y + (self->playerAngles[playerID] << 16) - (self->endLen << 15);94if (player->groundVel < 0 && Player_CheckCollisionTouch(player, self, &self->hitboxSlideEnd)) {95self->activePlayers &= ~(1 << playerID);96player->state = Player_State_Roll;97player->collisionMode = CMODE_RWALL;98player->tileCollisions = TILECOLLISION_DOWN;99player->angle = 216;100}101}102else if (!((1 << playerID) & self->activePlayers) && player->onGround && player->groundVel > 0103&& Player_CheckCollisionTouch(player, self, &self->hitboxSlideEnd)) {104player->tileCollisions = TILECOLLISION_NONE;105player->state = Player_State_Static;106player->velocity.x = 0;107player->velocity.y = 0;108RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);109self->playerAngles[playerID] = (player->position.y + (self->endLen << 15) - self->position.y) >> 16;110self->activePlayers |= (1 << playerID);111}112break;113114default: break;115}116}117else {118switch (self->type) {119case TWISTINGSLIDE_START:120if (player->state == Player_State_Static) {121if (!((1 << playerID) & self->activePlayers)) {122self->playerAngles[playerID] = (player->position.y - self->position.y + 0x4A0000) >> 16;123self->activePlayers |= 1 << playerID;124}125126int32 angle = 221 * self->playerAngles[playerID];127if (221 * self->playerAngles[playerID] >= 0x3FC0)128angle = 170 * self->playerAngles[playerID];129130player->position.x = self->position.x - 0x2800 * RSDK.Cos256((angle >> 8) + 0xC0);131player->position.y = self->position.y + ((self->playerAngles[playerID] - 74) << 16);132if (player->groundVel < 0 && Player_CheckCollisionTouch(player, self, &self->hitboxSlideStart)) {133self->activePlayers &= ~(1 << playerID);134player->state = Player_State_Roll;135player->collisionMode = CMODE_ROOF;136player->tileCollisions = TILECOLLISION_DOWN;137player->angle = 0x70;138}139}140else if (!((1 << playerID) & self->activePlayers) && player->onGround && player->groundVel > 0) {141if (Player_CheckCollisionTouch(player, self, &self->hitboxSlideStart)) {142player->tileCollisions = TILECOLLISION_NONE;143player->state = Player_State_Static;144player->velocity.x = 0;145player->velocity.y = 0;146RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);147self->playerAngles[playerID] = (player->position.y - self->position.y + 0x4A0000) >> 16;148self->activePlayers |= 1 << playerID;149}150}151break;152153case TWISTINGSLIDE_STRIP:154if (player->state == Player_State_Static) {155if (!((1 << playerID) & self->activePlayers)) {156self->playerAngles[playerID] = (0xC00000 + player->position.y - self->position.y) >> 16;157self->activePlayers |= 1 << playerID;158}159160player->position.x = 0xAA00 * self->playerAngles[playerID] + self->position.x - 0x800000;161player->position.y = self->position.y + ((self->playerAngles[playerID] - 0xC0) << 16);162}163break;164165case TWISTINGSLIDE_TWIST:166if (player->state == Player_State_Static) {167if (!((1 << playerID) & self->activePlayers)) {168self->playerAngles[playerID] = (0xC00000 + player->position.y - self->position.y) >> 16;169self->activePlayers |= 1 << playerID;170}171172player->position.x = self->position.x - 0x2800 * RSDK.Cos256(((170 * self->playerAngles[playerID]) >> 8) + 0x40);173player->position.y = self->position.y + ((self->playerAngles[playerID] - 0xC0) << 16);174}175break;176177case TWISTINGSLIDE_END:178if (player->state == Player_State_Static) {179if (!((1 << playerID) & self->activePlayers)) {180self->playerAngles[playerID] = (player->position.y + (self->endLen << 15) - self->position.y) >> 16;181self->activePlayers |= 1 << playerID;182}183184player->position.x = self->position.x + 0xAA00 * self->playerAngles[playerID] - ((self->endLen / 3) << 16);185player->position.y = self->position.y + (self->playerAngles[playerID] << 16) - (self->endLen << 15);186187if (player->groundVel > 0 && Player_CheckCollisionTouch(player, self, &self->hitboxSlideEnd)) {188self->activePlayers &= ~(1 << playerID);189player->state = Player_State_Roll;190player->collisionMode = CMODE_RWALL;191player->tileCollisions = TILECOLLISION_DOWN;192player->angle = 40;193}194}195else if (!((1 << playerID) & self->activePlayers) && player->onGround && player->groundVel < 0196&& Player_CheckCollisionTouch(player, self, &self->hitboxSlideEnd)) {197player->tileCollisions = TILECOLLISION_NONE;198player->state = Player_State_Static;199player->velocity.x = 0;200player->velocity.y = 0;201202RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);203self->playerAngles[playerID] = (player->position.y + (self->endLen << 15) - self->position.y) >> 16;204self->activePlayers |= 1 << playerID;205}206break;207208default: break;209}210}211212if (((1 << playerID) & self->activePlayers)) {213if (self->direction) {214self->playerAngles[playerID] += ((-player->groundVel >> 16) * RSDK.Sin256(40)) >> 8;215216if (player->groundVel <= 0)217player->groundVel -= 20 * RSDK.Cos256(40);218else219player->groundVel -= 80 * RSDK.Cos256(40);220221if (player->groundVel < -0x180000)222player->groundVel = -0x180000;223}224else {225self->playerAngles[playerID] += ((player->groundVel >> 16) * RSDK.Sin256(40)) >> 8;226227if (player->groundVel <= 0)228player->groundVel += 20 * RSDK.Cos256(40);229else230player->groundVel += 80 * RSDK.Cos256(40);231232if (player->groundVel > 0x180000)233player->groundVel = 0x180000;234}235236if (player->characterID == ID_TAILS)237player->animator.speed = 120;238else239player->animator.speed = ((abs(player->groundVel) * 0xF0) / 0x60000) + 0x30;240241if (player->animator.speed > 0xF0)242player->animator.speed = 0xF0;243244int32 x = player->position.x - storeX;245int32 y = player->position.y - storeY;246if (player->position.x != storeX && y) {247if (player->groundVel <= 0) {248x = storeX - player->position.x;249y = storeY - player->position.y;250}251252player->angle = RSDK.ATan2(x, y);253player->rotation = 2 * player->angle;254}255}256}257}258259void TwistingSlide_LateUpdate(void) {}260261void TwistingSlide_StaticUpdate(void) {}262263void TwistingSlide_Draw(void) {}264265void TwistingSlide_Create(void *data)266{267RSDK_THIS(TwistingSlide);268269if (!SceneInfo->inEditor) {270self->active = ACTIVE_BOUNDS;271272switch (self->type) {273case TWISTINGSLIDE_START:274self->updateRange.y = 0x780000;275self->updateRange.x = 0x800000;276self->minY = self->position.y - 0x4A0000;277self->maxY = self->position.y + 0x780000;278break;279280case TWISTINGSLIDE_STRIP:281self->updateRange.x = 0xC00000;282self->updateRange.y = 0xC00000;283self->minY = self->position.y - 0xC00000;284self->maxY = self->position.y + 0xC00000;285break;286287case TWISTINGSLIDE_TWIST:288self->updateRange.y = 0xC00000;289self->updateRange.x = 0x800000;290self->minY = self->position.y - 0xC00000;291self->maxY = self->position.y + 0xC00000;292break;293294case TWISTINGSLIDE_END:295self->minY = self->position.y - (self->endLen << 15);296self->maxY = self->position.y + (self->endLen << 15);297self->updateRange.y = 0xC00000;298self->updateRange.x = 0x800000;299break;300301default: break;302}303304TwistingSlide_SetupHitboxes();305}306}307308void TwistingSlide_StageLoad(void)309{310TwistingSlide->hitbox.left = -1;311TwistingSlide->hitbox.top = 1;312TwistingSlide->hitbox.right = 1;313TwistingSlide->hitbox.bottom = 1;314}315316void TwistingSlide_SetupHitboxes(void)317{318RSDK_THIS(TwistingSlide);319320switch (self->type) {321case TWISTINGSLIDE_START:322self->hitboxSlide.left = -56;323self->hitboxSlide.top = -120;324self->hitboxSlide.right = 52;325self->hitboxSlide.bottom = 120;326327self->hitboxSlideStart.top = -46;328self->hitboxSlideStart.bottom = -38;329self->hitboxSlideStart.left = ((-40 * RSDK.Cos256(48)) >> 8) - 4;330self->hitboxSlideStart.right = ((-40 * RSDK.Cos256(48)) >> 8) + 4;331break;332333case TWISTINGSLIDE_STRIP:334case TWISTINGSLIDE_TWIST:335self->hitboxSlide.left = -132;336self->hitboxSlide.top = -196;337self->hitboxSlide.right = 132;338self->hitboxSlide.bottom = 196;339break;340341case TWISTINGSLIDE_END:342self->hitboxSlide.left = self->endLen / -3;343self->hitboxSlide.top = -(self->endLen >> 1);344self->hitboxSlide.right = self->endLen / 3;345self->hitboxSlide.bottom = self->endLen >> 1;346347self->hitboxSlideEnd.left = self->hitboxSlide.right - 4;348self->hitboxSlideEnd.top = self->hitboxSlide.bottom - 4;349self->hitboxSlideEnd.right = self->hitboxSlide.right + 4;350self->hitboxSlideEnd.bottom = self->hitboxSlide.bottom + 4;351break;352353default: break;354}355}356357#if GAME_INCLUDE_EDITOR358void TwistingSlide_EditorDraw(void)359{360RSDK_THIS(TwistingSlide);361362TwistingSlide_SetupHitboxes();363364if (showGizmos()) {365DrawHelpers_DrawHitboxOutline(self->position.x, self->position.y, &self->hitboxSlideStart, self->direction, 0xFF0000);366DrawHelpers_DrawHitboxOutline(self->position.x, self->position.y, &self->hitboxSlide, self->direction, 0xFF0000);367DrawHelpers_DrawHitboxOutline(self->position.x, self->position.y, &self->hitboxSlideEnd, self->direction, 0xFF0000);368}369}370371void TwistingSlide_EditorLoad(void)372{373374RSDK_ACTIVE_VAR(TwistingSlide, type);375RSDK_ENUM_VAR("Start", TWISTINGSLIDE_START);376RSDK_ENUM_VAR("Long Strip", TWISTINGSLIDE_STRIP);377RSDK_ENUM_VAR("Twist", TWISTINGSLIDE_TWIST);378RSDK_ENUM_VAR("End", TWISTINGSLIDE_END);379380RSDK_ACTIVE_VAR(TwistingSlide, direction);381RSDK_ENUM_VAR("No Flip", FLIP_NONE);382RSDK_ENUM_VAR("Flip X", FLIP_X);383}384#endif385386void TwistingSlide_Serialize(void)387{388RSDK_EDITABLE_VAR(TwistingSlide, VAR_UINT8, type);389RSDK_EDITABLE_VAR(TwistingSlide, VAR_ENUM, endLen);390RSDK_EDITABLE_VAR(TwistingSlide, VAR_UINT8, direction);391}392393394