Path: blob/master/SonicMania/Objects/TMZ/BallHog.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: BallHog Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectBallHog *BallHog;1011void BallHog_Update(void)12{13RSDK_THIS(BallHog);1415StateMachine_Run(self->state);16}1718void BallHog_LateUpdate(void) {}1920void BallHog_StaticUpdate(void) {}2122void BallHog_Draw(void)23{24RSDK_THIS(BallHog);2526RSDK.DrawSprite(&self->animator, NULL, false);27}2829void BallHog_Create(void *data)30{31RSDK_THIS(BallHog);3233self->visible = true;34self->drawGroup = Zone->objectDrawGroup[0];35self->active = ACTIVE_BOUNDS;36self->updateRange.x = 0x800000;37self->updateRange.y = 0x800000;3839if (data) {40RSDK.SetSpriteAnimation(BallHog->aniFrames, 4, &self->animator, true, 0);41self->state = BallHog_State_Bomb;42}43else {44self->startPos = self->position;45self->startDir = self->direction;4647if (!self->bombTime)48self->bombTime = 6;4950if (!self->numJumps)51self->numJumps = 3;5253self->drawFX |= FX_FLIP;54self->jumpCount = self->numJumps;55self->timer = 20;5657RSDK.SetSpriteAnimation(BallHog->aniFrames, 0, &self->animator, true, 0);5859self->state = BallHog_State_Init;60}61}6263void BallHog_StageLoad(void)64{65if (RSDK.CheckSceneFolder("TMZ1") || RSDK.CheckSceneFolder("TMZ2"))66BallHog->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/BallHog.bin", SCOPE_STAGE);6768BallHog->hitboxBadnik.left = -12;69BallHog->hitboxBadnik.top = -18;70BallHog->hitboxBadnik.right = 12;71BallHog->hitboxBadnik.bottom = 18;7273BallHog->hitboxBomb.left = -6;74BallHog->hitboxBomb.top = -6;75BallHog->hitboxBomb.right = 6;76BallHog->hitboxBomb.bottom = 6;7778BallHog->sfxExplosion = RSDK.GetSfx("Stage/Explosion.wav");79BallHog->sfxArrowHit = RSDK.GetSfx("PSZ/ArrowHit.wav");80BallHog->sfxDrop = RSDK.GetSfx("TMZ1/HogDrop.wav");81BallHog->sfxJump = RSDK.GetSfx("TMZ1/HogJump.wav");8283DEBUGMODE_ADD_OBJ(BallHog);84}8586void BallHog_DebugSpawn(void)87{88RSDK_THIS(DebugMode);8990CREATE_ENTITY(BallHog, NULL, self->position.x, self->position.y);91}9293void BallHog_DebugDraw(void)94{95RSDK.SetSpriteAnimation(BallHog->aniFrames, 0, &DebugMode->animator, true, 0);96RSDK.DrawSprite(&DebugMode->animator, NULL, false);97}9899void BallHog_CheckPlayerCollisions(void)100{101RSDK_THIS(BallHog);102103foreach_active(Player, player)104{105if (Player_CheckBadnikTouch(player, self, &BallHog->hitboxBadnik))106Player_CheckBadnikBreak(player, self, true);107}108}109110void BallHog_CheckOffScreen(void)111{112RSDK_THIS(BallHog);113114if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {115self->position = self->startPos;116self->direction = self->startDir;117BallHog_Create(NULL);118}119}120121void BallHog_State_Init(void)122{123RSDK_THIS(BallHog);124125self->active = ACTIVE_NORMAL;126127self->state = BallHog_State_Idle;128BallHog_State_Idle();129}130131void BallHog_State_Idle(void)132{133RSDK_THIS(BallHog);134135if (!--self->timer) {136self->timer = 20;137RSDK.SetSpriteAnimation(BallHog->aniFrames, 1, &self->animator, true, 0);138self->state = BallHog_State_Jump;139}140141RSDK.ProcessAnimation(&self->animator);142143BallHog_CheckPlayerCollisions();144BallHog_CheckOffScreen();145}146147void BallHog_State_Jump(void)148{149RSDK_THIS(BallHog);150151if (self->timer) {152if (!--self->timer) {153RSDK.PlaySfx(BallHog->sfxJump, false, 255);154self->velocity.y = -0x203D9;155self->position.y -= 0x29999;156}157}158else {159self->position.y += self->velocity.y;160self->velocity.y += 0x95C0;161162if (self->velocity.y > 0 && RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x140000, 2)) {163self->velocity.y = 0;164self->timer = 10;165RSDK.SetSpriteAnimation(BallHog->aniFrames, 2, &self->animator, true, 0);166self->state = BallHog_State_Land;167}168}169170RSDK.ProcessAnimation(&self->animator);171172BallHog_CheckPlayerCollisions();173BallHog_CheckOffScreen();174}175176void BallHog_State_Land(void)177{178RSDK_THIS(BallHog);179180if (!--self->timer) {181RSDK.SetSpriteAnimation(BallHog->aniFrames, 0, &self->animator, true, 0);182183if (!--self->jumpCount) {184self->timer = 28;185self->jumpCount = self->numJumps + 1;186self->state = BallHog_State_DropBomb;187}188else {189self->timer = 20;190self->state = BallHog_State_Idle;191}192}193194RSDK.ProcessAnimation(&self->animator);195196BallHog_CheckPlayerCollisions();197BallHog_CheckOffScreen();198}199200void BallHog_State_DropBomb(void)201{202RSDK_THIS(BallHog);203204if (--self->timer) {205if (self->timer == 8)206RSDK.SetSpriteAnimation(BallHog->aniFrames, 3, &self->animator, true, 0);207}208else {209self->timer = 18;210RSDK.PlaySfx(BallHog->sfxDrop, false, 0xFF);211212EntityBallHog *bomb = CREATE_ENTITY(BallHog, INT_TO_VOID(true), self->position.x, self->position.y);213if (self->direction) {214bomb->position.x += 0x40000;215bomb->velocity.x = 0x10000;216}217else {218bomb->position.x -= 0x40000;219bomb->velocity.x = -0x10000;220}221222bomb->position.y += 0xC0000;223bomb->timer = 60 * self->bombTime;224225self->state = BallHog_State_Land;226}227228RSDK.ProcessAnimation(&self->animator);229230BallHog_CheckPlayerCollisions();231BallHog_CheckOffScreen();232}233234void BallHog_State_Bomb(void)235{236RSDK_THIS(BallHog);237238self->position.x += self->velocity.x;239self->position.y += self->velocity.y;240self->velocity.y += 0x3800;241242if (RSDK.CheckOnScreen(self, &self->updateRange)) {243if (self->velocity.y > 0 && RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x80000, 4)) {244RSDK.PlaySfx(BallHog->sfxArrowHit, false, 255);245int32 storeY = self->position.y;246247self->velocity.y = -0x30000;248RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x20000, 0x80000, 8);249int32 y1 = self->position.y;250251self->position.y = storeY;252RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x20000, 0x80000, 8);253int32 y2 = self->position.y;254255self->position.y = storeY;256if (self->velocity.x <= 0 ? y1 < y2 : y2 < y1)257self->velocity.x = -self->velocity.x;258}259260RSDK.ProcessAnimation(&self->animator);261262bool32 shouldExplode = false;263foreach_active(Player, player)264{265if (Player_CheckCollisionTouch(player, self, &BallHog->hitboxBomb)) {266#if MANIA_USE_PLUS267if (!Player_CheckMightyUnspin(player, 0x100, 2, &player->uncurlTimer)) {268#endif269Player_Hurt(player, self);270shouldExplode = true;271foreach_break;272#if MANIA_USE_PLUS273}274#endif275}276}277278if (shouldExplode || !--self->timer) {279RSDK.PlaySfx(BallHog->sfxExplosion, false, 255);280CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1];281282destroyEntity(self);283}284}285else {286destroyEntity(self);287}288}289290#if GAME_INCLUDE_EDITOR291void BallHog_EditorDraw(void) { BallHog_Draw(); }292293void BallHog_EditorLoad(void)294{295BallHog->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/BallHog.bin", SCOPE_STAGE);296297RSDK_ACTIVE_VAR(BallHog, direction);298RSDK_ENUM_VAR("Left", FLIP_NONE);299RSDK_ENUM_VAR("Right", FLIP_X);300}301#endif302303void BallHog_Serialize(void)304{305RSDK_EDITABLE_VAR(BallHog, VAR_UINT8, direction);306RSDK_EDITABLE_VAR(BallHog, VAR_UINT8, numJumps);307RSDK_EDITABLE_VAR(BallHog, VAR_UINT8, bombTime);308}309310311