Path: blob/master/SonicMania/Objects/GHZ/Batbrain.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Batbrain Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectBatbrain *Batbrain;1011void Batbrain_Update(void)12{13RSDK_THIS(Batbrain);14StateMachine_Run(self->state);15}1617void Batbrain_LateUpdate(void) {}1819void Batbrain_StaticUpdate(void) {}2021void Batbrain_Draw(void)22{23RSDK_THIS(Batbrain);24RSDK.DrawSprite(&self->animator, NULL, false);25}2627void Batbrain_Create(void *data)28{29RSDK_THIS(Batbrain);30self->visible = true;31self->drawFX |= FX_FLIP;32self->drawGroup = Zone->objectDrawGroup[0];33self->startPos.x = self->position.x;34self->startPos.y = self->position.y;35self->active = ACTIVE_BOUNDS;36self->updateRange.x = 0x800000;37self->updateRange.y = 0x800000;38RSDK.SetSpriteAnimation(Batbrain->aniFrames, 0, &self->animator, true, 0);39self->state = Batbrain_State_Init;40}4142void Batbrain_StageLoad(void)43{44if (RSDK.CheckSceneFolder("GHZ"))45Batbrain->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Batbrain.bin", SCOPE_STAGE);4647Batbrain->hitboxBadnik.left = -12;48Batbrain->hitboxBadnik.top = -18;49Batbrain->hitboxBadnik.right = 12;50Batbrain->hitboxBadnik.bottom = 18;5152Batbrain->sfxFlap = RSDK.GetSfx("Stage/Flap.wav");5354DEBUGMODE_ADD_OBJ(Batbrain);55}5657void Batbrain_DebugDraw(void)58{59RSDK.SetSpriteAnimation(Batbrain->aniFrames, 0, &DebugMode->animator, true, 0);60RSDK.DrawSprite(&DebugMode->animator, NULL, false);61}6263void Batbrain_DebugSpawn(void)64{65RSDK_THIS(DebugMode);6667CREATE_ENTITY(Batbrain, NULL, self->position.x, self->position.y);68}6970void Batbrain_CheckPlayerCollisions(void)71{72RSDK_THIS(Batbrain);7374foreach_active(Player, player)75{76if (Player_CheckBadnikTouch(player, self, &Batbrain->hitboxBadnik))77Player_CheckBadnikBreak(player, self, true);78}79}8081void Batbrain_CheckOffScreen(void)82{83RSDK_THIS(Batbrain);8485if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {86self->position.x = self->startPos.x;87self->position.y = self->startPos.y;88Batbrain_Create(NULL);89}90}9192void Batbrain_State_Init(void)93{94RSDK_THIS(Batbrain);9596self->active = ACTIVE_NORMAL;97self->velocity.x = 0;98self->velocity.y = 0;99self->state = Batbrain_State_CheckPlayerInRange;100Batbrain_State_CheckPlayerInRange();101}102103void Batbrain_State_CheckPlayerInRange(void)104{105RSDK_THIS(Batbrain);106107int32 targetDistance = 0x7FFFFFFF;108EntityPlayer *backupPlayer = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);109EntityPlayer *targetPlayer = NULL;110111foreach_active(Player, player)112{113int32 distance = abs(player->position.x - self->position.x);114if (distance >= targetDistance) {115backupPlayer = player;116}117else {118backupPlayer = player;119targetDistance = distance;120}121122if (distance < 0x800000) {123if (player->position.y >= self->position.y && (!targetPlayer || player->position.y < targetPlayer->position.y))124targetPlayer = player;125}126}127128EntityPlayer *playerPtr = backupPlayer;129if (targetPlayer) {130playerPtr = targetPlayer;131int32 distance = targetPlayer->position.y - self->position.y;132if (distance >= 0 && distance <= 0x800000 && !RSDK.Rand(0, 8)) {133self->state = Batbrain_State_DropToPlayer;134self->targetY = playerPtr->position.y;135self->target = playerPtr;136RSDK.SetSpriteAnimation(Batbrain->aniFrames, 1, &self->animator, true, 0);137}138}139140self->direction = playerPtr->position.x >= self->position.x;141142Batbrain_CheckPlayerCollisions();143Batbrain_CheckOffScreen();144}145146void Batbrain_State_DropToPlayer(void)147{148RSDK_THIS(Batbrain);149150self->position.y += self->velocity.y;151self->velocity.y += 0x1800;152self->direction = self->target->position.x >= self->position.x;153154if (self->targetY - self->position.y < 0x100000) {155self->velocity.y = 0;156if (self->direction == FLIP_NONE)157self->velocity.x = -0x10000;158else159self->velocity.x = 0x10000;160RSDK.SetSpriteAnimation(Batbrain->aniFrames, 2, &self->animator, true, 0);161self->state = Batbrain_State_Fly;162}163164RSDK.ProcessAnimation(&self->animator);165166Batbrain_CheckPlayerCollisions();167Batbrain_CheckOffScreen();168}169170void Batbrain_State_Fly(void)171{172RSDK_THIS(Batbrain);173174EntityPlayer *target = self->target;175self->position.x += self->velocity.x;176177if (abs(target->position.x - self->position.x) >= 0x800000 && !RSDK.Rand(0, 8))178self->state = Batbrain_State_FlyToCeiling;179180if (!(Zone->timer & 0xF))181RSDK.PlaySfx(Batbrain->sfxFlap, false, 255);182183RSDK.ProcessAnimation(&self->animator);184185Batbrain_CheckPlayerCollisions();186Batbrain_CheckOffScreen();187}188189void Batbrain_State_FlyToCeiling(void)190{191RSDK_THIS(Batbrain);192193self->position.x += self->velocity.x;194self->position.y += self->velocity.y;195self->velocity.y -= 0x1800;196197// RWALL? shouldn't this be ROOF? is this a holdover from v4's weird id system?198if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, 0, -0xC0000, true)) {199self->velocity.x = 0;200self->velocity.y = 0;201self->state = Batbrain_State_CheckPlayerInRange;202RSDK.SetSpriteAnimation(Batbrain->aniFrames, 0, &self->animator, true, 0);203}204205if (!(Zone->timer & 0xF))206RSDK.PlaySfx(Batbrain->sfxFlap, false, 255);207208RSDK.ProcessAnimation(&self->animator);209210Batbrain_CheckPlayerCollisions();211Batbrain_CheckOffScreen();212}213214#if GAME_INCLUDE_EDITOR215void Batbrain_EditorDraw(void) { Batbrain_Draw(); }216217void Batbrain_EditorLoad(void) { Batbrain->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Batbrain.bin", SCOPE_STAGE); }218#endif219220void Batbrain_Serialize(void) {}221222223