Path: blob/master/SonicMania/Objects/SPZ/Funnel.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Funnel Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectFunnel *Funnel;1011void Funnel_Update(void)12{13RSDK_THIS(Funnel);1415for (int32 p = 0; p < Player->playerCount; ++p) {16if (!self->playerTimers[p]) {17EntityPlayer *player = RSDK_GET_ENTITY(p, Player);1819if ((1 << p) & self->activePlayers) {20if (!Player_CheckValidState(player)) {21self->activePlayers &= ~(1 << p);22if (!self->activePlayers)23RSDK.StopSfx(Funnel->sfxFunnel);24}25else {26if (Player_CheckValidState(player) && player->state == Player_State_Static) {27if (player->sidekick == false && ++self->playerScoreTimer[p] >= 30) {28self->playerScoreTimer[p] = 0;29EntityScoreBonus *bonus = CREATE_ENTITY(ScoreBonus, NULL, self->position.x, self->position.y - 0x180000);30bonus->drawGroup = Zone->objectDrawGroup[1];31bonus->animator.frameID = 0;32Player_GiveScore(player, 100);33}3435self->playerYVel[p] += 64 + (self->playerYVel[p] >> 8);3637int32 distX = MAX(((self->position.y - player->position.y) >> 8) - 0xA00, 0x400);3839player->position.x = distX * RSDK.Cos256(self->playerAngle[p]) + self->position.x;40self->playerAngle[p] -= self->playerXVel[p] >> 16;4142if (self->playerXVel[p] <= 0)43self->playerXVel[p] = self->playerXVel[p] - self->playerYVel[p] - 128;44else45self->playerXVel[p] = self->playerXVel[p] + self->playerYVel[p] + 128;4647if (player->position.y >= self->position.y) {48player->scale.x = 0x200;49player->scale.y = 0x200;50}51else {52player->drawFX |= FX_SCALE;53player->scale.x = ((((player->position.y - self->position.y) >> 16) * RSDK.Sin256(self->playerAngle[p])) >> 7) + 0x200;54player->scale.y = player->scale.x;55}5657player->velocity.y += (self->playerYVel[p] >> 5) + 64;58if (player->position.y > self->position.y + 0x140000) {59self->activePlayers &= ~(1 << p);60player->drawFX &= ~FX_SCALE;61player->interaction = true;62player->tileCollisions = TILECOLLISION_DOWN;63player->scale.x = 0x200;64player->scale.y = 0x200;65player->position.x = self->position.x;66player->velocity.x = 0;67self->playerTimers[p] = 32;6869if (player->camera)70player->scrollDelay = 1;7172if (!self->activePlayers)73RSDK.StopSfx(Funnel->sfxFunnel);7475Camera->centerBounds.y = 0x20000;76player->state = Player_State_Air;77}78}79else {80self->activePlayers &= ~(1 << p);81player->drawFX &= ~FX_SCALE;82player->interaction = true;83player->tileCollisions = TILECOLLISION_DOWN;84player->scale.x = 0x200;85player->scale.y = 0x200;86player->position.x = self->position.x;87player->velocity.x = 0;88self->playerTimers[p] = 32;8990if (player->camera)91player->scrollDelay = 1;9293if (!self->activePlayers)94RSDK.StopSfx(Funnel->sfxFunnel);9596Camera->centerBounds.y = 0x20000;97player->state = Player_State_Air;98}99}100}101else {102if (Player_CheckValidState(player) && Player_CheckCollisionTouch(player, self, &Funnel->hitboxFunnel)) {103104int32 dy = 0;105int32 distY = (self->position.y - player->position.y) >> 16;106if (distY - 10 >= 0)107dy = distY - 10;108109int32 distX = abs(player->position.x - self->position.x) >> 16;110if ((distX <= dy && player->position.y < self->position.y) || (player->position.y < self->position.y - 0x280000 && distX <= 64)) {111if (player->camera) {112player->scrollDelay = 0;113Camera_SetupLerp(CAMERA_LERP_SIN1024_2, p, self->position.x, self->position.y - 0x400000, 8);114}115116if (abs(player->velocity.y) > abs(player->velocity.x)) {117if (player->position.x >= self->position.x)118player->velocity.x -= (player->velocity.y >> 1);119else120player->velocity.x += (player->velocity.y >> 1);121122player->velocity.y >>= 2;123}124125self->playerXVel[p] = CLAMP(player->velocity.x, -0x100000, 0x100000);126127int32 x = ((player->position.x - self->position.x) >> 16) * ((player->position.x - self->position.x) >> 16);128int32 y = dy * dy - x;129if (player->position.x < self->position.x)130x = -x;131132self->playerAngle[p] = RSDK.ATan2(x, y);133134player->velocity.y -= abs(9 * (player->velocity.x >> 4));135player->velocity.y = CLAMP(player->velocity.y, 0x1000, 0x10000);136137#if MANIA_USE_PLUS138if (player->state == Player_State_MightyHammerDrop)139player->velocity.y = 0x80000;140else141#endif142RSDK.PlaySfx(Funnel->sfxFunnel, false, 0xFF);143144player->velocity.x = 0;145self->playerScoreTimer[p] = 0;146self->playerYVel[p] = 0;147self->activePlayers |= 1 << p;148RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);149150player->interaction = false;151player->tileCollisions = TILECOLLISION_NONE;152player->state = Player_State_Static;153player->nextGroundState = StateMachine_None;154player->nextAirState = StateMachine_None;155}156else if (player->velocity.y <= 0x10000) {157int32 max = 0;158if (player->position.y >= self->position.y) {159max = 28;160}161else {162max = 0;163if (distY >= 0)164max = (self->position.y - player->position.y) >> 16;165max += 40;166}167168if (distX < max) {169int32 x = RSDK.Rand(0x20000, MAX(abs(player->velocity.y + player->velocity.x) >> 8, 0x4000));170int32 y = x;171if (player->position.y >= self->position.y + 0x160000) {172x = player->velocity.x;173}174else {175if (player->position.y < self->position.y && player->velocity.y > 0)176continue;177178if (player->position.x >= self->position.x) {179if (player->velocity.x > 0 && player->position.y >= self->position.y)180continue;181}182else {183if (player->velocity.x < 0 && player->position.y >= self->position.y)184continue;185x = -x;186}187}188189if (player->position.y < self->position.y || player->position.y > self->position.y + 0x160000) {190if (player->velocity.y > 0)191continue;192}193else {194y = player->velocity.y;195}196197if (player->animator.animationID != ANI_FLY) {198player->velocity.x = x;199player->groundVel = x;200}201202player->velocity.y = y;203player->onGround = false;204player->applyJumpCap = false;205RSDK.PlaySfx(Funnel->sfxPimPom, false, 0xFF);206}207}208else {209int32 max = 0;210if (player->position.y >= self->position.y) {211max = 28;212}213else {214max = 0;215if (distY >= 0)216max = (self->position.y - player->position.y) >> 16;217max += 40;218}219220if (distX < max) {221int32 x = RSDK.Rand(0x20000, MAX(abs(player->velocity.y + player->velocity.x) >> 8, 0x4000));222int32 y = x;223if (player->position.y >= self->position.y + 0x160000) {224x = player->velocity.x;225x = -x;226}227else {228if (player->position.y < self->position.y && player->velocity.y > 0)229continue;230else if (player->position.x < self->position.x) {231if (player->velocity.x < 0 && player->position.y >= self->position.y)232continue;233}234else if (player->velocity.x > 0 && player->position.y >= self->position.y)235continue;236else237x = -x;238}239240if (player->position.y < self->position.y || player->position.y > self->position.y + 0x160000) {241if (player->velocity.y > 0)242continue;243y = -y;244}245else {246y = player->velocity.y;247}248249if (player->animator.animationID != ANI_FLY) {250player->velocity.x = x;251player->groundVel = x;252}253254player->velocity.y = y;255player->onGround = false;256player->applyJumpCap = false;257RSDK.PlaySfx(Funnel->sfxPimPom, false, 0xFF);258}259}260}261}262}263else {264self->playerTimers[p]--;265}266}267}268269void Funnel_LateUpdate(void) {}270271void Funnel_StaticUpdate(void)272{273foreach_all(Funnel, funnel) { RSDK.AddDrawListRef(Zone->objectDrawGroup[0], RSDK.GetEntitySlot(funnel)); }274}275276void Funnel_Draw(void)277{278RSDK_THIS(Funnel);279280self->animator.frameID = SceneInfo->currentDrawGroup == self->drawGroup;281RSDK.DrawSprite(&self->animator, NULL, false);282}283284void Funnel_Create(void *data)285{286RSDK_THIS(Funnel);287288RSDK.SetSpriteAnimation(Funnel->aniFrames, 0, &self->animator, true, 0);289290if (!SceneInfo->inEditor) {291self->active = ACTIVE_BOUNDS;292self->updateRange.x = 0x1000000;293self->updateRange.y = 0x1000000;294self->visible = true;295self->drawGroup = Zone->objectDrawGroup[1] + 1;296self->state = Funnel_State_None;297}298}299300void Funnel_StageLoad(void)301{302Funnel->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/Funnel.bin", SCOPE_STAGE);303304Funnel->hitboxFunnel.left = -64;305Funnel->hitboxFunnel.top = -48;306Funnel->hitboxFunnel.right = 64;307Funnel->hitboxFunnel.bottom = 0;308309Funnel->active = ACTIVE_ALWAYS;310311Funnel->sfxFunnel = RSDK.GetSfx("SPZ/Funnel.wav");312Funnel->sfxPimPom = RSDK.GetSfx("Stage/PimPom.wav");313}314315void Funnel_State_None(void)316{317// this is never used actually LOL318}319320#if GAME_INCLUDE_EDITOR321void Funnel_EditorDraw(void)322{323RSDK_THIS(Funnel);324325self->animator.frameID = 1;326RSDK.DrawSprite(&self->animator, NULL, false);327328self->animator.frameID = 0;329RSDK.DrawSprite(&self->animator, NULL, false);330}331332void Funnel_EditorLoad(void) { Funnel->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/Funnel.bin", SCOPE_STAGE); }333#endif334335void Funnel_Serialize(void) {}336337338