Path: blob/master/SonicMania/Objects/ERZ/PhantomGunner.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PhantomGunner Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectPhantomGunner *PhantomGunner;1011void PhantomGunner_Update(void)12{13RSDK_THIS(PhantomGunner);1415StateMachine_Run(self->state);16}1718void PhantomGunner_LateUpdate(void) {}1920void PhantomGunner_StaticUpdate(void) {}2122void PhantomGunner_Draw(void)23{24RSDK_THIS(PhantomGunner);2526RSDK.SetActivePalette(4, 0, ScreenInfo[SceneInfo->currentScreenID].size.y);2728if (self->stateDraw) {29StateMachine_Run(self->stateDraw);30}31else {32RSDK.DrawSprite(&self->mainAnimator, NULL, false);33}3435RSDK.SetActivePalette(0, 0, ScreenInfo[SceneInfo->currentScreenID].size.y);36}3738void PhantomGunner_Create(void *data)39{40RSDK_THIS(PhantomGunner);4142if (!SceneInfo->inEditor) {43self->startPos = self->position;44self->visible = true;45self->drawGroup = 2;46self->active = ACTIVE_NORMAL;47self->updateRange.x = 0x800000;48self->updateRange.y = 0x800000;4950self->type = VOID_TO_INT(data);51switch (self->type) {52case PHANTOMGUNNER_BOSS:53self->drawFX = FX_FLIP;54self->active = ACTIVE_NEVER;5556RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 0, &self->mainAnimator, true, 0);57RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 1, &self->fxAnimator, true, 0);5859self->originPos = self->position;60self->screenPos.x = (self->position.x >> 16) - ScreenInfo->center.x;61self->screenPos.y = (self->position.y >> 16) - ScreenInfo->center.y;6263self->stateDraw = PhantomGunner_Draw_Gunner;64self->state = PhantomGunner_State_Idle;65break;6667case PHANTOMGUNNER_LAUNCHROCKET:68RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 10, &self->mainAnimator, true, 0);69RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 11, &self->fxAnimator, true, 0);7071self->stateDraw = PhantomGunner_Draw_RocketLaunch;72self->state = PhantomGunner_State_LaunchedRocket;73break;7475case PHANTOMGUNNER_NAPALM_EXPLOSION:76self->originPos = self->position;7778self->state = PhantomGunner_State_NapalmExplosion;79break;8081case PHANTOMGUNNER_MORTAR_EXPLOSION:82self->originPos = self->position;8384self->state = PhantomGunner_State_MortarExplosion;85break;8687default: break;88}89}90}9192void PhantomGunner_StageLoad(void)93{94PhantomGunner->aniFrames = RSDK.LoadSpriteAnimation("Phantom/PhantomGunner.bin", SCOPE_STAGE);9596PhantomGunner->hitboxNapalm.left = -8;97PhantomGunner->hitboxNapalm.top = 4;98PhantomGunner->hitboxNapalm.right = 8;99PhantomGunner->hitboxNapalm.bottom = 26;100101PhantomGunner->hitboxMortar.left = -16;102PhantomGunner->hitboxMortar.top = -32;103PhantomGunner->hitboxMortar.right = 16;104PhantomGunner->hitboxMortar.bottom = -16;105106PhantomGunner->hitboxDud.left = -8;107PhantomGunner->hitboxDud.top = -8;108PhantomGunner->hitboxDud.right = 8;109PhantomGunner->hitboxDud.bottom = 8;110111PhantomGunner->sfxCannonFire = RSDK.GetSfx("Stage/CannonFire.wav");112}113114void PhantomGunner_HandleDudExhaust(void)115{116RSDK_THIS(PhantomGunner);117118if (!(Zone->timer & 7)) {119int32 x = self->position.x + (RSDK.Sin512(self->rotation) << 11);120int32 y = self->position.y - (RSDK.Cos512(self->rotation) << 11);121EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);122123RSDK.SetSpriteAnimation(Explosion->aniFrames, 3, &debris->animator, true, 0);124debris->velocity.x = RSDK.Sin512(self->rotation) << 8;125debris->velocity.y = RSDK.Sin512(self->rotation) << 4;126debris->drawGroup = Zone->objectDrawGroup[0];127debris->timer = 41;128}129}130131void PhantomGunner_HandleMalfunctionDudExhaust(void)132{133RSDK_THIS(PhantomGunner);134135if (Zone->timer & 3) {136if ((Zone->timer & 3) == 2) {137int32 x = self->position.x + (RSDK.Sin512(self->rotation) * 0x600);138int32 y = self->position.y - (RSDK.Cos512(self->rotation) * 0x600);139EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);140141RSDK.SetSpriteAnimation(Explosion->aniFrames, 2, &debris->animator, true, 0);142debris->drawGroup = Zone->objectDrawGroup[1];143debris->drawFX = FX_SCALE;144debris->timer = 52;145debris->scale.x = (self->scale.x * RSDK.Rand(128, 384)) >> 9;146debris->scale.y = debris->scale.x;147}148}149else {150int32 x = self->position.x + (RSDK.Sin512(self->rotation) << 11);151int32 y = self->position.y - (RSDK.Cos512(self->rotation) << 11);152EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_Move, x, y);153154RSDK.SetSpriteAnimation(Explosion->aniFrames, 3, &debris->animator, true, 0);155debris->velocity.x = RSDK.Sin512(self->rotation) << 8;156debris->velocity.y = RSDK.Sin512(self->rotation) << 4;157debris->drawGroup = Zone->objectDrawGroup[0];158debris->drawFX = FX_SCALE;159debris->timer = 41;160debris->scale.y = self->scale.x;161}162}163164void PhantomGunner_SpawnDust(void)165{166RSDK_THIS(PhantomGunner);167168for (int32 i = 0; i < 4; ++i) {169int32 x = self->position.x + RSDK.Rand(-0x100000, 0x100000);170int32 y = self->position.y + RSDK.Rand(-0x280000, -0x180000);171EntityDust *dust = CREATE_ENTITY(Dust, NULL, x, y);172dust->state = Dust_State_DustPuff;173dust->drawGroup = Zone->objectDrawGroup[1];174}175}176177void PhantomGunner_HandleRotations(int32 angle)178{179RSDK_THIS(PhantomGunner);180181int32 ang = angle - self->rotation;182183if (abs(angle - self->rotation) >= abs(angle - self->rotation - 0x200)) {184if (abs(angle - self->rotation - 0x200) < abs(angle - self->rotation + 0x200))185self->rotation += (ang - 0x200) >> 4;186else187self->rotation += (ang + 0x200) >> 4;188}189else {190if (abs(angle - self->rotation) < abs(angle - self->rotation + 0x200))191self->rotation += ang >> 4;192else193self->rotation += (ang + 0x200) >> 4;194}195196self->rotation &= 0x1FF;197}198199void PhantomGunner_CheckPlayerMissileCollisions(void)200{201RSDK_THIS(PhantomGunner);202203foreach_active(Player, player)204{205if (self->parachuteAnimator.frameID > 0 && player->velocity.y >= 0 && Player_CheckBadnikTouch(player, self, &PhantomGunner->hitboxMortar)206&& player->animator.animationID != ANI_HURT) {207RSDK.SetSpriteAnimation(-1, 0, &self->parachuteAnimator, true, 0);208player->velocity.y = -0x60000;209PhantomGunner_SpawnDust();210self->state = PhantomGunner_State_Napalm;211}212else {213if (Player_CheckBadnikTouch(player, self, &PhantomGunner->hitboxNapalm)) {214int32 anim = player->animator.animationID;215if (anim == ANI_JUMP || anim == ANI_SPINDASH || anim == ANI_DROPDASH) {216EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), self->position.x, self->position.y);217explosion->interaction = false;218explosion->drawGroup = Zone->objectDrawGroup[1];219if (self->parachuteAnimator.animationID == 12 && self->parachuteAnimator.frameID > 0)220PhantomGunner_SpawnDust();221RSDK.PlaySfx(PhantomEgg->sfxExplosion2, false, 255);222destroyEntity(self);223foreach_break;224}225}226}227}228}229230void PhantomGunner_CheckPlayerExplosionCollisions(void)231{232foreach_active(Player, player)233{234foreach_active(Explosion, explosion)235{236if (explosion->animator.frameID <= 6) {237if (Player_CheckCollisionTouch(player, explosion, &PhantomGunner->hitboxDud)) {238Player_ElementHurt(player, explosion, SHIELD_FIRE);239}240}241}242}243}244245void PhantomGunner_Hit(EntityPhantomGunner *entity)246{247RSDK.PlaySfx(PhantomEgg->sfxHit, false, 255);248entity->invincibilityTimer = 48;249}250251void PhantomGunner_Draw_Gunner(void)252{253RSDK_THIS(PhantomGunner);254255if (self->invincibilityTimer & 1) {256RSDK.CopyPalette(6, 128, 4, 128, 128);257258RSDK.DrawSprite(&self->mainAnimator, NULL, false);259260self->direction = FLIP_X;261RSDK.DrawSprite(&self->fxAnimator, NULL, false);262263self->direction = FLIP_NONE;264RSDK.DrawSprite(&self->fxAnimator, NULL, false);265266RSDK.CopyPalette(5, 128, 4, 128, 128);267}268else {269RSDK.DrawSprite(&self->mainAnimator, NULL, false);270271self->direction = FLIP_X;272RSDK.DrawSprite(&self->fxAnimator, NULL, false);273274self->direction = FLIP_NONE;275RSDK.DrawSprite(&self->fxAnimator, NULL, false);276}277}278279void PhantomGunner_Draw_RocketLaunch(void)280{281RSDK_THIS(PhantomGunner);282283EntityPhantomGunner *parent = self->parent;284285RSDK.SetClipBounds(0, 0, 0, ScreenInfo->size.x, ((self->originPos.y + parent->position.y) >> 16) - ScreenInfo->position.y);286287Vector2 drawPos;288drawPos.x = parent->position.x + self->originPos.x;289drawPos.y = self->position.y;290RSDK.DrawSprite(&self->mainAnimator, &drawPos, false);291292RSDK.SetClipBounds(0, 0, 0, ScreenInfo->size.x, ScreenInfo->size.y);293294drawPos.y = parent->position.y + self->originPos.y;295RSDK.DrawSprite(&self->fxAnimator, &drawPos, false);296}297298void PhantomGunner_Draw_Rocket(void)299{300RSDK_THIS(PhantomGunner);301302RSDK.DrawSprite(&self->mainAnimator, NULL, false);303RSDK.DrawSprite(&self->tailAnimator, NULL, false);304RSDK.DrawSprite(&self->parachuteAnimator, NULL, false);305}306307void PhantomGunner_State_ResetState(void)308{309RSDK_THIS(PhantomGunner);310311if (self->invincibilityTimer > 0)312self->invincibilityTimer--;313314self->position.x += (ScreenInfo->position.x - self->screenPos.x) << 15;315self->position.y = BadnikHelpers_Oscillate(self->originPos.y, 3, 11);316317self->screenPos = ScreenInfo->position;318319RSDK.ProcessAnimation(&self->fxAnimator);320321if (++self->timer == 60) {322self->position = self->startPos;323self->originPos = self->startPos;324self->timer = 0;325self->rocketLaunchCount = 0;326self->screenPos.x = (self->position.x >> 16) - ScreenInfo->center.x;327self->screenPos.y = (self->position.y >> 16) - ScreenInfo->center.y;328self->stateDraw = PhantomGunner_Draw_Gunner;329self->state = PhantomGunner_State_Idle;330self->active = ACTIVE_NEVER;331}332}333334void PhantomGunner_State_Idle(void)335{336RSDK_THIS(PhantomGunner);337338if (self->invincibilityTimer > 0)339self->invincibilityTimer--;340341self->position.x += (ScreenInfo->position.x - self->screenPos.x) << 15;342self->position.y = BadnikHelpers_Oscillate(self->originPos.y, 3, 11);343344self->screenPos = ScreenInfo->position;345RSDK.ProcessAnimation(&self->fxAnimator);346347self->fireAnimTimer = 8;348if (++self->timer < 120 || RSDK.GetEntityCount(PhantomGunner->classID, true) >= 2) {349PhantomGunner_CheckPlayerExplosionCollisions();350}351else {352if (++self->rocketLaunchCount == 2) {353PhantomEgg_SetupWarpFX();354self->timer = 0;355self->state = PhantomGunner_State_ResetState;356}357else {358PhantomGunner->launchedRocketID = 0;359self->timer = 0;360RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 2, &self->mainAnimator, true, 0);361362self->state = PhantomGunner_State_LaunchRockets;363PhantomGunner_CheckPlayerExplosionCollisions();364}365}366}367368void PhantomGunner_State_LaunchRockets(void)369{370RSDK_THIS(PhantomGunner);371372if (self->invincibilityTimer > 0)373self->invincibilityTimer--;374375self->position.x += (ScreenInfo->position.x - self->screenPos.x) << 15;376self->position.y = BadnikHelpers_Oscillate(self->originPos.y, 3, 11);377378self->screenPos = ScreenInfo->position;379380RSDK.ProcessAnimation(&self->mainAnimator);381RSDK.ProcessAnimation(&self->fxAnimator);382383if (++self->timer == 8) {384EntityPhantomGunner *rocket = CREATE_ENTITY(PhantomGunner, INT_TO_VOID(PHANTOMGUNNER_LAUNCHROCKET), self->position.x, self->position.y);385rocket->parent = self;386rocket->originPos.x = PhantomGunner->rocketOffsets[self->rocketOffsetID] << 16;387rocket->originPos.y = PhantomGunner->rocketOffsets[self->rocketOffsetID + 1] << 16;388rocket->position.x += rocket->originPos.x;389rocket->position.y += rocket->originPos.y + 0x100000;390self->rocketOffsetID = (self->rocketOffsetID - 14) & 0x1F;391392RSDK.PlaySfx(PhantomGunner->sfxCannonFire, false, 255);393}394395if (self->mainAnimator.frameID == self->mainAnimator.frameCount - 1) {396self->timer = 0;397398if (--self->fireAnimTimer > 0) {399if (!(self->fireAnimTimer & 1))400RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 2, &self->mainAnimator, true, 0);401else402RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 3, &self->mainAnimator, true, 0);403}404else {405RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 0, &self->mainAnimator, true, 0);406self->state = PhantomGunner_State_Idle;407}408}409410PhantomGunner_CheckPlayerExplosionCollisions();411}412413void PhantomGunner_State_LaunchedRocket(void)414{415RSDK_THIS(PhantomGunner);416417RSDK.ProcessAnimation(&self->mainAnimator);418RSDK.ProcessAnimation(&self->fxAnimator);419420self->position.y -= 0x80000;421422if (++self->timer == 60) {423EntityPhantomGunner *parent = self->parent;424425self->timer = 0;426if ((PhantomGunner->launchedRocketID & 3) == 3)427self->type = PHANTOMGUNNER_DUD;428else429self->type = (PhantomGunner->launchedRocketID & 1) + PHANTOMGUNNER_MORTAR;430431++PhantomGunner->launchedRocketID;432self->drawGroup = Zone->objectDrawGroup[0];433self->position.y = (ScreenInfo->position.y - 64) << 16;434435bool32 canFire = false;436while (!canFire) {437canFire = true;438self->position.x = parent->position.x + RSDK.Rand(-0x1000000, 0x1000000);439440foreach_active(PhantomGunner, gunner)441{442if (gunner != self && gunner->type >= PHANTOMGUNNER_MORTAR) {443int32 dist = abs(gunner->position.x - self->position.x);444if (dist < 0x180000 && gunner->position.y - self->position.y < 0x800000)445canFire = false;446}447}448}449450if (self->type == PHANTOMGUNNER_MORTAR) {451RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 4, &self->mainAnimator, true, 0);452RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 5, &self->tailAnimator, true, 0);453RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 12, &self->parachuteAnimator, true, 0);454455self->state = PhantomGunner_State_Mortar;456self->timer = RSDK.Rand(0, 2) << 8;457self->stateDraw = PhantomGunner_Draw_Rocket;458}459else if (self->type == PHANTOMGUNNER_NAPALM) {460RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 6, &self->mainAnimator, true, 0);461RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 7, &self->tailAnimator, true, 0);462463self->state = PhantomGunner_State_Napalm;464self->stateDraw = PhantomGunner_Draw_Rocket;465}466else if (self->type == PHANTOMGUNNER_DUD) {467RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 8, &self->mainAnimator, true, 0);468RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 9, &self->tailAnimator, true, 0);469470self->position.x = parent->position.x;471self->drawFX = FX_ROTATE;472self->velocity.x = (Zone->timer & 1) ? -0x40000 : 0x40000;473474self->state = PhantomGunner_State_Dud_Active;475self->stateDraw = PhantomGunner_Draw_Rocket;476}477}478}479480void PhantomGunner_State_Mortar(void)481{482RSDK_THIS(PhantomGunner);483484RSDK.ProcessAnimation(&self->parachuteAnimator);485RSDK.ProcessAnimation(&self->tailAnimator);486487if (self->parachuteAnimator.frameID) {488self->drawFX = FX_ROTATE;489if (self->velocity.y > 0xC000)490self->velocity.y -= 0x3800;491492self->rotation = RSDK.Sin512(self->timer) >> 6;493self->timer = (self->timer + 4) & 0x1FF;494}495else if (self->velocity.y < 0x40000)496self->velocity.y += 0x3800;497498self->position.y += self->velocity.y;499500PhantomGunner_CheckPlayerMissileCollisions();501if (self->classID) {502if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {503if (self->type == PHANTOMGUNNER_NAPALM) {504EntityPhantomGunner *napalm =505CREATE_ENTITY(PhantomGunner, INT_TO_VOID(PHANTOMGUNNER_NAPALM_EXPLOSION), self->position.x, self->position.y);506napalm->velocity.x = self->velocity.y > 0x20000 ? 0x80000 : 0x40000;507destroyEntity(self);508}509else {510CREATE_ENTITY(PhantomGunner, INT_TO_VOID(PHANTOMGUNNER_MORTAR_EXPLOSION), self->position.x, self->position.y);511destroyEntity(self);512}513}514}515}516517void PhantomGunner_State_Napalm(void)518{519RSDK_THIS(PhantomGunner);520521RSDK.ProcessAnimation(&self->tailAnimator);522523if (self->velocity.y < 0x40000)524self->velocity.y += 0x1800;525526self->position.y += self->velocity.y;527528PhantomGunner_CheckPlayerMissileCollisions();529if (self->classID) {530if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x100000, true)) {531if (self->type == PHANTOMGUNNER_NAPALM) {532EntityPhantomGunner *napalm =533CREATE_ENTITY(PhantomGunner, INT_TO_VOID(PHANTOMGUNNER_NAPALM_EXPLOSION), self->position.x, self->position.y);534napalm->velocity.x = self->velocity.y > 0x20000 ? 0x80000 : 0x40000;535destroyEntity(self);536}537else {538CREATE_ENTITY(PhantomGunner, INT_TO_VOID(PHANTOMGUNNER_MORTAR_EXPLOSION), self->position.x, self->position.y);539destroyEntity(self);540}541}542}543}544545void PhantomGunner_State_Dud_Active(void)546{547RSDK_THIS(PhantomGunner);548549RSDK.ProcessAnimation(&self->tailAnimator);550EntityPhantomGunner *parent = self->parent;551552++self->timer;553554self->velocity.x = RSDK.Cos256(self->timer) << 11;555if (self->position.y < parent->position.y - 0x800000) {556if (self->velocity.y < 0x20000)557self->velocity.y += 0x2000;558}559560if (self->position.y > parent->position.y - 0x200000) {561if (self->velocity.y > -0x20000)562self->velocity.y -= 0x2000;563}564565self->position.x += self->velocity.x;566self->position.y += self->velocity.y;567PhantomGunner_HandleDudExhaust();568569int32 angle = RSDK.ATan2(self->velocity.y, -self->velocity.x);570PhantomGunner_HandleRotations(2 * angle);571572if (self->timer == 320) {573EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ITEMBOX), self->position.x, self->position.y);574explosion->interaction = false;575explosion->drawGroup = Zone->objectDrawGroup[1];576destroyEntity(self);577}578else {579foreach_active(Player, player)580{581if (Player_CheckBadnikTouch(player, self, &PhantomGunner->hitboxDud)) {582self->angle = self->rotation << 8;583self->timer = 0;584self->drawFX = FX_SCALE | FX_ROTATE;585self->groundVel = 0x4000;586self->scale.x = 0x200;587self->scale.y = 0x200;588self->state = PhantomGunner_State_Dud_HitByPlayer;589RSDK.PlaySfx(PhantomEgg->sfxHit, false, 255);590}591}592}593}594595void PhantomGunner_State_Dud_HitByPlayer(void)596{597RSDK_THIS(PhantomGunner);598599RSDK.ProcessAnimation(&self->tailAnimator);600601self->angle += self->groundVel;602self->rotation = self->angle >> 8;603self->groundVel -= self->groundVel >> 3;604605PhantomGunner_HandleDudExhaust();606607if (self->groundVel < 128) {608RSDK.PlaySfx(PhantomEgg->sfxRocketJet, false, 255);609self->state = PhantomGunner_State_Dud_Malfunction;610}611}612613void PhantomGunner_State_Dud_Malfunction(void)614{615RSDK_THIS(PhantomGunner);616617RSDK.ProcessAnimation(&self->tailAnimator);618619EntityPhantomGunner *parent = self->parent;620621int32 angle = RSDK.ATan2((parent->position.y - self->position.y) >> 16, -((parent->position.x - self->position.x) >> 16));622PhantomGunner_HandleRotations(2 * angle);623624self->rotation &= 0x1FF;625self->position.x -= RSDK.Sin512(self->rotation) << 9;626self->scale.x -= 6;627self->position.y += RSDK.Cos512(self->rotation) << 9;628self->scale.y = self->scale.x;629630PhantomGunner_HandleMalfunctionDudExhaust();631if (self->scale.x < 0x80) {632PhantomGunner_Hit(parent);633634self->position.x = parent->position.x;635self->position.y = parent->position.y;636self->visible = false;637self->state = PhantomGunner_State_Dud_Explode;638}639}640641void PhantomGunner_State_Dud_Explode(void)642{643RSDK_THIS(PhantomGunner);644645if (!(Zone->timer % 3) && !(Zone->timer & 4)) {646int32 x = self->position.x + RSDK.Rand(-0x100000, 0x100000);647int32 y = self->position.y + RSDK.Rand(-0x100000, 0x100000);648EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS), x, y);649explosion->interaction = false;650explosion->drawGroup = 1;651explosion->scale = self->scale;652}653654if (++self->timer == 16)655destroyEntity(self);656}657658void PhantomGunner_State_NapalmExplosion(void)659{660RSDK_THIS(PhantomGunner);661662if (!(Zone->timer & 3)) {663CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->originPos.x - self->napalmExplosionPos, self->position.y);664CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->originPos.x + self->napalmExplosionPos, self->position.y);665}666667self->napalmExplosionPos += self->velocity.x;668669if (++self->timer == 16)670destroyEntity(self);671}672673void PhantomGunner_State_MortarExplosion(void)674{675RSDK_THIS(PhantomGunner);676677if (!(Zone->timer & 3))678CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ITEMBOX), self->position.x, self->position.y);679680self->position.y -= 0x40000;681682if (++self->timer == 16)683destroyEntity(self);684}685686#if GAME_INCLUDE_EDITOR687void PhantomGunner_EditorDraw(void)688{689RSDK_THIS(PhantomGunner);690691self->drawFX = FX_FLIP;692RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 0, &self->mainAnimator, false, 0);693RSDK.SetSpriteAnimation(PhantomGunner->aniFrames, 1, &self->fxAnimator, false, 0);694695self->originPos = self->position;696self->screenPos.x = (self->position.x >> 16) - ScreenInfo->center.x;697self->screenPos.y = (self->position.y >> 16) - ScreenInfo->center.y;698699PhantomGunner_Draw_Gunner();700}701702void PhantomGunner_EditorLoad(void) { PhantomGunner->aniFrames = RSDK.LoadSpriteAnimation("Phantom/PhantomGunner.bin", SCOPE_STAGE); }703#endif704705void PhantomGunner_Serialize(void) {}706707708