Path: blob/master/SonicMania/Objects/SSZ/Dango.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Dango Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectDango *Dango;1011void Dango_Update(void)12{13RSDK_THIS(Dango);1415StateMachine_Run(self->state);1617if (self->rollDelay > 0)18self->rollDelay--;19}2021void Dango_LateUpdate(void) {}2223void Dango_StaticUpdate(void) {}2425void Dango_Draw(void)26{27RSDK_THIS(Dango);2829RSDK.DrawSprite(&self->animator, NULL, false);30}3132void Dango_Create(void *data)33{34RSDK_THIS(Dango);3536self->visible = true;37self->drawGroup = Zone->objectDrawGroup[0];38self->drawFX |= FX_FLIP;39self->startPos = self->position;40self->startDir = self->direction;41self->active = ACTIVE_BOUNDS;42self->updateRange.x = 0x800000;43self->updateRange.y = 0x800000;4445RSDK.SetSpriteAnimation(Dango->aniFrames, 1, &self->animator, true, 0);46self->state = Dango_State_Init;47}4849void Dango_StageLoad(void)50{51if (RSDK.CheckSceneFolder("SSZ1"))52Dango->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/Dango.bin", SCOPE_STAGE);53else if (RSDK.CheckSceneFolder("SSZ2"))54Dango->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/Dango.bin", SCOPE_STAGE);5556Dango->hitboxBadnik.top = -14;57Dango->hitboxBadnik.left = -14;58Dango->hitboxBadnik.right = 14;59Dango->hitboxBadnik.bottom = 14;6061Dango->hitboxCurlRange.top = -128;62Dango->hitboxCurlRange.left = -112;63Dango->hitboxCurlRange.right = -18;64Dango->hitboxCurlRange.bottom = 128;6566Dango->sfxBumper = RSDK.GetSfx("Stage/Bumper3.wav");6768DEBUGMODE_ADD_OBJ(Dango);69}7071void Dango_DebugSpawn(void)72{73RSDK_THIS(DebugMode);7475EntityDango *dango = CREATE_ENTITY(Dango, NULL, self->position.x, self->position.y);76RSDK.SetSpriteAnimation(Dango->aniFrames, 2, &dango->animator, true, 0);7778dango->state = Dango_State_Falling_Curled;79dango->groundVel = dango->direction == FLIP_NONE ? -0x20000 : 0x20000;80}8182void Dango_DebugDraw(void)83{84RSDK.SetSpriteAnimation(Dango->aniFrames, 0, &DebugMode->animator, true, 0);85RSDK.DrawSprite(&DebugMode->animator, NULL, false);86}8788void Dango_CheckOffScreen(void)89{90RSDK_THIS(Dango);9192if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {93self->position = self->startPos;94self->direction = self->startDir;95Dango_Create(NULL);96}97}9899void Dango_CheckPlayerCollisions(void)100{101RSDK_THIS(Dango);102103foreach_active(Player, player)104{105if (Player_CheckBadnikTouch(player, self, &Dango->hitboxBadnik)) {106int32 anim = player->animator.animationID;107108bool32 bumpPlayer = anim == ANI_JUMP || anim == ANI_SPINDASH || anim == ANI_DROPDASH;109bumpPlayer &= self->state == Dango_State_Rolling;110#if MANIA_USE_PLUS111if (player->characterID == ID_MIGHTY)112bumpPlayer |= anim == ANI_CROUCH || player->jumpAbilityState > 1;113bumpPlayer &= player->state != Player_State_MightyHammerDrop;114#endif115116if (bumpPlayer) {117if (anim != ANI_JUMP)118RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);119RSDK.PlaySfx(Dango->sfxBumper, false, 0xFF);120121if (player->velocity.x <= 0) {122if (self->groundVel > player->velocity.x) {123if (self->groundVel > -0x20000)124self->groundVel = -0x20000;125}126}127else if (self->groundVel < player->velocity.x) {128self->groundVel = player->velocity.x;129if (self->groundVel < 0x20000)130self->groundVel = 0x20000;131}132133self->velocity.x = self->groundVel;134135#if MANIA_USE_PLUS136if (!(player->characterID == ID_MIGHTY && player->jumpAbilityState > 1)) {137#endif138player->groundVel = (player->position.x - self->position.x) >> 2;139player->velocity.x = player->groundVel;140player->velocity.y = (player->position.y - self->position.y) >> 2;141player->onGround = false;142#if MANIA_USE_PLUS143}144#endif145146if ((self->position.x > player->position.x && self->velocity.x < 0)147|| (self->position.x < player->position.x && self->velocity.x > 0)) {148self->groundVel = -self->groundVel;149self->velocity.x = -self->velocity.x;150}151}152else {153Player_CheckBadnikBreak(player, self, true);154}155}156}157}158159bool32 Dango_HandleMovement(StateMachine(nextState), uint8 anim)160{161RSDK_THIS(Dango);162163bool32 changeState = false;164165int32 storeX = self->position.x;166int32 storeY = self->position.y;167self->position.x += self->groundVel;168169bool32 collidedWall = false;170if (self->groundVel <= 0)171collidedWall = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_RWALL, 0, Dango->hitboxBadnik.left << 16, 0, 4);172else173collidedWall = RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_LWALL, 0, Dango->hitboxBadnik.right << 16, 0, 4);174175if (RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xD0000, 2)) {176uint16 tile = RSDK.GetTile(Zone->fgLayer[0], self->position.x >> 16, (self->position.y + 0xD0000) >> 16);177self->angle = RSDK.GetTileAngle(tile, 0, 0);178179if (self->groundVel <= 0) {180if (self->angle < 0x80 && self->angle > 0x10)181changeState = true;182else183self->velocity.x = (self->groundVel >> 8) * RSDK.Cos256(self->angle);184}185else {186if ((uint32)(self->angle - 0x81) <= 0x6E)187changeState = true;188else189self->velocity.x = (self->groundVel >> 8) * RSDK.Cos256(self->angle);190}191}192else {193changeState = true;194}195196if (collidedWall)197changeState = true;198199if (self->preventStateChange)200changeState = false;201202if (changeState) {203self->position.x = storeX;204self->position.y = storeY;205RSDK.SetSpriteAnimation(Dango->aniFrames, anim, &self->animator, true, 0);206207self->state = nextState;208self->preventStateChange = true;209}210211return changeState;212}213214void Dango_State_Init(void)215{216RSDK_THIS(Dango);217218self->active = ACTIVE_NORMAL;219self->groundVel = self->direction == FLIP_NONE ? -0x6000 : 0x6000;220self->velocity.y = 0;221222self->state = Dango_State_Walking;223Dango_State_Walking();224}225226void Dango_State_Walking(void)227{228RSDK_THIS(Dango);229230if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xD0000, false)) {231RSDK.ProcessAnimation(&self->animator);232233Dango_CheckPlayerCollisions();234Dango_CheckOffScreen();235236if (!Dango_HandleMovement(Dango_State_Turning, 5) && self->rollDelay <= 0) {237foreach_active(Player, player)238{239if (Player_CheckCollisionTouch(player, self, &Dango->hitboxCurlRange)) {240RSDK.SetSpriteAnimation(Dango->aniFrames, 3, &self->animator, true, 0);241self->state = Dango_State_Curling;242}243}244}245}246else {247self->state = Dango_State_Falling_Uncurled;248Dango_State_Falling_Uncurled();249}250}251252void Dango_State_Turning(void)253{254RSDK_THIS(Dango);255256RSDK.ProcessAnimation(&self->animator);257258if (self->animator.frameID == self->animator.frameCount - 1) {259RSDK.SetSpriteAnimation(Dango->aniFrames, 1, &self->animator, true, 0);260self->preventStateChange = false;261self->groundVel = -self->groundVel;262self->velocity.x = -self->velocity.x;263264self->state = Dango_State_Walking;265self->direction ^= FLIP_X;266}267else {268Dango_CheckPlayerCollisions();269Dango_CheckOffScreen();270}271}272273void Dango_State_Falling_Uncurled(void)274{275RSDK_THIS(Dango);276277RSDK.ProcessAnimation(&self->animator);278279self->position.x += self->groundVel;280self->position.y += self->velocity.y;281self->velocity.y += 0x3800;282283if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xD0000, true)) {284self->velocity.y = 0;285RSDK.SetSpriteAnimation(Dango->aniFrames, 1, &self->animator, true, 0);286287self->state = Dango_State_Walking;288}289else {290Dango_CheckPlayerCollisions();291Dango_CheckOffScreen();292}293}294295void Dango_State_Curling(void)296{297RSDK_THIS(Dango);298299RSDK.ProcessAnimation(&self->animator);300if (self->animator.frameID == self->animator.frameCount - 1) {301RSDK.SetSpriteAnimation(Dango->aniFrames, 2, &self->animator, true, 0);302self->state = Dango_State_Rolling;303self->groundVel = self->direction == FLIP_NONE ? -0x20000 : 0x20000;304}305else {306Dango_CheckPlayerCollisions();307Dango_CheckOffScreen();308}309}310311void Dango_State_Rolling(void)312{313RSDK_THIS(Dango);314315RSDK.ProcessAnimation(&self->animator);316317if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xD0000, false)) {318Dango_CheckPlayerCollisions();319Dango_CheckOffScreen();320321Dango_HandleMovement(Dango_State_Uncurling, 4);322}323else {324self->state = Dango_State_Falling_Curled;325Dango_State_Falling_Curled();326}327}328329void Dango_State_Falling_Curled(void)330{331RSDK_THIS(Dango);332333RSDK.ProcessAnimation(&self->animator);334335self->position.x += self->groundVel;336self->position.y += self->velocity.y;337self->velocity.y += 0x3800;338339if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xD0000, true)) {340self->velocity.y = 0;341self->state = Dango_State_Rolling;342}343else {344Dango_CheckPlayerCollisions();345Dango_CheckOffScreen();346}347}348349void Dango_State_Uncurling(void)350{351RSDK_THIS(Dango);352353RSDK.ProcessAnimation(&self->animator);354355if (self->animator.frameID == self->animator.frameCount - 1) {356RSDK.SetSpriteAnimation(Dango->aniFrames, 1, &self->animator, true, 0);357self->preventStateChange = false;358self->rollDelay = 30;359self->groundVel = self->direction == FLIP_NONE ? -0x6000 : 0x6000;360self->state = Dango_State_Walking;361}362else {363Dango_CheckPlayerCollisions();364Dango_CheckOffScreen();365}366}367368#if MANIA_USE_PLUS369void Dango_StateTaunt_Setup(void)370{371RSDK_THIS(Dango);372373if (++self->timer == 180) {374self->timer = 0;375self->groundVel = 0x60000;376self->state = Dango_StateTaunt_RollIn;377378RSDK.SetSpriteAnimation(Dango->aniFrames, 2, &self->animator, true, 0);379}380}381382void Dango_StateTaunt_RollIn(void)383{384RSDK_THIS(Dango);385386RSDK.ProcessAnimation(&self->animator);387388self->position.x += self->groundVel;389RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0xE0000, 14);390391foreach_active(PhantomRuby, ruby)392{393if (abs(self->position.x - ruby->position.x) < 0x120000) {394RSDK.PlaySfx(Dango->sfxBumper, false, 255);395self->state = Dango_StateTaunt_KnockedRuby;396ruby->state = PhantomRuby_State_MoveGravity;397ruby->velocity.x = self->groundVel;398ruby->velocity.y = -0x80000;399400RSDK.SetSpriteAnimation(Dango->aniFrames, 4, &self->animator, true, 0);401}402}403}404405void Dango_StateTaunt_KnockedRuby(void)406{407RSDK_THIS(Dango);408409RSDK.ProcessAnimation(&self->animator);410411self->groundVel -= self->groundVel >> 2;412self->position.x += self->groundVel;413414if (self->groundVel < 0x8000) {415RSDK.SetSpriteAnimation(Dango->aniFrames, 6, &self->animator, true, 0);416self->state = Dango_StateTaunt_Taunting;417}418}419420void Dango_StateTaunt_Taunting(void)421{422RSDK_THIS(Dango);423424RSDK.ProcessAnimation(&self->animator);425426if (self->animator.frameID == self->animator.frameCount - 1)427++self->timer;428429if (self->timer == 32) {430RSDK.SetSpriteAnimation(Dango->aniFrames, 5, &self->animator, true, 0);431self->timer = 0;432self->state = Dango_StateTaunt_Turning;433}434}435436void Dango_StateTaunt_Turning(void)437{438RSDK_THIS(Dango);439440RSDK.ProcessAnimation(&self->animator);441442if (self->animator.frameID == self->animator.frameCount - 1) {443RSDK.SetSpriteAnimation(Dango->aniFrames, 3, &self->animator, true, 0);444self->direction = FLIP_NONE;445self->state = Dango_StateTaunt_RollOut;446}447}448449void Dango_StateTaunt_RollOut(void)450{451RSDK_THIS(Dango);452453RSDK.ProcessAnimation(&self->animator);454455if (self->animator.animationID == 3) {456if (self->animator.frameID == self->animator.frameCount - 1)457RSDK.SetSpriteAnimation(Dango->aniFrames, 2, &self->animator, true, 0);458}459else {460self->position.x -= 0x40000;461}462463if (!RSDK.CheckOnScreen(self, NULL))464destroyEntity(self);465}466#endif467468#if GAME_INCLUDE_EDITOR469void Dango_EditorDraw(void) { Dango_Draw(); }470471void Dango_EditorLoad(void)472{473if (RSDK.CheckSceneFolder("SSZ1"))474Dango->aniFrames = RSDK.LoadSpriteAnimation("SSZ1/Dango.bin", SCOPE_STAGE);475else if (RSDK.CheckSceneFolder("SSZ2"))476Dango->aniFrames = RSDK.LoadSpriteAnimation("SSZ2/Dango.bin", SCOPE_STAGE);477}478#endif479480void Dango_Serialize(void) {}481482483