Path: blob/master/SonicMania/Objects/AIZ/Sweep.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Sweep Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectSweep *Sweep;1011void Sweep_Update(void)12{13RSDK_THIS(Sweep);14StateMachine_Run(self->state);15if (self->state != Sweep_State_Projectile) {16EntityWater *water = self->water;17if (water)18self->position.y = water->position.y - (water->size.y >> 1) - 0x90000;19else20self->position.y = Water->waterLevel - 0x90000;21}22}2324void Sweep_LateUpdate(void) {}2526void Sweep_StaticUpdate(void) {}2728void Sweep_Draw(void)29{30RSDK_THIS(Sweep);31RSDK.DrawSprite(&self->animator, NULL, false);32}3334void Sweep_Create(void *data)35{36RSDK_THIS(Sweep);3738if (!SceneInfo->inEditor) {39self->visible = true;40self->drawFX |= FX_FLIP;41self->drawGroup = Zone->objectDrawGroup[0];42self->startPos = self->position;43self->startDir = self->direction;44self->timer = 128;45self->hasShot = false;4647if (data) {48self->active = ACTIVE_NORMAL;49self->updateRange.x = 0x200000;50self->updateRange.y = 0x200000;51RSDK.SetSpriteAnimation(Sweep->aniFrames, 4, &self->animator, true, 0);52self->state = Sweep_State_Projectile;53}54else {55self->active = ACTIVE_BOUNDS;56self->updateRange.x = 0x800000;57self->updateRange.y = 0x800000;58RSDK.SetSpriteAnimation(Sweep->aniFrames, 0, &self->animator, true, 0);5960foreach_all(Water, water)61{62Hitbox hitboxWater;63Hitbox hitbox;6465hitboxWater.right = water->size.x >> 17;66hitboxWater.left = -(water->size.x >> 17);67hitboxWater.bottom = water->size.y >> 17;68hitboxWater.top = -(water->size.y >> 17);6970hitbox.left = 1;71hitbox.top = 64;72hitbox.right = 1;73hitbox.bottom = 64;74if (water->type == WATER_POOL && RSDK.CheckObjectCollisionTouchBox(water, &hitboxWater, self, &hitbox)) {75self->water = water;76}77}78self->state = Sweep_State_Init;79}80}81}8283void Sweep_StageLoad(void)84{85if (RSDK.CheckSceneFolder("CPZ"))86Sweep->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Sweep.bin", SCOPE_STAGE);87#if MANIA_USE_PLUS88else if (RSDK.CheckSceneFolder("AIZ"))89Sweep->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Sweep.bin", SCOPE_STAGE);90#endif9192Sweep->hitboxBadnik.left = -10;93Sweep->hitboxBadnik.top = -7;94Sweep->hitboxBadnik.right = 10;95Sweep->hitboxBadnik.bottom = 4;9697Sweep->hitboxRange.left = -256;98Sweep->hitboxRange.top = -16;99Sweep->hitboxRange.right = 0;100Sweep->hitboxRange.bottom = 16;101102Sweep->hitboxProjectile.left = -13;103Sweep->hitboxProjectile.top = -3;104Sweep->hitboxProjectile.right = -8;105Sweep->hitboxProjectile.bottom = 3;106107Sweep->sfxPon = RSDK.GetSfx("Stage/Pon.wav");108109DEBUGMODE_ADD_OBJ(Sweep);110}111112void Sweep_DebugSpawn(void)113{114RSDK_THIS(DebugMode);115116EntitySweep *sweep = CREATE_ENTITY(Sweep, NULL, self->position.x, self->position.y);117sweep->direction = self->direction;118sweep->startDir = self->direction;119}120121void Sweep_DebugDraw(void)122{123RSDK.SetSpriteAnimation(Sweep->aniFrames, 0, &DebugMode->animator, true, 0);124RSDK.DrawSprite(&DebugMode->animator, NULL, false);125}126127void Sweep_CheckOffScreen(void)128{129RSDK_THIS(Sweep);130131if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {132self->position = self->startPos;133self->direction = self->startDir;134Sweep_Create(NULL);135}136}137138void Sweep_CheckPlayerCollisions(void)139{140RSDK_THIS(Sweep);141142foreach_active(Player, player)143{144Hitbox hitbox;145Hitbox *playerHitbox = Player_GetHitbox(player);146RSDK.GetHitbox(&player->animator, 0);147148EntityShield *shield = RSDK_GET_ENTITY(Player->playerCount + RSDK.GetEntitySlot(player), Shield);149if (shield->classID == Shield->classID && shield->state == Shield_State_Insta) {150hitbox.left = 2 * playerHitbox->left - (playerHitbox->left >> 1);151hitbox.top = 2 * playerHitbox->top - (playerHitbox->top >> 1);152hitbox.right = 2 * playerHitbox->right - (playerHitbox->right >> 1);153hitbox.bottom = 2 * playerHitbox->bottom - (playerHitbox->bottom >> 1);154playerHitbox = &hitbox;155}156157int32 side = MathHelpers_CheckBoxCollision(self, &Sweep->hitboxBadnik, player, playerHitbox);158if (side) {159if (self->state != Sweep_State_Turn160&& ((self->direction == FLIP_NONE && side == C_LEFT) || (self->direction == FLIP_X && side == C_RIGHT)))161Player_Hurt(player, self);162else163Player_CheckBadnikBreak(player, self, true);164}165}166}167168void Sweep_CheckShoot(void)169{170RSDK_THIS(Sweep);171172if (!self->hasShot && self->timer <= 16) {173foreach_active(Player, player)174{175if (Player_CheckCollisionTouch(player, self, &Sweep->hitboxRange)) {176RSDK.SetSpriteAnimation(Sweep->aniFrames, 3, &self->animator, true, 0);177EntitySweep *projectile = CREATE_ENTITY(Sweep, INT_TO_VOID(true), self->position.x, self->position.y);178if (!self->direction)179projectile->velocity.x = -0x30000;180else181projectile->velocity.x = 0x30000;182projectile->direction = self->direction;183projectile->active = ACTIVE_NORMAL;184RSDK.PlaySfx(Sweep->sfxPon, false, 255);185self->hasShot = true;186self->stateStore = self->state;187self->state = Sweep_State_FiredShot;188foreach_break;189}190}191}192}193194void Sweep_State_Init(void)195{196RSDK_THIS(Sweep);197198self->active = ACTIVE_NORMAL;199self->timer = 32;200self->hasShot = false;201self->state = Sweep_State_Idle;202Sweep_State_Idle();203}204205void Sweep_State_Idle(void)206{207RSDK_THIS(Sweep);208209self->timer--;210if (self->timer) {211Sweep_CheckShoot();212}213else {214self->hasShot = false;215self->timer = 64;216RSDK.SetSpriteAnimation(Sweep->aniFrames, 0, &self->animator, true, 1);217self->state = Sweep_State_Dash;218}219220Sweep_CheckPlayerCollisions();221Sweep_CheckOffScreen();222}223224void Sweep_State_Dash(void)225{226RSDK_THIS(Sweep);227228RSDK.ProcessAnimation(&self->animator);229self->timer--;230if (self->timer <= 0) {231self->timer = 32;232self->hasShot = false;233RSDK.SetSpriteAnimation(Sweep->aniFrames, 1, &self->animator, true, 0);234self->state = Sweep_State_Stop;235}236else {237if (self->direction && self->velocity.x < 0x20000) {238self->velocity.x += 0x3800;239}240else if (!self->direction && self->velocity.x > -0x20000) {241self->velocity.x -= 0x3800;242}243self->position.x += self->velocity.x;244}245246Sweep_CheckPlayerCollisions();247Sweep_CheckOffScreen();248}249250void Sweep_State_Stop(void)251{252RSDK_THIS(Sweep);253254RSDK.ProcessAnimation(&self->animator);255self->timer--;256if (self->timer <= 0) {257RSDK.SetSpriteAnimation(Sweep->aniFrames, 2, &self->animator, true, 0);258self->state = Sweep_State_Turn;259}260else if (!self->velocity.x) {261Sweep_CheckShoot();262}263else {264if (self->direction) {265if (self->velocity.x > 0)266self->velocity.x -= 0x3800;267else268self->velocity.x = 0;269}270else {271if (self->velocity.x > 0)272self->velocity.x += 0x3800;273else274self->velocity.x = 0;275}276self->position.x += self->velocity.x;277}278279Sweep_CheckPlayerCollisions();280Sweep_CheckOffScreen();281}282283void Sweep_State_FiredShot(void)284{285RSDK_THIS(Sweep);286287RSDK.ProcessAnimation(&self->animator);288289if (self->animator.frameID == self->animator.frameCount - 1) {290RSDK.SetSpriteAnimation(Sweep->aniFrames, 1, &self->animator, true, 4);291self->state = self->stateStore;292StateMachine_Run(self->state);293}294else {295Sweep_CheckPlayerCollisions();296Sweep_CheckOffScreen();297}298}299300void Sweep_State_Turn(void)301{302RSDK_THIS(Sweep);303304self->position.x += self->velocity.x;305306RSDK.ProcessAnimation(&self->animator);307308if (self->animator.frameID == self->animator.frameCount - 1) {309RSDK.SetSpriteAnimation(Sweep->aniFrames, 0, &self->animator, true, 0);310self->timer = 32;311self->direction ^= FLIP_X;312self->state = Sweep_State_Idle;313Sweep_State_Idle();314}315else {316Sweep_CheckPlayerCollisions();317Sweep_CheckOffScreen();318}319}320321void Sweep_State_Projectile(void)322{323RSDK_THIS(Sweep);324325self->position.x += self->velocity.x;326327if (RSDK.CheckOnScreen(self, NULL)) {328RSDK.ProcessAnimation(&self->animator);329330foreach_active(Player, player)331{332if (Player_CheckCollisionTouch(player, self, &Sweep->hitboxProjectile)) {333Player_ProjectileHurt(player, self);334}335}336}337else {338destroyEntity(self);339}340}341342#if GAME_INCLUDE_EDITOR343void Sweep_EditorDraw(void)344{345RSDK_THIS(Sweep);346RSDK.SetSpriteAnimation(Sweep->aniFrames, 0, &self->animator, true, 0);347Sweep_Draw();348}349350void Sweep_EditorLoad(void)351{352if (RSDK.CheckSceneFolder("CPZ"))353Sweep->aniFrames = RSDK.LoadSpriteAnimation("CPZ/Sweep.bin", SCOPE_STAGE);354#if MANIA_USE_PLUS355else if (RSDK.CheckSceneFolder("AIZ"))356Sweep->aniFrames = RSDK.LoadSpriteAnimation("AIZ/Sweep.bin", SCOPE_STAGE);357#endif358}359#endif360361void Sweep_Serialize(void) {}362363364