Path: blob/master/SonicMania/Objects/PGZ/IceBomba.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: IceBomba Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectIceBomba *IceBomba;1011void IceBomba_Update(void)12{13RSDK_THIS(IceBomba);1415StateMachine_Run(self->state);16}1718void IceBomba_LateUpdate(void) {}1920void IceBomba_StaticUpdate(void) {}2122void IceBomba_Draw(void)23{24RSDK_THIS(IceBomba);2526Vector2 drawPos = self->position;27drawPos.x += 0x40000;28drawPos.y += 0x1A0000;2930int32 dirStore = self->direction;31self->direction = FLIP_NONE;32RSDK.DrawSprite(&self->bombAnimator, &drawPos, false);33RSDK.DrawSprite(&self->bodyAnimator, NULL, false);3435self->direction = dirStore;36self->inkEffect = INK_ALPHA;37RSDK.DrawSprite(&self->wingAnimator, NULL, false);3839self->inkEffect = INK_NONE;40}4142void IceBomba_Create(void *data)43{44RSDK_THIS(IceBomba);4546self->visible = true;47self->drawGroup = Zone->objectDrawGroup[0];4849if (!SceneInfo->inEditor) {50self->dip <<= 7;51self->drawFX |= FX_FLIP;5253if (data) {54self->active = ACTIVE_NORMAL;55self->updateRange.x = 0x400000;56self->updateRange.y = 0x800000;57RSDK.SetSpriteAnimation(IceBomba->aniFrames, 2, &self->bodyAnimator, true, 0);58self->state = IceBomba_State_Bomb;59}60else {61self->active = ACTIVE_BOUNDS;62self->alpha = 0x80;63self->startDist = self->dist;64self->updateRange.x = (self->dist + 0x80) << 16;65self->updateRange.y = (self->dip + 0x8000) << 8;66self->startPos = self->position;67RSDK.SetSpriteAnimation(IceBomba->aniFrames, 0, &self->bodyAnimator, true, 0);68RSDK.SetSpriteAnimation(IceBomba->aniFrames, 1, &self->wingAnimator, true, 0);69RSDK.SetSpriteAnimation(IceBomba->aniFrames, 2, &self->bombAnimator, true, 0);7071self->direction = self->dir;72if (self->dir) {73self->bodyAnimator.frameID = 4;74self->bombAnimator.frameID = 4;75}76else {77self->bodyAnimator.frameID = 0;78self->bombAnimator.frameID = 0;79}8081self->state = IceBomba_State_Init;82}83}84}8586void IceBomba_StageLoad(void)87{88if (RSDK.CheckSceneFolder("PSZ1")) // PGZ1 doesn't have this badnik anywhere, the anim file doesn't even exist in the files...89IceBomba->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/IceBomba.bin", SCOPE_STAGE);90else if (RSDK.CheckSceneFolder("PSZ2"))91IceBomba->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/IceBomba.bin", SCOPE_STAGE);9293IceBomba->hitboxBadnik.left = -12;94IceBomba->hitboxBadnik.top = -12;95IceBomba->hitboxBadnik.right = 12;96IceBomba->hitboxBadnik.bottom = 12;9798IceBomba->hitboxBomb.left = -16;99IceBomba->hitboxBomb.top = -16;100IceBomba->hitboxBomb.right = 16;101IceBomba->hitboxBomb.bottom = 16;102103IceBomba->hitboxRange.left = -12;104IceBomba->hitboxRange.top = 64;105IceBomba->hitboxRange.right = 12;106IceBomba->hitboxRange.bottom = 128;107108IceBomba->sfxExplosion = RSDK.GetSfx("Stage/Explosion.wav");109IceBomba->sfxFreeze = RSDK.GetSfx("PSZ/Freeze.wav");110111DEBUGMODE_ADD_OBJ(IceBomba);112}113114void IceBomba_DebugDraw(void)115{116RSDK.SetSpriteAnimation(IceBomba->aniFrames, 0, &DebugMode->animator, true, 0);117RSDK.DrawSprite(&DebugMode->animator, NULL, false);118}119120void IceBomba_DebugSpawn(void)121{122RSDK_THIS(IceBomba);123124CREATE_ENTITY(IceBomba, NULL, self->position.x, self->position.y);125}126127void IceBomba_HandlePlayerCollisions(void)128{129RSDK_THIS(IceBomba);130131int32 storeDir = self->direction;132self->direction = FLIP_NONE;133134foreach_active(Player, player)135{136if (Player_CheckBadnikTouch(player, self, &IceBomba->hitboxBadnik)) {137if (Player_CheckBadnikBreak(player, self, false)) {138if (self->state != IceBomba_State_FlyAway) {139EntityIceBomba *bomb = CREATE_ENTITY(IceBomba, INT_TO_VOID(true), self->position.x, self->position.y);140if (self->direction)141bomb->position.x -= 0x40000;142else143bomb->position.x += 0x40000;144bomb->position.y += 0x1A0000;145bomb->direction = self->direction;146}147148destroyEntity(self);149}150}151else if (self->state != IceBomba_State_FlyAway) {152Vector2 storePos = self->position;153self->position.x += 0x40000 * (self->direction ? -1 : 1);154self->position.y += 0x1A0000;155156if (Player_CheckCollisionTouch(player, self, &IceBomba->hitboxBomb)) {157RSDK.PlaySfx(IceBomba->sfxExplosion, false, 0xFF);158CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];159RSDK.SetSpriteAnimation(-1, 0, &self->bombAnimator, true, 0);160self->state = IceBomba_State_FlyAway;161Ice_FreezePlayer(player);162}163164self->position = storePos;165}166}167168self->direction = storeDir;169}170171void IceBomba_State_Init(void)172{173RSDK_THIS(IceBomba);174175self->active = ACTIVE_NORMAL;176self->angle = 0;177self->direction = self->dir;178self->startDir = self->dir;179self->velocity.x = 0x8000 * (self->dir ? 1 : -1);180181self->state = IceBomba_State_Flying;182IceBomba_State_Flying();183}184185void IceBomba_CheckOffScreen(void)186{187RSDK_THIS(IceBomba);188189if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {190self->dip >>= 7;191self->position = self->startPos;192IceBomba_Create(NULL);193}194}195196void IceBomba_State_Flying(void)197{198RSDK_THIS(IceBomba);199200RSDK.ProcessAnimation(&self->wingAnimator);201202self->angle += 4;203204self->position.x += self->velocity.x;205self->position.y = self->startPos.y + self->dip * RSDK.Sin1024(self->angle);206207if (--self->startDist <= 0) {208RSDK.SetSpriteAnimation(-1, 1, &self->wingAnimator, true, 0);209self->state = IceBomba_State_Turning;210}211212foreach_active(Player, player)213{214if (Player_CheckCollisionTouch(player, self, &IceBomba->hitboxRange)) {215EntityIceBomba *bomb = CREATE_ENTITY(IceBomba, INT_TO_VOID(true), self->position.x, self->position.y);216bomb->position.x += 0x40000 * (self->direction ? -1 : 1);217bomb->position.y += 0x1A0000;218bomb->direction = self->direction;219RSDK.SetSpriteAnimation(-1, 0, &self->bombAnimator, true, 0);220self->state = IceBomba_State_FlyAway;221foreach_break;222}223}224225IceBomba_HandlePlayerCollisions();226IceBomba_CheckOffScreen();227}228229void IceBomba_State_Turning(void)230{231RSDK_THIS(IceBomba);232233self->angle += 4;234235self->position.x += self->velocity.x;236self->position.y = self->dip * RSDK.Sin1024(self->angle) + self->startPos.y;237self->velocity.x += 0x1000 * (self->direction ? -1 : 1);238239int32 animTimer = ++self->bodyAnimator.timer;240if (self->direction) {241if (animTimer >= 3) {242--self->bombAnimator.frameID;243--self->bodyAnimator.frameID;244self->bodyAnimator.timer = 0;245246if (self->bodyAnimator.frameID <= 0) {247self->direction ^= FLIP_X;248self->startDist = 2 * self->dist;249self->velocity.x = 0x8000 * (self->direction ? 1 : -1);250RSDK.SetSpriteAnimation(IceBomba->aniFrames, 1, &self->wingAnimator, true, 0);251self->state = IceBomba_State_Flying;252}253}254}255else if (animTimer >= 3) {256++self->bombAnimator.frameID;257++self->bodyAnimator.frameID;258self->bodyAnimator.timer = 0;259if (self->bodyAnimator.frameID >= 4) {260self->direction ^= FLIP_X;261self->startDist = 2 * self->dist;262self->velocity.x = 0x8000;263RSDK.SetSpriteAnimation(IceBomba->aniFrames, 1, &self->wingAnimator, true, 0);264self->state = IceBomba_State_Flying;265}266}267268IceBomba_HandlePlayerCollisions();269IceBomba_CheckOffScreen();270}271272void IceBomba_State_FlyAway(void)273{274RSDK_THIS(IceBomba);275276RSDK.ProcessAnimation(&self->wingAnimator);277278if (self->direction) {279if (self->bodyAnimator.frameID < 4) {280++self->bodyAnimator.frameID;281++self->bombAnimator.frameID;282}283}284else {285if (self->bodyAnimator.frameID > 0) {286--self->bodyAnimator.frameID;287--self->bombAnimator.frameID;288}289}290291self->position.x += self->velocity.x;292self->position.y -= 0x20000;293294IceBomba_HandlePlayerCollisions();295IceBomba_CheckOffScreen();296}297298void IceBomba_State_Bomb(void)299{300RSDK_THIS(IceBomba);301302self->position.y += self->velocity.y;303self->velocity.y += 0x3800;304305if (RSDK.CheckOnScreen(self, NULL)) {306if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {307RSDK.PlaySfx(IceBomba->sfxExplosion, false, 255);308CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];309310CREATE_ENTITY(Ice, INT_TO_VOID(ICE_CHILD_PILLAR), self->position.x, self->position.y + 0x100000);311RSDK.PlaySfx(IceBomba->sfxFreeze, false, 0xFF);312destroyEntity(self);313}314315foreach_active(Player, player)316{317if (Player_CheckCollisionTouch(player, self, &IceBomba->hitboxBomb)) {318RSDK.PlaySfx(IceBomba->sfxExplosion, false, 0xFF);319CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];320321Ice_FreezePlayer(player);322destroyEntity(self);323foreach_break;324}325}326}327else {328destroyEntity(self);329}330}331332#if GAME_INCLUDE_EDITOR333void IceBomba_EditorDraw(void)334{335RSDK_THIS(IceBomba);336337self->drawFX |= FX_FLIP;338self->active = ACTIVE_BOUNDS;339self->alpha = 0x80;340self->startDist = self->dist;341self->updateRange.x = (self->dist + 0x80) << 16;342self->updateRange.y = ((self->dip << 7) + 0x8000) << 8;343344RSDK.SetSpriteAnimation(IceBomba->aniFrames, 0, &self->bodyAnimator, true, 0);345RSDK.SetSpriteAnimation(IceBomba->aniFrames, 1, &self->wingAnimator, true, 0);346RSDK.SetSpriteAnimation(IceBomba->aniFrames, 2, &self->bombAnimator, true, 0);347348self->direction = self->dir;349if (self->dir) {350self->bodyAnimator.frameID = 4;351self->bombAnimator.frameID = 4;352}353else {354self->bodyAnimator.frameID = 0;355self->bombAnimator.frameID = 0;356}357358IceBomba_Draw();359}360361void IceBomba_EditorLoad(void)362{363if (RSDK.CheckSceneFolder("PSZ1"))364IceBomba->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/IceBomba.bin", SCOPE_STAGE);365else if (RSDK.CheckSceneFolder("PSZ2"))366IceBomba->aniFrames = RSDK.LoadSpriteAnimation("PSZ2/IceBomba.bin", SCOPE_STAGE);367368RSDK_ACTIVE_VAR(IceBomba, dir);369RSDK_ENUM_VAR("Left", FLIP_NONE);370RSDK_ENUM_VAR("Right", FLIP_X);371}372#endif373374void IceBomba_Serialize(void)375{376RSDK_EDITABLE_VAR(IceBomba, VAR_UINT8, dir);377RSDK_EDITABLE_VAR(IceBomba, VAR_UINT16, dist);378RSDK_EDITABLE_VAR(IceBomba, VAR_UINT16, dip);379}380381