Path: blob/master/SonicMania/Objects/MMZ/PohBee.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PohBee Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPohBee *PohBee;1011void PohBee_Update(void)12{13RSDK_THIS(PohBee);1415RSDK.ProcessAnimation(&self->bodyAnimator);16RSDK.ProcessAnimation(&self->wingsAnimator);1718StateMachine_Run(self->state);1920PohBee_SetupHitboxes();21PohBee_CheckPlayerCollisions();2223if (self->drawGroup != 1 && self->state != PohBee_State_Init)24PohBee_CheckOffScreen();25}2627void PohBee_LateUpdate(void) {}2829void PohBee_StaticUpdate(void) {}3031void PohBee_Draw(void) { PohBee_DrawSprites(); }3233void PohBee_Create(void *data)34{35RSDK_THIS(PohBee);3637self->visible = true;3839if (self->planeFilter > 0 && ((uint8)(self->planeFilter - 1) & 2))40self->drawGroup = Zone->objectDrawGroup[1];41else42self->drawGroup = Zone->objectDrawGroup[0];4344self->startPos = self->position;45self->startDir = self->direction;46self->drawFX = FX_FLIP;47self->active = ACTIVE_BOUNDS;48self->updateRange.x = 0x800000;49self->updateRange.y = 0x800000;50self->state = PohBee_State_Init;51}5253void PohBee_StageLoad(void)54{55if (RSDK.CheckSceneFolder("MMZ"))56PohBee->aniFrames = RSDK.LoadSpriteAnimation("MMZ/PohBee.bin", SCOPE_STAGE);5758PohBee->hitbox.left = -16;59PohBee->hitbox.top = -16;60PohBee->hitbox.right = 16;61PohBee->hitbox.bottom = 16;6263DEBUGMODE_ADD_OBJ(PohBee);64}6566void PohBee_DebugSpawn(void)67{68RSDK_THIS(PohBee);6970EntityPohBee *pohBee = CREATE_ENTITY(PohBee, NULL, self->position.x, self->position.y);71pohBee->direction = self->direction;72pohBee->startDir = self->direction;73}7475void PohBee_DebugDraw(void)76{77RSDK.SetSpriteAnimation(PohBee->aniFrames, 2, &DebugMode->animator, true, 0);78RSDK.DrawSprite(&DebugMode->animator, NULL, false);7980RSDK.SetSpriteAnimation(PohBee->aniFrames, 0, &DebugMode->animator, true, 0);81RSDK.DrawSprite(&DebugMode->animator, NULL, false);82}8384void PohBee_CheckOffScreen(void)85{86RSDK_THIS(PohBee);8788if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {89self->direction = self->startDir;90self->position = self->startPos;91PohBee_Create(NULL);92}93}9495void PohBee_CheckPlayerCollisions(void)96{97RSDK_THIS(PohBee);9899foreach_active(Player, player)100{101if (self->planeFilter <= 0 || player->collisionPlane == ((uint8)(self->planeFilter - 1) & 1)) {102if (Player_CheckBadnikTouch(player, self, &PohBee->hitbox)) {103if (self->drawGroup == 1) {104if (Player_CheckBadnikBreak(player, self, false)) {105CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y)->drawGroup = 1;106destroyEntity(self);107}108}109else {110Player_CheckBadnikBreak(player, self, true);111}112}113114for (int32 i = 0; i < self->spikeCount + 1; ++i) {115if (Player_CheckCollisionTouch(player, self, &self->hitboxes[i])) {116#if MANIA_USE_PLUS117int32 storeX = self->position.x;118int32 storeY = self->position.y;119self->position = PohBee_GetSpikePos(i, (self->drawGroup != 1) + 6);120if (!Player_CheckMightyUnspin(player, 0x300, 2, &player->uncurlTimer)) {121#endif122Player_Hurt(player, self);123#if MANIA_USE_PLUS124}125self->position.x = storeX;126self->position.y = storeY;127#endif128}129}130}131}132}133134void PohBee_DrawSprites(void)135{136RSDK_THIS(PohBee);137138self->drawFX = FX_FLIP;139140int32 offsetY = 16;141int32 shift = 7;142if (self->drawGroup == 1) {143offsetY = 15;144shift = 6;145self->drawFX |= FX_SCALE;146}147148if (self->bodyAnimator.animationID != 1)149RSDK.DrawSprite(&self->wingsAnimator, NULL, false);150151RSDK.DrawSprite(&self->bodyAnimator, NULL, false);152153Vector2 chainDrawPos;154chainDrawPos.x = self->position.x;155chainDrawPos.y = self->position.y + (16 << offsetY);156self->drawFX |= FX_ROTATE;157158int32 id = 4;159for (int32 i = 0; i < 10; ++i) {160Vector2 drawPos = chainDrawPos;161drawPos.x += (id * RSDK.Cos512(self->chainAngle[0])) << shift;162drawPos.y += (id * RSDK.Sin512(self->chainAngle[0])) << shift;163RSDK.DrawSprite(&self->chainAnimator, &drawPos, false);164id += 8;165}166167Vector2 drawPos = PohBee_GetSpikePos(0, shift);168RSDK.DrawSprite(&self->spikeAnimator, &drawPos, false);169170if (self->spikeCount == 1) {171id = 4;172for (int32 i = 0; i < 4; ++i) {173drawPos = chainDrawPos;174drawPos.x += (id * RSDK.Cos512(self->chainAngle[1])) << shift;175drawPos.y += (id * RSDK.Sin512(self->chainAngle[1])) << shift;176RSDK.DrawSprite(&self->chainAnimator, &drawPos, false);177id += 8;178}179180drawPos = PohBee_GetSpikePos(1, shift);181RSDK.DrawSprite(&self->spikeAnimator, &drawPos, false);182}183}184185Vector2 PohBee_GetSpikePos(uint8 spikeID, uint8 shift)186{187RSDK_THIS(PohBee);188189Vector2 spikePos = self->position;190spikePos.y = self->position.y + (self->drawGroup == 1 ? 0x100000 : 0x80000);191192switch (spikeID) {193default: break;194195case 0:196spikePos.x += (84 * RSDK.Cos512(self->chainAngle[0])) << shift;197spikePos.y += (84 * RSDK.Sin512(self->chainAngle[0])) << shift;198break;199200case 1:201spikePos.x += (36 * RSDK.Cos512(self->chainAngle[1])) << shift;202spikePos.y += (36 * RSDK.Sin512(self->chainAngle[1])) << shift;203break;204}205206return spikePos;207}208209void PohBee_SetupHitboxes(void)210{211RSDK_THIS(PohBee);212213for (int32 i = 0; i < 2; ++i) {214Vector2 pos = PohBee_GetSpikePos(i, 7);215int32 x = (pos.x - self->position.x) >> 16;216int32 y = (pos.y - self->position.y) >> 16;217218Hitbox hitbox;219hitbox.left = x - 12;220hitbox.top = y - 12;221hitbox.right = x + 12;222hitbox.bottom = y + 12;223if (self->direction == FLIP_X) {224hitbox.left = 12 - x;225hitbox.right = -hitbox.right;226}227228self->hitboxes[i] = hitbox;229}230}231232void PohBee_State_Init(void)233{234RSDK_THIS(PohBee);235236if (self->drawGroup != 1)237self->active = ACTIVE_NORMAL;238239self->position = self->startPos;240self->direction = self->startDir;241self->chainAngle[0] = 0x80;242self->chainAngle[1] = 0xAC;243244RSDK.SetSpriteAnimation(PohBee->aniFrames, 0, &self->bodyAnimator, true, 0);245RSDK.SetSpriteAnimation(PohBee->aniFrames, 2, &self->wingsAnimator, true, 0);246RSDK.SetSpriteAnimation(PohBee->aniFrames, 3, &self->chainAnimator, true, 0);247RSDK.SetSpriteAnimation(PohBee->aniFrames, 4, &self->spikeAnimator, true, 0);248249self->state = PohBee_State_Move;250251PohBee_State_Move();252}253254void PohBee_State_Move(void)255{256RSDK_THIS(PohBee);257258int32 distX = abs(self->position.x - self->startPos.x);259260int32 move = (2 * (self->direction != FLIP_NONE) - 1) << 15;261if (self->bodyAnimator.animationID == 1) {262switch (self->bodyAnimator.frameID) {263default:264case 0: break;265266case 1: move >>= 1; break;267case 2: move = 0; break;268case 3: move = (-0x8000 * (2 * (self->direction != FLIP_NONE) - 1)) >> 1; break;269case 4: move = -0x8000 * (2 * (self->direction != FLIP_NONE) - 1); break;270}271}272273self->position.x += move;274275if (distX < self->amplitude.x) {276self->isTurning = false;277}278else if (!self->bodyAnimator.animationID && !self->isTurning) {279RSDK.SetSpriteAnimation(PohBee->aniFrames, 1, &self->bodyAnimator, true, 0);280self->isTurning = true;281}282if (self->bodyAnimator.animationID == 1 && self->bodyAnimator.frameID == self->bodyAnimator.frameCount - 1) {283RSDK.SetSpriteAnimation(PohBee->aniFrames, 0, &self->bodyAnimator, true, 0);284self->direction = self->direction == FLIP_NONE;285}286287self->angle = (self->angle + 8) & 0x1FF;288self->position.y = self->startPos.y + (RSDK.Sin512(self->angle) << 7) * (self->amplitude.y >> 16);289290self->chainPos[0] = (self->chainPos[0] + 9) & 0x7FF;291self->chainAngle[0] = (0x70 * ((RSDK.Sin512(self->chainPos[0] >> 2) >> 2) + 0x88)) >> 7;292293self->chainPos[1] = (self->chainPos[1] + 10) & 0x7FF;294self->chainAngle[1] = (0x70 * ((RSDK.Sin512(self->chainPos[1] >> 2) >> 2) + 0x90)) >> 7;295}296297#if GAME_INCLUDE_EDITOR298void PohBee_EditorDraw(void)299{300RSDK_THIS(PohBee);301302self->chainAngle[0] = 0x80;303self->chainAngle[1] = 0xAC;304RSDK.SetSpriteAnimation(PohBee->aniFrames, 0, &self->bodyAnimator, true, 0);305RSDK.SetSpriteAnimation(PohBee->aniFrames, 2, &self->wingsAnimator, true, 0);306RSDK.SetSpriteAnimation(PohBee->aniFrames, 3, &self->chainAnimator, true, 0);307RSDK.SetSpriteAnimation(PohBee->aniFrames, 4, &self->spikeAnimator, true, 0);308309PohBee_DrawSprites();310}311312void PohBee_EditorLoad(void)313{314PohBee->aniFrames = RSDK.LoadSpriteAnimation("MMZ/PohBee.bin", SCOPE_STAGE);315316RSDK_ACTIVE_VAR(PohBee, direction);317RSDK_ENUM_VAR("Left", FLIP_NONE);318RSDK_ENUM_VAR("Right", FLIP_X);319320RSDK_ACTIVE_VAR(PohBee, spikeCount);321RSDK_ENUM_VAR("1 Spike", 0);322RSDK_ENUM_VAR("2 Spikes", 1);323324RSDK_ACTIVE_VAR(PohBee, planeFilter);325RSDK_ENUM_VAR("None", PLANEFILTER_NONE);326RSDK_ENUM_VAR("AL", PLANEFILTER_AL);327RSDK_ENUM_VAR("BL", PLANEFILTER_BL);328RSDK_ENUM_VAR("AH", PLANEFILTER_AH);329RSDK_ENUM_VAR("BH", PLANEFILTER_BH);330}331#endif332333void PohBee_Serialize(void)334{335RSDK_EDITABLE_VAR(PohBee, VAR_UINT8, direction);336RSDK_EDITABLE_VAR(PohBee, VAR_UINT8, spikeCount);337RSDK_EDITABLE_VAR(PohBee, VAR_VECTOR2, amplitude);338RSDK_EDITABLE_VAR(PohBee, VAR_ENUM, planeFilter);339}340341342