Path: blob/master/SonicMania/Objects/GHZ/Splats.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Splats Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectSplats *Splats;1011void Splats_Update(void)12{13RSDK_THIS(Splats);14StateMachine_Run(self->state);15}1617void Splats_LateUpdate(void) {}1819void Splats_StaticUpdate(void) {}2021void Splats_Draw(void)22{23RSDK_THIS(Splats);2425RSDK.DrawSprite(&self->splashAnimator, NULL, false);26RSDK.DrawSprite(&self->mainAnimator, NULL, false);27}2829void Splats_Create(void *data)30{31RSDK_THIS(Splats);3233self->startPos = self->position;34self->startDir = self->direction;35self->visible = true;36self->active = ACTIVE_BOUNDS;37self->updateRange.x = 0x800000;38self->updateRange.y = 0x800000;3940if (self->bounceCount < 1)41self->bounceCount = 1;4243if (Splats->initialState == Splats_State_BounceAround) {44self->drawFX |= FX_FLIP;45self->drawGroup = Zone->objectDrawGroup[0];46RSDK.SetSpriteAnimation(Splats->aniFrames, 0, &self->mainAnimator, true, 0);47self->state = Splats_State_Init;48}49else {50switch (VOID_TO_INT(data)) {51case SPLATS_SPAWNER:52self->drawGroup = Zone->objectDrawGroup[1];53self->delay = 0;54RSDK.SetSpriteAnimation(Splats->aniFrames, 1, &self->mainAnimator, true, 0);55self->state = Splats_State_Init;56break;5758case SPLATS_INKSPLATS:59self->drawFX |= FX_FLIP;60self->drawGroup = Zone->objectDrawGroup[0];61self->active = ACTIVE_NORMAL;62RSDK.SetSpriteAnimation(Splats->aniFrames, 0, &self->mainAnimator, true, 0);63self->mainAnimator.loopIndex = 1;64self->state = Splats_State_JumpOutOfJar;65self->mainAnimator.frameCount = 2;66break;6768case SPLATS_SPLAT:69self->drawFX |= FX_FLIP;70self->inkEffect |= INK_ALPHA;71self->alpha = 256;72self->drawGroup = Zone->objectDrawGroup[1];73self->active = ACTIVE_NORMAL;74RSDK.SetSpriteAnimation(Splats->aniFrames, 3, &self->mainAnimator, true, 0);75self->state = Splats_State_InkSplat;76break;77}78}79}8081void Splats_StageLoad(void)82{83if (RSDK.CheckSceneFolder("GHZ")) {84Splats->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Splats.bin", SCOPE_STAGE);8586Splats->initialState = Splats_State_BounceAround;87}88else if (RSDK.CheckSceneFolder("PSZ1")) {89Splats->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Splats.bin", SCOPE_STAGE);9091Splats->initialState = Splats_State_InkJarSpawner;92}9394Splats->hitboxBadnikGHZ.left = -10;95Splats->hitboxBadnikGHZ.top = -20;96Splats->hitboxBadnikGHZ.right = 6;97Splats->hitboxBadnikGHZ.bottom = 20;9899Splats->hitboxJar.left = -18;100Splats->hitboxJar.top = -26;101Splats->hitboxJar.right = 18;102Splats->hitboxJar.bottom = 17;103104Splats->hitboxBadnikPGZ.left = -18;105Splats->hitboxBadnikPGZ.top = -146;106Splats->hitboxBadnikPGZ.right = 18;107Splats->hitboxBadnikPGZ.bottom = -18;108109DEBUGMODE_ADD_OBJ(Splats);110111Splats->sfxSplatsSpawn = RSDK.GetSfx("PSZ/SplatsSpawn.wav");112Splats->sfxSplatsLand = RSDK.GetSfx("PSZ/SplatsLand.wav");113}114115void Splats_DebugDraw(void)116{117if (Splats->initialState == Splats_State_BounceAround)118RSDK.SetSpriteAnimation(Splats->aniFrames, 0, &DebugMode->animator, true, 0);119else120RSDK.SetSpriteAnimation(Splats->aniFrames, 1, &DebugMode->animator, true, 0);121122RSDK.DrawSprite(&DebugMode->animator, NULL, false);123}124125void Splats_DebugSpawn(void)126{127RSDK_THIS(DebugMode);128CREATE_ENTITY(Splats, NULL, self->position.x, self->position.y);129}130131void Splats_CheckPlayerCollisions(void)132{133RSDK_THIS(Splats);134135foreach_active(Player, player)136{137if (Player_CheckBadnikTouch(player, self, &Splats->hitboxBadnikGHZ)) {138if (Splats->initialState == Splats_State_BounceAround) {139Player_CheckBadnikBreak(player, self, true);140}141else {142if (Player_CheckBadnikBreak(player, self, false)) {143EntitySplats *parent = self->parent;144if (parent) {145if (parent->classID == Splats->classID)146--parent->activeCount;147}148destroyEntity(self);149foreach_break;150}151}152}153}154}155156void Splats_CheckOffScreen(void)157{158RSDK_THIS(Splats);159if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {160self->position = self->startPos;161self->direction = self->startDir;162self->isOnScreen = false;163Splats_Create(NULL);164}165}166167void Splats_State_Init(void)168{169RSDK_THIS(Splats);170self->active = ACTIVE_NORMAL;171self->velocity.x = -0x10000;172173self->state = Splats->initialState;174StateMachine_Run(self->state);175}176177void Splats_State_BounceAround(void)178{179RSDK_THIS(Splats);180181self->position.x += self->velocity.x;182self->position.y += self->velocity.y;183self->velocity.y += 0x3800;184185if (self->velocity.y > 0 && RSDK.ObjectTileCollision(self, Zone->collisionLayers, 0, 0, 0, 0x100000, true)) {186if (self->bounceCount && ++self->activeCount >= self->bounceCount) {187self->activeCount = 0;188self->direction ^= FLIP_X;189self->velocity.x = -self->velocity.x;190}191self->position.y -= 0x80000;192self->velocity.y = -0x40000;193}194195self->mainAnimator.frameID = self->velocity.y < 0;196197Splats_CheckPlayerCollisions();198Splats_CheckOffScreen();199}200201void Splats_State_SetupInkJar(void)202{203RSDK_THIS(Splats);204205self->isOnScreen = false;206self->delay = 0;207self->active = ACTIVE_NORMAL;208209self->state = Splats_State_InkJarSpawner;210Splats_State_InkJarSpawner();211}212213void Splats_State_InkJarSpawner(void)214{215RSDK_THIS(Splats);216217if (!self->isOnScreen) {218if (!self->onScreen)219return;220self->isOnScreen = true;221}222223RSDK.ProcessAnimation(&self->splashAnimator);224225bool32 disableSpawn = false;226foreach_active(Player, player)227{228Player_CheckCollisionBox(player, self, &Splats->hitboxJar);229disableSpawn |= Player_CheckCollisionTouch(player, self, &Splats->hitboxBadnikPGZ);230disableSpawn |= (player->animator.animationID == ANI_SPINDASH);231}232233if (--self->delay <= 0) {234if (disableSpawn || (self->activeCount >= self->numActive)) {235self->delay++;236}237else {238RSDK.SetSpriteAnimation(Splats->aniFrames, 2, &self->splashAnimator, true, 0);239self->delay = self->minDelay;240RSDK.PlaySfx(Splats->sfxSplatsSpawn, false, 0xFF);241242EntitySplats *splats = CREATE_ENTITY(Splats, INT_TO_VOID(SPLATS_INKSPLATS), self->position.x, self->position.y - 0x60000);243splats->parent = self;244splats->bounceCount = self->bounceCount;245splats->direction = self->direction;246splats->velocity.y = -0x60000;247if (self->direction == FLIP_NONE)248splats->velocity.x = -0x10000;249else250splats->velocity.x = 0x10000;251252++self->activeCount;253}254}255256if (!RSDK.CheckOnScreen(self, NULL)) {257self->state = Splats_State_SetupInkJar;258self->active = ACTIVE_NORMAL;259}260}261262void Splats_State_JumpOutOfJar(void)263{264RSDK_THIS(Splats);265266RSDK.ProcessAnimation(&self->mainAnimator);267268self->position.y += self->velocity.y;269self->velocity.y += 0x3800;270271if (self->velocity.y > -0x40000)272self->position.x += self->velocity.x;273274if (self->velocity.y > 0) {275self->mainAnimator.loopIndex = 4;276self->mainAnimator.frameCount = 5;277if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, 0, 0, 0, 0x120000, true)) {278RSDK.PlaySfx(Splats->sfxSplatsLand, false, 255);279EntitySplats *splat = CREATE_ENTITY(Splats, INT_TO_VOID(SPLATS_SPLAT), self->position.x, self->position.y);280splat->direction = self->direction;281self->delay = 4;282self->state = Splats_State_HandleLanding;283}284}285Splats_CheckPlayerCollisions();286}287288void Splats_State_HandleBouncing(void)289{290RSDK_THIS(Splats);291292RSDK.ProcessAnimation(&self->mainAnimator);293self->position.x += self->velocity.x;294self->position.y += self->velocity.y;295self->velocity.y += 0x3800;296297if (self->velocity.y > 0) {298self->mainAnimator.loopIndex = 4;299self->mainAnimator.frameCount = 5;300if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, 0, 0, 0, 0x120000, true)) {301RSDK.PlaySfx(Splats->sfxSplatsLand, false, 0xFF);302if (self->bounceCount) {303if (++self->activeCount < self->bounceCount) {304self->delay = 4;305self->state = Splats_State_HandleLanding;306}307else {308RSDK.SetSpriteAnimation(Splats->aniFrames, 4, &self->mainAnimator, true, 0);309self->state = Splats_State_NoMoreJumps;310self->activeCount = 0;311}312}313314EntitySplats *splat = CREATE_ENTITY(Splats, INT_TO_VOID(SPLATS_SPLAT), self->position.x, self->position.y);315splat->direction = self->direction;316}317}318319if (RSDK.CheckOnScreen(self, NULL)) {320Splats_CheckPlayerCollisions();321}322else {323EntitySplats *parent = self->parent;324if (parent && parent->classID == Splats->classID)325--parent->activeCount;326327destroyEntity(self);328}329}330331void Splats_State_HandleLanding(void)332{333RSDK_THIS(Splats);334335if (--self->delay <= 0) {336RSDK.SetSpriteAnimation(Splats->aniFrames, 0, &self->mainAnimator, true, 0);337self->mainAnimator.loopIndex = 1;338self->mainAnimator.frameCount = 2;339self->position.y -= 0x80000;340self->velocity.y = -0x40000;341self->state = Splats_State_HandleBouncing;342}343344if (RSDK.CheckOnScreen(self, NULL)) {345Splats_CheckPlayerCollisions();346}347else {348EntitySplats *parent = self->parent;349if (parent && parent->classID == Splats->classID)350--parent->activeCount;351352destroyEntity(self);353}354}355356void Splats_State_NoMoreJumps(void)357{358RSDK_THIS(Splats);359360RSDK.ProcessAnimation(&self->mainAnimator);361362if (self->mainAnimator.frameID == self->mainAnimator.frameCount - 1) {363RSDK.SetSpriteAnimation(Splats->aniFrames, 0, &self->mainAnimator, true, 0);364self->position.y -= 0x80000;365self->mainAnimator.frameCount = 2;366self->mainAnimator.loopIndex = 1;367self->direction ^= FLIP_X;368self->velocity.y = -0x40000;369self->velocity.x = -self->velocity.x;370self->state = Splats_State_HandleBouncing;371}372373if (RSDK.CheckOnScreen(self, NULL)) {374Splats_CheckPlayerCollisions();375}376else {377EntitySplats *parent = self->parent;378if (parent && parent->classID == Splats->classID)379--parent->activeCount;380381destroyEntity(self);382}383}384385void Splats_State_InkSplat(void)386{387RSDK_THIS(Splats);388RSDK.ProcessAnimation(&self->mainAnimator);389390if (self->delay >= 30) {391self->alpha -= 2;392if (!self->alpha)393destroyEntity(self);394}395else {396self->delay++;397}398}399400#if GAME_INCLUDE_EDITOR401void Splats_EditorDraw(void)402{403RSDK_THIS(Splats);404405if (RSDK.CheckSceneFolder("GHZ")) {406self->drawFX |= FX_FLIP;407self->drawGroup = Zone->objectDrawGroup[0];408RSDK.SetSpriteAnimation(Splats->aniFrames, 0, &self->mainAnimator, true, 0);409}410else {411self->drawFX = FX_NONE;412self->drawGroup = Zone->objectDrawGroup[1];413RSDK.SetSpriteAnimation(Splats->aniFrames, 1, &self->mainAnimator, true, 0);414}415416Splats_Draw();417}418419void Splats_EditorLoad(void)420{421if (RSDK.CheckSceneFolder("GHZ"))422Splats->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Splats.bin", SCOPE_STAGE);423else if (RSDK.CheckSceneFolder("PSZ1"))424Splats->aniFrames = RSDK.LoadSpriteAnimation("PSZ1/Splats.bin", SCOPE_STAGE);425426RSDK_ACTIVE_VAR(Splats, direction);427RSDK_ENUM_VAR("Left", FLIP_NONE);428RSDK_ENUM_VAR("Right", FLIP_X);429}430#endif431432void Splats_Serialize(void)433{434RSDK_EDITABLE_VAR(Splats, VAR_UINT8, bounceCount);435RSDK_EDITABLE_VAR(Splats, VAR_UINT8, direction);436RSDK_EDITABLE_VAR(Splats, VAR_UINT8, numActive);437RSDK_EDITABLE_VAR(Splats, VAR_UINT16, minDelay);438}439440441