Path: blob/master/SonicMania/Objects/MMZ/MechaBu.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: MechaBu Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectMechaBu *MechaBu;1011void MechaBu_Update(void)12{13RSDK_THIS(MechaBu);1415StateMachine_Run(self->state);1617Vector2 offset = MechaBu_GetSawOffset();18self->sawPos.x = self->position.x + offset.x;19self->sawPos.y = self->position.y + offset.y;20}2122void MechaBu_LateUpdate(void) {}2324void MechaBu_StaticUpdate(void) {}2526void MechaBu_Draw(void)27{28RSDK_THIS(MechaBu);2930RSDK.DrawSprite(&self->badnikAnimator, NULL, false);31RSDK.DrawSprite(&self->sawAnimator, &self->sawPos, false);32RSDK.DrawSprite(&self->hornAnimator, NULL, false);33}3435void MechaBu_Create(void *data)36{37RSDK_THIS(MechaBu);3839self->visible = true;40if (self->planeFilter > 0 && (((uint8)self->planeFilter - 1) & 2))41self->drawGroup = Zone->objectDrawGroup[1];42else43self->drawGroup = Zone->objectDrawGroup[0];4445self->drawFX |= FX_FLIP;46self->startPos = self->position;47self->startDir = self->direction;48self->active = ACTIVE_BOUNDS;49self->updateRange.x = 0x800000;50self->updateRange.y = 0x800000;5152RSDK.SetSpriteAnimation(MechaBu->aniFrames, 1, &self->badnikAnimator, true, 0);53RSDK.SetSpriteAnimation(MechaBu->aniFrames, 3, &self->hornAnimator, true, 0);54RSDK.SetSpriteAnimation(MechaBu->aniFrames, 7, &self->sawAnimator, true, 0);5556self->state = MechaBu_State_Init;57}5859void MechaBu_StageLoad(void)60{61if (RSDK.CheckSceneFolder("MMZ"))62MechaBu->aniFrames = RSDK.LoadSpriteAnimation("MMZ/MechaBu.bin", SCOPE_STAGE);6364MechaBu->hitboxSaw.left = -14;65MechaBu->hitboxSaw.top = -14;66MechaBu->hitboxSaw.right = 14;67MechaBu->hitboxSaw.bottom = 14;6869MechaBu->hitboxUnused.left = -8;70MechaBu->hitboxUnused.top = -12;71MechaBu->hitboxUnused.right = 8;72MechaBu->hitboxUnused.bottom = 12;7374DEBUGMODE_ADD_OBJ(MechaBu);7576MechaBu->sfxSawUp = RSDK.GetSfx("MMZ/SawUp.wav");77MechaBu->sfxSawDown = RSDK.GetSfx("MMZ/SawDown.wav");78}7980void MechaBu_DebugSpawn(void)81{82RSDK_THIS(DebugMode);8384CREATE_ENTITY(MechaBu, NULL, self->position.x, self->position.y);85}8687void MechaBu_DebugDraw(void)88{89RSDK.SetSpriteAnimation(MechaBu->aniFrames, 0, &DebugMode->animator, true, 0);90RSDK.DrawSprite(&DebugMode->animator, NULL, false);91}9293void MechaBu_CheckPlayerCollisions(void)94{95RSDK_THIS(MechaBu);9697foreach_active(Player, player)98{99if (self->planeFilter <= 0 || player->collisionPlane == (((uint8)self->planeFilter - 1) & 1)) {100Vector2 posStore = self->position;101self->position = self->sawPos;102if (Player_CheckCollisionTouch(player, self, &MechaBu->hitboxSaw)) {103self->position = posStore;104#if MANIA_USE_PLUS105if (!Player_CheckMightyUnspin(player, 0x200, 2, &player->uncurlTimer))106#endif107Player_Hurt(player, self);108}109else {110self->position = posStore;111if (Player_CheckBadnikTouch(player, self, &MechaBu->hitboxSaw) && Player_CheckBadnikBreak(player, self, false)) {112EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->sawPos.x, self->sawPos.y);113RSDK.SetSpriteAnimation(MechaBu->aniFrames, 7, &debris->animator, false, 0);114debris->velocity.x = RSDK.Rand(-2, 3) << 16;115debris->velocity.y = RSDK.Rand(-4, -1) << 16;116debris->gravityStrength = 0x3800;117debris->drawGroup = self->drawGroup;118debris->updateRange.x = 0x200000;119debris->updateRange.y = 0x200000;120destroyEntity(self);121}122}123}124}125}126127void MechaBu_CheckOffScreen(void)128{129RSDK_THIS(MechaBu);130131if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {132self->position = self->startPos;133self->direction = self->startDir;134MechaBu_Create(NULL);135}136}137138Vector2 MechaBu_GetSawOffset(void)139{140RSDK_THIS(MechaBu);141142Vector2 offset;143switch (self->hornAnimator.animationID) {144case 4:145offset.x = MechaBu->sawOffsets[8];146offset.y = MechaBu->sawOffsets[9];147break;148149case 5:150offset.x = MechaBu->sawOffsets[2 * (4 - self->hornAnimator.frameID) + 0];151offset.y = MechaBu->sawOffsets[2 * (4 - self->hornAnimator.frameID) + 1];152break;153154case 6:155offset.x = MechaBu->sawOffsets[(2 * self->hornAnimator.frameID) + 0];156offset.y = MechaBu->sawOffsets[(2 * self->hornAnimator.frameID) + 1];157break;158159default:160offset.x = MechaBu->sawOffsets[0];161offset.y = MechaBu->sawOffsets[1];162break;163}164165return offset;166}167168void MechaBu_State_Init(void)169{170RSDK_THIS(MechaBu);171172self->active = ACTIVE_NORMAL;173self->sawTimer = 0;174self->velocity.x = -0x10000;175self->velocity.y = 0;176177self->state = MechaBu_State_Moving;178MechaBu_State_Moving();179}180181void MechaBu_State_Moving(void)182{183RSDK_THIS(MechaBu);184185RSDK.ProcessAnimation(&self->badnikAnimator);186RSDK.ProcessAnimation(&self->hornAnimator);187RSDK.ProcessAnimation(&self->sawAnimator);188189self->sawTimer++;190if (self->sawTimer == 60) {191if (self->onScreen == 1)192RSDK.PlaySfx(MechaBu->sfxSawUp, false, 255);193194RSDK.SetSpriteAnimation(MechaBu->aniFrames, 6, &self->hornAnimator, true, 0);195}196else if (self->sawTimer == 120) {197if (self->onScreen == 1)198RSDK.PlaySfx(MechaBu->sfxSawDown, false, 255);199200self->sawTimer = 0;201RSDK.SetSpriteAnimation(MechaBu->aniFrames, 5, &self->hornAnimator, true, 0);202}203204self->position.x += self->velocity.x;205206if (RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xF0000, 8)) {207bool32 collidedWall = false;208bool32 collidedFloor = false;209if (self->velocity.x <= 0) {210collidedWall = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, -0x120000, 0, true);211collidedFloor = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x20000, 0x100000, false);212}213else {214collidedWall = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, 0x120000, 0, true);215collidedFloor = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x20000, 0x100000, false);216}217218if (!collidedFloor || collidedWall) {219self->timer = 0;220self->state = MechaBu_State_Stopped;221}222}223else {224RSDK.SetSpriteAnimation(MechaBu->aniFrames, 1, &self->badnikAnimator, true, 0);225self->timer = 0;226227bool32 collided = false;228if (self->velocity.x >= 0)229collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, -0x10000, 0xF0000, 8);230else231collided = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0x10000, 0xF0000, 8);232233self->state = collided ? MechaBu_State_Stopped : MechaBu_State_Falling;234}235236MechaBu_CheckPlayerCollisions();237MechaBu_CheckOffScreen();238}239240void MechaBu_State_Stopped(void)241{242RSDK_THIS(MechaBu);243244RSDK.ProcessAnimation(&self->badnikAnimator);245RSDK.ProcessAnimation(&self->hornAnimator);246RSDK.ProcessAnimation(&self->sawAnimator);247248if (++self->timer == 48) {249self->velocity.x = -self->velocity.x;250251self->state = MechaBu_State_Moving;252MechaBu_State_Moving();253}254255MechaBu_CheckPlayerCollisions();256MechaBu_CheckOffScreen();257}258259void MechaBu_State_Falling(void)260{261RSDK_THIS(MechaBu);262263RSDK.ProcessAnimation(&self->badnikAnimator);264RSDK.ProcessAnimation(&self->hornAnimator);265RSDK.ProcessAnimation(&self->sawAnimator);266267self->position.x += self->velocity.x;268self->position.y += self->velocity.y;269self->velocity.y += 0x3800;270271if (RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xF0000, 8)) {272self->velocity.y = 0;273RSDK.SetSpriteAnimation(MechaBu->aniFrames, 0, &self->badnikAnimator, true, 0);274275self->state = MechaBu_State_Moving;276MechaBu_State_Moving();277}278else {279bool32 collided = false;280if (self->velocity.x <= 0)281collided = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_RWALL, 0, -0x120000, 0, true);282else283collided = RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_LWALL, 0, 0x120000, 0, true);284285if (collided)286self->velocity.x = 0;287288MechaBu_CheckPlayerCollisions();289MechaBu_CheckOffScreen();290}291}292293#if GAME_INCLUDE_EDITOR294void MechaBu_EditorDraw(void)295{296RSDK_THIS(MechaBu);297298self->sawPos.x = self->position.x + -0x150000;299self->sawPos.y = self->position.y + -0xF0000;300301MechaBu_Draw();302}303304void MechaBu_EditorLoad(void)305{306MechaBu->aniFrames = RSDK.LoadSpriteAnimation("MMZ/MechaBu.bin", SCOPE_STAGE);307308RSDK_ACTIVE_VAR(MechaBu, planeFilter);309RSDK_ENUM_VAR("None", PLANEFILTER_NONE);310RSDK_ENUM_VAR("AL", PLANEFILTER_AL);311RSDK_ENUM_VAR("BL", PLANEFILTER_BL);312RSDK_ENUM_VAR("AH", PLANEFILTER_AH);313RSDK_ENUM_VAR("BH", PLANEFILTER_BH);314}315#endif316317void MechaBu_Serialize(void) { RSDK_EDITABLE_VAR(MechaBu, VAR_ENUM, planeFilter); }318319320