Path: blob/master/SonicMania/Objects/OOZ/Aquis.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Aquis Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectAquis *Aquis;1011void Aquis_Update(void)12{13RSDK_THIS(Aquis);1415StateMachine_Run(self->state);16}1718void Aquis_LateUpdate(void) {}1920void Aquis_StaticUpdate(void) {}2122void Aquis_Draw(void)23{24RSDK_THIS(Aquis);2526if (self->mainAnimator.animationID == 4) {27RSDK.DrawSprite(&self->mainAnimator, NULL, false);28}29else {30RSDK.DrawSprite(&self->mainAnimator, NULL, false);31RSDK.DrawSprite(&self->wingAnimator, NULL, false);32}33}3435void Aquis_Create(void *data)36{37RSDK_THIS(Aquis);3839self->visible = true;40self->drawGroup = Zone->objectDrawGroup[0];41self->drawFX |= FX_FLIP;42self->startPos = self->position;43self->startDir = self->direction;44self->timer = 128;45self->playerInRange = 0;4647if (data) {48self->active = ACTIVE_NORMAL;49self->updateRange.x = 0x200000;50self->updateRange.y = 0x200000;51RSDK.SetSpriteAnimation(Aquis->aniFrames, 2, &self->mainAnimator, true, 0);52self->state = Aquis_State_Shot;53}54else {55self->active = ACTIVE_BOUNDS;56self->updateRange.x = 0x800000;57self->updateRange.y = 0x800000;58self->remainingTurns = 3;59RSDK.SetSpriteAnimation(Aquis->aniFrames, 0, &self->mainAnimator, true, 0);60RSDK.SetSpriteAnimation(Aquis->aniFrames, 3, &self->wingAnimator, true, 0);61self->state = Aquis_State_Init;62}63}6465void Aquis_StageLoad(void)66{67if (RSDK.CheckSceneFolder("OOZ1") || RSDK.CheckSceneFolder("OOZ2"))68Aquis->aniFrames = RSDK.LoadSpriteAnimation("OOZ/Aquis.bin", SCOPE_STAGE);6970Aquis->hitboxBadnik.left = -10;71Aquis->hitboxBadnik.top = -16;72Aquis->hitboxBadnik.right = 10;73Aquis->hitboxBadnik.bottom = 16;7475Aquis->hitboxRange.left = -96;76Aquis->hitboxRange.top = -64;77Aquis->hitboxRange.right = 64;78Aquis->hitboxRange.bottom = 128;7980Aquis->hitboxProjectile.left = -3;81Aquis->hitboxProjectile.top = -3;82Aquis->hitboxProjectile.right = 3;83Aquis->hitboxProjectile.bottom = 3;8485Aquis->sfxShot = RSDK.GetSfx("Stage/Shot.wav");8687DEBUGMODE_ADD_OBJ(Aquis);88}8990void Aquis_DebugSpawn(void)91{92RSDK_THIS(Aquis);9394EntityAquis *aquis = CREATE_ENTITY(Aquis, NULL, self->position.x, self->position.y);95aquis->direction = self->direction;96aquis->startDir = self->direction;97}9899void Aquis_DebugDraw(void)100{101RSDK.SetSpriteAnimation(Aquis->aniFrames, 0, &DebugMode->animator, true, 0);102RSDK.DrawSprite(&DebugMode->animator, NULL, false);103}104105void Aquis_CheckPlayerCollisions(void)106{107RSDK_THIS(Aquis);108109foreach_active(Player, player)110{111if (Player_CheckBadnikTouch(player, self, &Aquis->hitboxBadnik))112Player_CheckBadnikBreak(player, self, true);113}114}115116void Aquis_CheckOffScreen(void)117{118RSDK_THIS(Aquis);119120if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {121self->position = self->startPos;122self->direction = self->startDir;123Aquis_Create(NULL);124}125}126127void Aquis_State_Init(void)128{129RSDK_THIS(Aquis);130131self->active = ACTIVE_NORMAL;132self->timer = 32;133134self->state = Aquis_State_Idle;135Aquis_State_Idle();136}137138void Aquis_State_Idle(void)139{140RSDK_THIS(Aquis);141142if (!--self->timer) {143if (self->remainingTurns--) {144self->velocity.y = -0x10000;145self->timer = 128;146self->playerInRange = false;147self->state = Aquis_State_Moving;148}149else {150self->velocity.y = 0;151152if (self->direction == FLIP_X) {153self->velocity.x = 0;154self->state = Aquis_State_Turning;155RSDK.SetSpriteAnimation(Aquis->aniFrames, 4, &self->mainAnimator, true, 0);156}157else {158self->velocity.x = -0x20000;159self->state = Aquis_State_Flee;160}161}162}163164RSDK.ProcessAnimation(&self->mainAnimator);165RSDK.ProcessAnimation(&self->wingAnimator);166167Aquis_CheckPlayerCollisions();168Aquis_CheckOffScreen();169}170171void Aquis_State_Moving(void)172{173RSDK_THIS(Aquis);174175self->position.x += self->velocity.x;176self->position.y += self->velocity.y;177178EntityPlayer *playerPtr = Player_GetNearestPlayer();179if (playerPtr) {180bool32 changeDir = false;181if (playerPtr->position.x >= self->position.x) {182self->velocity.x += 0x1000;183184if (self->velocity.x > 0x10000)185self->velocity.x = 0x10000;186187changeDir = self->direction == FLIP_NONE;188}189else {190self->velocity.x -= 0x1000;191192if (self->velocity.x < -0x10000)193self->velocity.x = -0x10000;194195changeDir = self->direction == FLIP_X;196}197198if (changeDir) {199self->state = Aquis_State_Turning;200RSDK.SetSpriteAnimation(Aquis->aniFrames, 4, &self->mainAnimator, true, 0);201}202203if (playerPtr->position.y >= self->position.y) {204self->velocity.y += 0x1000;205206if (self->velocity.y > 0x10000)207self->velocity.y = 0x10000;208}209else {210self->velocity.y -= 0x1000;211212if (self->velocity.y < -0x10000)213self->velocity.y = -0x10000;214}215}216217if (self->state != Aquis_State_Turning) {218if (!self->timer--) {219self->timer = 32;220self->state = Aquis_State_Idle;221self->velocity.x = 0;222self->velocity.y = 0;223}224225if (!self->playerInRange) {226foreach_active(Player, player)227{228if (player->velocity.y < 0 && !player->onGround)229continue;230231if (Player_CheckCollisionTouch(player, self, &Aquis->hitboxRange)) {232self->playerInRange = true;233self->timer = 64;234RSDK.SetSpriteAnimation(Aquis->aniFrames, 1, &self->mainAnimator, true, 0);235self->state = Aquis_State_Shoot;236237if (player->position.x >= self->position.x) {238if (player->velocity.x <= (self->position.x - player->position.x) >> 5) {239RSDK.SetSpriteAnimation(Aquis->aniFrames, 4, &self->mainAnimator, true, 0);240self->state = Aquis_State_Turning;241}242}243else if (player->velocity.x >= (self->position.x - player->position.x) >> 5) {244RSDK.SetSpriteAnimation(Aquis->aniFrames, 4, &self->mainAnimator, true, 0);245self->state = Aquis_State_Turning;246}247}248}249}250}251252RSDK.ProcessAnimation(&self->mainAnimator);253RSDK.ProcessAnimation(&self->wingAnimator);254255Aquis_CheckPlayerCollisions();256Aquis_CheckOffScreen();257}258259void Aquis_State_Shoot(void)260{261RSDK_THIS(Aquis);262263if (--self->timer) {264if (self->timer == 33) {265EntityAquis *shot = CREATE_ENTITY(Aquis, INT_TO_VOID(true), self->position.x, self->position.y);266267if (self->direction) {268shot->position.x += 0x100000;269shot->velocity.x = 0x30000;270}271else {272shot->position.x -= 0x100000;273shot->velocity.x = -0x30000;274}275276shot->position.y -= 0xA0000;277shot->velocity.y = 0x20000;278shot->direction = self->direction;279shot->active = ACTIVE_NORMAL;280RSDK.PlaySfx(Aquis->sfxShot, false, 255);281}282}283else {284self->timer = 32;285self->remainingTurns = 0;286self->state = Aquis_State_Idle;287self->velocity.x = 0;288self->velocity.y = 0;289}290291RSDK.ProcessAnimation(&self->mainAnimator);292RSDK.ProcessAnimation(&self->wingAnimator);293294Aquis_CheckPlayerCollisions();295Aquis_CheckOffScreen();296}297298void Aquis_State_Turning(void)299{300RSDK_THIS(Aquis);301302self->position.x += self->velocity.x;303self->position.y += self->velocity.y;304305RSDK.ProcessAnimation(&self->mainAnimator);306307if (self->mainAnimator.frameID == self->mainAnimator.frameCount - 1) {308RSDK.SetSpriteAnimation(Aquis->aniFrames, 0, &self->mainAnimator, true, 0);309self->direction ^= FLIP_X;310311if (self->remainingTurns < 0) {312self->velocity.x = -0x20000;313314self->state = Aquis_State_Flee;315Aquis_State_Flee();316}317else if (self->playerInRange) {318self->timer = 64;319RSDK.SetSpriteAnimation(Aquis->aniFrames, 1, &self->mainAnimator, true, 0);320321self->state = Aquis_State_Shoot;322Aquis_State_Shoot();323}324else {325self->state = Aquis_State_Moving;326Aquis_State_Moving();327}328}329else {330if (self->timer > 1)331self->timer--;332333Aquis_CheckPlayerCollisions();334Aquis_CheckOffScreen();335}336}337338void Aquis_State_Flee(void)339{340RSDK_THIS(Aquis);341342self->position.x += self->velocity.x;343self->position.y += self->velocity.y;344345RSDK.ProcessAnimation(&self->wingAnimator);346347Aquis_CheckPlayerCollisions();348Aquis_CheckOffScreen();349}350351void Aquis_State_Shot(void)352{353RSDK_THIS(Aquis);354355self->position.x += self->velocity.x;356self->position.y += self->velocity.y;357358if (RSDK.CheckOnScreen(self, NULL)) {359RSDK.ProcessAnimation(&self->mainAnimator);360361foreach_active(Player, player)362{363if (Player_CheckCollisionTouch(player, self, &Aquis->hitboxProjectile))364Player_ProjectileHurt(player, self);365}366}367else {368destroyEntity(self);369}370}371372#if GAME_INCLUDE_EDITOR373void Aquis_EditorDraw(void)374{375RSDK_THIS(Aquis);376377RSDK.DrawSprite(&self->mainAnimator, NULL, false);378RSDK.DrawSprite(&self->wingAnimator, NULL, false);379}380381void Aquis_EditorLoad(void) { Aquis->aniFrames = RSDK.LoadSpriteAnimation("OOZ/Aquis.bin", SCOPE_STAGE); }382#endif383384void Aquis_Serialize(void) {}385386387