Path: blob/master/SonicMania/Objects/MSZ/Cactula.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Cactula Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectCactula *Cactula;1011void Cactula_Update(void)12{13RSDK_THIS(Cactula);1415StateMachine_Run(self->state);16}1718void Cactula_LateUpdate(void) {}1920void Cactula_StaticUpdate(void) {}2122void Cactula_Draw(void)23{24RSDK_THIS(Cactula);2526Vector2 drawPos;27drawPos.x = self->position.x;28drawPos.y = self->position.y + self->offsetY;2930RSDK.DrawSprite(&self->bodyBottomAnimator, &drawPos, false);31RSDK.DrawSprite(&self->propellerAnimator, &drawPos, false);32RSDK.DrawSprite(&self->bodyTopAnimator, NULL, false);33}3435void Cactula_Create(void *data)36{37RSDK_THIS(Cactula);3839self->visible = true;40self->drawGroup = Zone->objectDrawGroup[0] + 1;41self->drawFX = FX_FLIP;42self->active = ACTIVE_BOUNDS;43self->updateRange.x = 0x800000;44self->updateRange.y = 0x800000;45self->offsetY = 0x80000;4647RSDK.SetSpriteAnimation(Cactula->aniFrames, 0, &self->bodyTopAnimator, true, 0);48RSDK.SetSpriteAnimation(Cactula->aniFrames, 0, &self->bodyBottomAnimator, true, 1);49RSDK.SetSpriteAnimation(Cactula->aniFrames, 1, &self->propellerAnimator, true, 0);5051self->state = Cactula_State_CheckPlayerInRange;52}5354void Cactula_StageLoad(void)55{56if (RSDK.CheckSceneFolder("MSZ"))57Cactula->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Cactula.bin", SCOPE_STAGE);5859Cactula->hitboxBadnik.left = -12;60Cactula->hitboxBadnik.top = -12;61Cactula->hitboxBadnik.right = 12;62Cactula->hitboxBadnik.bottom = 12;6364DEBUGMODE_ADD_OBJ(Cactula);6566Cactula->sfxCactDrop = RSDK.GetSfx("MSZ/CactDrop.wav");67Soundboard_LoadSfx("MSZ/CactChopper.wav", true, Cactula_SfxChecK_CactChopper, StateMachine_None);68}6970void Cactula_DebugSpawn(void)71{72RSDK_THIS(DebugMode);7374CREATE_ENTITY(Cactula, NULL, self->position.x, self->position.y);75}7677void Cactula_DebugDraw(void)78{79RSDK.SetSpriteAnimation(Cactula->aniFrames, 0, &DebugMode->animator, true, 0);80RSDK.DrawSprite(&DebugMode->animator, NULL, false);81}8283void Cactula_CheckPlayerCollisions(void)84{85RSDK_THIS(Cactula);8687foreach_active(Player, player)88{89if (Player_CheckBadnikTouch(player, self, &Cactula->hitboxBadnik))90Player_CheckBadnikBreak(player, self, true);91}92}9394bool32 Cactula_SfxChecK_CactChopper(void)95{96int32 count = 0;9798foreach_active(Cactula, cactula)99{100if (cactula->state == Cactula_State_Rising || cactula->state == Cactula_State_DropBomb)101++count;102}103104return count > 0;105}106107void Cactula_State_CheckPlayerInRange(void)108{109RSDK_THIS(Cactula);110111EntityPlayer *player = Player_GetNearestPlayerX();112113if (abs(self->position.x - player->position.x) < 0x800000) {114self->velocity.y = -0x20000;115self->state = Cactula_State_Rising;116}117118Cactula_CheckPlayerCollisions();119}120121void Cactula_State_Rising(void)122{123RSDK_THIS(Cactula);124125RSDK.ProcessAnimation(&self->propellerAnimator);126127self->offsetY += self->velocity.y;128self->velocity.y += 0x4000;129130if (self->offsetY >= 0 && self->velocity.y >= 0) {131self->offsetY = 0;132self->velocity.y = -0xA000;133self->state = Cactula_State_DropBomb;134}135Cactula_CheckPlayerCollisions();136}137138void Cactula_State_DropBomb(void)139{140RSDK_THIS(Cactula);141142RSDK.ProcessAnimation(&self->propellerAnimator);143144self->velocity.y += 0x100;145self->position.y += self->velocity.y;146147EntityPlayer *player = Player_GetNearestPlayerX();148if (RSDK.CheckOnScreen(self, NULL) || self->position.y <= player->position.y) {149if (!self->droppedBomb && abs(self->position.x - player->position.x) < 0x100000) {150RSDK.PlaySfx(Cactula->sfxCactDrop, false, 255);151EntityProjectile *projectile = CREATE_ENTITY(Projectile, Projectile_State_MoveGravity, self->position.x, self->position.y);152projectile->gravityStrength = 0x3800;153projectile->drawGroup = Zone->objectDrawGroup[0];154projectile->hitbox.left = -6;155projectile->hitbox.top = -6;156projectile->hitbox.right = 6;157projectile->hitbox.bottom = 6;158projectile->type = PROJECTILE_BASIC2;159projectile->hurtDelay = 16;160RSDK.SetSpriteAnimation(Cactula->aniFrames, 2, &projectile->animator, true, 0);161self->droppedBomb = true;162}163164if (RSDK.GetTile(Zone->fgLayer[1], self->position.x >> 20, self->position.y >> 20) == (uint16)-1)165Cactula_CheckPlayerCollisions();166}167else {168destroyEntity(self);169}170}171172#if GAME_INCLUDE_EDITOR173void Cactula_EditorDraw(void) { Cactula_Draw(); }174175void Cactula_EditorLoad(void) { Cactula->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Cactula.bin", SCOPE_STAGE); }176#endif177178void Cactula_Serialize(void) {}179180181