Path: blob/master/SonicMania/Objects/ERZ/PhantomMissile.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PhantomMissile Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPhantomMissile *PhantomMissile;1011void PhantomMissile_Update(void) {}1213void PhantomMissile_LateUpdate(void)14{15RSDK_THIS(PhantomMissile);1617StateMachine_Run(self->state);18}1920void PhantomMissile_StaticUpdate(void) {}2122void PhantomMissile_Draw(void)23{24RSDK_THIS(PhantomMissile);2526RSDK.DrawSprite(&self->missileAnimator, NULL, false);27RSDK.DrawSprite(&self->targetOutsideAnimator, &self->targetPos, false);2829if (Zone->timer & 0x10)30RSDK.DrawSprite(&self->targetNumbersAnimator, &self->targetPos, false);31else32RSDK.DrawSprite(&self->targetInsideAnimator, &self->targetPos, false);33}3435void PhantomMissile_Create(void *data)36{37RSDK_THIS(PhantomMissile);3839if (!SceneInfo->inEditor) {40self->visible = true;41self->drawGroup = Zone->objectDrawGroup[0];42self->drawFX = FX_ROTATE;43self->updateRange.x = 0x800000;44self->updateRange.y = 0x800000;45self->state = PhantomMissile_State_Attached;4647RSDK.SetSpriteAnimation(PhantomMissile->aniFrames, 0, &self->missileAnimator, true, 0);48}49}5051void PhantomMissile_StageLoad(void)52{53PhantomMissile->aniFrames = RSDK.LoadSpriteAnimation("Phantom/EggMissile.bin", SCOPE_STAGE);5455PhantomMissile->hitbox.left = -16;56PhantomMissile->hitbox.top = -12;57PhantomMissile->hitbox.right = 16;58PhantomMissile->hitbox.bottom = 12;59}6061void PhantomMissile_GetTargetPos(void)62{63RSDK_THIS(PhantomMissile);6465int32 distance = 0x7FFFFFFF;6667for (int32 p = SLOT_PLAYER1; p < Player->playerCount; ++p) {68EntityPlayer *player = RSDK_GET_ENTITY(p, Player);6970if (player->sidekick == true && player->stateInput != Player_Input_P2_Player) {71int32 storeX = self->position.x;72int32 storeY = self->position.y;73self->position.x = self->targetPos.x;74self->position.y = self->targetPos.y;7576while (!RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, 16)) {77self->position.y += 0x100000;78}7980int32 y = self->position.y;81self->position.x = storeX;82self->position.y = storeY;83self->targetPos.y = y;84foreach_break;85}8687int32 rx = (self->position.x - player->position.x) >> 16;88int32 ry = (self->position.y - player->position.y) >> 16;89int32 dist = rx * rx + ry * ry;90if (dist < distance) {91distance = dist;92self->targetPos.x = player->position.x;93self->targetPos.y = player->position.y;94}95}96}9798void PhantomMissile_HandleExhaust(void)99{100RSDK_THIS(PhantomMissile);101102if (!(Zone->timer & 3)) {103int32 x = self->position.x - (RSDK.Sin512(self->rotation) << 11);104int32 y = self->position.y + (RSDK.Cos512(self->rotation) << 11);105EntityDust *dust = CREATE_ENTITY(Dust, NULL, x, y);106107dust->state = Dust_State_DustPuff;108dust->drawGroup = Zone->objectDrawGroup[1];109dust->inkEffect = INK_BLEND;110}111}112113void PhantomMissile_State_Attached(void)114{115RSDK_THIS(PhantomMissile);116117if (self->parent) {118self->position.x = self->parent->position.x;119self->position.y = self->parent->position.y;120self->oscillateAngle = (self->oscillateAngle + 6) & 0xFF;121int32 off = 8 * RSDK.Sin256(self->oscillateAngle) + 0x2000;122123self->position.x += off * RSDK.Sin256(self->angle);124self->position.y -= off * RSDK.Cos256(self->angle);125self->rotation = 2 * self->angle;126127if (self->timer > 0) {128if (!--self->timer) {129self->velocity.x = 0x300 * RSDK.Sin256(self->angle) + self->parent->velocity.x;130self->velocity.y = -0x300 * RSDK.Cos256(self->angle) + self->parent->velocity.y;131self->timer = 8;132self->state = PhantomMissile_State_PrepareLaunch;133}134}135}136}137138void PhantomMissile_State_PrepareLaunch(void)139{140RSDK_THIS(PhantomMissile);141142self->velocity.y += 0x3800;143self->position.x += self->velocity.x;144self->position.y += self->velocity.y;145146if (!--self->timer) {147self->targetRadius = 0x400;148self->state = PhantomMissile_State_Launched;149RSDK.PlaySfx(PhantomEgg->sfxRocketJet, false, 255);150}151}152153void PhantomMissile_State_Launched(void)154{155RSDK_THIS(PhantomMissile);156157RSDK.ProcessAnimation(&self->missileAnimator);158159if (self->targetRadius < 0x600)160self->targetRadius += 4;161162self->position.x += self->targetRadius * RSDK.Sin256(self->angle);163self->position.y -= self->targetRadius * RSDK.Cos256(self->angle);164165if (++self->timer == 24) {166self->timer = 32;167self->targetRadius >>= 1;168PhantomMissile_GetTargetPos();169170RSDK.SetSpriteAnimation(PhantomMissile->aniFrames, 1, &self->targetOutsideAnimator, true, 0);171RSDK.SetSpriteAnimation(PhantomMissile->aniFrames, 2, &self->targetInsideAnimator, true, 0);172RSDK.SetSpriteAnimation(PhantomMissile->aniFrames, 3, &self->targetNumbersAnimator, true, self->id);173174self->drawGroup = Zone->objectDrawGroup[1];175self->state = PhantomMissile_State_Attacking;176}177178PhantomMissile_HandleExhaust();179}180181void PhantomMissile_State_Attacking(void)182{183RSDK_THIS(PhantomMissile);184185RSDK.ProcessAnimation(&self->missileAnimator);186RSDK.ProcessAnimation(&self->targetOutsideAnimator);187RSDK.ProcessAnimation(&self->targetInsideAnimator);188RSDK.ProcessAnimation(&self->targetNumbersAnimator);189190if (self->targetRadius < 0x800)191self->targetRadius += 4;192193if (self->timer > 4)194self->timer--;195196int32 shift = self->timer >> 2;197int32 rx = (self->targetPos.x - self->position.x) >> 16;198int32 ry = (self->targetPos.y - self->position.y) >> 16;199int32 angle = RSDK.ATan2(-ry, rx);200int32 rot = 2 * angle - self->rotation;201202if (abs(rot) >= abs(rot - 0x200)) {203if (abs(rot - 0x200) < abs(rot + 0x200))204self->rotation += ((rot - 0x200) >> shift);205else206self->rotation += ((rot + 0x200) >> shift);207}208else {209if (abs(rot) < abs(rot + 0x200))210self->rotation += (rot >> shift);211else212self->rotation += ((rot + 0x200) >> shift);213}214215self->rotation &= 0x1FF;216217self->position.x += self->targetRadius * RSDK.Sin512(self->rotation);218self->position.y -= self->targetRadius * RSDK.Cos512(self->rotation);219220if (rx * rx + ry * ry < 64) {221CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ITEMBOX), self->targetPos.x, self->targetPos.y - 0x80000)->drawGroup =222Zone->objectDrawGroup[1];223224RSDK.SetSpriteAnimation(PhantomMissile->aniFrames, 0, &self->missileAnimator, true, 0);225RSDK.SetSpriteAnimation(-1, 1, &self->targetOutsideAnimator, true, 0);226RSDK.SetSpriteAnimation(-1, 0, &self->targetInsideAnimator, true, 0);227RSDK.SetSpriteAnimation(-1, 0, &self->targetNumbersAnimator, true, 0);228229self->timer = 0;230self->reattachRadius = 0;231self->drawGroup = Zone->objectDrawGroup[0];232self->visible = false;233self->state = PhantomMissile_State_Explode;234235Camera_ShakeScreen(0, 0, 3);236RSDK.PlaySfx(PhantomEgg->sfxMissile, false, 255);237}238239PhantomMissile_HandleExhaust();240}241242void PhantomMissile_State_Explode(void)243{244RSDK_THIS(PhantomMissile);245246foreach_active(Player, player)247{248if (Player_CheckCollisionTouch(player, self, &PhantomMissile->hitbox)) {249Player_ElementHurt(player, self, SHIELD_FIRE);250}251}252253if (++self->timer >= 16 && self->parent) {254self->position.x = self->parent->position.x;255self->position.y = self->parent->position.y;256self->timer = 0;257self->visible = true;258self->state = PhantomMissile_State_Reattach;259}260}261262void PhantomMissile_State_Reattach(void)263{264RSDK_THIS(PhantomMissile);265266if (self->parent) {267self->position.x = self->parent->position.x;268self->position.y = self->parent->position.y;269270if (self->reattachRadius >= 0x2000) {271self->oscillateAngle = 0;272self->state = PhantomMissile_State_Attached;273}274else {275self->reattachRadius += 0x100;276}277278self->position.x += self->reattachRadius * RSDK.Sin256(self->angle);279self->position.y -= self->reattachRadius * RSDK.Cos256(self->angle);280self->rotation = self->angle << 1;281}282}283284void PhantomMissile_State_Destroyed(void)285{286RSDK_THIS(PhantomMissile);287288self->velocity.y += 0x3800;289self->position.x += self->velocity.x;290self->position.y += self->velocity.y;291292self->rotation = (self->rotation + self->groundVel) & 0x1FF;293294if (!RSDK.CheckOnScreen(self, NULL))295destroyEntity(self);296}297298#if GAME_INCLUDE_EDITOR299void PhantomMissile_EditorDraw(void)300{301RSDK_THIS(PhantomMissile);302303RSDK.SetSpriteAnimation(PhantomMissile->aniFrames, 0, &self->missileAnimator, false, 0);304305RSDK.DrawSprite(&self->missileAnimator, NULL, false);306}307308void PhantomMissile_EditorLoad(void) { PhantomMissile->aniFrames = RSDK.LoadSpriteAnimation("Phantom/EggMissile.bin", SCOPE_STAGE); }309#endif310311void PhantomMissile_Serialize(void) {}312313314