Path: blob/master/SonicMania/Objects/HCZ/Buggernaut.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Buggernaut Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67// NOTE:8// This object was prolly based on Unused/Wisp9// it looks like it has the same structure, and even has "buzzCount", even though its set to -11011#include "Game.h"1213ObjectBuggernaut *Buggernaut;1415void Buggernaut_Update(void)16{17RSDK_THIS(Buggernaut);1819StateMachine_Run(self->state);20}2122void Buggernaut_LateUpdate(void) {}2324void Buggernaut_StaticUpdate(void) {}2526void Buggernaut_Draw(void)27{28RSDK_THIS(Buggernaut);2930RSDK.DrawSprite(&self->bodyAnimator, NULL, false);3132self->inkEffect = INK_ALPHA;33RSDK.DrawSprite(&self->wingAnimator, NULL, false);3435self->inkEffect = INK_NONE;36}3738void Buggernaut_Create(void *data)39{40RSDK_THIS(Buggernaut);4142self->visible = true;43self->drawGroup = Zone->objectDrawGroup[0] + 1;4445if (!SceneInfo->inEditor) {46self->drawFX |= FX_FLIP;47self->startPos = self->position;48self->active = ACTIVE_BOUNDS;49self->updateRange.x = 0x800000;50self->updateRange.y = 0x800000;51self->direction = FLIP_NONE;52self->alpha = 128;53self->timer = 16;54self->buzzCount = -1;5556RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 0, &self->bodyAnimator, true, 0);57RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 2, &self->wingAnimator, true, 0);5859self->state = Buggernaut_State_Init;60}61}6263void Buggernaut_StageLoad(void)64{65Buggernaut->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Buggernaut.bin", SCOPE_STAGE);6667Buggernaut->hitboxBadnik.left = -8;68Buggernaut->hitboxBadnik.top = -8;69Buggernaut->hitboxBadnik.right = 8;70Buggernaut->hitboxBadnik.bottom = 8;7172Buggernaut->hitboxParentRange.left = -64;73Buggernaut->hitboxParentRange.top = -64;74Buggernaut->hitboxParentRange.right = 64;75Buggernaut->hitboxParentRange.bottom = 64;7677DEBUGMODE_ADD_OBJ(Buggernaut);78}7980void Buggernaut_DebugSpawn(void)81{82RSDK_THIS(DebugMode);8384CREATE_ENTITY(Buggernaut, NULL, self->position.x, self->position.y);85}8687void Buggernaut_DebugDraw(void)88{89RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 0, &DebugMode->animator, true, 0);90RSDK.DrawSprite(&DebugMode->animator, NULL, false);91}9293void Buggernaut_CheckPlayerCollisions(void)94{95RSDK_THIS(Buggernaut);9697foreach_active(Player, player)98{99if (Player_CheckBadnikTouch(player, self, &Buggernaut->hitboxBadnik))100Player_CheckBadnikBreak(player, self, true);101}102}103104void Buggernaut_CheckOffScreen(void)105{106RSDK_THIS(Buggernaut);107108if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {109if (self->bodyAnimator.animationID) {110destroyEntity(self);111}112else {113self->position = self->startPos;114Buggernaut_Create(NULL);115}116}117}118119bool32 Buggernaut_HandleTileCollisionsX(void)120{121RSDK_THIS(Buggernaut);122123bool32 collided = false;124if (self->velocity.x <= 0) {125collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x90000, -0x80000, false);126collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x90000, 0x80000, false);127}128else {129collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x90000, -0x80000, false);130collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x90000, 0x80000, false);131}132133if (collided)134self->velocity.x = -self->velocity.x;135136return collided;137}138139bool32 Buggernaut_HandleTileCollisionsY(void)140{141RSDK_THIS(Buggernaut);142143bool32 collided = false;144if (self->velocity.y <= 0) {145collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x80000, -0x90000, false);146collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x80000, 0x90000, false);147}148else {149collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x80000, 0x90000, false);150collided |= RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x80000, 0x90000, false);151}152153if (collided)154self->velocity.y = -self->velocity.y;155156return collided;157}158159void Buggernaut_State_Init(void)160{161RSDK_THIS(Buggernaut);162163self->active = ACTIVE_NORMAL;164int32 x = self->position.x;165int32 y = self->position.y;166self->velocity.x = 0;167self->velocity.y = 0;168169EntityBuggernaut *child = CREATE_ENTITY(Buggernaut, INT_TO_VOID(true), x, y);170RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 1, &child->bodyAnimator, true, 0);171RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 3, &child->wingAnimator, true, 0);172child->active = ACTIVE_NORMAL;173child->drawGroup = self->drawGroup - 1;174child->parent = self;175child->passThrough = self->passThrough;176child->isPermanent = true;177child->state = Buggernaut_State_Child;178179self->state = Buggernaut_State_Idle;180Buggernaut_State_Idle();181}182183void Buggernaut_State_Idle(void)184{185RSDK_THIS(Buggernaut);186187if (--self->timer <= 0) {188if (--self->buzzCount) {189self->velocity.y = -0x10000;190self->timer = 96;191self->state = Buggernaut_State_FlyTowardTarget;192}193else {194self->velocity.x = RSDK.Rand(-2, 3) << 16;195self->velocity.y = RSDK.Rand(-2, 3) << 16;196197if (!self->velocity.x || !self->velocity.y)198self->velocity.x = -0x20000;199200self->velocity.y = -0x20000;201self->state = Buggernaut_State_FlyAway;202}203}204205RSDK.ProcessAnimation(&self->wingAnimator);206207Buggernaut_CheckPlayerCollisions();208Buggernaut_CheckOffScreen();209}210211void Buggernaut_State_FlyTowardTarget(void)212{213RSDK_THIS(Buggernaut);214215self->position.x += self->velocity.x;216self->position.y += self->velocity.y;217218EntityPlayer *player = Player_GetNearestPlayer();219if (player) {220if (player->position.x >= self->position.x) {221self->velocity.x += 0x1000;222223if (self->velocity.x > 0x20000)224self->velocity.x = 0x20000;225226self->direction = FLIP_X;227}228else {229self->velocity.x -= 0x1000;230231if (self->velocity.x < -0x20000)232self->velocity.x = -0x20000;233234self->direction = FLIP_NONE;235}236237if (player->position.y >= self->position.y) {238self->velocity.y += 0x1000;239240if (self->velocity.y > 0x20000)241self->velocity.y = 0x20000;242}243else {244self->velocity.y -= 0x1000;245246if (self->velocity.y < -0x20000)247self->velocity.y = -0x20000;248}249}250251if (self->velocity.y > 0 && self->position.y > Water->waterLevel - 0x80000)252self->velocity.y = -self->velocity.y;253254if (!self->passThrough) {255if (abs(self->velocity.x) <= abs(self->velocity.y)) {256if (!Buggernaut_HandleTileCollisionsY())257Buggernaut_HandleTileCollisionsX();258}259else if (!Buggernaut_HandleTileCollisionsX()) {260Buggernaut_HandleTileCollisionsY();261}262}263264if (!--self->timer) {265self->timer = RSDK.Rand(0, 32);266self->state = Buggernaut_State_Idle;267self->velocity.x = 0;268self->velocity.y = 0;269self->direction = FLIP_NONE;270}271272RSDK.ProcessAnimation(&self->wingAnimator);273274Buggernaut_CheckPlayerCollisions();275Buggernaut_CheckOffScreen();276}277278void Buggernaut_State_FlyAway(void)279{280RSDK_THIS(Buggernaut);281282self->position.x += self->velocity.x;283self->position.y += self->velocity.y;284285RSDK.ProcessAnimation(&self->wingAnimator);286287if (!self->bodyAnimator.animationID)288Buggernaut_CheckPlayerCollisions();289290Buggernaut_CheckOffScreen();291}292293void Buggernaut_State_Child(void)294{295RSDK_THIS(Buggernaut);296297self->position.x += self->velocity.x;298self->position.y += self->velocity.y;299300if (!self->parent || self->parent->classID != Buggernaut->classID) {301foreach_active(Buggernaut, buggernaut)302{303if (buggernaut->bodyAnimator.animationID == 0304&& RSDK.CheckObjectCollisionTouchBox(buggernaut, &Buggernaut->hitboxBadnik, self, &Buggernaut->hitboxParentRange)) {305self->parent = buggernaut;306foreach_break;307}308}309310if (!self->parent) {311self->velocity.x = RSDK.Rand(-2, 3) << 16;312self->velocity.y = RSDK.Rand(-2, 3) << 16;313314if (!self->velocity.y || !self->velocity.x)315self->velocity.x = -0x20000;316self->velocity.y = -0x20000;317self->state = Buggernaut_State_FlyAway;318}319}320321if (self->parent) {322if (self->parent->position.x >= self->position.x) {323self->velocity.x += 0x2000;324325if (self->velocity.x > 0x20000)326self->velocity.x = 0x20000;327328self->direction = FLIP_X;329}330else {331self->velocity.x -= 0x2000;332333if (self->velocity.x < -0x20000)334self->velocity.x = -0x20000;335336self->direction = FLIP_NONE;337}338339if (self->parent->position.y >= self->position.y) {340self->velocity.y += 0x2000;341342if (self->velocity.y > 0x20000)343self->velocity.y = 0x20000;344}345else {346self->velocity.y -= 0x2000;347348if (self->velocity.y < -0x20000)349self->velocity.y = -0x20000;350}351352if (self->velocity.y > 0 && self->position.y > Water->waterLevel - 0x80000)353self->velocity.y = -self->velocity.y;354355if (!self->passThrough) {356if (abs(self->velocity.x) <= abs(self->velocity.y)) {357if (!Buggernaut_HandleTileCollisionsY())358Buggernaut_HandleTileCollisionsX();359}360else if (!Buggernaut_HandleTileCollisionsX()) {361Buggernaut_HandleTileCollisionsY();362}363}364}365366RSDK.ProcessAnimation(&self->wingAnimator);367368if (self->parent->state == Buggernaut_State_Init)369destroyEntity(self);370}371372#if GAME_INCLUDE_EDITOR373void Buggernaut_EditorDraw(void)374{375RSDK_THIS(Buggernaut);376377self->drawFX = FX_FLIP;378self->alpha = 0x80;379RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 0, &self->bodyAnimator, true, 0);380RSDK.SetSpriteAnimation(Buggernaut->aniFrames, 2, &self->wingAnimator, true, 0);381382Buggernaut_Draw();383}384385void Buggernaut_EditorLoad(void)386{387Buggernaut->aniFrames = RSDK.LoadSpriteAnimation("HCZ/Buggernaut.bin", SCOPE_STAGE);388389// despite being editable, this variable is set to FLIP_NONE on create, thereby making the editable var's value unused390RSDK_ACTIVE_VAR(Buggernaut, direction);391RSDK_ENUM_VAR("(Unused)", FLIP_NONE);392// RSDK_ENUM_VAR("No Flip", FLIP_NONE);393// RSDK_ENUM_VAR("Flip X", FLIP_X);394}395#endif396397void Buggernaut_Serialize(void)398{399RSDK_EDITABLE_VAR(Buggernaut, VAR_UINT8, direction);400RSDK_EDITABLE_VAR(Buggernaut, VAR_BOOL, passThrough);401}402403404