Path: blob/master/SonicMania/Objects/SPZ/CircleBumper.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: CircleBumper Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectCircleBumper *CircleBumper;1011void CircleBumper_Update(void)12{13RSDK_THIS(CircleBumper);1415StateMachine_Run(self->stateMove);1617StateMachine_Run(self->stateCollide);18}1920void CircleBumper_LateUpdate(void) {}2122void CircleBumper_StaticUpdate(void) {}2324void CircleBumper_Draw(void)25{26RSDK_THIS(CircleBumper);2728RSDK.DrawSprite(&self->animator, &self->drawPos, false);29}3031void CircleBumper_Create(void *data)32{33RSDK_THIS(CircleBumper);3435self->visible = true;36self->drawGroup = Zone->objectDrawGroup[1];37self->drawPos = self->position;38self->active = ACTIVE_BOUNDS;39self->amplitude.x >>= 10;40self->amplitude.y >>= 10;4142switch (self->type) {43default:44case CIRCLEBUMPER_FIXED:45self->updateRange.x = 0x400000;46self->updateRange.y = 0x400000;47RSDK.SetSpriteAnimation(CircleBumper->aniFrames, 0, &self->animator, true, 0);48self->stateMove = CircleBumper_Move_Fixed;49break;5051case CIRCLEBUMPER_LINEAR:52self->updateRange.x = (abs(self->amplitude.x) + 0x1000) << 10;53self->updateRange.y = (abs(self->amplitude.y) + 0x1000) << 10;54self->stateMove = CircleBumper_Move_Linear;55break;5657case CIRCLEBUMPER_CIRCLE:58self->updateRange.x = (abs(self->amplitude.x) + 0x1000) << 10;59self->updateRange.y = (abs(self->amplitude.y) + 0x1000) << 10;60RSDK.SetSpriteAnimation(CircleBumper->aniFrames, 0, &self->animator, true, 0);61self->stateMove = CircleBumper_Move_Circular;62break;6364case CIRCLEBUMPER_TRACK:65self->updateRange.x = (abs(self->amplitude.x) + 0x2000) << 9;66self->updateRange.y = (abs(self->amplitude.y) + 0x2000) << 9;67self->stateMove = CircleBumper_Move_Track;68break;6970case CIRCLEBUMPER_PATH:71self->updateRange.x = 0x400000;72self->updateRange.y = 0x400000;73self->active = ACTIVE_NEVER;74self->stateMove = CircleBumper_Move_Path;75break;76}7778RSDK.SetSpriteAnimation(CircleBumper->aniFrames, 0, &self->animator, true, 0);79self->stateCollide = CircleBumper_Collide_Normal;80if (!self->hitCount)81self->hitCount = 5;82}8384void CircleBumper_StageLoad(void)85{86if (RSDK.CheckSceneFolder("SPZ1"))87CircleBumper->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/CircleBumper.bin", SCOPE_STAGE);88else if (RSDK.CheckSceneFolder("SPZ2"))89CircleBumper->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/CircleBumper.bin", SCOPE_STAGE);90else if (RSDK.CheckSceneFolder("Blueprint"))91CircleBumper->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/CircleBumper.bin", SCOPE_STAGE);9293CircleBumper->hitboxBumper.left = -7;94CircleBumper->hitboxBumper.top = -6;95CircleBumper->hitboxBumper.right = 7;96CircleBumper->hitboxBumper.bottom = 6;9798CircleBumper->sfxBumper = RSDK.GetSfx("Stage/Bumper.wav");99100DEBUGMODE_ADD_OBJ(CircleBumper);101}102103void CircleBumper_DebugDraw(void)104{105RSDK.SetSpriteAnimation(CircleBumper->aniFrames, 0, &DebugMode->animator, true, 0);106RSDK.DrawSprite(&DebugMode->animator, NULL, false);107}108109void CircleBumper_DebugSpawn(void)110{111RSDK_THIS(DebugMode);112113CREATE_ENTITY(CircleBumper, NULL, self->position.x, self->position.y);114}115116void CircleBumper_CheckPlayerCollisions(void)117{118RSDK_THIS(CircleBumper);119120int32 storeX = self->position.x;121int32 storeY = self->position.y;122123self->position.x = self->drawPos.x;124self->position.y = self->drawPos.y;125foreach_active(Player, player)126{127if (player->animator.animationID != ANI_HURT && Player_CheckBadnikTouch(player, self, &CircleBumper->hitboxBumper)) {128self->animator.frameID = 0;129self->stateCollide = CircleBumper_Collide_Bumped;130RSDK.PlaySfx(CircleBumper->sfxBumper, false, 0xFF);131self->active = ACTIVE_NORMAL;132133int32 angle = RSDK.ATan2(player->position.x - self->position.x, player->position.y - self->position.y);134int32 xVel = 0x700 * RSDK.Cos256(angle);135int32 yVel = 0x700 * RSDK.Sin256(angle);136if (player->state == Player_State_FlyCarried)137RSDK_GET_ENTITY(SLOT_PLAYER2, Player)->flyCarryTimer = 30;138139#if MANIA_USE_PLUS140if (player->state == Player_State_MightyHammerDrop) {141RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);142}143else {144#endif145int32 anim = player->animator.animationID;146if (anim != ANI_FLY && anim != ANI_FLY_LIFT_TIRED && player->state != Player_State_TailsFlight) {147if (player->state != Player_State_DropDash)148player->state = Player_State_Air;149if (anim != ANI_JUMP && anim != ANI_JOG && anim != ANI_RUN && anim != ANI_DASH)150player->animator.animationID = ANI_WALK;151}152#if MANIA_USE_PLUS153}154#endif155if (player->animator.animationID != ANI_FLY) {156player->velocity.x = xVel;157player->groundVel = xVel;158player->applyJumpCap = false;159}160161player->velocity.y = yVel;162player->onGround = false;163player->tileCollisions = TILECOLLISION_DOWN;164165if (self->hitCount) {166EntityScoreBonus *bonus = CREATE_ENTITY(ScoreBonus, NULL, self->position.x, self->position.y);167bonus->animator.frameID = 16;168Player_GiveScore(player, 10);169--self->hitCount;170}171}172}173174self->position.x = storeX;175self->position.y = storeY;176}177178void CircleBumper_Collide_Normal(void) { CircleBumper_CheckPlayerCollisions(); }179180void CircleBumper_Collide_Bumped(void)181{182RSDK_THIS(CircleBumper);183184CircleBumper_CheckPlayerCollisions();185186RSDK.ProcessAnimation(&self->animator);187188if (self->animator.frameID == self->animator.frameCount - 1) {189self->animator.frameID = 0;190self->active = ACTIVE_BOUNDS;191self->stateCollide = CircleBumper_Collide_Normal;192}193}194195void CircleBumper_Move_Fixed(void)196{197RSDK_THIS(CircleBumper);198199self->drawPos.x = self->position.x;200self->drawPos.y = self->position.y;201}202203void CircleBumper_Move_Linear(void)204{205RSDK_THIS(CircleBumper);206207self->drawPos.x = self->position.x + self->amplitude.x * RSDK.Sin1024(self->speed * Zone->timer);208self->drawPos.y = self->position.y + self->amplitude.y * RSDK.Sin1024(self->speed * Zone->timer);209}210211void CircleBumper_Move_Circular(void)212{213RSDK_THIS(CircleBumper);214215self->drawPos.x = self->position.x + self->amplitude.x * RSDK.Cos1024(self->speed * Zone->timer + 4 * self->angle);216self->drawPos.y = self->position.y + self->amplitude.y * RSDK.Sin1024(self->speed * Zone->timer + 4 * self->angle);217}218219void CircleBumper_Move_Path(void)220{221RSDK_THIS(CircleBumper);222223self->drawPos.x += self->velocity.x;224self->drawPos.y += self->velocity.y;225Entity *node = RSDK_GET_ENTITY_GEN(self->speed);226227if (self->velocity.x <= 0) {228if (self->drawPos.x < node->position.x)229self->drawPos.x = node->position.x;230}231else if (self->drawPos.x > node->position.x) {232self->drawPos.x = node->position.x;233}234235if (self->velocity.y <= 0) {236if (self->drawPos.y < node->position.y)237self->drawPos.y = node->position.y;238}239else if (self->drawPos.y > node->position.y) {240self->drawPos.y = node->position.y;241}242}243244void CircleBumper_Move_Track(void)245{246RSDK_THIS(CircleBumper);247248int32 timer = Zone->timer << 7;249if (((timer >> 16) & 1) == self->direction) {250self->drawPos.x = self->position.x + (timer * self->amplitude.x >> 6) - (self->amplitude.x << 15);251self->drawPos.y = self->position.y + (timer * self->amplitude.y >> 6) - (self->amplitude.y << 15);252}253else {254self->drawPos.x = self->position.x + (self->amplitude.x << 15) - (timer * self->amplitude.x >> 6);255self->drawPos.y = self->position.y + (self->amplitude.y << 15) - (timer * self->amplitude.y >> 6);256}257}258259#if GAME_INCLUDE_EDITOR260void CircleBumper_EditorDraw(void)261{262RSDK_THIS(CircleBumper);263264Vector2 amplitude;265amplitude.x = self->amplitude.x >> 10;266amplitude.y = self->amplitude.y >> 10;267switch (self->type) {268default:269case CIRCLEBUMPER_FIXED:270self->updateRange.x = 0x400000;271self->updateRange.y = 0x400000;272break;273274case CIRCLEBUMPER_LINEAR:275self->updateRange.x = (abs(amplitude.x) + 0x1000) << 10;276self->updateRange.y = (abs(amplitude.y) + 0x1000) << 10;277break;278279case CIRCLEBUMPER_CIRCLE:280self->updateRange.x = (abs(amplitude.x) + 0x1000) << 10;281self->updateRange.y = (abs(amplitude.y) + 0x1000) << 10;282break;283284case CIRCLEBUMPER_TRACK:285self->updateRange.x = (abs(amplitude.x) + 0x2000) << 9;286self->updateRange.y = (abs(amplitude.y) + 0x2000) << 9;287break;288289case CIRCLEBUMPER_PATH:290self->updateRange.x = 0x400000;291self->updateRange.y = 0x400000;292break;293}294295RSDK.SetSpriteAnimation(CircleBumper->aniFrames, 0, &self->animator, true, 0);296self->drawPos = self->position;297298CircleBumper_Draw();299300if (showGizmos()) {301RSDK_DRAWING_OVERLAY(true);302303Vector2 pos;304switch (self->type) {305case CIRCLEBUMPER_LINEAR:306self->updateRange.x = (abs(amplitude.x) + 0x1000) << 10;307self->updateRange.y = (abs(amplitude.y) + 0x1000) << 10;308309// draw distance previews310self->inkEffect = INK_BLEND;311self->drawPos.x = amplitude.x * RSDK.Sin1024(0x100) + self->position.x;312self->drawPos.y = amplitude.y * RSDK.Sin1024(0x100) + self->position.y;313pos = self->drawPos;314CircleBumper_Draw();315316self->drawPos.x = amplitude.x * RSDK.Sin1024(0x300) + self->position.x;317self->drawPos.y = amplitude.y * RSDK.Sin1024(0x300) + self->position.y;318CircleBumper_Draw();319320RSDK.DrawLine(pos.x, pos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, 0, INK_NONE, false);321break;322323case CIRCLEBUMPER_CIRCLE:324self->updateRange.x = (abs(amplitude.x) + 0x1000) << 10;325self->updateRange.y = (abs(amplitude.y) + 0x1000) << 10;326327// draw distance preview328self->inkEffect = INK_BLEND;329self->drawPos.x = amplitude.x * RSDK.Cos1024(4 * self->angle) + self->position.x;330self->drawPos.y = amplitude.y * RSDK.Sin1024(4 * self->angle) + self->position.y;331332CircleBumper_Draw();333break;334335case CIRCLEBUMPER_TRACK:336self->updateRange.x = (abs(amplitude.x) + 0x2000) << 9;337self->updateRange.y = (abs(amplitude.y) + 0x2000) << 9;338339// draw distance preview340self->inkEffect = INK_BLEND;341342// draw distance previews343self->inkEffect = INK_BLEND;344self->drawPos.x = self->position.x + (0x100 * amplitude.x >> 6) - (amplitude.x << 15);345self->drawPos.y = self->position.y + (0x100 * amplitude.y >> 6) - (amplitude.y << 15);346pos = self->drawPos;347CircleBumper_Draw();348349self->drawPos.x = self->position.x + (amplitude.x << 15) - (0x000 * amplitude.x >> 6);350self->drawPos.y = self->position.y + (amplitude.y << 15) - (0x000 * amplitude.y >> 6);351CircleBumper_Draw();352353RSDK.DrawLine(pos.x, pos.y, self->drawPos.x, self->drawPos.y, 0x00FF00, 0x00, INK_NONE, false);354break;355356case CIRCLEBUMPER_PATH: {357Entity *target = RSDK_GET_ENTITY_GEN(self->speed);358359if (target)360DrawHelpers_DrawArrow(self->position.x, self->position.y, target->position.x, target->position.y, 0x00FF00, INK_NONE, 0xFF);361break;362}363364default:365case CIRCLEBUMPER_FIXED:366// nothin'367break;368}369370self->inkEffect = INK_NONE;371RSDK_DRAWING_OVERLAY(false);372}373}374375void CircleBumper_EditorLoad(void)376{377if (RSDK.CheckSceneFolder("SPZ1"))378CircleBumper->aniFrames = RSDK.LoadSpriteAnimation("SPZ1/CircleBumper.bin", SCOPE_STAGE);379else if (RSDK.CheckSceneFolder("SPZ2"))380CircleBumper->aniFrames = RSDK.LoadSpriteAnimation("SPZ2/CircleBumper.bin", SCOPE_STAGE);381else if (RSDK.CheckSceneFolder("Blueprint"))382CircleBumper->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/CircleBumper.bin", SCOPE_STAGE);383384RSDK_ACTIVE_VAR(CircleBumper, type);385RSDK_ENUM_VAR("Fixed", CIRCLEBUMPER_FIXED);386RSDK_ENUM_VAR("Linear", CIRCLEBUMPER_LINEAR);387RSDK_ENUM_VAR("Circle", CIRCLEBUMPER_CIRCLE);388RSDK_ENUM_VAR("Track", CIRCLEBUMPER_TRACK);389RSDK_ENUM_VAR("Path", CIRCLEBUMPER_PATH);390}391#endif392393void CircleBumper_Serialize(void)394{395RSDK_EDITABLE_VAR(CircleBumper, VAR_ENUM, hitCount);396RSDK_EDITABLE_VAR(CircleBumper, VAR_ENUM, type);397RSDK_EDITABLE_VAR(CircleBumper, VAR_VECTOR2, amplitude);398RSDK_EDITABLE_VAR(CircleBumper, VAR_ENUM, speed);399RSDK_EDITABLE_VAR(CircleBumper, VAR_INT32, angle);400}401402403