Path: blob/master/SonicMania/Objects/LRZ/Fireworm.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Fireworm Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectFireworm *Fireworm;1011void Fireworm_Update(void)12{13RSDK_THIS(Fireworm);1415StateMachine_Run(self->state);16}1718void Fireworm_LateUpdate(void) {}1920void Fireworm_StaticUpdate(void) {}2122void Fireworm_Draw(void)23{24RSDK_THIS(Fireworm);2526self->drawFX &= ~FX_FLIP;27Fireworm->holeAnimator.frameID = 0;28RSDK.DrawSprite(&Fireworm->holeAnimator, &self->startPos, false);2930self->drawFX |= FX_FLIP;31if (self->state) {32// Draw Body33for (int32 i = FIREWORM_SEGMENT_COUNT - 1; i > 0; --i) {34self->direction = self->bodyDirections[i];35RSDK.DrawSprite(&self->bodyAnimators[i], &self->bodyPositions[i], false);36RSDK.DrawSprite(&self->flameAnimators[i], &self->bodyPositions[i], false);37}3839// Draw Head40self->direction = self->bodyDirections[0];41RSDK.DrawSprite(&self->bodyAnimators[0], NULL, false);42}43}4445void Fireworm_Create(void *data)46{47RSDK_THIS(Fireworm);4849self->drawFX |= FX_FLIP;5051// Head52RSDK.SetSpriteAnimation(Fireworm->aniFrames, 0, &self->bodyAnimators[0], true, 0);5354if (!SceneInfo->inEditor) {55for (int32 i = 0; i < FIREWORM_SEGMENT_COUNT; ++i) {56self->bodyPositions[i].x = self->position.x;57self->bodyPositions[i].y = self->position.y;58self->bodyOriginY[i] = self->position.y;59}6061self->startPos = self->position;62self->startDir = self->direction;63self->visible = true;64self->active = ACTIVE_BOUNDS;65self->updateRange.x = 0x800000;66self->updateRange.y = 0x800000;67self->drawGroup = Zone->objectDrawGroup[0];68self->state = Fireworm_State_Init;69}70}7172void Fireworm_StageLoad(void)73{74if (RSDK.CheckSceneFolder("LRZ1"))75Fireworm->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Fireworm.bin", SCOPE_STAGE);76else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3"))77Fireworm->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/Fireworm.bin", SCOPE_STAGE);7879RSDK.SetSpriteAnimation(Fireworm->aniFrames, 6, &Fireworm->holeAnimator, true, 0);8081Fireworm->hitboxBadnik.left = -8;82Fireworm->hitboxBadnik.top = -8;83Fireworm->hitboxBadnik.right = 8;84Fireworm->hitboxBadnik.bottom = 8;8586Fireworm->hitboxRange.left = -128;87Fireworm->hitboxRange.top = -128;88Fireworm->hitboxRange.right = 128;89Fireworm->hitboxRange.bottom = 128;9091DEBUGMODE_ADD_OBJ(Fireworm);92}9394void Fireworm_DebugSpawn(void)95{96RSDK_THIS(DebugMode);9798CREATE_ENTITY(Fireworm, NULL, self->position.x, self->position.y);99}100101void Fireworm_DebugDraw(void)102{103RSDK.SetSpriteAnimation(Fireworm->aniFrames, 0, &DebugMode->animator, true, 0);104RSDK.DrawSprite(&DebugMode->animator, NULL, false);105}106107void Fireworm_CheckPlayerCollisions(void)108{109RSDK_THIS(Fireworm);110111foreach_active(Player, player)112{113// Collide with the head114self->position.x = self->bodyPositions[0].x;115self->position.y = self->bodyPositions[0].y;116117if (Player_CheckBadnikTouch(player, self, &Fireworm->hitboxBadnik) && Player_CheckBadnikBreak(player, self, false)) {118for (int32 i = 1; i < FIREWORM_SEGMENT_COUNT; ++i) {119EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->bodyPositions[i].x, self->bodyPositions[i].y);120RSDK.SetSpriteAnimation(Fireworm->aniFrames, 3, &debris->animator, true, 0);121debris->velocity.x = RSDK.Rand(-0x40000, 0x40000);122debris->velocity.y = RSDK.Rand(-0x40000, 0x40000);123debris->gravityStrength = 0x3800;124debris->drawGroup = Zone->objectDrawGroup[0];125debris->updateRange.x = 0x400000;126debris->updateRange.y = 0x400000;127}128129self->state = StateMachine_None;130foreach_break;131}132else {133// Collide with the rest of the body134for (int32 i = 1; i < FIREWORM_SEGMENT_COUNT; ++i) {135self->position.x = self->bodyPositions[i].x;136self->position.y = self->bodyPositions[i].y;137138if (Player_CheckCollisionTouch(player, self, &Fireworm->hitboxBadnik)) {139#if MANIA_USE_PLUS140if (!Player_CheckMightyUnspin(player, 0x300, 2, &player->uncurlTimer))141#endif142Player_Hurt(player, self);143}144}145}146}147148if (self->state) {149self->position.x = self->bodyPositions[0].x;150self->position.y = self->bodyPositions[0].y;151}152}153154void Fireworm_CheckOffScreen(void)155{156RSDK_THIS(Fireworm);157158if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {159self->timer = 0;160self->position = self->startPos;161self->direction = self->startDir;162163for (int32 i = 0; i < FIREWORM_SEGMENT_COUNT; ++i) {164self->bodyVelocities[i].x = 0;165self->bodyAngles[i] = 0;166self->bodyTimers[i] = 0;167168if (i > 0) {169RSDK.SetSpriteAnimation(-1, 0, &self->bodyAnimators[i], true, 0);170RSDK.SetSpriteAnimation(-1, 0, &self->flameAnimators[i], true, 0);171}172}173174Fireworm_Create(NULL);175}176}177178void Fireworm_State_Init(void)179{180RSDK_THIS(Fireworm);181182self->active = ACTIVE_NORMAL;183184self->state = Fireworm_State_AwaitPlayer;185Fireworm_State_AwaitPlayer();186}187188void Fireworm_State_AwaitPlayer(void)189{190RSDK_THIS(Fireworm);191192foreach_active(Player, player)193{194if (Player_CheckCollisionTouch(player, self, &Fireworm->hitboxRange)) {195for (int32 i = 0; i < FIREWORM_SEGMENT_COUNT; ++i) {196self->bodyDirections[i] = player->position.x >= self->position.x;197}198199self->startDir = self->bodyDirections[0];200201if (self->startDir) {202self->bodyVelocities[0].x = 0x10000;203self->boundsL = self->position.x - 0x3C0000;204self->boundsR = self->position.x + 0xBC0000;205}206else {207self->bodyVelocities[0].x = -0x10000;208self->boundsL = self->position.x - 0xBC0000;209self->boundsR = self->position.x + 0x3C0000;210}211212self->state = Fireworm_State_HeadAppear;213foreach_break;214}215}216217if (self->state == Fireworm_State_BodyAppear)218Fireworm_CheckOffScreen();219}220221void Fireworm_State_HeadAppear(void)222{223RSDK_THIS(Fireworm);224225RSDK.ProcessAnimation(&self->bodyAnimators[0]);226227if (self->bodyAnimators[0].frameID == 3) {228for (int32 i = 1; i < FIREWORM_SEGMENT_COUNT; ++i) {229RSDK.SetSpriteAnimation(Fireworm->aniFrames, 3, &self->bodyAnimators[i], true, 0);230self->flameExhaustDelays[i] = RSDK.Rand(0, 60);231}232233self->state = Fireworm_State_BodyAppear;234}235}236237void Fireworm_State_BodyAppear(void)238{239RSDK_THIS(Fireworm);240241++self->timer;242243for (int32 i = 0; i < FIREWORM_SEGMENT_COUNT; ++i) {244if (self->timer == (i * 10) + 4) {245self->bodyVelocities[i].x = self->bodyDirections[i] ? 0x10000 : -0x10000;246247if (i == FIREWORM_SEGMENT_COUNT - 1) {248self->timer = 0;249self->state = Fireworm_State_FlyAround;250}251}252}253254Fireworm_State_FlyAround();255}256257void Fireworm_State_FlyAround(void)258{259RSDK_THIS(Fireworm);260261for (int32 i = 0; i < FIREWORM_SEGMENT_COUNT; ++i) {262if (!self->bodyVelocities[i].x)263continue;264265RSDK.ProcessAnimation(&self->bodyAnimators[i]);266RSDK.ProcessAnimation(&self->flameAnimators[i]);267268self->bodyPositions[i].x += self->bodyVelocities[i].x;269270if (self->bodyVelocities[i].x <= 0) {271if (self->bodyPositions[i].x > self->boundsL) {272self->bodyVelocities[i].x -= 0xC00;273274if (self->bodyVelocities[i].x < -0x10000)275self->bodyVelocities[i].x = -0x10000;276}277else {278self->bodyVelocities[i].x += 0xC00;279280if (self->bodyVelocities[i].x > 0x10000)281self->bodyVelocities[i].x = 0x10000;282283if (!self->bodyTimers[i]) {284if (i)285RSDK.SetSpriteAnimation(Fireworm->aniFrames, 4, &self->bodyAnimators[i], true, 0);286else287RSDK.SetSpriteAnimation(Fireworm->aniFrames, 2, &self->bodyAnimators[i], true, 0);288289self->bodyDirections[i] = FLIP_X;290self->bodyVelocities[i].y = self->startDir ? 0x10000 : -0x10000;291self->bodyTimers[i] = 32;292}293}294}295else {296if (self->bodyPositions[i].x < self->boundsR) {297self->bodyVelocities[i].x += 0xC00;298299if (self->bodyVelocities[i].x > 0x10000)300self->bodyVelocities[i].x = 0x10000;301}302else {303self->bodyVelocities[i].x -= 0xC00;304305if (self->bodyVelocities[i].x < -0x10000)306self->bodyVelocities[i].x = -0x10000;307308if (!self->bodyTimers[i]) {309if (i)310RSDK.SetSpriteAnimation(Fireworm->aniFrames, 4, &self->bodyAnimators[i], true, 0);311else312RSDK.SetSpriteAnimation(Fireworm->aniFrames, 2, &self->bodyAnimators[i], true, 0);313314self->bodyDirections[i] = FLIP_NONE;315self->bodyVelocities[i].y = self->startDir ? -0x10000 : 0x10000;316self->bodyTimers[i] = 32;317}318}319}320321if (self->bodyTimers[i]) {322self->bodyTimers[i]--;323self->bodyOriginY[i] += self->bodyVelocities[i].y;324}325326if (!--self->flameExhaustDelays[i]) {327RSDK.SetSpriteAnimation(Fireworm->aniFrames, 5, &self->flameAnimators[i], true, 0);328self->flameExhaustDelays[i] = RSDK.Rand(0, 60) + 32;329}330331self->bodyAngles[i] += 16;332self->bodyPositions[i].y = (RSDK.Sin1024(self->bodyAngles[i]) << 8) + self->bodyOriginY[i];333self->bodyAngles[i] %= 0xC00;334}335336Fireworm_CheckPlayerCollisions();337Fireworm_CheckOffScreen();338}339340#if GAME_INCLUDE_EDITOR341void Fireworm_EditorDraw(void)342{343RSDK_THIS(Fireworm);344345for (int32 i = 0; i < FIREWORM_SEGMENT_COUNT; ++i) {346self->bodyPositions[i].x = self->position.x + (self->direction ? 0x100000 : -0x100000) * i;347self->bodyPositions[i].y = self->position.y;348self->bodyOriginY[i] = self->position.y;349}350351self->startPos.x = self->position.x;352self->startPos.y = self->position.y;353self->startDir = self->direction;354355for (int32 i = 1; i < FIREWORM_SEGMENT_COUNT; ++i) {356RSDK.SetSpriteAnimation(Fireworm->aniFrames, 3, &self->bodyAnimators[i], true, 0);357}358359Fireworm_Draw();360}361362void Fireworm_EditorLoad(void)363{364if (RSDK.CheckSceneFolder("LRZ1"))365Fireworm->aniFrames = RSDK.LoadSpriteAnimation("LRZ1/Fireworm.bin", SCOPE_STAGE);366else if (RSDK.CheckSceneFolder("LRZ2") || RSDK.CheckSceneFolder("LRZ3"))367Fireworm->aniFrames = RSDK.LoadSpriteAnimation("LRZ2/Fireworm.bin", SCOPE_STAGE);368369RSDK.SetSpriteAnimation(Fireworm->aniFrames, 6, &Fireworm->holeAnimator, true, 0);370371RSDK_ACTIVE_VAR(Fireworm, direction);372RSDK_ENUM_VAR("Left", FLIP_NONE);373RSDK_ENUM_VAR("Right", FLIP_X);374}375#endif376377void Fireworm_Serialize(void) { RSDK_EDITABLE_VAR(Fireworm, VAR_UINT8, direction); }378379380