Path: blob/master/SonicMania/Objects/SBZ/Bomb.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Bomb Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectBomb *Bomb = NULL;1011void Bomb_Update(void)12{13RSDK_THIS(Bomb);14StateMachine_Run(self->state);15}1617void Bomb_LateUpdate(void) {}1819void Bomb_StaticUpdate(void) {}2021void Bomb_Draw(void)22{23RSDK_THIS(Bomb);24Vector2 drawPos;2526if (self->state == Bomb_State_Explode) {27drawPos.x = self->position.x;28drawPos.y = self->fuseOffset + self->position.y;29RSDK.DrawSprite(&self->fuseAnimator, &drawPos, false);30}31RSDK.DrawSprite(&self->mainAnimator, NULL, false);32}3334void Bomb_Create(void *data)35{36RSDK_THIS(Bomb);3738self->visible = true;39if (self->planeFilter > 0 && (((uint8)self->planeFilter - 1) & 2))40self->drawGroup = Zone->objectDrawGroup[1];41else42self->drawGroup = Zone->objectDrawGroup[0];43self->active = ACTIVE_BOUNDS;44self->updateRange.x = 0x800000;45self->updateRange.y = 0x800000;46if (data) {47RSDK.SetSpriteAnimation(Bomb->aniFrames, 4, &self->mainAnimator, true, 0);48self->state = Bomb_State_Shrapnel;49}50else {51self->startDir = self->direction;52self->startPos = self->position;53if (self->direction == FLIP_NONE)54self->velocity.x = -0x1000;55else56self->velocity.x = 0x1000;57self->drawFX |= FX_FLIP;58self->timer = 1536;59RSDK.SetSpriteAnimation(Bomb->aniFrames, 1, &self->mainAnimator, true, 0);60RSDK.SetSpriteAnimation(Bomb->aniFrames, 3, &self->fuseAnimator, true, 0);61self->state = Bomb_State_Init;62}63}6465void Bomb_StageLoad(void)66{67if (RSDK.CheckSceneFolder("MMZ"))68Bomb->aniFrames = RSDK.LoadSpriteAnimation("MMZ/Bomb.bin", SCOPE_STAGE);6970Bomb->hitboxHurt.left = -12;71Bomb->hitboxHurt.top = -18;72Bomb->hitboxHurt.right = 12;73Bomb->hitboxHurt.bottom = 18;7475Bomb->hitboxRange.left = -96;76Bomb->hitboxRange.top = -96;77Bomb->hitboxRange.right = 96;78Bomb->hitboxRange.bottom = 96;7980Bomb->hitboxShrapnel.left = -6;81Bomb->hitboxShrapnel.top = -6;82Bomb->hitboxShrapnel.right = 6;83Bomb->hitboxShrapnel.bottom = 6;8485Bomb->sfxExplosion = RSDK.GetSfx("Stage/Explosion.wav");8687DEBUGMODE_ADD_OBJ(Bomb);88}8990void Bomb_DebugSpawn(void)91{92RSDK_THIS(Bomb);93CREATE_ENTITY(Bomb, NULL, self->position.x, self->position.y);94}9596void Bomb_DebugDraw(void)97{98RSDK.SetSpriteAnimation(Bomb->aniFrames, 0, &DebugMode->animator, true, 0);99RSDK.DrawSprite(&DebugMode->animator, 0, false);100}101102void Bomb_CheckOffScreen(void)103{104RSDK_THIS(Bomb);105106if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {107self->position = self->startPos;108self->direction = self->startDir;109Bomb_Create(NULL);110}111}112113void Bomb_CheckPlayerCollisions(void)114{115RSDK_THIS(Bomb);116117foreach_active(Player, player)118{119if (self->planeFilter <= 0 || player->collisionPlane == ((self->planeFilter - 1) & 1)) {120if (self->state != Bomb_State_Explode) {121if (Player_CheckCollisionTouch(player, self, &Bomb->hitboxRange)) {122RSDK.SetSpriteAnimation(Bomb->aniFrames, 2, &self->mainAnimator, true, 0);123self->timer = 144;124self->state = Bomb_State_Explode;125}126}127if (Player_CheckCollisionTouch(player, self, &Bomb->hitboxHurt)) {128Player_Hurt(player, self);129}130}131}132}133134void Bomb_State_Init(void)135{136RSDK_THIS(Bomb);137138self->active = ACTIVE_NORMAL;139self->state = Bomb_State_Walk;140Bomb_State_Walk();141}142143void Bomb_State_Walk(void)144{145RSDK_THIS(Bomb);146147self->position.x += self->velocity.x;148149if (!--self->timer) {150self->timer = 180;151self->state = Bomb_State_Idle;152}153else {154bool32 groundCollided = false;155if ((self->direction & FLIP_Y)) // RWall??? it should be roof right???156groundCollided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_RWALL, 0, 0, -0x100000, 2);157else158groundCollided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, 2);159160if (!groundCollided) {161self->timer = 180;162RSDK.SetSpriteAnimation(Bomb->aniFrames, 0, &self->mainAnimator, true, 0);163self->state = Bomb_State_Idle;164}165}166167RSDK.ProcessAnimation(&self->mainAnimator);168169Bomb_CheckPlayerCollisions();170Bomb_CheckOffScreen();171}172173void Bomb_State_Idle(void)174{175RSDK_THIS(Bomb);176177if (!--self->timer) {178self->direction ^= FLIP_X;179self->velocity.x = -self->velocity.x;180self->timer = 0x600;181RSDK.SetSpriteAnimation(Bomb->aniFrames, 1, &self->mainAnimator, true, 0);182self->state = Bomb_State_Walk;183}184185RSDK.ProcessAnimation(&self->mainAnimator);186187Bomb_CheckPlayerCollisions();188Bomb_CheckOffScreen();189}190191void Bomb_State_Explode(void)192{193RSDK_THIS(Bomb);194195if ((self->direction & FLIP_Y))196self->fuseOffset -= 0x1000;197else198self->fuseOffset += 0x1000;199200if (--self->timer > 0) {201RSDK.ProcessAnimation(&self->mainAnimator);202RSDK.ProcessAnimation(&self->fuseAnimator);203Bomb_CheckPlayerCollisions();204Bomb_CheckOffScreen();205}206else {207RSDK.PlaySfx(Bomb->sfxExplosion, false, 255);208EntityBomb *debris = CREATE_ENTITY(Bomb, INT_TO_VOID(true), self->position.x, self->position.y);209debris->velocity.x = -0x20000;210debris->velocity.y = -0x30000;211debris->planeFilter = self->planeFilter;212debris->drawGroup = self->drawGroup;213214debris = CREATE_ENTITY(Bomb, INT_TO_VOID(true), self->position.x, self->position.y);215debris->velocity.x = -0x10000;216debris->velocity.y = -0x20000;217debris->planeFilter = self->planeFilter;218debris->drawGroup = self->drawGroup;219220debris = CREATE_ENTITY(Bomb, INT_TO_VOID(true), self->position.x, self->position.y);221debris->velocity.x = 0x20000;222debris->velocity.y = -0x30000;223debris->planeFilter = self->planeFilter;224debris->drawGroup = self->drawGroup;225226debris = CREATE_ENTITY(Bomb, INT_TO_VOID(true), self->position.x, self->position.y);227debris->velocity.x = 0x10000;228debris->velocity.y = -0x20000;229debris->planeFilter = self->planeFilter;230debris->drawGroup = self->drawGroup;231232EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y);233explosion->planeFilter = self->planeFilter;234explosion->drawGroup = self->drawGroup + 1;235236destroyEntity(self);237}238}239240void Bomb_State_Shrapnel(void)241{242RSDK_THIS(Bomb);243244self->position.x += self->velocity.x;245self->position.y += self->velocity.y;246self->velocity.y += 0x1800;247if (RSDK.CheckOnScreen(self, &self->updateRange)) {248RSDK.ProcessAnimation(&self->mainAnimator);249250foreach_active(Player, player)251{252if (self->planeFilter <= 0 || player->collisionPlane == ((self->planeFilter - 1) & 1)) {253if (Player_CheckCollisionTouch(player, self, &Bomb->hitboxShrapnel)) {254Player_ProjectileHurt(player, self);255}256}257}258}259else {260destroyEntity(self);261}262}263264#if GAME_INCLUDE_EDITOR265void Bomb_EditorDraw(void) { Bomb_Draw(); }266267void Bomb_EditorLoad(void)268{269Bomb->aniFrames = RSDK.LoadSpriteAnimation("MMZ/Bomb.bin", SCOPE_STAGE);270271RSDK_ACTIVE_VAR(Bomb, planeFilter);272RSDK_ENUM_VAR("None", PLANEFILTER_NONE);273RSDK_ENUM_VAR("AL", PLANEFILTER_AL);274RSDK_ENUM_VAR("BL", PLANEFILTER_BL);275RSDK_ENUM_VAR("AH", PLANEFILTER_AH);276RSDK_ENUM_VAR("BH", PLANEFILTER_BH);277278RSDK_ACTIVE_VAR(Bomb, direction);279RSDK_ENUM_VAR("Left", FLIP_NONE);280RSDK_ENUM_VAR("Right", FLIP_X);281RSDK_ENUM_VAR("Left (Flip Y)", FLIP_Y);282RSDK_ENUM_VAR("Right (Flip Y)", FLIP_XY);283}284#endif285286void Bomb_Serialize(void)287{288RSDK_EDITABLE_VAR(Bomb, VAR_UINT8, direction);289RSDK_EDITABLE_VAR(Bomb, VAR_ENUM, planeFilter);290}291292293