From 455aa0aa2c35da2dfca64c24a5cc2c36f488c110 Mon Sep 17 00:00:00 2001 From: Alejandro Asenjo Nitti <96613413+sonicdcer@users.noreply.github.com> Date: Sun, 5 May 2024 17:23:49 -0300 Subject: [PATCH] Initial Katina documentation (#228) * initial docs * func names * docs * more docs * more katina docs * format * format * yRot * more docs * more docs * this * some fixes * fixes * ActorAllRange * These should not be used here * corrections * some renamings * more docs * format * Merge remote-tracking branch 'origin' into fox_ka_docs * ActorCutscene * PR review * comment * bump torch * PR review * review --- Makefile | 2 +- assets/yaml/us/ast_katina.yaml | 46 +- include/i4.h | 18 +- include/sf64object.h | 8 +- include/variables.h | 2 +- linker_scripts/us/symbol_addrs_overlays.txt | 4 +- src/engine/fox_360.c | 11 +- src/engine/fox_demo.c | 6 +- src/engine/fox_edata_info.c | 10 +- src/engine/fox_effect.c | 6 +- src/engine/fox_enmy.c | 6 +- src/engine/fox_hud.c | 6 +- src/engine/fox_play.c | 2 +- src/overlays/ovl_i4/fox_ka.c | 1949 ++++++++++++------- src/overlays/ovl_i4/fox_sz.c | 4 +- src/overlays/ovl_i5/fox_ma.c | 1 + src/sys/sys_fault.c | 2 +- tools/Torch | 2 +- 18 files changed, 1292 insertions(+), 793 deletions(-) diff --git a/Makefile b/Makefile index 5938057c..4bf4ec97 100644 --- a/Makefile +++ b/Makefile @@ -425,7 +425,7 @@ extract: assets: @echo "Extracting assets from ROM..." - @$(TORCH) code $(BASEROM_UNCOMPRESSED) -v + @$(TORCH) code $(BASEROM_UNCOMPRESSED) @$(TORCH) header $(BASEROM_UNCOMPRESSED) @$(TORCH) modding export $(BASEROM_UNCOMPRESSED) diff --git a/assets/yaml/us/ast_katina.yaml b/assets/yaml/us/ast_katina.yaml index ddacbdd3..efc3f21c 100644 --- a/assets/yaml/us/ast_katina.yaml +++ b/assets/yaml/us/ast_katina.yaml @@ -20,15 +20,16 @@ D_KA_6000000: D_KA_6001260: { type: TEXTURE, format: IA8, width: 8, height: 8, offset: 0x6001260, ctype: u8, symbol: D_KA_6001260 } -D_KA_60012A0: - { type: GFX, offset: 0x60012A0, symbol: D_KA_60012A0 } +aDestroyedHatch1DL: + { type: GFX, offset: 0x60012A0, symbol: aDestroyedHatch1DL } -D_KA_6001530: - { type: GFX, offset: 0x6001530, symbol: D_KA_6001530 } +aKaEnemy1DL: + { type: GFX, offset: 0x6001530, symbol: aKaEnemy1DL } D_KA_6001968: { type: TEXTURE, format: RGBA16, width: 32, height: 32, offset: 0x6001968, ctype: u16, symbol: D_KA_6001968 } +# Mothership model D_KA_6002170: { type: GFX, offset: 0x6002170, symbol: D_KA_6002170 } @@ -56,8 +57,8 @@ D_KA_60062F8: D_KA_6006AF8: { type: TEXTURE, format: RGBA16, width: 32, height: 32, offset: 0x6006AF8, ctype: u16, symbol: D_KA_6006AF8 } -D_KA_6007300: - { type: GFX, offset: 0x6007300, symbol: D_KA_6007300 } +aDestroyedMothershipDL: + { type: GFX, offset: 0x6007300, symbol: aDestroyedMothershipDL } D_KA_6009250: { type: GFX, offset: 0x6009250, symbol: D_KA_6009250 } @@ -71,8 +72,8 @@ D_KA_6009CB0: D_KA_600ABD0: { type: TEXTURE, format: RGBA16, width: 44, height: 44, offset: 0x600ABD0, ctype: u16, symbol: D_KA_600ABD0 } -D_KA_600BAF0: - { type: GFX, offset: 0x600BAF0, symbol: D_KA_600BAF0 } +aKaFLBaseDL: + { type: GFX, offset: 0x600BAF0, symbol: aKaFLBaseDL } D_KA_600BDB0: { type: TEXTURE, format: RGBA16, width: 16, height: 16, offset: 0x600BDB0, ctype: u16, symbol: D_KA_600BDB0 } @@ -80,8 +81,8 @@ D_KA_600BDB0: D_KA_600C2D8: { type: TEXTURE, format: RGBA16, width: 16, height: 16, offset: 0x600C2D8, ctype: u16, symbol: D_KA_600C2D8 } -D_KA_600C4E0: - { type: GFX, offset: 0x600C4E0, symbol: D_KA_600C4E0 } +aKaFLBaseDestroyedDL: + { type: GFX, offset: 0x600C4E0, symbol: aKaFLBaseDestroyedDL } D_KA_600C760: { type: TEXTURE, format: RGBA16, width: 16, height: 16, offset: 0x600C760, ctype: u16, symbol: D_KA_600C760 } @@ -89,23 +90,24 @@ D_KA_600C760: D_KA_600C960: { type: TEXTURE, format: RGBA16, width: 16, height: 16, offset: 0x600C960, ctype: u16, symbol: D_KA_600C960 } +# Mothership Core D_KA_600CB60: { type: GFX, offset: 0x600CB60, symbol: D_KA_600CB60 } D_KA_600BFB0: { type: GFX, offset: 0x600BFB0, symbol: D_KA_600BFB0 } -D_KA_600CDC0: - { type: GFX, offset: 0x600CDC0, symbol: D_KA_600CDC0 } +aDestroyedHatch2DL: + { type: GFX, offset: 0x600CDC0, symbol: aDestroyedHatch2DL } -D_KA_600D090: - { type: GFX, offset: 0x600D090, symbol: D_KA_600D090 } +aDestroyedCoreDL: + { type: GFX, offset: 0x600D090, symbol: aDestroyedCoreDL } -D_KA_600D290: - { type: GFX, offset: 0x600D290, symbol: D_KA_600D290 } +aDestroyedHatch4DL: + { type: GFX, offset: 0x600D290, symbol: aDestroyedHatch4DL } -D_KA_600D4E0: - { type: GFX, offset: 0x600D4E0, symbol: D_KA_600D4E0 } +aDestroyedHatch3DL: + { type: GFX, offset: 0x600D4E0, symbol: aDestroyedHatch3DL } D_KA_600D730: { type: GFX, offset: 0x600D730, symbol: D_KA_600D730 } @@ -119,8 +121,8 @@ D_KA_600DBC0: D_KA_600DC48: { type: TEXTURE, format: IA8, width: 32, height: 32, offset: 0x600DC48, ctype: u8, symbol: D_KA_600DC48 } -D_KA_600E050: - { type: GFX, offset: 0x600E050, symbol: D_KA_600E050 } +aKaCornerianFighterDL: + { type: GFX, offset: 0x600E050, symbol: aKaCornerianFighterDL } D_KA_600E7E8: { type: TEXTURE, format: RGBA16, width: 16, height: 16, offset: 0x600E7E8, ctype: u16, symbol: D_KA_600E7E8 } @@ -134,8 +136,8 @@ D_KA_600EBE8: D_KA_600EDE8: { type: TEXTURE, format: RGBA16, width: 16, height: 16, offset: 0x600EDE8, ctype: u16, symbol: D_KA_600EDE8 } -D_KA_600EFF0: - { type: GFX, offset: 0x600EFF0, symbol: D_KA_600EFF0 } +aKaEnemy1LowPolyDL: + { type: GFX, offset: 0x600EFF0, symbol: aKaEnemy1LowPolyDL } D_KA_600F1D0: { type: GFX, offset: 0x600F1D0, symbol: D_KA_600F1D0 } diff --git a/include/i4.h b/include/i4.h index 76bb4bca..d4188c53 100644 --- a/include/i4.h +++ b/include/i4.h @@ -14,7 +14,7 @@ void Bolse_LevelStart(Player*); void Bolse_LevelComplete(Player*); void Katina_LevelStart(Player*); void Katina_LevelComplete(Player*); -void Katina_80197F10(Actor*); +void Katina_SFTeamFlyTowardsCamera(Actor*); void SectorZ_LevelStart(Player*); void SectorZ_LevelComplete(Player*); void SectorZ_8019DD20(Actor*); @@ -25,9 +25,9 @@ void Fortuna_8018BA2C(void); void Bolse_UpdateEventHandler(Actor*); void Bolse_80191ED8(void); void Bolse_DrawDynamicGround(void); -void Katina_Boss316_Init(Boss *); +void Katina_BossSetup(Boss *); void Katina_UpdateEvents(Actor*); -void Katina_80198930(void); +void Katina_BossInit(void); void SectorZ_80199900(Actor *, s32); void SectorZ_Missile_Update(Actor*); void SectorZ_UpdateEvents(Actor*); @@ -39,12 +39,12 @@ void Bolse_80191054(Effect*); void Bolse_80191180(Effect*); void Bolse_801912FC(Boss*); void Bolse_80191AFC(Boss*); -void Katina_80192984(Effect*); -void Katina_80192A68(Effect*); -void Katina_80193718(Boss*); -void Katina_80193B1C(Boss*); -void Katina_801946C4(Boss*); -void Katina_801968F4(Boss*); +void Katina_LaserEnergyParticlesUpdate(Effect*); +void Katina_LaserEnergyParticlesDraw(Effect*); +void Katina_BaseUpdate(Boss*); +void Katina_Base_Draw(Boss*); +void Katina_BossUpdate(Boss*); +void Katina_BossDraw(Boss*); void SectorZ_8019E234(Actor*); void SectorZ_8019E3A8(Actor*); void SectorZ_8019E454(Boss*); diff --git a/include/sf64object.h b/include/sf64object.h index 574ac14b..8b8899a2 100644 --- a/include/sf64object.h +++ b/include/sf64object.h @@ -652,7 +652,7 @@ typedef enum ObjectId { /* 336 */ OBJ_ITEM_GOLD_RING, /* 337 */ OBJ_ITEM_WING_REPAIR, /* 338 */ OBJ_ITEM_TRAINING_RING, - /* 339 */ OBJ_EFFECT_339, + /* 339 */ OBJ_EFFECT_FIRE_SMOKE, /* 340 */ OBJ_EFFECT_340, /* 341 */ OBJ_EFFECT_341, /* 342 */ OBJ_EFFECT_342, @@ -1244,8 +1244,8 @@ typedef Boss Boss312; typedef Boss Boss313; typedef Boss Boss314; typedef Boss BossSO; -typedef Boss Boss316; -typedef Boss Boss317; +typedef Boss Saucerer; +typedef Boss Frontlinebase; typedef Boss BossAQ; typedef Boss Boss319; typedef Boss Boss320; @@ -1267,7 +1267,7 @@ typedef Item Item1UP; typedef Item ItemGoldRing; typedef Item ItemWingRepair; typedef Item ItemTrainingRing; -typedef Effect Effect339; +typedef Effect EffectFireSmoke; typedef Effect Effect340; typedef Effect Effect341; typedef Effect Effect342; diff --git a/include/variables.h b/include/variables.h index fa6760d2..2080cfa7 100644 --- a/include/variables.h +++ b/include/variables.h @@ -108,7 +108,7 @@ extern u8 gKaAllyKillCount; extern s32 gAllRangeCheckpoint; extern s32 gAllRangeEventTimer; extern s32 gAllRangeCountdown[3]; -extern s32 gShowAllRangeCountdown; +extern bool gShowAllRangeCountdown; extern s32 gAllRangeFrameCount; extern f32 gAllRangeCountdownScale; diff --git a/linker_scripts/us/symbol_addrs_overlays.txt b/linker_scripts/us/symbol_addrs_overlays.txt index 71fee18e..5e44bc6c 100644 --- a/linker_scripts/us/symbol_addrs_overlays.txt +++ b/linker_scripts/us/symbol_addrs_overlays.txt @@ -38,7 +38,7 @@ D_i4_8019F2BC = 0x8019F2BC; // type:f32 segment:ovl_i4 force_migration:True D_i4_8019F2CC = 0x8019F2CC; // type:f32 segment:ovl_i4 force_migration:True D_i4_8019F2DC = 0x8019F2DC; // type:f32 segment:ovl_i4 force_migration:True D_i4_8019F2F0 = 0x8019F2F0; // type:s32 segment:ovl_i4 force_migration:True -D_i4_8019F340 = 0x8019F340; // type:f32 segment:ovl_i4 force_migration:True +sCsLevelCompleteActorPos = 0x8019F340; // type:f32 segment:ovl_i4 force_migration:True sOptionCardPosY = 0x801AE570; // type:f32 size:0x18 force_migration:True segment:ovl_menu sOptionCardTextPosX = 0x801AE588; // type:f32 size:0x18 force_migration:True segment:ovl_menu sOptionCardTextPosY = 0x801AE5A0; // type:f32 size:0x18 force_migration:True segment:ovl_menu @@ -155,7 +155,7 @@ D_i3_801C2768 = 0x801C2768; //segment:ovl_i3 size:0x38 D_i3_801C27A0 = 0x801C27A0; //segment:ovl_i3 size:0x20 Katina_UpdateEvents = 0x80198594;//segment:ovl_i4 -Katina_Boss316_Init = 0x80193CA4;//segment:ovl_i4 +Katina_BossSetup = 0x80193CA4;//segment:ovl_i4 SectorZ_Missile_Update = 0x80199C60;//segment:ovl_i4 SectorZ_80199900 = 0x80199900;//segment:ovl_i4 D_i4_801A03C0 = 0x801A03C0;//segment:ovl_i4 diff --git a/src/engine/fox_360.c b/src/engine/fox_360.c index d158a64f..d9c30a34 100644 --- a/src/engine/fox_360.c +++ b/src/engine/fox_360.c @@ -45,7 +45,7 @@ u8 gKaAllyKillCount; s32 gAllRangeCheckpoint; s32 gAllRangeEventTimer; s32 gAllRangeCountdown[3]; -s32 gShowAllRangeCountdown; +bool gShowAllRangeCountdown; s32 gAllRangeFrameCount; f32 gAllRangeCountdownScale; @@ -1171,8 +1171,9 @@ bool func_360_80031900(Actor* actor) { Matrix_MultVec3fNoTranslate(gCalcMatrix, &sp24, &sp18); if (sp18.z > 0.0f) { return true; + } else { + return false; } - return false; } static Vec3f sSectorZRetreatPath[6] = { @@ -2279,15 +2280,15 @@ void ActorAllRange_Draw(ActorAllRange* this) { } else if (gCurrentLevel == LEVEL_KATINA) { switch (this->unk_0B6) { case 0: - gSPDisplayList(gMasterDisp++, D_KA_600EFF0); + gSPDisplayList(gMasterDisp++, aKaEnemy1LowPolyDL); break; case 1: - gSPDisplayList(gMasterDisp++, D_KA_600E050); + gSPDisplayList(gMasterDisp++, aKaCornerianFighterDL); Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, -60.0f, MTXF_APPLY); Actor_DrawEngineGlow(this, 0); break; case 3: - gSPDisplayList(gMasterDisp++, D_KA_6001530); + gSPDisplayList(gMasterDisp++, aKaEnemy1DL); Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, 30.0f, MTXF_APPLY); ActorAllRange_DrawShield(this); break; diff --git a/src/engine/fox_demo.c b/src/engine/fox_demo.c index 8bc30a7c..f28533d7 100644 --- a/src/engine/fox_demo.c +++ b/src/engine/fox_demo.c @@ -2374,7 +2374,7 @@ void ActorCutscene_Update(ActorCutscene* this) { break; case LEVEL_KATINA: - Katina_80197F10(this); + Katina_SFTeamFlyTowardsCamera(this); break; case LEVEL_SECTOR_Z: @@ -2745,14 +2745,14 @@ void ActorCutscene_Draw(Actor* actor) { if ((actor->index == 3) && (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_LEVEL_COMPLETE)) { gSPDisplayList(gMasterDisp++, D_D00B880); } else { - gSPDisplayList(gMasterDisp++, D_KA_600E050); + gSPDisplayList(gMasterDisp++, aKaCornerianFighterDL); } Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, -60.0f, MTXF_APPLY); Actor_DrawEngineGlow(actor, 0); break; case 34: - gSPDisplayList(gMasterDisp++, D_KA_6001530); + gSPDisplayList(gMasterDisp++, aKaEnemy1DL); break; case 35: diff --git a/src/engine/fox_edata_info.c b/src/engine/fox_edata_info.c index fbff7caf..dbb7726c 100644 --- a/src/engine/fox_edata_info.c +++ b/src/engine/fox_edata_info.c @@ -247,7 +247,7 @@ ObjectInfo gObjectInfo[] = { /* OBJ_SCENERY_151 */ {(void*) D_FO_60066E0, 0, (ObjectFunc) NULL, D_FO_600FEB8, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, /* OBJ_SCENERY_152 */ {(void*) D_BO_600F4C0, 0, (ObjectFunc) NULL, D_BO_6011C10, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, /* OBJ_SCENERY_153 */ {(void*) D_BO_600B8B0, 0, (ObjectFunc) NULL, D_BO_6011C48, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, - /* OBJ_SCENERY_154 */ {(void*) D_KA_600BAF0, 0, (ObjectFunc) NULL, D_KA_601115C, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, + /* OBJ_SCENERY_154 */ {(void*) aKaFLBaseDL, 0, (ObjectFunc) NULL, D_KA_601115C, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, /* OBJ_SCENERY_155 */ {(void*) NULL, 0, (ObjectFunc) NULL, gNoHitbox, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, /* OBJ_SCENERY_156 */ {(void*) SectorY_80197CB8, 1, (ObjectFunc) NULL, D_SY_6034368, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, /* OBJ_SCENERY_157 */ {(void*) D_SZ_6001DA0, 0, (ObjectFunc) NULL, D_SZ_600924C, 0.0f, 0, 0, 40, 0, 0.0f, 0 }, @@ -409,8 +409,8 @@ ObjectInfo gObjectInfo[] = { /* OBJ_BOSS_313 */ {(void*) SectorZ_8019E98C, 1, (ObjectFunc) SectorZ_8019E454, D_SZ_6009388, 0.0f, 0, 0, 40, 0, 0.0f, 10 }, /* OBJ_BOSS_314 */ {(void*) SectorY_8019E2C4, 2, (ObjectFunc) SectorY_8019C888, gNoHitbox, 0.0f, 0, 0, 40, 0, 0.0f, 10 }, /* OBJ_BOSS_SO */ {(void*) Solar_801A71B8, 2, (ObjectFunc) Solar_801A5B3C, gNoHitbox, 0.0f, 0, 0, 40, 0, 0.0f, 10 }, - /* OBJ_BOSS_316 */ {(void*) Katina_801968F4, 1, (ObjectFunc) Katina_801946C4, D_KA_6011058, 0.0f, 0, 0, 40, 0, 0.0f, 10 }, - /* OBJ_BOSS_317 */ {(void*) Katina_80193B1C, 1, (ObjectFunc) Katina_80193718, D_KA_601115C, 0.0f, 0, 0, 40, 1, 0.0f, 10 }, + /* OBJ_BOSS_316 */ {(void*) Katina_BossDraw, 1, (ObjectFunc) Katina_BossUpdate, D_KA_6011058, 0.0f, 0, 0, 40, 0, 0.0f, 10 }, + /* OBJ_BOSS_317 */ {(void*) Katina_Base_Draw, 1, (ObjectFunc) Katina_BaseUpdate, D_KA_601115C, 0.0f, 0, 0, 40, 1, 0.0f, 10 }, /* OBJ_BOSS_AQ */ {(void*) Aquas_801B4D84, 2, (ObjectFunc) Aquas_801B134C, D_AQ_6030F74, 10000.0f, 0, 0, 40, 0, 0.0f, 10 }, /* OBJ_BOSS_319 */ {(void*) Venom1_801985E4, 1, (ObjectFunc) Venom1_80194398,D_VE1_8019A9B8, 3000.0f, 0, 0, 40, 1, 0.0f, 10 }, /* OBJ_BOSS_320 */ {(void*) Andross_801928C8, 2, (ObjectFunc) Andross_8018DBF0, D_ANDROSS_C038DC0, 10000.0f, 0, 0, 40, 0, 0.0f, 10 }, @@ -432,7 +432,7 @@ ObjectInfo gObjectInfo[] = { /* OBJ_ITEM_GOLD_RING */ {(void*) ItemGoldRing_Draw, 1, (ObjectFunc) ItemGoldRing_Update, gItemSupplyRingHitbox, 700.0f, 0, 0, 0, 0, 0.0f, 0 }, /* OBJ_ITEM_WING_REPAIR */ {(void*) D_arwing_3007650, 0, (ObjectFunc) ItemWingRepair_Update, gItemLasersHitbox, 700.0f, 0, 0, 0, 0, 0.0f, 0 }, /* OBJ_ITEM_TRAINING_RING */ {(void*) gItemTrainingRingDL, 0, (ObjectFunc) Training_ItemRing_Update, D_TR_6009CFC, 700.0f, 0, 0, 0, 0, 0.0f, 0 }, - /* OBJ_EFFECT_339 */ {(void*) func_effect_8007D55C, 1, (ObjectFunc) func_effect_8007D2F4, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, + /* OBJ_EFFECT_FIRE_SMOKE */ {(void*) func_effect_8007D55C, 1, (ObjectFunc) func_effect_8007D2F4, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, /* OBJ_EFFECT_340 */ {(void*) func_effect_8007D55C, 1, (ObjectFunc) func_effect_8007D748, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, /* OBJ_EFFECT_341 */ {(void*) func_effect_8007D55C, 1, (ObjectFunc) func_effect_8007D8A8, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, /* OBJ_EFFECT_342 */ {(void*) func_effect_8007E330, 1, (ObjectFunc) func_effect_8007E298, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, @@ -451,7 +451,7 @@ ObjectInfo gObjectInfo[] = { /* OBJ_EFFECT_355 */ {(void*) func_effect_80078AEC, 1, (ObjectFunc) func_effect_800802B8, NULL, 100.0f, 1, 0, 20, 1, 0.0f, 0 }, /* OBJ_EFFECT_356 */ {(void*) func_effect_80078C84, 1, (ObjectFunc) func_effect_800802F8, NULL, 100.0f, 1, 0, 20, 0, 0.0f, 0 }, /* OBJ_EFFECT_357 */ {(void*) func_effect_800798F0, 1, (ObjectFunc) func_effect_8007968C, NULL, 100.0f, 0, 1, 0, 0, 0.0f, 0 }, - /* OBJ_EFFECT_358 */ {(void*) Katina_80192A68, 1, (ObjectFunc) Katina_80192984, NULL, 100.0f, 1, 1, 0, 0, 0.0f, 0 }, + /* OBJ_EFFECT_358 */ {(void*) Katina_LaserEnergyParticlesDraw, 1, (ObjectFunc) Katina_LaserEnergyParticlesUpdate, NULL, 100.0f, 1, 1, 0, 0, 0.0f, 0 }, /* OBJ_EFFECT_359 */ {(void*) func_effect_8007AA60, 1, (ObjectFunc) func_effect_8007A994, NULL, -100.0f, 1, 2, 0, 0, 0.0f, 0 }, /* OBJ_EFFECT_360 */ {(void*) func_effect_8007BEE8, 1, (ObjectFunc) func_effect_8007BE54, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, /* OBJ_EFFECT_361 */ {(void*) func_effect_8007BEE8, 1, (ObjectFunc) func_effect_8007BDE0, NULL, -200.0f, 1, 2, 0, 0, 0.0f, 0 }, diff --git a/src/engine/fox_effect.c b/src/engine/fox_effect.c index 096b5f76..53d4a472 100644 --- a/src/engine/fox_effect.c +++ b/src/engine/fox_effect.c @@ -167,7 +167,7 @@ Effect* func_effect_8007783C(ObjectId objId) { void func_effect_800778C4(Effect* effect, f32 xPos, f32 yPos, f32 zPos, f32 xVel, f32 yVel, f32 zVel, f32 scale2) { Effect_Initialize(effect); effect->obj.status = OBJ_INIT; - effect->obj.id = OBJ_EFFECT_339; + effect->obj.id = OBJ_EFFECT_FIRE_SMOKE; effect->obj.pos.x = xPos; effect->obj.pos.y = yPos; @@ -628,6 +628,7 @@ void func_effect_800794CC(f32 xPos, f32 yPos, f32 zPos, f32 scale2) { } } +// Broken pieces and debris effect void func_effect_8007953C(f32 xPos, f32 yPos, f32 zPos, f32 scale2) { s32 i; @@ -1226,6 +1227,7 @@ void func_effect_8007B2BC(Effect* effect, f32 xPos, f32 yPos, f32 zPos, f32 scal Object_SetInfo(&effect->info, effect->obj.id); } +// Orange-yellowish light effect simulating an explosion void func_effect_8007B344(f32 xPos, f32 yPos, f32 zPos, f32 scale1, s32 arg4) { s32 i; @@ -1791,7 +1793,7 @@ void func_effect_8007CAF0(Effect* effect) { void func_effect_8007CC00(Effect* effect, f32 xPos, f32 yPos, f32 zPos, f32 scale2) { Effect_Initialize(effect); effect->obj.status = OBJ_INIT; - effect->obj.id = OBJ_EFFECT_339; + effect->obj.id = OBJ_EFFECT_FIRE_SMOKE; effect->obj.pos.x = xPos; effect->obj.pos.y = yPos; effect->obj.pos.z = zPos; diff --git a/src/engine/fox_enmy.c b/src/engine/fox_enmy.c index c3f9c42b..65002e7e 100644 --- a/src/engine/fox_enmy.c +++ b/src/engine/fox_enmy.c @@ -458,7 +458,7 @@ void Object_Load(ObjectInit* objInit, f32 xMax, f32 xMin, f32 yMax, f32 yMin) { } } } - if ((objInit->id >= OBJ_ITEM_LASERS) && (objInit->id < OBJ_EFFECT_339)) { + if ((objInit->id >= OBJ_ITEM_LASERS) && (objInit->id < OBJ_EFFECT_FIRE_SMOKE)) { for (i = 0; i < ARRAY_COUNT(gItems); i++) { if (gItems[i].obj.status == OBJ_FREE) { Item_Load(&gItems[i], objInit); @@ -466,7 +466,7 @@ void Object_Load(ObjectInit* objInit, f32 xMax, f32 xMin, f32 yMax, f32 yMin) { } } } - if (objInit->id >= OBJ_EFFECT_339 && objInit->id <= OBJ_UNK_406) { + if (objInit->id >= OBJ_EFFECT_FIRE_SMOKE && objInit->id <= OBJ_UNK_406) { switch (objInit->id) { case OBJ_UNK_403: D_MA_801BA1E8 = 99; @@ -1188,7 +1188,7 @@ void Object_Init(s32 index, ObjectId objId) { Andross_Boss320_Init(&gBosses[index]); break; case OBJ_BOSS_316: - Katina_Boss316_Init(&gBosses[index]); + Katina_BossSetup(&gBosses[index]); break; case OBJ_BOSS_314: SectorY_Boss314_Init(&gBosses[index]); diff --git a/src/engine/fox_hud.c b/src/engine/fox_hud.c index 40c67dcc..92894176 100644 --- a/src/engine/fox_hud.c +++ b/src/engine/fox_hud.c @@ -5417,7 +5417,7 @@ void func_hud_80094D20(f32 x, f32 y) { temp4 = gDisplayedHitCount; } - boolTemp = 0; + boolTemp = false; i = 1000; temp3 %= i; temp4 %= i; @@ -5430,7 +5430,7 @@ void func_hud_80094D20(f32 x, f32 y) { temp = temp3 / i; temp2 = temp4 / i; - if ((temp != 0) || (boolTemp == 1)) { + if ((temp != 0) || (boolTemp == true)) { if (temp != temp2) { D_hud_80161720[j] += 0.4f; if (D_hud_80161720[j] <= 0.9f) { @@ -5466,7 +5466,7 @@ void func_hud_80094D20(f32 x, f32 y) { if (xScale != 0.0f) { TextureRect_8bIA(&gMasterDisp, D_800D24DC[temp], 16, 15, x1, y1, xScale, 1.0f); } - boolTemp = 1; + boolTemp = true; } if ((!boolTemp) && (xScale != 0.0f)) { diff --git a/src/engine/fox_play.c b/src/engine/fox_play.c index b1244887..a613f799 100644 --- a/src/engine/fox_play.c +++ b/src/engine/fox_play.c @@ -2666,7 +2666,7 @@ void Play_Init(void) { ActorAllRange_SpawnTeam(); break; case LEVEL_KATINA: - Katina_80198930(); + Katina_BossInit(); if (!D_ctx_8017782C) { ActorAllRange_SpawnTeam(); } diff --git a/src/overlays/ovl_i4/fox_ka.c b/src/overlays/ovl_i4/fox_ka.c index 41233361..1a790c0b 100644 --- a/src/overlays/ovl_i4/fox_ka.c +++ b/src/overlays/ovl_i4/fox_ka.c @@ -1,7 +1,7 @@ /* * File: fox_ka.c * System: Katina - * Description: Level: Karina + * Description: Level: Katina */ #include "global.h" @@ -15,9 +15,47 @@ Vec3f D_i4_8019F168[] = { { 700.0f, 50.0f, -700.0f }, { -500.0f, 150.0f, -500 }, f32 D_i4_8019F18C[] = { 200.0f, 160.0f, 185.0f }; u8 D_i4_8019F198[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -s32 D_i4_8019F1C0[] = { - -1, 11, -1, 13, -1, 15, -1, 17, -1, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 2, 2, 4, 3, 2, +s32 sEnemySpawnTargets[] = { + -1, + AI360_10 + 1, + -1, + AI360_10 + 3, + -1, + AI360_10 + 5, + -1, + AI360_10 + 7, + -1, + AI360_10 + 9, + AI360_10, + AI360_10 + 1, + AI360_10 + 2, + AI360_10 + 3, + AI360_10 + 4, + AI360_10 + 5, + AI360_10 + 6, + AI360_10 + 7, + AI360_10 + 8, + AI360_10 + 9, + AI360_10, + AI360_10 + 1, + AI360_10 + 2, + AI360_10 + 3, + AI360_10 + 4, + AI360_10 + 5, + AI360_10 + 6, + AI360_10 + 7, + AI360_10 + 8, + AI360_10 + 9, + AI360_10, + AI360_10 + 1, + AI360_10 + 2, + AI360_10 + 3, + AI360_10 + 4, + AI360_SLIPPY, + AI360_SLIPPY, + 4, + 3, + 2, }; f32 D_i4_8019F260[] = { 377.0f, -600.0f, 700.0f }; f32 D_i4_8019F26C[] = { 50.0f, -50.0f, -100.0f }; @@ -32,7 +70,7 @@ f32 D_i4_8019F2DC[] = { 180.0f, 0.0f, 0.0f, 0.0f, 0.0f }; s32 D_i4_8019F2F0[] = { 100000, 100000, 100000, 100000, 1, 16, 15, 8, 3, 7, 12, 2, 5, 14, 9, 4, 10, 13, 6, 11, }; -Vec3f D_i4_8019F340[] = { +Vec3f sCsLevelCompleteActorPos[] = { { 500.0f, -100.0f, 500.0f }, { -500.0f, -70.0f, 500.0f }, { 0.0f, -140.0f, 1000.0f }, { -500.0f, -200.0f, 1000.0f }, { 1000.0f, -230.0f, 1500.0f }, { -1500.0f, -300.0f, 2300.0f }, { -500.0f, -250.0f, 2000.0f }, { 500.0f, -300.0f, 2200.0f }, { 1500.0f, -280.0f, 2100.0f }, @@ -53,71 +91,163 @@ f32 D_i4_801A0550; f32 D_i4_801A0554; f32 D_i4_801A0558; -void Katina_801995B4(Actor*); -void Katina_80198AA0(Actor*); +void Katina_EnemyDraw(ActorAllRange*); +void Katina_EnemyUpdate(ActorAllRange*); void Katina_801981F8(Actor*); -void Katina_801927E0(Effect* effect, f32 x, f32 y, f32 z, f32 x2, f32 y2, f32 z2) { +typedef enum KaActorIwork { + /* 0 */ KA_ACTOR_IWORK_0, + /* 1 */ KA_ACTOR_IWORK_1, + /* 2 */ KA_ACTOR_IWORK_2, + /* 4 */ KA_ACTOR_IWORK_4 = 4, + /* 5 */ KA_ACTOR_IWORK_5, + /* 8 */ KA_ACTOR_IWORK_8 = 8, + /* 11 */ KA_ACTOR_IWORK_11 = 11, + /* 23 */ KA_ACTOR_LOW_POLY = 23, +} KaActorIwork; + +typedef enum KaActorFwork { + /* 0 */ KA_ACTOR_FWORK_0, + /* 1 */ KA_ACTOR_FWORK_1, + /* 2 */ KA_ACTOR_FWORK_2, + /* 3 */ KA_ACTOR_FWORK_3, + /* 4 */ KA_ACTOR_FWORK_4, + /* 5 */ KA_ACTOR_FWORK_5, + /* 6 */ KA_ACTOR_FWORK_6, + /* 7 */ KA_ACTOR_FWORK_7, + /* 8 */ KA_ACTOR_FWORK_8, + /* 9 */ KA_ACTOR_FWORK_9, + /* 10 */ KA_ACTOR_FWORK_10, + /* 11 */ KA_ACTOR_FWORK_11, + /* 12 */ KA_ACTOR_FWORK_12, + /* 13 */ KA_ACTOR_FWORK_13, + /* 14 */ KA_ACTOR_FWORK_14, + /* 19 */ KA_ACTOR_FWORK_19 = 19, + /* 20 */ KA_ACTOR_FWORK_20, + /* 21 */ KA_ACTOR_FWORK_21, + /* 29 */ KA_ACTOR_FWORK_29 = 29, +} KaActorFwork; + +typedef enum KaBosses { + /* 0 */ KA_BOSS_BASE, + /* 1 */ KA_BOSS_MOTHERSHIP +} KaBosses; + +typedef enum KaBossSwork { + /* 0 */ BOSS_HATCH_1_FLASH_TIMER, + /* 1 */ BOSS_HATCH_2_FLASH_TIMER, + /* 2 */ BOSS_HATCH_3_FLASH_TIMER, + /* 3 */ BOSS_HATCH_4_FLASH_TIMER, + /* 4 */ BOSS_CORE_FLASH_TIMER, + /* 5 */ BOSS_SWORK_5, + /* 6 */ BOSS_SWORK_6, + /* 7 */ BOSS_SWORK_7, + /* 8 */ BOSS_SWORK_8, + /* 9 */ BOSS_SWORK_9, + /* 10 */ BOSS_HATCH_1_HP, + /* 11 */ BOSS_HATCH_2_HP, + /* 12 */ BOSS_HATCH_3_HP, + /* 13 */ BOSS_HATCH_4_HP, + /* 14 */ BOSS_CORE_HP, + /* 15 */ BOSS_HATCH_DESTROY_COUNT, + /* 16 */ BOSS_CORE_TIMER +} KaBossSwork; + +typedef enum KaBossFwork { + /* 0 */ BOSS_HATCH_1_ANGLE, + /* 1 */ BOSS_HATCH_2_ANGLE, + /* 2 */ BOSS_HATCH_3_ANGLE, + /* 3 */ BOSS_HATCH_4_ANGLE, + /* 4 */ BOSS_CORE_LEVEL, + /* 5 */ BOSS_HATCH_1_ANGLE_TARGET, + /* 6 */ BOSS_HATCH_2_ANGLE_TARGET, + /* 7 */ BOSS_HATCH_3_ANGLE_TARGET, + /* 8 */ BOSS_HATCH_4_ANGLE_TARGET, + /* 9 */ BOSS_CORE_TARGET_LEVEL, + /* 10 */ BOSS_MOVEMENT_SPEED, + /* 11 */ BOSS_Y_ROT_SPEED, + /* 12 */ BOSS_Y_ROT_SPEED_TARGET, + /* 13 */ BOSS_FWORK_13, + /* 14 */ BOSS_LASER_LIGHT_SCALE, + /* 15 */ BOSS_LASER_LENGTH +} KaBossFwork; + +typedef enum KaBaseStates { + /* 0 */ KA_BOSS_BASE_IDLE, + /* 1 */ KA_BASE_STATE_1, + /* 2 */ KA_BASE_STATE_2 +} KaBaseStates; + +// Particle effects visible while the Mothership is charging it's laser +void Katina_LaserEnergyParticlesSetup(Effect358* this, f32 x, f32 y, f32 z, f32 x2, f32 y2, f32 z2) { f32 yRot; f32 xRot; f32 distXZ; Vec3f src; Vec3f dest; - Effect_Initialize(effect); - effect->obj.status = OBJ_ACTIVE; - effect->obj.id = OBJ_EFFECT_358; - effect->obj.pos.x = x; - effect->obj.pos.y = y; - effect->obj.pos.z = z; + Effect_Initialize(this); + this->obj.status = OBJ_ACTIVE; + this->obj.id = OBJ_EFFECT_358; + + this->obj.pos.x = x; + this->obj.pos.y = y; + this->obj.pos.z = z; + xRot = Math_Atan2F(x2 - x, z2 - z); distXZ = sqrtf(SQ(x2 - x) + SQ(z2 - z)); yRot = -Math_Atan2F(y2 - y, distXZ); + Matrix_RotateY(gCalcMatrix, xRot, MTXF_NEW); Matrix_RotateX(gCalcMatrix, yRot, MTXF_APPLY); + src.x = 0.0f; src.y = 0.0f; src.z = 30.0f; + Matrix_MultVec3f(gCalcMatrix, &src, &dest); - effect->unk_60.x = dest.x; - effect->unk_60.y = dest.y; - effect->unk_60.z = dest.z; - Object_SetInfo(&effect->info, effect->obj.id); + + this->unk_60.x = dest.x; + this->unk_60.y = dest.y; + this->unk_60.z = dest.z; + + Object_SetInfo(&this->info, this->obj.id); } -void Katina_80192908(f32 x, f32 y, f32 z, f32 x2, f32 y2, f32 z2) { +// Allocation of particle effects visible while the Mothership is charging it's laser +void Katina_LaserEnergyParticlesSpawn(f32 x, f32 y, f32 z, f32 x2, f32 y2, f32 z2) { s32 i; for (i = ARRAY_COUNT(gEffects) - 1; i >= 0; i--) { if (gEffects[i].obj.status == OBJ_FREE) { - Katina_801927E0(&gEffects[i], x, y, z, x2, y2, z2); + Katina_LaserEnergyParticlesSetup(&gEffects[i], x, y, z, x2, y2, z2); break; } } } -void Katina_80192984(Effect* effect) { - effect->vel.x = effect->unk_60.x * effect->scale1; - effect->vel.y = effect->unk_60.y * effect->scale1; - effect->vel.z = effect->unk_60.z * effect->scale1; +void Katina_LaserEnergyParticlesUpdate(Effect358* this) { + this->vel.x = this->unk_60.x * this->scale1; + this->vel.y = this->unk_60.y * this->scale1; + this->vel.z = this->unk_60.z * this->scale1; - Math_SmoothStepToF(&effect->scale1, 1.0f, 1.0f, 0.02f, 0.0f); + Math_SmoothStepToF(&this->scale1, 1.0f, 1.0f, 0.02f, 0.0f); - if (effect->unk_44 < 253) { - effect->unk_44 += 3; + if (this->unk_44 < 253) { + this->unk_44 += 3; } - if ((fabsf(effect->obj.pos.x - gBosses[1].obj.pos.x) <= 30.0f) && - (fabsf(effect->obj.pos.z - gBosses[1].obj.pos.z) <= 30.0f)) { - Object_Kill(&effect->obj, effect->sfxSource); + if ((fabsf(this->obj.pos.x - gBosses[KA_BOSS_MOTHERSHIP].obj.pos.x) <= 30.0f) && + (fabsf(this->obj.pos.z - gBosses[KA_BOSS_MOTHERSHIP].obj.pos.z) <= 30.0f)) { + Object_Kill(&this->obj, this->sfxSource); } } -void Katina_80192A68(Effect* effect) { +void Katina_LaserEnergyParticlesDraw(Effect358* this) { RCP_SetupDL(&gMasterDisp, 67); - gDPSetPrimColor(gMasterDisp++, 0, 0, 48, 48, 255, effect->unk_44); - gDPSetEnvColor(gMasterDisp++, 0, 0, 0, effect->unk_44); + gDPSetPrimColor(gMasterDisp++, 0, 0, 48, 48, 255, this->unk_44); + gDPSetEnvColor(gMasterDisp++, 0, 0, 0, this->unk_44); Matrix_Scale(gGfxMatrix, 0.4f, 0.4f, 0.4f, MTXF_APPLY); Matrix_SetGfxMtx(&gMasterDisp); @@ -127,45 +257,54 @@ void Katina_80192A68(Effect* effect) { RCP_SetupDL(&gMasterDisp, 64); } -void Katina_80192B4C(Effect* effect, f32 x, f32 y, f32 z, f32 xVel, f32 yVel, f32 zVel, f32 scale) { - Effect_Initialize(effect); +// Explosion/Fire effect with smoke. +void Katina_FireSmokeEffectSetup(EffectFireSmoke* this, f32 x, f32 y, f32 z, f32 xVel, f32 yVel, f32 zVel, f32 scale) { + Effect_Initialize(this); - effect->obj.status = OBJ_INIT; - effect->obj.id = OBJ_EFFECT_339; + this->obj.status = OBJ_INIT; + this->obj.id = OBJ_EFFECT_FIRE_SMOKE; - effect->obj.pos.x = x; - effect->obj.pos.y = y; - effect->obj.pos.z = z; + this->obj.pos.x = x; + this->obj.pos.y = y; + this->obj.pos.z = z; - effect->vel.x = xVel; - effect->vel.y = yVel; - effect->vel.z = zVel; + this->vel.x = xVel; + this->vel.y = yVel; + this->vel.z = zVel; - effect->scale2 = scale; - effect->scale1 = 0.5f; - effect->unk_4C = 2; - effect->obj.rot.z = RAND_FLOAT(360.0f); - Object_SetInfo(&effect->info, effect->obj.id); - effect->unk_44 = 230; + this->scale2 = scale; + this->scale1 = 0.5f; + + this->unk_4C = 2; + this->obj.rot.z = RAND_FLOAT(360.0f); + + Object_SetInfo(&this->info, this->obj.id); + + this->unk_44 = 230; } -void Katina_80192C08(f32 x, f32 y, f32 z, f32 xVel, f32 yVel, f32 zVel, f32 scale) { +// Explosion/Fire effect with smoke. +void Katina_FireSmokeEffectSpawn(f32 x, f32 y, f32 z, f32 xVel, f32 yVel, f32 zVel, f32 scale) { s32 i; for (i = ARRAY_COUNT(gEffects) - 1; i >= 0; i--) { if (gEffects[i].obj.status == OBJ_FREE) { - Katina_80192B4C(&gEffects[i], x, y, z, xVel, yVel, zVel, scale); + Katina_FireSmokeEffectSetup(&gEffects[i], x, y, z, xVel, yVel, zVel, scale); break; } } } -void Katina_80192C8C(void) { - Actor* actor = &gActors[4]; +/** + * Start cutscene where Bill is seen chasing an enemy + * while one of his teammates defeats it. + */ +void Katina_StartCutsceneUpdate(void) { + ActorCutscene* actor = &gActors[4]; s32 i; Vec3f dest; - Matrix_RotateY(gCalcMatrix, -0.7853982f, MTXF_NEW); + Matrix_RotateY(gCalcMatrix, -(M_PI / 4), MTXF_NEW); for (i = 0; i < 3; i++, actor++) { if (actor->obj.status == OBJ_FREE) { @@ -180,7 +319,7 @@ void Katina_80192C8C(void) { actor->vel.z = dest.z; actor->unk_0B6 = D_i4_8019F15C[i]; actor->unk_0C9 = 1; - actor->iwork[11] = 1; + actor->iwork[KA_ACTOR_IWORK_11] = 1; Object_SetInfo(&actor->info, actor->obj.id); AUDIO_PLAY_SFX(0x31000011, actor->sfxSource, 4); } @@ -215,13 +354,16 @@ void Katina_LevelStart(Player* player) { case 0: gCsFrameCount = 0; - Katina_80192C8C(); + + Katina_StartCutsceneUpdate(); + gCsCamEyeX = 3535.0f; gCsCamEyeY = 500.0f; gCsCamEyeZ = 3535.0f; gCsCamAtX = gActors[4].obj.pos.x; gCsCamAtY = gActors[4].obj.pos.y; gCsCamAtZ = gActors[4].obj.pos.z; + player->csState = 11; D_ctx_80177A48[0] = 1.0f; break; @@ -230,9 +372,11 @@ void Katina_LevelStart(Player* player) { gCsCamAtX = gActors[4].obj.pos.x; gCsCamAtY = gActors[4].obj.pos.y; gCsCamAtZ = gActors[4].obj.pos.z; + gActors[4].obj.rot.z -= 0.2f; gActors[5].obj.rot.z += 0.3f; gActors[6].obj.rot.z += 0.7f; + if (gCsFrameCount == 100) { gCsFrameCount = 80; player->csState = 12; @@ -243,6 +387,7 @@ void Katina_LevelStart(Player* player) { gActors[4].vel.y += 0.3f; gActors[4].vel.z += 0.7f; gActors[4].obj.rot.z -= 1.0f; + if (gCsFrameCount == 120) { ActorAllRange_SpawnTeam(); player->csState = 13; @@ -250,7 +395,8 @@ void Katina_LevelStart(Player* player) { player->pos.y = 1300.0f; player->pos.z = 10000.0f; player->rot.x = -10.0f; - for (i = 1, actor = &gActors[1]; i < 4; i++, actor++) { + + for (i = 1, actor = &gActors[1]; i <= 3; i++, actor++) { actor->obj.pos.x = D_i4_8019F168[i - 1].x + player->pos.x; actor->obj.pos.y = D_i4_8019F168[i - 1].y + player->pos.y; actor->obj.pos.z = D_i4_8019F168[i - 1].z + player->pos.z; @@ -268,23 +414,29 @@ void Katina_LevelStart(Player* player) { player->cam.at.z = gCsCamAtZ = player->pos.z; player->cam.eye.x = gCsCamEyeX = 100.0f; player->cam.eye.z = gCsCamEyeZ = 7000.0f; + if (gCsFrameCount == 240) { Object_Kill(&gActors[4].obj, gActors[4].sfxSource); Object_Kill(&gActors[6].obj, gActors[6].sfxSource); player->state_1C8 = PLAYERSTATE_1C8_ACTIVE; player->unk_014 = 0.0001f; + AUDIO_PLAY_BGM(gBgmSeqId); + gLevelStartStatusScreenTimer = 80; - for (actor = &gActors[1], i = 1; i < 4; i += 1, actor++) { + + for (actor = &gActors[1], i = 1; i <= 3; i++, actor++) { actor->timer_0BC = 0; } gAllRangeEventTimer = -610; } break; } + src.x = 0.0f; src.y = 0.0f; src.z = 100.0f; + switch (gCsFrameCount) { case 15: Radio_PlayMessage(gMsg_ID_18000, RCID_BILL); @@ -321,6 +473,7 @@ void Katina_LevelStart(Player* player) { for (j = 0; j < 10; j++) { func_effect_800794CC(gActors[5].obj.pos.x, gActors[5].obj.pos.y, gActors[5].obj.pos.z, 1.0f); } + func_effect_8007A6F0(&gActors[5].obj.pos, 0x2903B009); break; @@ -328,20 +481,27 @@ void Katina_LevelStart(Player* player) { Object_Kill(&gActors[5].obj, gActors[5].sfxSource); break; } + Matrix_RotateY(gCalcMatrix, (player->rot.y + player->yRot_114 + 180.0f) * M_DTOR, MTXF_NEW); Matrix_RotateX(gCalcMatrix, -(player->rot.x * M_DTOR), MTXF_APPLY); + src.x = 0; src.y = 0.0f; src.z = player->baseSpeed; + Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); + player->vel.x = dest.x; player->vel.z = dest.z; player->vel.y = dest.y; + player->pos.x += player->vel.x; player->pos.y += player->vel.y; player->pos.z += player->vel.z; + player->trueZpos = player->pos.z; player->bankAngle = player->rot.z + player->zRotBank + player->zRotBarrelRoll; + Math_SmoothStepToF(&player->cam.eye.x, gCsCamEyeX, D_ctx_80177A48[0], 50000.0f, 0.0f); Math_SmoothStepToF(&player->cam.eye.y, gCsCamEyeY, D_ctx_80177A48[0], 50000.0f, 0.0f); Math_SmoothStepToF(&player->cam.eye.z, gCsCamEyeZ, D_ctx_80177A48[0], 50000.0f, 0.0f); @@ -350,34 +510,36 @@ void Katina_LevelStart(Player* player) { Math_SmoothStepToF(&player->cam.at.z, gCsCamAtZ, D_ctx_80177A48[0], 50000.0f, 0.0f); } -void Katina_80193718(Boss* boss) { +void Katina_BaseUpdate(Frontlinebase* this) { s32 i; f32 posX; Vec3f src; Vec3f dest; Actor* actor; - switch (boss->state) { - case 0: + switch (this->state) { + case KA_BOSS_BASE_IDLE: break; - case 1: - boss->timer_050 = 4; - boss->state++; - func_effect_8007B344(boss->obj.pos.x, boss->obj.pos.y + 250.0f, boss->obj.pos.z + 600.0f, 71.0f, 5); + case KA_BASE_STATE_1: + this->timer_050 = 4; + this->state++; + func_effect_8007B344(this->obj.pos.x, this->obj.pos.y + 250.0f, this->obj.pos.z + 600.0f, 71.0f, 5); gCameraShake = 25; gLight1R = 255; gLight1G = 0; gLight1B = 0; - case 2: - if (boss->timer_050 == 1) { + case KA_BASE_STATE_2: + if (this->timer_050 == 1) { src.x = 0.0f; src.y = 0.0f; src.z = 500.0f; + for (posX = 50.0f, i = 0; posX < 600.0f; i++) { Matrix_RotateY(gCalcMatrix, i * 13.0f * M_DTOR, MTXF_NEW); Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); + if (dest.z > 0.0f) { func_effect_8007953C(dest.x, posX, dest.z, 1.3f); posX += 6.25f; @@ -385,77 +547,87 @@ void Katina_80193718(Boss* boss) { } } - for (actor = &gActors[10], i = 10; i < ARRAY_COUNT(gActors); i++, actor++) { + // Kill all active enemy and ally actors + for (actor = &gActors[AI360_10], i = 10; i < ARRAY_COUNT(gActors); i++, actor++) { if (actor->obj.status == OBJ_ACTIVE) { actor->obj.status = OBJ_DYING; actor->timer_0BC = 30; } } } + for (i = 0; i < 1; i++) { - Katina_80192C08(RAND_FLOAT_CENTERED(700.0f) + boss->obj.pos.x, - RAND_FLOAT_CENTERED(400.0f) + (boss->obj.pos.y + 200.0f), - RAND_FLOAT_CENTERED(700.0f) + boss->obj.pos.z, RAND_FLOAT_CENTERED(50.0f), - RAND_FLOAT(40.0f) + 30.0f, RAND_FLOAT_CENTERED(50.0f), RAND_FLOAT(10.0f) + 10.0f); + Katina_FireSmokeEffectSpawn(RAND_FLOAT_CENTERED(700.0f) + this->obj.pos.x, + RAND_FLOAT_CENTERED(400.0f) + (this->obj.pos.y + 200.0f), + RAND_FLOAT_CENTERED(700.0f) + this->obj.pos.z, RAND_FLOAT_CENTERED(50.0f), + RAND_FLOAT(40.0f) + 30.0f, RAND_FLOAT_CENTERED(50.0f), + RAND_FLOAT(10.0f) + 10.0f); } break; } - if (boss->dmgType != DMG_NONE) { - boss->dmgType = DMG_NONE; - AUDIO_PLAY_SFX(0x29121007, boss->sfxSource, 4); + + if (this->dmgType != DMG_NONE) { + this->dmgType = DMG_NONE; + AUDIO_PLAY_SFX(0x29121007, this->sfxSource, 4); } } -void Katina_80193B1C(Boss* boss) { +void Katina_Base_Draw(Frontlinebase* this) { gSPFogPosition(gMasterDisp++, gFogNear, 1002); Matrix_Translate(gGfxMatrix, 0.0f, 20.0f, 0.0f, MTXF_APPLY); Matrix_SetGfxMtx(&gMasterDisp); - if (boss->state == 0) { - gSPDisplayList(gMasterDisp++, D_KA_600BAF0); + + if (this->state == KA_BOSS_BASE_IDLE) { + gSPDisplayList(gMasterDisp++, aKaFLBaseDL); } else { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - gSPDisplayList(gMasterDisp++, D_KA_600C4E0); + gSPDisplayList(gMasterDisp++, aKaFLBaseDestroyedDL); } } -void Katina_Boss316_Init(Boss316* this) { - this->swork[10] = 100; - this->swork[11] = 100; - this->swork[12] = 100; - this->swork[13] = 100; - this->swork[14] = 400; - this->fwork[9] = 850.0f; - this->fwork[4] = 850.0f; +void Katina_BossSetup(Saucerer* this) { + this->swork[BOSS_HATCH_1_HP] = 100; + this->swork[BOSS_HATCH_2_HP] = 100; + this->swork[BOSS_HATCH_3_HP] = 100; + this->swork[BOSS_HATCH_4_HP] = 100; + this->swork[BOSS_CORE_HP] = 400; + this->fwork[BOSS_CORE_TARGET_LEVEL] = 850.0f; + this->fwork[BOSS_CORE_LEVEL] = 850.0f; this->vwork[0].y = 1000.0f; } -void Katina_80193CE4(Boss* boss, s32 idx) { +void Katina_Hatch_Destroy(Saucerer* this, s32 hatchIdx) { s32 i; Vec3f pos; - func_effect_8007D2C8(boss->obj.pos.x + (boss->vwork[idx + 1].x * 1.3f), - boss->obj.pos.y + (boss->vwork[idx + 1].y * 1.3f), - boss->obj.pos.z + (boss->vwork[idx + 1].z * 1.3f), 15.0f); - boss->swork[idx + 5] = 60; + func_effect_8007D2C8(this->obj.pos.x + (this->vwork[hatchIdx + 1].x * 1.3f), + this->obj.pos.y + (this->vwork[hatchIdx + 1].y * 1.3f), + this->obj.pos.z + (this->vwork[hatchIdx + 1].z * 1.3f), 15.0f); + this->swork[hatchIdx + 5] = 60; for (i = 0; i < 20; i++) { - func_effect_800794CC(boss->obj.pos.x + RAND_FLOAT_CENTERED(300.0f) + (boss->vwork[idx + 1].x * 1.3f), - boss->obj.pos.y + RAND_FLOAT_CENTERED(300.0f) + (boss->vwork[idx + 1].y * 1.3f), - boss->obj.pos.z + RAND_FLOAT_CENTERED(300.0f) + (boss->vwork[idx + 1].z * 1.3f), 1.55f); + func_effect_800794CC(this->obj.pos.x + RAND_FLOAT_CENTERED(300.0f) + (this->vwork[hatchIdx + 1].x * 1.3f), + this->obj.pos.y + RAND_FLOAT_CENTERED(300.0f) + (this->vwork[hatchIdx + 1].y * 1.3f), + this->obj.pos.z + RAND_FLOAT_CENTERED(300.0f) + (this->vwork[hatchIdx + 1].z * 1.3f), + 1.55f); } - pos.x = boss->obj.pos.x + (boss->vwork[idx + 1].x * 1.3f); - pos.y = boss->obj.pos.y + (boss->vwork[idx + 1].y * 1.3f); - pos.z = boss->obj.pos.z + (boss->vwork[idx + 1].z * 1.3f); + pos.x = this->obj.pos.x + (this->vwork[hatchIdx + 1].x * 1.3f); + pos.y = this->obj.pos.y + (this->vwork[hatchIdx + 1].y * 1.3f); + pos.z = this->obj.pos.z + (this->vwork[hatchIdx + 1].z * 1.3f); + func_effect_8007A6F0(&pos, 0x2903B009); - boss->swork[15] += 1; + + this->swork[BOSS_HATCH_DESTROY_COUNT]++; + BonusText_Display(pos.x, pos.y - 300.0f, pos.z, 5); + gHitCount += 6; D_ctx_80177850 = 15; } -void Katina_80193EF0(Boss* boss) { +void Katina_BossHandleDamage(Saucerer* this) { s32 i; s32 pad; Vec3f src; @@ -463,28 +635,31 @@ void Katina_80193EF0(Boss* boss) { Vec3f sfxSource; f32 y; - if (boss->dmgType != DMG_NONE) { - boss->dmgType = DMG_NONE; + if (this->dmgType != DMG_NONE) { + this->dmgType = DMG_NONE; if (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_STANDBY) { return; } - switch (boss->dmgPart) { + switch (this->dmgPart) { case 0: case 1: case 2: case 3: - if (boss->swork[10 + boss->dmgPart] > 0) { - boss->swork[00 + boss->dmgPart] = 20; - boss->swork[10 + boss->dmgPart] -= boss->damage; - sfxSource.x = (boss->vwork[1 + boss->dmgPart].x * 1.3f) + boss->obj.pos.x; - sfxSource.y = (boss->vwork[1 + boss->dmgPart].y * 1.3f) + boss->obj.pos.y; - sfxSource.z = (boss->vwork[1 + boss->dmgPart].z * 1.3f) + boss->obj.pos.z; + if (this->swork[10 + this->dmgPart] > 0) { + this->swork[00 + this->dmgPart] = 20; + this->swork[10 + this->dmgPart] -= this->damage; + + sfxSource.x = (this->vwork[1 + this->dmgPart].x * 1.3f) + this->obj.pos.x; + sfxSource.y = (this->vwork[1 + this->dmgPart].y * 1.3f) + this->obj.pos.y; + sfxSource.z = (this->vwork[1 + this->dmgPart].z * 1.3f) + this->obj.pos.z; + func_effect_8007A6F0(&sfxSource, 0x29034003); - if (boss->swork[10 + boss->dmgPart] <= 0) { - boss->swork[10 + boss->dmgPart] = 0; - Katina_80193CE4(boss, boss->dmgPart); + + if (this->swork[10 + this->dmgPart] <= 0) { + this->swork[10 + this->dmgPart] = 0; + Katina_Hatch_Destroy(this, this->dmgPart); } } break; @@ -493,20 +668,24 @@ void Katina_80193EF0(Boss* boss) { case 5: case 6: case 7: - if ((boss->swork[14] > 0) && (boss->state > 10)) { - boss->swork[4] = 20; - boss->swork[14] = boss->swork[14] - boss->damage; + if ((this->swork[BOSS_CORE_HP] > 0) && (this->state > 10)) { + this->swork[BOSS_CORE_FLASH_TIMER] = 20; + this->swork[BOSS_CORE_HP] -= this->damage; - if (boss->swork[14] < 100) { - func_effect_8007A6F0(&boss->obj.pos, 0x2943500F); + if (this->swork[BOSS_CORE_HP] < 100) { + func_effect_8007A6F0(&this->obj.pos, 0x2943500F); } else { - func_effect_8007A6F0(&boss->obj.pos, 0x29034003); + func_effect_8007A6F0(&this->obj.pos, 0x29034003); } - if (boss->swork[14] <= 0) { - func_effect_8007D2C8(boss->obj.pos.x, boss->obj.pos.y - 1000.0f, boss->obj.pos.z, 15.0f); + if (this->swork[BOSS_CORE_HP] <= 0) { + // OBJ_EFFECT_FIRE_SMOKE + func_effect_8007D2C8(this->obj.pos.x, this->obj.pos.y - 1000.0f, this->obj.pos.z, 15.0f); + y = 0.0f; - boss->swork[9] = 80; + + this->swork[BOSS_SWORK_9] = 80; + src.x = 0.0f; src.y = 0.0f; src.z = 50.0f; @@ -514,19 +693,29 @@ void Katina_80193EF0(Boss* boss) { for (i = 0; i < 130; i++, y += 5.0f, src.z += 1.4f) { Matrix_RotateY(gCalcMatrix, i * 35.0f * M_DTOR, MTXF_NEW); Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); - func_effect_800794CC(boss->obj.pos.x + dest.x, boss->obj.pos.y - 1200.0f + y, - boss->obj.pos.z + dest.z, 1.6f); + + // Broken pieces of the core + // OBJ_EFFECT_357 + func_effect_800794CC(this->obj.pos.x + dest.x, this->obj.pos.y - 1200.0f + y, + this->obj.pos.z + dest.z, 1.6f); } - AUDIO_PLAY_SFX(0x2940D09A, boss->sfxSource, 4); + + AUDIO_PLAY_SFX(0x2940D09A, this->sfxSource, 4); + gScreenFlashTimer = 8; - boss->state = 20; - boss->timer_050 = 50; + this->state = 20; + this->timer_050 = 50; + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM, 50); SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 50); + Radio_PlayMessage(gMsg_ID_18066, RCID_BILL); - boss->obj.pos.y -= 1000.0f; - Boss_AwardBonus(boss); - boss->obj.pos.y += 1000.0f; + + this->obj.pos.y -= 1000.0f; + + Boss_AwardBonus(this); + + this->obj.pos.y += 1000.0f; } } break; @@ -536,90 +725,104 @@ void Katina_80193EF0(Boss* boss) { if (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_ACTIVE) { if ((gGameFrameCount % 16) == 0) { for (i = 0; i < 4; i++) { - if ((boss->swork[10 + i] <= 0) && (Rand_ZeroOne() < 0.2f)) { - func_effect_8007BFFC((boss->vwork[1 + i].x * 1.3f) + boss->obj.pos.x, - (boss->vwork[1 + i].y * 1.3f) + boss->obj.pos.y, - (boss->vwork[1 + i].z * 1.3f) + boss->obj.pos.z, boss->vel.x, boss->vel.y, - boss->vel.z, 7.0f, 5); + if ((this->swork[10 + i] <= 0) && (Rand_ZeroOne() < 0.2f)) { + func_effect_8007BFFC((this->vwork[1 + i].x * 1.3f) + this->obj.pos.x, + (this->vwork[1 + i].y * 1.3f) + this->obj.pos.y, + (this->vwork[1 + i].z * 1.3f) + this->obj.pos.z, this->vel.x, this->vel.y, + this->vel.z, 7.0f, 5); } } } } for (i = 0; i < 5; i++) { - if (boss->swork[5 + i] != 0) { - boss->swork[5 + i]--; + if (this->swork[5 + i] != 0) { + this->swork[5 + i]--; if (i < 4) { - Katina_80192C08(boss->vwork[1 + i].x * 1.3f + boss->obj.pos.x, - boss->vwork[1 + i].y * 1.1f + boss->obj.pos.y, - boss->vwork[1 + i].z * 1.3f + boss->obj.pos.z, boss->vwork[1 + i].x * 0.05f, - boss->vwork[1 + i].y * 0.05f, boss->vwork[1 + i].z * 0.05f, 15.0f); + Katina_FireSmokeEffectSpawn(this->vwork[1 + i].x * 1.3f + this->obj.pos.x, + this->vwork[1 + i].y * 1.1f + this->obj.pos.y, + this->vwork[1 + i].z * 1.3f + this->obj.pos.z, this->vwork[1 + i].x * 0.05f, + this->vwork[1 + i].y * 0.05f, this->vwork[1 + i].z * 0.05f, 15.0f); } else { - Katina_80192C08(boss->obj.pos.x, boss->obj.pos.y - 700.0f, boss->obj.pos.z, 0.0f, -40.0f, 0.0f, 10.0f); + Katina_FireSmokeEffectSpawn(this->obj.pos.x, this->obj.pos.y - 700.0f, this->obj.pos.z, 0.0f, -40.0f, + 0.0f, 10.0f); } } } } -void Katina_80194458(Boss* boss, Vec3f* pos, f32 arg2) { +void Katina_BossSpawnEnemies(Saucerer* this, Vec3f* pos, f32 arg2) { s32 i; - Actor* actor = &gActors[20]; + ActorAllRange* actor = &gActors[20]; for (i = 10; i < 49; i++, actor++) { if (actor->obj.status == OBJ_FREE) { Actor_Initialize(actor); actor->obj.status = OBJ_ACTIVE; actor->obj.id = OBJ_ACTOR_ALLRANGE; - actor->obj.pos.x = boss->obj.pos.x + pos->x; - actor->obj.pos.y = boss->obj.pos.y + pos->y; - actor->obj.pos.z = boss->obj.pos.z + pos->z; + + actor->obj.pos.x = this->obj.pos.x + pos->x; + actor->obj.pos.y = this->obj.pos.y + pos->y; + actor->obj.pos.z = this->obj.pos.z + pos->z; + actor->state = 1; actor->timer_0BC = 20; actor->unk_0F4.y = arg2; actor->unk_0F4.x = -30.0f; + actor->aiType = i + AI360_10; actor->unk_0B6 = D_i4_8019F198[i - 10]; - actor->aiIndex = D_i4_8019F1C0[i - 10]; + actor->aiIndex = sEnemySpawnTargets[i - 10]; + actor->health = 24; if (actor->unk_0B6 >= 2) { actor->health = 1000; } + actor->unk_0C9 = 1; + if (D_i4_801A0540 < 9600) { actor->itemDrop = DROP_SILVER_RING_10p; } + actor->timer_0C2 = 30; actor->timer_0C4 = 400; + Object_SetInfo(&actor->info, actor->obj.id); + AUDIO_PLAY_SFX(0x2903305F, actor->sfxSource, 4); - actor->info.action = (ObjectFunc) Katina_80198AA0; - actor->info.draw = (ObjectFunc) Katina_801995B4; + + actor->info.action = (ObjectFunc) Katina_EnemyUpdate; + actor->info.draw = (ObjectFunc) Katina_EnemyDraw; break; } } } -void Katina_801945FC(Boss* boss) { +/** + * Sets the angle for the enemies coming out of the mothership + */ +void Katina_SetOutcomingEnemyAngle(Saucerer* this) { f32 angle; f32 distY; s32 i; for (i = 0, angle = 360.0f; i < 4; i++) { - if (boss->swork[i + 10] > 0) { - distY = boss->obj.rot.y + angle; + if (this->swork[i + BOSS_HATCH_1_HP] > 0) { + distY = this->obj.rot.y + angle; if (distY > 360.0f) { distY -= 360.0f; } - Katina_80194458(boss, &boss->vwork[i + 1], distY); + Katina_BossSpawnEnemies(this, &this->vwork[i + 1], distY); } angle -= 90.0f; } } -void Katina_801946C4(Boss* boss) { +void Katina_BossUpdate(Saucerer* this) { s32 i; - s32 rot_count; - s32 en_count; + s32 rotCount; + s32 enemyCount; s32 pad[2]; f32 angle; f32 scale; @@ -630,110 +833,152 @@ void Katina_801946C4(Boss* boss) { gBossFrameCount++; - en_count = 0; + enemyCount = 0; + for (i = 10, actor = &gActors[i]; i < ARRAY_COUNT(gActors); i++, actor++) { - if (actor->obj.status == OBJ_ACTIVE && actor->unk_0B6 == 0) { - en_count++; + if ((actor->obj.status == OBJ_ACTIVE) && (actor->unk_0B6 == 0)) { + enemyCount++; } } - if (boss->swork[16] != 0) { - boss->swork[16]--; + if (this->swork[BOSS_CORE_TIMER] != 0) { + this->swork[BOSS_CORE_TIMER]--; } - if ((((boss->swork[10] <= 0) && (boss->swork[11] <= 0) && (boss->swork[12] <= 0) && (boss->swork[13] <= 0)) || - (boss->swork[16] == 1)) && - (boss->state < 10)) { - boss->state = 10; - boss->timer_050 = 50; + /** + * Summon core if all hatches are destroyed or after 3 minutes from mothership appearance. + */ + if ((((this->swork[BOSS_HATCH_1_HP] <= 0) && (this->swork[BOSS_HATCH_2_HP] <= 0) && + (this->swork[BOSS_HATCH_3_HP] <= 0) && (this->swork[BOSS_HATCH_4_HP] <= 0)) || + (this->swork[BOSS_CORE_TIMER] == 1)) && + (this->state < 10)) { + this->state = 10; + this->timer_050 = 50; } - if (boss->timer_054 == 1) { + if (this->timer_054 == 1) { Radio_PlayMessage(gMsg_ID_18040, RCID_BILL); } - switch (boss->state) { + switch (this->state) { case 0: + /** + * Send Mothership whether you killed 10 enemies or after 2 minutes of gameplay + */ if (((gHitCount >= 10) || (gAllRangeEventTimer > 3840))) { if ((D_edisplay_801615D0.y < 0.0f)) { - boss->state = 1; - boss->vwork[0].y = 2000.0f; - boss->unk_05E = 1; - AUDIO_PLAY_SFX(0x11000011, boss->sfxSource, 0); + this->state = 1; + + this->vwork[0].y = 2000.0f; + + this->unk_05E = 1; + + AUDIO_PLAY_SFX(0x11000011, this->sfxSource, 0); + D_i4_801A0548 = 100.0f; D_i4_801A0544 = 100.0f; D_i4_801A0550 = 70.0f; D_i4_801A054C = 70.0f; D_i4_801A0558 = 50.0f; D_i4_801A0554 = 50.0f; - boss->fwork[12] = 0.4f; - boss->fwork[10] = 10.0f; + + this->fwork[BOSS_Y_ROT_SPEED_TARGET] = 0.4f; + this->fwork[BOSS_MOVEMENT_SPEED] = 10.0f; + Radio_PlayMessage(gMsg_ID_18030, RCID_BILL); - AUDIO_PLAY_SFX(0x11037025, boss->sfxSource, 0); + + AUDIO_PLAY_SFX(0x11037025, this->sfxSource, 0); } } break; + /** + * Wait for mothership to aproach the base to start cutscene. + */ case 1: if ((gPlayer[0].state_1C8 == PLAYERSTATE_1C8_ACTIVE) || (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_U_TURN)) { - if (boss->obj.pos.z < 4500.0f) { - boss->state++; + if (this->obj.pos.z < 4500.0f) { + this->state++; + gPlayer[0].state_1C8 = PLAYERSTATE_1C8_STANDBY; + gPlayer[0].cam.eye.x = -900.0f; gPlayer[0].cam.eye.y = 100.0f; gPlayer[0].cam.eye.z = 1400.0f; + gPlayer[0].cam.at.x = -730.0f; gPlayer[0].cam.at.y = 130.0f; gPlayer[0].cam.at.z = 1160.0f; + gPlayer[0].camRoll = 0.0f; - boss->obj.pos.x = -4500.0f; - boss->obj.pos.z = 4500.0f; - boss->timer_050 = 500; - boss->fwork[10] = 60.0f; + + this->obj.pos.x = -4500.0f; + this->obj.pos.z = 4500.0f; + + this->timer_050 = 500; + this->fwork[BOSS_MOVEMENT_SPEED] = 60.0f; + + // Checkpoint reached gAllRangeCheckpoint = 1; gSavedHitCount = gHitCount; for (i = TEAM_ID_FALCO; i <= TEAM_ID_PEPPY; i++) { gSavedTeamShields[i] = gTeamShields[i]; } + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM, 10); SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 10); } } break; + /** + * Cutscene: Close up + */ case 2: gPlayer[0].cam.at.y += 0.2f; + Math_SmoothStepToF(&D_ctx_801779A8[gMainController], 30.0f, 1.0f, 1.65f, 0.0f); - if (boss->timer_050 == 460) { + + if (this->timer_050 == 460) { D_i4_801A0548 = 10.0f; D_i4_801A0550 = 7.0f; D_i4_801A0558 = 5.0f; } + Math_SmoothStepToF(&D_i4_801A0544, D_i4_801A0548, 1.0f, 4.0f, 0); Math_SmoothStepToF(&D_i4_801A054C, D_i4_801A0550, 1.0f, 2.8f, 0); Math_SmoothStepToF(&D_i4_801A0554, D_i4_801A0558, 1.0f, 2.0f, 0); + gLight1R = D_i4_801A0544; gLight1G = D_i4_801A054C; gLight1B = D_i4_801A0554; - if (boss->timer_050 == 170) { - boss->state++; + + if (this->timer_050 == 170) { + this->state++; + gPlayer[0].cam.eye.x = -2500.0f; gPlayer[0].cam.eye.y = 250.0f; gPlayer[0].cam.eye.z = 2500.0f; gPlayer[0].cam.at.x = 0.0f; gPlayer[0].cam.at.y = 1000.0f; gPlayer[0].cam.at.z = 0.0f; - boss->unk_05E = 0; - boss->obj.pos.x = -500.0f; - boss->obj.pos.z = 500.0f; + + this->unk_05E = 0; + + this->obj.pos.x = -500.0f; + this->obj.pos.z = 500.0f; + gLight1R = 50; gLight1G = 35; gLight1B = 25; + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM, 50); SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 50); - boss->timer_050 = 80; - boss->fwork[12] = 0.0f; - boss->obj.rot.y = 217.0f; + + this->timer_050 = 80; + this->fwork[BOSS_Y_ROT_SPEED_TARGET] = 0.0f; + this->obj.rot.y = 217.0f; + for (i = 10; i < ARRAY_COUNT(gActors); i++) { if (gActors[i].unk_0B6 == 0) { Object_Kill(&gActors[i].obj, gActors[i].sfxSource); @@ -742,315 +987,409 @@ void Katina_801946C4(Boss* boss) { } break; + /** + * Cutscene: Open hatches. + */ case 3: - if (boss->timer_050 == 0) { - boss->state++; - boss->timer_050 = 60; - AUDIO_PLAY_SFX(0x1903203F, boss->sfxSource, 0); - boss->fwork[5] = 30.0f; - boss->fwork[6] = 30.0f; - boss->fwork[7] = 30.0f; - boss->fwork[8] = 30.0f; + if (this->timer_050 == 0) { + this->state++; + this->timer_050 = 60; + AUDIO_PLAY_SFX(0x1903203F, this->sfxSource, 0); + this->fwork[BOSS_HATCH_1_ANGLE_TARGET] = 30.0f; + this->fwork[BOSS_HATCH_2_ANGLE_TARGET] = 30.0f; + this->fwork[BOSS_HATCH_3_ANGLE_TARGET] = 30.0f; + this->fwork[BOSS_HATCH_4_ANGLE_TARGET] = 30.0f; } break; + /** + * Cutscene: Hatches opened completely. + */ case 4: - if (boss->timer_050 == 0) { - boss->state++; - boss->timer_050 = 100; - boss->timer_052 = 310; - AUDIO_PLAY_SFX(0x19034042, boss->sfxSource, 0); + if (this->timer_050 == 0) { + this->state++; + this->timer_050 = 100; + this->timer_052 = 310; + AUDIO_PLAY_SFX(0x19034042, this->sfxSource, 0); } break; + /** + * Cutscene: Boss music starts, enemies coming out of the mothership. + * Return control to the player after cutscene ends and close the hatches. + */ case 5: - if (boss->timer_050 == 1) { + if (this->timer_050 == 1) { AUDIO_PLAY_BGM(SEQ_ID_KA_BOSS | SEQ_FLAG); } - if ((boss->timer_050 == 0) && ((boss->timer_052 % 16) == 0)) { - Katina_801945FC(boss); + if ((this->timer_050 == 0) && ((this->timer_052 % 16) == 0)) { + Katina_SetOutcomingEnemyAngle(this); } - if (boss->timer_052 == 0) { - AUDIO_PLAY_SFX(0x19032040, boss->sfxSource, 0); - boss->state++; + if (this->timer_052 == 0) { + AUDIO_PLAY_SFX(0x19032040, this->sfxSource, 0); + + this->state++; + if (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_STANDBY) { gPlayer[0].state_1C8 = PLAYERSTATE_1C8_ACTIVE; func_play_800B7184(&gPlayer[0], 1); } + gPlayer[0].unk_014 = 0.0f; - boss->fwork[5] = 0.0f; - boss->fwork[6] = 0.0f; - boss->fwork[7] = 0.0f; - boss->fwork[8] = 0.0f; - boss->fwork[12] = 0.4f; - boss->fwork[10] = 0.0f; + + // Close hatches. + this->fwork[BOSS_HATCH_1_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_2_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_3_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_4_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_Y_ROT_SPEED_TARGET] = 0.4f; + this->fwork[BOSS_MOVEMENT_SPEED] = 0.0f; + Radio_PlayMessage(gMsg_ID_18035, RCID_FALCO); - boss->timer_052 = 70; - boss->timer_054 = 200; - boss->timer_056 = 1280; - boss->swork[16] = 5760; + + this->timer_052 = 70; + this->timer_054 = 200; + this->timer_056 = 1280; + + this->swork[BOSS_CORE_TIMER] = 5760; + gBossFrameCount = 0; + D_i4_801A0540 = 0; } break; + /** + * Open hatches for 10 seconds when there's less than 30 enemies + * or after 40 seconds have passed + */ case 6: - if (boss->timer_052 == 1) { - AUDIO_PLAY_SFX(0x19034042, boss->sfxSource, 0); + if (this->timer_052 == 1) { + AUDIO_PLAY_SFX(0x19034042, this->sfxSource, 0); } - if (boss->timer_050 == 0) { - boss->timer_050 = RAND_INT(100.0f) + 100; - boss->vwork[0].x = RAND_FLOAT_CENTERED(10000.0f); - boss->vwork[0].z = RAND_FLOAT_CENTERED(10000.0f); + if (this->timer_050 == 0) { + this->timer_050 = RAND_INT(100.0f) + 100; + this->vwork[0].x = RAND_FLOAT_CENTERED(10000.0f); + this->vwork[0].z = RAND_FLOAT_CENTERED(10000.0f); } - Math_SmoothStepToF(&boss->fwork[10], 30.0f, 0.1f, 0.5f, 0.0f); - if ((en_count < 30) || (boss->timer_056 == 0)) { - boss->state = 7; - boss->timer_050 = 300; - AUDIO_PLAY_SFX(0x1903203F, boss->sfxSource, 0); - boss->fwork[12] = 0.0f; - boss->fwork[8] = 30.0f; - boss->fwork[7] = 30.0f; - boss->fwork[6] = 30.0f; - boss->fwork[5] = 30.0f; + + Math_SmoothStepToF(&this->fwork[BOSS_MOVEMENT_SPEED], 30.0f, 0.1f, 0.5f, 0.0f); + + if ((enemyCount < 30) || (this->timer_056 == 0)) { + this->state = 7; + this->timer_050 = 300; + + AUDIO_PLAY_SFX(0x1903203F, this->sfxSource, 0); + + this->fwork[BOSS_Y_ROT_SPEED_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_4_ANGLE_TARGET] = 30.0f; + this->fwork[BOSS_HATCH_3_ANGLE_TARGET] = 30.0f; + this->fwork[BOSS_HATCH_2_ANGLE_TARGET] = 30.0f; + this->fwork[BOSS_HATCH_1_ANGLE_TARGET] = 30.0f; + Radio_PlayMessage(gMsg_ID_18045, RCID_BILL); } break; + /** + * Send out more enemies. + * Close hatches after 10 seconds. + */ case 7: - Math_SmoothStepToF(&boss->fwork[10], 0.0f, 0.1f, 0.5f, 0.0f); - if ((boss->timer_050 < 200) && ((boss->timer_050 % 16) == 0)) { - Katina_801945FC(boss); + Math_SmoothStepToF(&this->fwork[10], 0.0f, 0.1f, 0.5f, 0.0f); + + if ((this->timer_050 < 200) && ((this->timer_050 % 16) == 0)) { + Katina_SetOutcomingEnemyAngle(this); } - if (boss->timer_050 == 240) { - AUDIO_PLAY_SFX(0x19034042, boss->sfxSource, 0); + if (this->timer_050 == 240) { + AUDIO_PLAY_SFX(0x19034042, this->sfxSource, 0); } - if (boss->timer_050 == 0) { - boss->state = 6; - boss->fwork[8] = 0.0f; - boss->fwork[7] = 0.0f; - boss->fwork[6] = 0.0f; - boss->fwork[5] = 0.0f; - boss->timer_056 = 1920; - boss->timer_052 = 70; - AUDIO_PLAY_SFX(0x19032040, boss->sfxSource, 0); + if (this->timer_050 == 0) { + this->state = 6; + this->fwork[BOSS_HATCH_4_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_3_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_2_ANGLE_TARGET] = 0.0f; + this->fwork[BOSS_HATCH_1_ANGLE_TARGET] = 0.0f; + this->timer_056 = 1920; + this->timer_052 = 70; + AUDIO_PLAY_SFX(0x19032040, this->sfxSource, 0); } break; + /** + * Start countdown and lower down core. + */ case 10: - if (boss->timer_050 == 0) { - boss->fwork[9] = 200.0f; - AUDIO_PLAY_SFX(0x19032041, boss->sfxSource, 0); - Audio_KillSfxBySourceAndId(boss->sfxSource, 0x11037025); - boss->state = 11; - boss->timer_050 = 100; + if (this->timer_050 == 0) { + this->fwork[BOSS_CORE_TARGET_LEVEL] = 200.0f; + AUDIO_PLAY_SFX(0x19032041, this->sfxSource, 0); + Audio_KillSfxBySourceAndId(this->sfxSource, 0x11037025); + this->state = 11; + this->timer_050 = 100; Radio_PlayMessage(gMsg_ID_18050, RCID_BILL); gAllRangeCountdownScale = 1.0f; - gShowAllRangeCountdown = 1; + gShowAllRangeCountdown = true; gAllRangeCountdown[0] = 1; gAllRangeCountdown[1] = 1; gAllRangeCountdown[2] = 30; } break; + /** + * Set a 1 minute timer for mothership attack. + */ case 11: - if (boss->timer_050 == 0) { - AUDIO_PLAY_SFX(0x19034042, boss->sfxSource, 0); - boss->state = 12; - boss->timer_050 = 1928; + if (this->timer_050 == 0) { + AUDIO_PLAY_SFX(0x19034042, this->sfxSource, 0); + this->state = 12; + this->timer_050 = 1928; Radio_PlayMessage(gMsg_ID_18055, RCID_BILL); - AUDIO_PLAY_SFX(0x11034043, boss->sfxSource, 0); + AUDIO_PLAY_SFX(0x11034043, this->sfxSource, 0); } break; + /** + * Start mothership attack after 13 seconds from Bill's warning + * Start cutscene for base destruction. + */ case 12: - if (boss->timer_050 == 400) { + if (this->timer_050 == 400) { Radio_PlayMessage(gMsg_ID_18065, RCID_BILL); } - boss->vwork[0].x = 0.0f; - boss->vwork[0].z = 0.0f; - Math_SmoothStepToF(&boss->fwork[10], 5.0f, 0.1f, 0.5f, 0.0f); - if (boss->timer_050 == 0 && - (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_ACTIVE || gPlayer[0].state_1C8 == PLAYERSTATE_1C8_U_TURN)) { - gShowAllRangeCountdown = 0; - boss->timer_050 = 1000; - boss->state = 15; - boss->obj.rot.y = 0.0f; - boss->obj.pos.y = 3500.0f; - boss->obj.pos.x = 0.0f; - boss->obj.pos.z = 0.0f; + this->vwork[0].x = 0.0f; + this->vwork[0].z = 0.0f; + + Math_SmoothStepToF(&this->fwork[BOSS_MOVEMENT_SPEED], 5.0f, 0.1f, 0.5f, 0.0f); + + if ((this->timer_050 == 0) && ((gPlayer[0].state_1C8 == PLAYERSTATE_1C8_ACTIVE) || + (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_U_TURN))) { + gShowAllRangeCountdown = false; + this->timer_050 = 1000; + this->state = 15; + this->obj.rot.y = 0.0f; + + this->obj.pos.y = 3500.0f; + this->obj.pos.x = 0.0f; + this->obj.pos.z = 0.0f; + + this->fwork[BOSS_Y_ROT_SPEED_TARGET] = 0.0f; + this->fwork[BOSS_MOVEMENT_SPEED] = 0.0f; - boss->fwork[12] = 0.0f; - boss->fwork[10] = 0.0f; SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM, 50); SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 50); + gPlayer[0].state_1C8 = PLAYERSTATE_1C8_STANDBY; + gPlayer[0].camRoll = 0.0f; - gPlayer[0].cam.eye.x = boss->obj.pos.x; + + gPlayer[0].cam.eye.x = this->obj.pos.x; gPlayer[0].cam.eye.y = 600.0f; - gPlayer[0].cam.eye.z = boss->obj.pos.z + 5000.0f; - gPlayer[0].cam.at.x = boss->obj.pos.x; - gPlayer[0].cam.at.y = boss->obj.pos.y - 500.0f; - gPlayer[0].cam.at.z = boss->obj.pos.z; + gPlayer[0].cam.eye.z = this->obj.pos.z + 5000.0f; + + gPlayer[0].cam.at.x = this->obj.pos.x; + gPlayer[0].cam.at.y = this->obj.pos.y - 500.0f; + gPlayer[0].cam.at.z = this->obj.pos.z; } break; + /** + * Rotate mothership into fire position. + */ case 15: - if (boss->timer_050 == 700) { + if (this->timer_050 == 700) { Radio_PlayMessage(gMsg_ID_18070, RCID_BILL); } - if (boss->timer_050 == 580) { + if (this->timer_050 == 580) { Radio_PlayMessage(gMsg_ID_18075, RCID_FOX); } - if (boss->timer_050 == 500) { + if (this->timer_050 == 500) { gPlayer[0].state_1C8 = PLAYERSTATE_1C8_LEVEL_COMPLETE; gPlayer[0].csState = 100; gPlayer[0].unk_234 = 0; gCsFrameCount = 5000; } - Math_SmoothStepToF(&boss->obj.pos.y, 3000.0f, 0.02f, 0.5f, 0.0f); - Math_SmoothStepToF(&boss->obj.rot.x, 180.0f, 0.02f, 0.3f, 0.0f); - Math_SmoothStepToF(&boss->fwork[13], 180.0f, 0.02f, 0.2f, 0.0f); - Math_SmoothStepToF(&gPlayer[0].cam.eye.z, boss->obj.pos.z + 8000.0f, 0.05f, 3.0f, 0.0f); - Math_SmoothStepToF(&gPlayer[0].cam.eye.y, boss->obj.pos.y - 1000.0f, 0.05f, 2.0f, 0.0f); - gPlayer[0].cam.at.y = boss->obj.pos.y - 500.0f; - boss->unk_05E = 0; - if (boss->timer_050 == 260) { - boss->obj.pos.y = 3000.0f; - boss->obj.rot.y = 0.0f; - boss->obj.rot.x = 180.0f; - boss->fwork[13] = 15.0f; + + Math_SmoothStepToF(&this->obj.pos.y, 3000.0f, 0.02f, 0.5f, 0.0f); + Math_SmoothStepToF(&this->obj.rot.x, 180.0f, 0.02f, 0.3f, 0.0f); + Math_SmoothStepToF(&this->fwork[BOSS_FWORK_13], 180.0f, 0.02f, 0.2f, 0.0f); + Math_SmoothStepToF(&gPlayer[0].cam.eye.z, this->obj.pos.z + 8000.0f, 0.05f, 3.0f, 0.0f); + Math_SmoothStepToF(&gPlayer[0].cam.eye.y, this->obj.pos.y - 1000.0f, 0.05f, 2.0f, 0.0f); + + gPlayer[0].cam.at.y = this->obj.pos.y - 500.0f; + + this->unk_05E = 0; + + if (this->timer_050 == 260) { + this->obj.pos.y = 3000.0f; + this->obj.rot.y = 0.0f; + this->obj.rot.x = 180.0f; + this->fwork[BOSS_FWORK_13] = 15.0f; + gPlayer[0].state_1C8 = PLAYERSTATE_1C8_STANDBY; - gPlayer[0].cam.eye.x = boss->obj.pos.x; + gPlayer[0].cam.eye.x = this->obj.pos.x; gPlayer[0].cam.eye.y = 600.0f; - gPlayer[0].cam.eye.z = boss->obj.pos.z - 1500.0f; - gPlayer[0].cam.at.x = boss->obj.pos.x; - gPlayer[0].cam.at.y = boss->obj.pos.y - 300.0f; - gPlayer[0].cam.at.z = boss->obj.pos.z; - boss->state = 16; - boss->timer_050 = 130; - boss->timer_052 = 1000; + gPlayer[0].cam.eye.z = this->obj.pos.z - 1500.0f; + gPlayer[0].cam.at.x = this->obj.pos.x; + gPlayer[0].cam.at.y = this->obj.pos.y - 300.0f; + gPlayer[0].cam.at.z = this->obj.pos.z; + + this->state = 16; + this->timer_050 = 130; + this->timer_052 = 1000; + D_i4_801A0548 = 100.0f; D_i4_801A0544 = 100.0f; D_i4_801A0550 = 70.0f; D_i4_801A054C = 70.0f; D_i4_801A0558 = 50.0f; D_i4_801A0554 = 50.0f; - Audio_KillSfxBySourceAndId(boss->sfxSource, 0x11034043); - AUDIO_PLAY_SFX(0x19406044, boss->sfxSource, 0); + + Audio_KillSfxBySourceAndId(this->sfxSource, 0x11034043); + AUDIO_PLAY_SFX(0x19406044, this->sfxSource, 0); } break; + /** + * Cutscene: Close up, start mothership attack. + */ case 16: Math_SmoothStepToF(&D_ctx_801779A8[gMainController], 30.0f, 1.0f, 1.6f, 0.0f); Math_SmoothStepToF(&gPlayer[0].cam.eye.z, 0.0f, 0.05f, 5.0f, 0.0f); - boss->fwork[13] += 0.1f; + this->fwork[BOSS_FWORK_13] += 0.1f; Math_SmoothStepToF(&gEnvLightyRot, 200.0f, 1.0f, 0.5f, 0.0f); + scale = 0.5f; + D_i4_801A0548 = 0.0f; D_i4_801A0550 = 100.0f; - rot_count = 0; D_i4_801A0558 = 255.0f; - if (boss->timer_050 == 0) { - rot_count = 4; - Math_SmoothStepToF(&boss->fwork[14], 10.0f, 0.02f, 0.05f, 0.0f); - } else if (boss->timer_050 < 40) { - rot_count = 2; - Math_SmoothStepToF(&boss->fwork[14], 10.0f, 0.02f, 0.05f, 0.0f); - } else if (boss->timer_050 < 80) { + + rotCount = 0; + + if (this->timer_050 == 0) { + rotCount = 4; + Math_SmoothStepToF(&this->fwork[BOSS_LASER_LIGHT_SCALE], 10.0f, 0.02f, 0.05f, 0.0f); + } else if (this->timer_050 < 40) { + rotCount = 2; + Math_SmoothStepToF(&this->fwork[BOSS_LASER_LIGHT_SCALE], 10.0f, 0.02f, 0.05f, 0.0f); + } else if (this->timer_050 < 80) { D_i4_801A0550 = 0.0f; - rot_count = 1; + rotCount = 1; scale = 3.0f; } + Math_SmoothStepToF(&D_i4_801A0544, D_i4_801A0548, 1.0f, scale, 0); Math_SmoothStepToF(&D_i4_801A054C, D_i4_801A0550, 1.0f, scale, 0); Math_SmoothStepToF(&D_i4_801A0554, D_i4_801A0558, 1.0f, scale, 0); - i = 0; + gLight1R = D_i4_801A0544; gLight1G = D_i4_801A054C; gLight1B = D_i4_801A0554; - for (i = 0; i < rot_count; i++) { + for (i = 0; i < rotCount; i++) { Matrix_RotateY(gCalcMatrix, RAND_FLOAT(2.0f) * M_PI, MTXF_NEW); src.x = 0.0f; src.y = 0.0f; src.z = RAND_FLOAT(400.0f) + 300.0f; Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); - Katina_80192908(boss->obj.pos.x + dest.x, boss->obj.pos.y - 500.0f, boss->obj.pos.z + dest.z, - boss->obj.pos.x, boss->obj.pos.y - 500.0f, boss->obj.pos.z); + Katina_LaserEnergyParticlesSpawn(this->obj.pos.x + dest.x, this->obj.pos.y - 500.0f, + this->obj.pos.z + dest.z, this->obj.pos.x, this->obj.pos.y - 500.0f, + this->obj.pos.z); } - if ((boss->timer_052 == 700) || (boss->timer_052 == 697)) { + if ((this->timer_052 == 700) || (this->timer_052 == 697)) { i = gGameFrameCount % 64U; Object_Kill(&gEffects[i].obj, gEffects[i].sfxSource); - func_effect_8007B344(boss->obj.pos.x, boss->obj.pos.y - 600.0f, boss->obj.pos.z, 90.0f, 0); - AUDIO_PLAY_SFX(0x1140B045, boss->sfxSource, 0); + func_effect_8007B344(this->obj.pos.x, this->obj.pos.y - 600.0f, this->obj.pos.z, 90.0f, 0); + AUDIO_PLAY_SFX(0x1140B045, this->sfxSource, 0); } - if (boss->timer_052 == 690) { - boss->state = 17; + if (this->timer_052 == 690) { + this->state = 17; + for (i = 0; i < ARRAY_COUNT(gEffects); i++) { if (gEffects[i].obj.id == OBJ_EFFECT_358) { Object_Kill(&gEffects[i].obj, gEffects[i].sfxSource); } } - gPlayer[0].cam.eye.x = boss->obj.pos.x; + + gPlayer[0].cam.eye.x = this->obj.pos.x; gPlayer[0].cam.eye.y = 300.0f; - gPlayer[0].cam.eye.z = boss->obj.pos.z + 2000.0f; - gPlayer[0].cam.at.x = boss->obj.pos.x; + gPlayer[0].cam.eye.z = this->obj.pos.z + 2000.0f; + + gPlayer[0].cam.at.x = this->obj.pos.x; gPlayer[0].cam.at.y = 1500.0f; - gPlayer[0].cam.at.z = boss->obj.pos.z; + gPlayer[0].cam.at.z = this->obj.pos.z; + gEnvLightyRot = 60.0f; + gLight1R = 100; gLight1G = 70; gLight1B = 50; - boss->timer_050 = 10; - boss->fwork[14] = 20.0f; + + this->timer_050 = 10; + this->fwork[BOSS_LASER_LIGHT_SCALE] = 20.0f; } break; + /** + * Cutscene: Mothership fires laser to the base. + */ case 17: - boss->fwork[13] += 0.1f; + this->fwork[BOSS_FWORK_13] += 0.1f; + Math_SmoothStepToF(&gPlayer[0].cam.at.y, 525.0f, 0.3f, 50.0f, 0.0f); - Math_SmoothStepToF(&boss->fwork[15], 8.0f, 1.0f, 2.0f, 0.0f); - if (boss->timer_050 == 1) { - gBosses[0].state = 1; - boss->state = 18; - boss->timer_050 = 50; - AUDIO_PLAY_SFX(0x11038046, boss->sfxSource, 0); + Math_SmoothStepToF(&this->fwork[BOSS_LASER_LENGTH], 8.0f, 1.0f, 2.0f, 0.0f); + + if (this->timer_050 == 1) { + gBosses[KA_BOSS_BASE].state = 1; + this->state = 18; + this->timer_050 = 50; + AUDIO_PLAY_SFX(0x11038046, this->sfxSource, 0); } break; + /** + * Cutscene: Base is hit by mothership's laser. + */ case 18: Math_SmoothStepToF(&D_ctx_801779A8[gMainController], 100.0f, 1.0f, 100.0f, 0.0f); Math_SmoothStepToF(&gPlayer[0].cam.at.y, 525.0f, 0.3f, 50.0f, 0.0f); - if (boss->timer_050 == 0) { + + if (this->timer_050 == 0) { gFillScreenAlphaTarget = 255; gFillScreenRed = 255; gFillScreenGreen = 255; gFillScreenBlue = 255; + if (gFillScreenAlpha == 255) { gPlayer[0].state_1C8 = PLAYERSTATE_1C8_LEVEL_COMPLETE; gPlayer[0].csState = 2; gPlayer[0].unk_234 = 1; + gCsFrameCount = 200; + Audio_StopPlayerNoise(0); Audio_KillSfxBySource(&gPlayer[0].sfxSource[0]); + gPlayer[0].csTimer = 50; gPlayer[0].baseSpeed = 0.0f; gPlayer[0].yRot_114 = 0.0f; gPlayer[0].rot.z = gPlayer[0].rot.y = gPlayer[0].rot.x = gPlayer[0].xRot_120 = gPlayer[0].yRot_114; + Play_ClearObjectData(); + gEnvLightyRot = 60.0f; + gLight1R = 100; gLight1G = 70; gLight1B = 50; @@ -1058,208 +1397,237 @@ void Katina_801946C4(Boss* boss) { } break; + /** + * Mothership core destroyed, setup for MISSION_ACCOMPLISHED. + */ case 20: - gShowAllRangeCountdown = 0; - Math_SmoothStepToF(&boss->fwork[10], 0.0f, 0.1f, 3.0f, 0.0f); - if ((boss->timer_050 == 0) && ((gPlayer[0].state_1C8 == PLAYERSTATE_1C8_ACTIVE) || + gShowAllRangeCountdown = false; + + Math_SmoothStepToF(&this->fwork[BOSS_MOVEMENT_SPEED], 0.0f, 0.1f, 3.0f, 0.0f); + + if ((this->timer_050 == 0) && ((gPlayer[0].state_1C8 == PLAYERSTATE_1C8_ACTIVE) || (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_U_TURN))) { gPlayer[0].state_1C8 = PLAYERSTATE_1C8_LEVEL_COMPLETE; gPlayer[0].csState = 0; gMissionStatus = MISSION_ACCOMPLISHED; - boss->obj.pos.z = 0.0f; - boss->health = -1; - boss->fwork[10] = 0.0f; - boss->state++; - boss->timer_050 = 1000; - boss->obj.rot.y = 30.0f; - boss->obj.pos.x = -4000.0f; - boss->unk_078.z = 7.0f; - AUDIO_PLAY_SFX(0x11404016, boss->sfxSource, 0); + this->obj.pos.z = 0.0f; + this->health = -1; + this->fwork[BOSS_MOVEMENT_SPEED] = 0.0f; + this->state++; + this->timer_050 = 1000; + this->obj.rot.y = 30.0f; + this->obj.pos.x = -4000.0f; + this->unk_078.z = 7.0f; + + AUDIO_PLAY_SFX(0x11404016, this->sfxSource, 0); + for (i = 0; i < ARRAY_COUNT(gEffects); i++) { Object_Kill(&gEffects[i].obj, gEffects[i].sfxSource); } } break; + /** + * Cutscene: Mothership falling to the ground. + */ case 21: - Matrix_RotateY(gCalcMatrix, boss->obj.rot.y * M_DTOR, MTXF_NEW); - Matrix_RotateX(gCalcMatrix, boss->obj.rot.x * M_DTOR, MTXF_APPLY); - boss->obj.pos.z += boss->unk_078.z; - if (boss->timer_050 == 820) { - AUDIO_PLAY_SFX(0x19408047, boss->sfxSource, 0); + Matrix_RotateY(gCalcMatrix, this->obj.rot.y * M_DTOR, MTXF_NEW); + Matrix_RotateX(gCalcMatrix, this->obj.rot.x * M_DTOR, MTXF_APPLY); + + this->obj.pos.z += this->unk_078.z; + + if (this->timer_050 == 820) { + AUDIO_PLAY_SFX(0x19408047, this->sfxSource, 0); } - if (boss->timer_050 > 820) { - boss->obj.rot.x += 0.075f; - boss->gravity = 0.1f; - if (boss->vel.y < -10.0f) { - boss->vel.y = -10.0f; + if (this->timer_050 > 820) { + this->obj.rot.x += 0.075f; + this->gravity = 0.1f; + if (this->vel.y < -10.0f) { + this->vel.y = -10.0f; } src.x = RAND_FLOAT_CENTERED(3000.0f); src.y = -800.0f; src.z = RAND_FLOAT_CENTERED(3000.0f); Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); - func_effect_800794CC(boss->obj.pos.x + dest.x, boss->obj.pos.y + dest.y, boss->obj.pos.z + dest.z, + func_effect_800794CC(this->obj.pos.x + dest.x, this->obj.pos.y + dest.y, this->obj.pos.z + dest.z, 1.55f); } else { - boss->obj.rot.x -= 0.06f; - boss->vel.y = 0.0f; - boss->gravity = 0.0f; - Math_SmoothStepToF(&boss->unk_078.z, 0.0f, 1.0f, 1.0f, 0.0f); - Katina_80192C08( - boss->obj.pos.x + 2000.0f + RAND_FLOAT(500.0f), (boss->obj.pos.y - 500.0f) + RAND_FLOAT(500.0f), - boss->obj.pos.z + 600.0f + RAND_FLOAT(1000.0f), 0.0f, 20.0f, 0.0f, RAND_FLOAT(20.0f) + 15.0f); + this->obj.rot.x -= 0.06f; + this->vel.y = 0.0f; + this->gravity = 0.0f; + Math_SmoothStepToF(&this->unk_078.z, 0.0f, 1.0f, 1.0f, 0.0f); + Katina_FireSmokeEffectSpawn( + this->obj.pos.x + 2000.0f + RAND_FLOAT(500.0f), (this->obj.pos.y - 500.0f) + RAND_FLOAT(500.0f), + this->obj.pos.z + 600.0f + RAND_FLOAT(1000.0f), 0.0f, 20.0f, 0.0f, RAND_FLOAT(20.0f) + 15.0f); } - if (((gGameFrameCount % 2) != 0) || (boss->timer_050 > 850)) { + if (((gGameFrameCount % 2) != 0) || (this->timer_050 > 850)) { src.x = RAND_FLOAT_CENTERED(4000.0f); src.y = RAND_FLOAT_CENTERED(600.0f) + -300.0f; src.z = RAND_FLOAT_CENTERED(4000.0f); Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); - Katina_80192C08(boss->obj.pos.x + dest.x, boss->obj.pos.y + dest.y, boss->obj.pos.z + dest.z, 0.0f, - 5.0f, 0.0f, RAND_FLOAT(15.0f) + 10.0f); + Katina_FireSmokeEffectSpawn(this->obj.pos.x + dest.x, this->obj.pos.y + dest.y, + this->obj.pos.z + dest.z, 0.0f, 5.0f, 0.0f, RAND_FLOAT(15.0f) + 10.0f); } break; } - if (boss->state != 0) { + + if (this->state != 0) { angle = 360.0f; + for (i = 0; i < 4; i++) { - Matrix_RotateY(gCalcMatrix, (boss->obj.rot.y + angle) * M_DTOR, MTXF_NEW); + Matrix_RotateY(gCalcMatrix, (this->obj.rot.y + angle) * M_DTOR, MTXF_NEW); src.x = 0.0f; src.y = -550.0f; src.z = 850.0f; - Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &boss->vwork[1 + i]); + Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &this->vwork[1 + i]); angle -= 90.0f; } - Math_SmoothStepToF(&boss->fwork[11], boss->fwork[12], 0.1f, 0.01f, 0.0f); - boss->obj.rot.y += boss->fwork[11]; + Math_SmoothStepToF(&this->fwork[BOSS_Y_ROT_SPEED], this->fwork[BOSS_Y_ROT_SPEED_TARGET], 0.1f, 0.01f, 0.0f); + this->obj.rot.y += this->fwork[BOSS_Y_ROT_SPEED]; - if (boss->obj.rot.y > 360.0f) { - boss->obj.rot.y -= 360.0f; + if (this->obj.rot.y > 360.0f) { + this->obj.rot.y -= 360.0f; } - if (boss->obj.rot.y < 0.0f) { - boss->obj.rot.y += 360.0f; + if (this->obj.rot.y < 0.0f) { + this->obj.rot.y += 360.0f; } + gRadarMarks[64].status = 1; gRadarMarks[64].type = 101; - gRadarMarks[64].pos.x = boss->obj.pos.x; - gRadarMarks[64].pos.y = boss->obj.pos.y; - gRadarMarks[64].pos.z = boss->obj.pos.z; - gRadarMarks[64].yRot = boss->unk_078.y + 180.0f; - if (boss->state < 6) { - Math_SmoothStepToF(&boss->obj.pos.x, boss->vwork[0].x, 0.01f, boss->fwork[10], 0); - Math_SmoothStepToF(&boss->obj.pos.y, boss->vwork[0].y, 0.01f, boss->fwork[10], 0); - Math_SmoothStepToF(&boss->obj.pos.z, boss->vwork[0].z, 0.01f, boss->fwork[10], 0); + gRadarMarks[64].pos.x = this->obj.pos.x; + gRadarMarks[64].pos.y = this->obj.pos.y; + gRadarMarks[64].pos.z = this->obj.pos.z; + gRadarMarks[64].yRot = this->unk_078.y + 180.0f; + + if (this->state < 6) { + Math_SmoothStepToF(&this->obj.pos.x, this->vwork[0].x, 0.01f, this->fwork[BOSS_MOVEMENT_SPEED], 0); + Math_SmoothStepToF(&this->obj.pos.y, this->vwork[0].y, 0.01f, this->fwork[BOSS_MOVEMENT_SPEED], 0); + Math_SmoothStepToF(&this->obj.pos.z, this->vwork[0].z, 0.01f, this->fwork[BOSS_MOVEMENT_SPEED], 0); } else { Math_SmoothStepToAngle( - &boss->unk_078.y, - Math_RadToDeg(Math_Atan2F(boss->vwork[0].x - boss->obj.pos.x, boss->vwork[0].z - boss->obj.pos.z)), + &this->unk_078.y, + Math_RadToDeg(Math_Atan2F(this->vwork[0].x - this->obj.pos.x, this->vwork[0].z - this->obj.pos.z)), 0.5f, 1.5f, 0.0001f); - boss->vel.x = SIN_DEG(boss->unk_078.y) * boss->fwork[10]; - boss->vel.z = COS_DEG(boss->unk_078.y) * boss->fwork[10]; + this->vel.x = SIN_DEG(this->unk_078.y) * this->fwork[BOSS_MOVEMENT_SPEED]; + this->vel.z = COS_DEG(this->unk_078.y) * this->fwork[BOSS_MOVEMENT_SPEED]; } + for (i = 0; i < 10; i++) { - if (boss->swork[i] != 0) { - boss->swork[i]--; + if (this->swork[i] != 0) { + this->swork[i]--; } } - if (boss->swork[10] != 0) { - Math_SmoothStepToF(&boss->fwork[0], boss->fwork[5], 0.03f, 0.5f, 0); + + if (this->swork[BOSS_HATCH_1_HP] != 0) { + Math_SmoothStepToF(&this->fwork[BOSS_HATCH_1_ANGLE], this->fwork[BOSS_HATCH_1_ANGLE_TARGET], 0.03f, 0.5f, + 0); } - if (boss->swork[11] != 0) { - Math_SmoothStepToF(&boss->fwork[1], boss->fwork[6], 0.03f, 0.5f, 0); + if (this->swork[BOSS_HATCH_2_HP] != 0) { + Math_SmoothStepToF(&this->fwork[BOSS_HATCH_2_ANGLE], this->fwork[BOSS_HATCH_2_ANGLE_TARGET], 0.03f, 0.5f, + 0); } - if (boss->swork[12] != 0) { - Math_SmoothStepToF(&boss->fwork[2], boss->fwork[7], 0.03f, 0.5f, 0); + if (this->swork[BOSS_HATCH_3_HP] != 0) { + Math_SmoothStepToF(&this->fwork[BOSS_HATCH_3_ANGLE], this->fwork[BOSS_HATCH_3_ANGLE_TARGET], 0.03f, 0.5f, + 0); } - if (boss->swork[13] != 0) { - Math_SmoothStepToF(&boss->fwork[3], boss->fwork[8], 0.03f, 0.5f, 0); + if (this->swork[BOSS_HATCH_4_HP] != 0) { + Math_SmoothStepToF(&this->fwork[BOSS_HATCH_4_ANGLE], this->fwork[BOSS_HATCH_4_ANGLE_TARGET], 0.03f, 0.5f, + 0); } - if (boss->swork[14] != 0) { - Math_SmoothStepToF(&boss->fwork[4], boss->fwork[9], 0.05f, 5.0f, 0); + if (this->swork[BOSS_CORE_HP] != 0) { + Math_SmoothStepToF(&this->fwork[BOSS_CORE_LEVEL], this->fwork[BOSS_CORE_TARGET_LEVEL], 0.05f, 5.0f, 0); } - boss->info.hitbox[2] = boss->fwork[0]; - boss->info.hitbox[12] = boss->fwork[1]; - boss->info.hitbox[22] = boss->fwork[2]; - boss->info.hitbox[32] = boss->fwork[3]; - boss->info.hitbox[43] = boss->fwork[4] - 200.0f + -750.0f; - boss->info.hitbox[49] = boss->fwork[4] - 200.0f + -850.0f; - boss->info.hitbox[55] = boss->fwork[4] - 200.0f + -950.0f; - boss->info.hitbox[61] = boss->fwork[4] - 200.0f + -1200.0f; - Katina_80193EF0(boss); + + this->info.hitbox[2] = this->fwork[BOSS_HATCH_1_ANGLE]; + this->info.hitbox[12] = this->fwork[BOSS_HATCH_2_ANGLE]; + this->info.hitbox[22] = this->fwork[BOSS_HATCH_3_ANGLE]; + this->info.hitbox[32] = this->fwork[BOSS_HATCH_4_ANGLE]; + this->info.hitbox[43] = this->fwork[BOSS_CORE_LEVEL] - 200.0f + -750.0f; + this->info.hitbox[49] = this->fwork[BOSS_CORE_LEVEL] - 200.0f + -850.0f; + this->info.hitbox[55] = this->fwork[BOSS_CORE_LEVEL] - 200.0f + -950.0f; + this->info.hitbox[61] = this->fwork[BOSS_CORE_LEVEL] - 200.0f + -1200.0f; + + Katina_BossHandleDamage(this); } } -bool Katina_801965A8(s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3f* rot, void* data) { - Boss* boss = (Boss*) data; +bool Katina_BossOverrideLimbDraw(s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3f* rot, void* data) { + Saucerer* boss = (Saucerer*) data; RCP_SetupDL(&gMasterDisp, 29); gDPSetPrimColor(gMasterDisp++, 0, 0, 40, 40, 255, 255); switch (limbIndex) { case 1: - rot->y += boss->fwork[0]; - if ((boss->swork[0] % 2) != 0) { + rot->y += boss->fwork[BOSS_HATCH_1_ANGLE]; + + if ((boss->swork[BOSS_HATCH_1_FLASH_TIMER] % 2) != 0) { RCP_SetupDL(&gMasterDisp, 30); } - if (boss->swork[10] <= 0) { + if (boss->swork[BOSS_HATCH_1_HP] <= 0) { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - *dList = D_KA_60012A0; + *dList = aDestroyedHatch1DL; } break; case 2: - rot->y += boss->fwork[1]; - if ((boss->swork[1] % 2) != 0) { + rot->y += boss->fwork[BOSS_HATCH_2_ANGLE]; + + if ((boss->swork[BOSS_HATCH_2_FLASH_TIMER] % 2) != 0) { RCP_SetupDL(&gMasterDisp, 30); } - if (boss->swork[11] <= 0) { + if (boss->swork[BOSS_HATCH_2_HP] <= 0) { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - *dList = D_KA_600CDC0; + *dList = aDestroyedHatch2DL; } break; case 3: - rot->y += boss->fwork[2]; - if ((boss->swork[2] % 2) != 0) { + rot->y += boss->fwork[BOSS_HATCH_3_ANGLE]; + + if ((boss->swork[BOSS_HATCH_3_FLASH_TIMER] % 2) != 0) { RCP_SetupDL(&gMasterDisp, 30); } - if (boss->swork[12] <= 0) { + if (boss->swork[BOSS_HATCH_3_HP] <= 0) { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - *dList = D_KA_600D4E0; + *dList = aDestroyedHatch3DL; } break; case 4: - rot->y -= boss->fwork[3]; - if ((boss->swork[3] % 2) != 0) { + rot->y -= boss->fwork[BOSS_HATCH_4_ANGLE]; + + if ((boss->swork[BOSS_HATCH_4_FLASH_TIMER] % 2) != 0) { RCP_SetupDL(&gMasterDisp, 30); } - if (boss->swork[13] <= 0) { + if (boss->swork[BOSS_HATCH_4_HP] <= 0) { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - *dList = D_KA_600D290; + *dList = aDestroyedHatch4DL; } break; case 9: - pos->x -= boss->fwork[4]; - if ((boss->swork[4] % 2) != 0) { + pos->x -= boss->fwork[BOSS_CORE_LEVEL]; + + if ((boss->swork[BOSS_CORE_FLASH_TIMER] % 2) != 0) { RCP_SetupDL(&gMasterDisp, 30); } - if (boss->swork[14] <= 0) { + if (boss->swork[BOSS_CORE_HP] <= 0) { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - *dList = D_KA_600D090; + *dList = aDestroyedCoreDL; } break; @@ -1267,44 +1635,49 @@ bool Katina_801965A8(s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3f* rot, void* d if (boss->health < 0) { RCP_SetupDL(&gMasterDisp, 57); gSPClearGeometryMode(gMasterDisp++, G_CULL_BACK); - *dList = D_KA_6007300; + *dList = aDestroyedMothershipDL; } break; } return 0; } -void Katina_801968F4(Boss* boss) { +void Katina_BossDraw(Saucerer* this) { Vec3f jointTable[30]; - if (boss->state != 0) { - if (boss->state < 20) { + if (this->state != 0) { + if (this->state < 20) { gSPFogPosition(gMasterDisp++, gFogNear, 1002); } else { gSPFogPosition(gMasterDisp++, gFogNear, 1006); } - Matrix_RotateY(gGfxMatrix, boss->fwork[13] * M_DTOR, MTXF_APPLY); + Matrix_RotateY(gGfxMatrix, this->fwork[BOSS_FWORK_13] * M_DTOR, MTXF_APPLY); + Animation_GetFrameData(&D_KA_60105D8, 0, jointTable); - Animation_DrawSkeleton(1, D_KA_6010744, jointTable, Katina_801965A8, NULL, boss, &gIdentityMatrix); + Animation_DrawSkeleton(1, D_KA_6010744, jointTable, Katina_BossOverrideLimbDraw, NULL, this, &gIdentityMatrix); gSPFogPosition(gMasterDisp++, gFogNear, gFogFar); - if (boss->fwork[14] > 0.0f) { + + if (this->fwork[BOSS_LASER_LIGHT_SCALE] > 0.0f) { RCP_SetupDL(&gMasterDisp, 67); Matrix_Push(&gGfxMatrix); gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(gMasterDisp++, 0, 255, 255, 255); Matrix_Translate(gGfxMatrix, 0.0f, 500.0f, 0.0f, MTXF_APPLY); - Matrix_Scale(gGfxMatrix, boss->fwork[14], boss->fwork[14], boss->fwork[14], MTXF_APPLY); + Matrix_Scale(gGfxMatrix, this->fwork[BOSS_LASER_LIGHT_SCALE], this->fwork[BOSS_LASER_LIGHT_SCALE], + this->fwork[BOSS_LASER_LIGHT_SCALE], MTXF_APPLY); Matrix_RotateX(gGfxMatrix, -90 * M_DTOR, MTXF_APPLY); Matrix_SetGfxMtx(&gMasterDisp); gSPDisplayList(gMasterDisp++, D_1024AC0); Matrix_Pop(&gGfxMatrix); + Matrix_Push(&gGfxMatrix); gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 255, 64); gDPSetEnvColor(gMasterDisp++, 0, 255, 255, 64); Matrix_Translate(gGfxMatrix, 0.0f, 500.0f, 0.0f, MTXF_APPLY); - Matrix_Scale(gGfxMatrix, boss->fwork[14] * 3.0f, boss->fwork[14] * 3.0f, boss->fwork[14] * 3.0f, + Matrix_Scale(gGfxMatrix, this->fwork[BOSS_LASER_LIGHT_SCALE] * 3.0f, + this->fwork[BOSS_LASER_LIGHT_SCALE] * 3.0f, this->fwork[BOSS_LASER_LIGHT_SCALE] * 3.0f, MTXF_APPLY); Matrix_RotateX(gGfxMatrix, -90 * M_DTOR, MTXF_APPLY); Matrix_SetGfxMtx(&gMasterDisp); @@ -1312,84 +1685,113 @@ void Katina_801968F4(Boss* boss) { Matrix_Pop(&gGfxMatrix); } - if (boss->fwork[15] > 0.0f) { + if (this->fwork[BOSS_LASER_LENGTH] > 0.0f) { RCP_SetupDL(&gMasterDisp, 41); gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 255, 128); Matrix_RotateX(gGfxMatrix, M_PI, MTXF_APPLY); - Matrix_Scale(gGfxMatrix, 0.3f, boss->fwork[15], 0.3f, MTXF_APPLY); + Matrix_Scale(gGfxMatrix, 0.3f, this->fwork[BOSS_LASER_LENGTH], 0.3f, MTXF_APPLY); Matrix_SetGfxMtx(&gMasterDisp); gSPDisplayList(gMasterDisp++, D_KA_600BFB0); } } } -void Katina_80196E30(Actor* actor, s32 idx) { - Actor_Initialize(actor); +/** + * Updates the arwing position of the teammates while + * leaving the stage in the context of a succeeded mission. + */ +void Katina_SFTeamMissionAccomUpdate(ActorCutscene* this, s32 idx) { + Actor_Initialize(this); - actor->obj.status = OBJ_INIT; - actor->obj.id = OBJ_ACTOR_CUTSCENE; - actor->obj.pos.x = D_i4_8019F260[idx + 1] + gPlayer[0].pos.x; - actor->obj.pos.y = D_i4_8019F26C[idx + 1] + gPlayer[0].pos.y; - actor->obj.pos.z = D_i4_8019F278[idx + 1] + gPlayer[0].pos.z; - actor->unk_0F4.y = D_i4_8019F284[idx + 1]; - actor->fwork[1] = D_i4_8019F290[idx + 1]; - actor->fwork[0] = 40.0f; + this->obj.status = OBJ_INIT; + this->obj.id = OBJ_ACTOR_CUTSCENE; - Object_SetInfo(&actor->info, actor->obj.id); + this->obj.pos.x = D_i4_8019F260[idx + 1] + gPlayer[0].pos.x; + this->obj.pos.y = D_i4_8019F26C[idx + 1] + gPlayer[0].pos.y; + this->obj.pos.z = D_i4_8019F278[idx + 1] + gPlayer[0].pos.z; - actor->iwork[11] = 1; - AUDIO_PLAY_SFX(0x3100000C, actor->sfxSource, 4); + this->unk_0F4.y = D_i4_8019F284[idx + 1]; + + this->fwork[KA_ACTOR_FWORK_1] = D_i4_8019F290[idx + 1]; + this->fwork[KA_ACTOR_FWORK_0] = 40.0f; + + Object_SetInfo(&this->info, this->obj.id); + + this->iwork[KA_ACTOR_IWORK_11] = 1; + + AUDIO_PLAY_SFX(0x3100000C, this->sfxSource, 4); } -void Katina_80196F40(Actor* actor, s32 idx) { - Actor_Initialize(actor); +/** + * Updates the arwing position of the teammates while + * fleeing the stage in the context of a failed mission. + */ +void Katina_SFTeamFleeUpdate(ActorCutscene* this, s32 idx) { + Actor_Initialize(this); - actor->obj.status = OBJ_INIT; - actor->obj.id = OBJ_ACTOR_CUTSCENE; - actor->obj.pos.x = D_i4_8019F29C[idx + 1]; - actor->obj.pos.y = D_i4_8019F2AC[idx + 1]; - actor->obj.pos.z = D_i4_8019F2BC[idx + 1]; - actor->unk_0F4.y = D_i4_8019F2CC[idx + 1]; - actor->fwork[1] = D_i4_8019F2DC[idx + 1]; - actor->fwork[0] = 40.0f; + this->obj.status = OBJ_INIT; + this->obj.id = OBJ_ACTOR_CUTSCENE; - Object_SetInfo(&actor->info, actor->obj.id); + this->obj.pos.x = D_i4_8019F29C[idx + 1]; + this->obj.pos.y = D_i4_8019F2AC[idx + 1]; + this->obj.pos.z = D_i4_8019F2BC[idx + 1]; - actor->iwork[11] = 1; - AUDIO_PLAY_SFX(0x3100000C, actor->sfxSource, 4); + this->unk_0F4.y = D_i4_8019F2CC[idx + 1]; + + this->fwork[KA_ACTOR_FWORK_1] = D_i4_8019F2DC[idx + 1]; + this->fwork[KA_ACTOR_FWORK_0] = 40.0f; + + Object_SetInfo(&this->info, this->obj.id); + + this->iwork[KA_ACTOR_IWORK_11] = 1; + + AUDIO_PLAY_SFX(0x3100000C, this->sfxSource, 4); } -void Katina_80197024(void) { +/** + * Updates the actor positions that follow + * fox at the level complete cutscene. + */ +void Katina_SFTeam_LevelComplete_Update(void) { s32 i; - s32 target; - Actor* actor = &gActors[0]; + s32 numActors; + ActorCutscene* actor = &gActors[0]; Rand_SetSeed(1, 29100, 9786); if (gMissionStatus != MISSION_COMPLETE) { - target = 19; + numActors = 19; } else { - target = 2; + numActors = 2; } - for (i = 0; i <= target; i++, actor++) { + for (i = 0; i <= numActors; i++, actor++) { if ((D_i4_8019F2F0[i] >= gKaAllyKillCount) && ((i >= 3) || (gTeamShields[i + 1] > 0))) { Actor_Initialize(actor); actor->obj.status = OBJ_INIT; actor->obj.id = OBJ_ACTOR_CUTSCENE; - actor->obj.pos.x = ((D_i4_8019F340[i].x * 0.5f) + gPlayer[0].pos.x) + RAND_FLOAT_CENTERED_SEEDED(2000.0f); - actor->obj.pos.y = (D_i4_8019F340[i].y + gPlayer[0].pos.y) - RAND_FLOAT_SEEDED(1000.0f); - actor->obj.pos.z = (D_i4_8019F340[i].z + gPlayer[0].pos.z) + RAND_FLOAT_SEEDED(1000.0f); + + actor->obj.pos.x = + (sCsLevelCompleteActorPos[i].x * 0.5f) + gPlayer[0].pos.x + RAND_FLOAT_CENTERED_SEEDED(2000.0f); + actor->obj.pos.y = (sCsLevelCompleteActorPos[i].y + gPlayer[0].pos.y) - RAND_FLOAT_SEEDED(1000.0f); + actor->obj.pos.z = (sCsLevelCompleteActorPos[i].z + gPlayer[0].pos.z) + RAND_FLOAT_SEEDED(1000.0f); + actor->unk_0F4.z = RAND_FLOAT_CENTERED_SEEDED(200.0f); - actor->vwork[0].x = (D_i4_8019F340[i].x * 0.5f) + gPlayer[0].pos.x; - actor->vwork[0].y = D_i4_8019F340[i].y + gPlayer[0].pos.y; - actor->vwork[0].z = D_i4_8019F340[i].z + gPlayer[0].pos.z; + + actor->vwork[0].x = (sCsLevelCompleteActorPos[i].x * 0.5f) + gPlayer[0].pos.x; + actor->vwork[0].y = sCsLevelCompleteActorPos[i].y + gPlayer[0].pos.y; + actor->vwork[0].z = sCsLevelCompleteActorPos[i].z + gPlayer[0].pos.z; + actor->state = 1; + if (i >= 3) { actor->unk_0B6 = 33; } + Object_SetInfo(&actor->info, actor->obj.id); - actor->iwork[11] = 1; + + actor->iwork[KA_ACTOR_IWORK_11] = 1; + AUDIO_PLAY_SFX(0x3100000C, actor->sfxSource, 4); } } @@ -1397,7 +1799,7 @@ void Katina_80197024(void) { void Katina_LevelComplete(Player* player) { s32 i; - Boss* boss = &gBosses[1]; + Saucerer* boss = &gBosses[KA_BOSS_MOTHERSHIP]; Vec3f src; Vec3f dest; f32 angle; @@ -1406,41 +1808,50 @@ void Katina_LevelComplete(Player* player) { player->wings.unk_0C = 0.0f; player->wings.unk_08 = 0.0f; player->wings.unk_04 = 0.0f; + player->aerobaticPitch = 0.0f; + D_ctx_80177A48[0] = 1.0f; + switch (player->csState) { case 0: Audio_StopSfxByBankAndSource(1, &player->sfxSource[0]); gCsFrameCount = 0; player->unk_234 = 1; + player->pos.x = boss->obj.pos.x; player->pos.y = 800.0f; player->pos.z = boss->obj.pos.z; + player->yRot_114 = player->xRot_120 = player->rot.x = player->camRoll = player->aerobaticPitch = 0.0f; player->rot.y = 120.0f; player->baseSpeed = 40.0f; + gCsCamEyeX = boss->obj.pos.x + 5000.0f; gCsCamEyeY = 750.0f; gCsCamEyeZ = boss->obj.pos.z; gCsCamAtX = boss->obj.pos.x; gCsCamAtY = 1000.0f; gCsCamAtZ = boss->obj.pos.z; + for (i = 10; i < 60; i++) { if (gActors[i].unk_0B6 == 0) { Object_Kill(&gActors[i].obj, gActors[i].sfxSource); } } + player->csState += 1; + if (gTeamShields[TEAM_ID_FALCO] > 0) { - Katina_80196E30(&gActors[1], 0); + Katina_SFTeamMissionAccomUpdate(&gActors[1], 0); } if (gTeamShields[TEAM_ID_SLIPPY] > 0) { - Katina_80196E30(&gActors[2], 1); + Katina_SFTeamMissionAccomUpdate(&gActors[2], 1); } if (gTeamShields[TEAM_ID_PEPPY] > 0) { - Katina_80196E30(&gActors[3], 2); + Katina_SFTeamMissionAccomUpdate(&gActors[3], 2); } break; @@ -1449,8 +1860,10 @@ void Katina_LevelComplete(Player* player) { gCsCamAtX = boss->obj.pos.x; gCsCamAtY = 1000.0f; gCsCamAtZ = boss->obj.pos.z; + Math_SmoothStepToF(&player->rot.z, Math_SmoothStepToAngle(&player->rot.y, 283.0f, 0.1f, 3.0f, 0.0f) * 20.0f, 0.1f, 1.0f, 0.0f); + for (i = 1; i < 4; i++) { angle = Math_SmoothStepToAngle(&gActors[i].unk_0F4.y, gActors[i].fwork[1], 0.1f, 3.0f, 0.0f); Math_SmoothStepToF(&gActors[i].unk_0F4.z, angle * 20.0f, 0.1f, 1.0f, 0.0f); @@ -1492,21 +1905,28 @@ void Katina_LevelComplete(Player* player) { case 2: if (player->csTimer == 0) { player->unk_240 = 1; + player->pos.x = 0.0f; player->pos.y = 3500.0f; player->pos.z = 150.0f; + player->csState = 3; + Audio_StartPlayerNoise(0); + if (gMissionStatus != MISSION_COMPLETE) { AUDIO_PLAY_BGM(SEQ_ID_GOOD_END); } else { AUDIO_PLAY_BGM(SEQ_ID_BAD_END); } + D_ctx_80177A98 = 0; D_ctx_80177A48[1] = 0.0f; D_ctx_80177A48[2] = 0.0f; - Katina_80197024(); + + Katina_SFTeam_LevelComplete_Update(); func_play_800A3FB0(); + gCsFrameCount = 0; } break; @@ -1514,18 +1934,24 @@ void Katina_LevelComplete(Player* player) { case 3: gFillScreenAlphaTarget = 0; gFillScreenAlphaStep = 2; + D_ctx_80177A48[1] -= D_ctx_80177A48[2]; + Matrix_RotateY(gCalcMatrix, D_ctx_80177A48[1] * M_DTOR, MTXF_NEW); + src.x = -1000.0f; src.y = 0.0f; src.z = 0.0f; + Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); + gCsCamEyeX = dest.x; gCsCamEyeY = 3600.0f; gCsCamEyeZ = 500.0f + dest.z; gCsCamAtX = 0.0f; gCsCamAtY = 3500.0f; gCsCamAtZ = player->pos.z + 500; + if (gCsFrameCount > 1010) { player->baseSpeed += 2.0f; player->rot.x += 0.1f; @@ -1554,6 +1980,7 @@ void Katina_LevelComplete(Player* player) { gLeveLClearStatus[LEVEL_KATINA] = Play_CheckMedalStatus(150) + 1; } } + switch (gCsFrameCount) { case 190: gLevelClearScreenTimer = 100; @@ -1611,19 +2038,19 @@ void Katina_LevelComplete(Player* player) { break; case 100: - Katina_80196F40(&gActors[1], 0); + Katina_SFTeamFleeUpdate(&gActors[1], 0); if (gTeamShields[TEAM_ID_FALCO] > 0) { - Katina_80196F40(&gActors[2], 1); + Katina_SFTeamFleeUpdate(&gActors[2], 1); } if (gTeamShields[TEAM_ID_SLIPPY] > 0) { - Katina_80196F40(&gActors[3], 2); + Katina_SFTeamFleeUpdate(&gActors[3], 2); } if (gTeamShields[TEAM_ID_PEPPY] > 0) { - Katina_80196F40(&gActors[4], 3); + Katina_SFTeamFleeUpdate(&gActors[4], 3); } - player->csState += 1; + player->csState++; break; case 101: @@ -1637,20 +2064,27 @@ void Katina_LevelComplete(Player* player) { gActors[4].unk_0F4.x += 0.08f; break; } + Matrix_RotateY(gCalcMatrix, (player->yRot_114 + player->rot.y + 180.0f) * M_DTOR, MTXF_NEW); Matrix_RotateX(gCalcMatrix, -((player->xRot_120 + player->rot.x) * M_DTOR), MTXF_APPLY); + src.x = 0.0f; src.y = 0.0f; src.z = player->baseSpeed; + Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); + player->vel.x = dest.x; player->vel.z = dest.z; player->vel.y = dest.y; + player->pos.x += player->vel.x; player->pos.y += player->vel.y; player->pos.z += player->vel.z; + player->bankAngle = player->rot.z; player->trueZpos = player->pos.z; + if (player->csState < 100) { Math_SmoothStepToF(&player->cam.eye.x, gCsCamEyeX, D_ctx_80177A48[0], 50000.0f, 0); Math_SmoothStepToF(&player->cam.eye.y, gCsCamEyeY, D_ctx_80177A48[0], 50000.0f, 0); @@ -1659,116 +2093,135 @@ void Katina_LevelComplete(Player* player) { Math_SmoothStepToF(&player->cam.at.y, gCsCamAtY, D_ctx_80177A48[0], 50000.0f, 0); Math_SmoothStepToF(&player->cam.at.z, gCsCamAtZ, D_ctx_80177A48[0], 50000.0f, 0); } + player->bobPhase += 10.0f; player->yBob = -SIN_DEG(player->bobPhase) * 0.3f; player->rockPhase += 8.0f; player->rockAngle = SIN_DEG(player->rockPhase); } -void Katina_80197F10(Actor* actor) { +// Makes your teammates fly towards the camera after defeating the mothership. +void Katina_SFTeamFlyTowardsCamera(ActorCutscene* this) { Vec3f src; Vec3f dest; - switch (actor->state) { + switch (this->state) { case 1: - Math_SmoothStepToF(&actor->obj.pos.x, actor->vwork[0].x, 0.02f, 2.0f, 0.0001f); - Math_SmoothStepToF(&actor->obj.pos.y, actor->vwork[0].y, 0.02f, 2.0f, 0.0001f); - Math_SmoothStepToF(&actor->obj.pos.z, actor->vwork[0].z, 0.02f, 2.0f, 0.0001f); - Math_SmoothStepToF(&actor->unk_0F4.z, 0.0f, 0.02f, 0.2f, 0.0001f); - if ((actor->unk_0B6 != 0) && ((((s32) (actor->index % 8U) * 10) + 800) < gCsFrameCount)) { - actor->state = 4; + Math_SmoothStepToF(&this->obj.pos.x, this->vwork[0].x, 0.02f, 2.0f, 0.0001f); + Math_SmoothStepToF(&this->obj.pos.y, this->vwork[0].y, 0.02f, 2.0f, 0.0001f); + Math_SmoothStepToF(&this->obj.pos.z, this->vwork[0].z, 0.02f, 2.0f, 0.0001f); + Math_SmoothStepToF(&this->unk_0F4.z, 0.0f, 0.02f, 0.2f, 0.0001f); + + if ((this->unk_0B6 != 0) && ((((s32) (this->index % 8U) * 10) + 800) < gCsFrameCount)) { + this->state = 4; } break; case 2: - actor->state = 3; - AUDIO_PLAY_SFX(0x09000002, actor->sfxSource, 0); - actor->fwork[29] = 5.0f; + this->state = 3; + AUDIO_PLAY_SFX(0x09000002, this->sfxSource, 0); + this->fwork[KA_ACTOR_FWORK_29] = 5.0f; case 3: - actor->iwork[11] = 2; - actor->fwork[0] += 2.0f; - actor->unk_0F4.x += 0.1f; - actor->fwork[21] += 0.4f; - if (actor->fwork[21] > 0.6f) { - actor->fwork[21] = 0.6f; + this->iwork[KA_ACTOR_IWORK_11] = 2; + this->fwork[KA_ACTOR_FWORK_0] += 2.0f; + this->unk_0F4.x += 0.1f; + this->fwork[KA_ACTOR_FWORK_21] += 0.4f; + if (this->fwork[KA_ACTOR_FWORK_21] > 0.6f) { + this->fwork[KA_ACTOR_FWORK_21] = 0.6f; } break; case 4: - Math_SmoothStepToF(&actor->unk_0F4.z, 120.0f, 0.1f, 3.0f, 0.0001f); - actor->obj.pos.x += actor->fwork[1]; - actor->obj.pos.y += actor->fwork[1]; - actor->fwork[1] -= 0.5f; + Math_SmoothStepToF(&this->unk_0F4.z, 120.0f, 0.1f, 3.0f, 0.0001f); + this->obj.pos.x += this->fwork[KA_ACTOR_FWORK_1]; + this->obj.pos.y += this->fwork[KA_ACTOR_FWORK_1]; + this->fwork[KA_ACTOR_FWORK_1] -= 0.5f; break; } - Matrix_RotateY(gCalcMatrix, (actor->unk_0F4.y + 180.0f) * M_DTOR, MTXF_NEW); - Matrix_RotateX(gCalcMatrix, -(actor->unk_0F4.x * M_DTOR), MTXF_APPLY); + + Matrix_RotateY(gCalcMatrix, (this->unk_0F4.y + 180.0f) * M_DTOR, MTXF_NEW); + Matrix_RotateX(gCalcMatrix, -(this->unk_0F4.x * M_DTOR), MTXF_APPLY); + src.x = 0.0f; src.y = 0.0f; - src.z = actor->fwork[0]; + src.z = this->fwork[KA_ACTOR_FWORK_0]; + Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); - actor->vel.x = dest.x; - actor->vel.y = dest.y; - actor->vel.z = dest.z; - actor->obj.rot.x = -actor->unk_0F4.x; - actor->obj.rot.y = actor->unk_0F4.y + 180.0f; - actor->obj.rot.z = -actor->unk_0F4.z; + + this->vel.x = dest.x; + this->vel.y = dest.y; + this->vel.z = dest.z; + + this->obj.rot.x = -this->unk_0F4.x; + this->obj.rot.y = this->unk_0F4.y + 180.0f; + this->obj.rot.z = -this->unk_0F4.z; } -void Katina_801981F8(Actor* actor) { +void Katina_801981F8(Actor* this) { s32 i; - Actor* actor_it; + ActorAllRange* actor; Vec3f src; Vec3f dest; s32 pad; - if (actor->timer_0C0 == 0 && (i = 0, (gPlayer[0].state_1C8 != PLAYERSTATE_1C8_STANDBY))) { - actor->timer_0C0 = 2; + if ((this->timer_0C0 == 0) && (gPlayer[0].state_1C8 != PLAYERSTATE_1C8_STANDBY)) { + this->timer_0C0 = 2; src.x = 0.0f; src.y = 0.0f; src.z = -5000.0f; - if (gBosses[1].state != 0) { + if (gBosses[KA_BOSS_MOTHERSHIP].state != 0) { src.z = -10000.0f; } - for (i = 0, actor_it = &gActors[10]; i < 20; i++, actor_it++) { - if (actor_it->obj.status == OBJ_FREE) { - Actor_Initialize(actor_it); - actor_it->unk_0B6 = D_i4_8019F430[i]; - if ((actor_it->unk_0B6 != 0) || (gBosses[1].state == 0)) { - actor_it->obj.status = OBJ_ACTIVE; - actor_it->obj.id = OBJ_ACTOR_ALLRANGE; - Matrix_RotateY(gCalcMatrix, actor->unk_04E * 18.0f * M_DTOR, MTXF_NEW); + // Spawn actors 10 to 20 as Cornerian Fighters, 20 to 29 as enemies. + for (i = 0, actor = &gActors[AI360_10]; i < 20; i++, actor++) { + if (actor->obj.status == OBJ_FREE) { + Actor_Initialize(actor); + + actor->unk_0B6 = D_i4_8019F430[i]; + + if ((actor->unk_0B6 != 0) || (gBosses[KA_BOSS_MOTHERSHIP].state == 0)) { + actor->obj.status = OBJ_ACTIVE; + actor->obj.id = OBJ_ACTOR_ALLRANGE; + + Matrix_RotateY(gCalcMatrix, this->unk_04E * 18.0f * M_DTOR, MTXF_NEW); Matrix_MultVec3fNoTranslate(gCalcMatrix, &src, &dest); - actor_it->obj.pos.x = dest.x; - actor_it->obj.pos.y = RAND_FLOAT(1000.0f) + 300.0f; - actor_it->obj.pos.z = dest.z; - actor_it->unk_0F4.y = actor->unk_04E * 18.0f; - actor_it->state = 1; - actor_it->aiType = i + AI360_10; - actor_it->aiIndex = D_i4_8019F444[i]; - actor_it->unk_0F4.x = 3.0f; - actor_it->health = 24; - if (actor_it->unk_0B6 >= 2) { - actor_it->health = 1000; + + actor->obj.pos.x = dest.x; + actor->obj.pos.y = RAND_FLOAT(1000.0f) + 300.0f; + actor->obj.pos.z = dest.z; + + actor->unk_0F4.y = this->unk_04E * 18.0f; + actor->state = 1; + actor->aiType = i + AI360_10; + actor->aiIndex = D_i4_8019F444[i]; + actor->unk_0F4.x = 3.0f; + actor->health = 24; + + if (actor->unk_0B6 >= 2) { + actor->health = 1000; } - actor_it->iwork[11] = 1; - actor_it->unk_0C9 = 1; + + actor->iwork[KA_ACTOR_IWORK_11] = 1; + actor->unk_0C9 = 1; + if (D_i4_801A0540 < 9600) { - actor_it->itemDrop = DROP_SILVER_RING_10p; + actor->itemDrop = DROP_SILVER_RING_10p; } - actor_it->timer_0C2 = 30; - Object_SetInfo(&actor_it->info, actor_it->obj.id); - if (actor_it->unk_0B6 == 1) { - actor_it->info.targetOffset = 0.0f; - actor_it->info.bonus = 0; - AUDIO_PLAY_SFX(0x3100000C, actor_it->sfxSource, 4); + + actor->timer_0C2 = 30; + Object_SetInfo(&actor->info, actor->obj.id); + + if (actor->unk_0B6 == 1) { + actor->info.targetOffset = 0.0f; + actor->info.bonus = 0; + AUDIO_PLAY_SFX(0x3100000C, actor->sfxSource, 4); } - actor_it->info.action = (ObjectFunc) Katina_80198AA0; - actor_it->info.draw = (ObjectFunc) Katina_801995B4; - actor->unk_04E++; + actor->info.action = (ObjectFunc) Katina_EnemyUpdate; + actor->info.draw = (ObjectFunc) Katina_EnemyDraw; + this->unk_04E++; } break; } @@ -1776,10 +2229,11 @@ void Katina_801981F8(Actor* actor) { } } -void Katina_8019848C(void) { - Actor* actor = &gActors[9]; +void Katina_BillFighterInit(void) { + ActorAllRange* actor = &gActors[AI360_BILL]; Actor_Initialize(actor); + actor->obj.status = OBJ_ACTIVE; actor->obj.pos.x = 0; actor->obj.pos.y = 1000.0f; @@ -1788,58 +2242,67 @@ void Katina_8019848C(void) { actor->aiIndex = AI360_10 + 17; actor->unk_0B6 = 2; actor->health = 1000; - actor->iwork[11] = 1; + actor->iwork[KA_ACTOR_IWORK_11] = 1; actor->unk_0C9 = 1; actor->timer_0C2 = 30; actor->obj.id = OBJ_ACTOR_ALLRANGE; + Object_SetInfo(&actor->info, actor->obj.id); + actor->info.targetOffset = 0.0f; actor->info.bonus = 0; + AUDIO_PLAY_SFX(0x3100000C, actor->sfxSource, 4); } -void Katina_UpdateEvents(Actor* actor) { +void Katina_UpdateEvents(ActorAllRange* this) { s32 pad[4]; f32 D_i4_8019F494[5] = { -200.0f, -100.0f, -0.0f, 100.0f, 200.0f }; - switch (actor->state) { + switch (this->state) { case 0: gProjectFar = 30000.0f; D_i4_801A0540 = 0; gKaKilledAlly = gKaAllyKillCount = 0; - actor->state = 2; + this->state = 2; + if (gAllRangeCheckpoint != 0) { gHitCount = gSavedHitCount; - gBosses[1].state = 6; - gBosses[1].obj.pos.x = 0.0f; - gBosses[1].obj.pos.z = 0.0f; - gBosses[1].obj.pos.y = 2000.0f; - AUDIO_PLAY_SFX(0x11037025, gBosses[1].sfxSource, 0); + + gBosses[KA_BOSS_MOTHERSHIP].state = 6; + gBosses[KA_BOSS_MOTHERSHIP].obj.pos.x = 0.0f; + gBosses[KA_BOSS_MOTHERSHIP].obj.pos.z = 0.0f; + gBosses[KA_BOSS_MOTHERSHIP].obj.pos.y = 2000.0f; + + AUDIO_PLAY_SFX(0x11037025, gBosses[KA_BOSS_MOTHERSHIP].sfxSource, 0); + gAllRangeEventTimer = 20000; - gBosses[1].swork[16] = 5760; + + gBosses[KA_BOSS_MOTHERSHIP].swork[BOSS_CORE_TIMER] = 5760; + gKaKilledAlly = 1; + AUDIO_PLAY_BGM(SEQ_ID_KA_BOSS | SEQ_FLAG); } - - Katina_8019848C(); + Katina_BillFighterInit(); case 2: D_i4_801A0540++; PRINTF("KT_time %d\n", D_i4_801A0540); - Katina_801981F8(actor); + Katina_801981F8(this); break; case 6: - gActors[1].aiIndex = AI360_FOX; - gActors[1].state = 2; - gActors[2].aiIndex = AI360_FOX; - gActors[2].state = 2; - gActors[3].aiIndex = AI360_FOX; - gActors[3].state = 2; + gActors[AI360_FALCO].aiIndex = AI360_FOX; + gActors[AI360_FALCO].state = 2; + gActors[AI360_SLIPPY].aiIndex = AI360_FOX; + gActors[AI360_SLIPPY].state = 2; + gActors[AI360_PEPPY].aiIndex = AI360_FOX; + gActors[AI360_PEPPY].state = 2; break; } - if (gBosses[1].state < 15) { + if (gBosses[KA_BOSS_MOTHERSHIP].state < 15) { switch (gAllRangeEventTimer) { case -500: Radio_PlayMessage(gMsg_ID_18005, RCID_BILL); @@ -1858,7 +2321,7 @@ void Katina_UpdateEvents(Actor* actor) { break; } - if (gBosses[1].state == 12) { + if (gBosses[KA_BOSS_MOTHERSHIP].state == 12) { if (((gAllRangeEventTimer % 256) == 0) && (Rand_ZeroOne() < 0.5f)) { AllRange_PlayMessage(gMsg_ID_18060, RCID_BILL); } @@ -1885,40 +2348,39 @@ void Katina_UpdateEvents(Actor* actor) { } } -void Katina_80198930(void) { - Boss* boss = &gBosses[0]; +void Katina_BossInit(void) { + Frontlinebase* base = &gBosses[KA_BOSS_BASE]; + Saucerer* mothership = &gBosses[KA_BOSS_MOTHERSHIP]; - Boss_Initialize(&boss[1]); + Boss_Initialize(mothership); + mothership->obj.status = OBJ_INIT; + mothership->obj.pos.x = -15000.0f; + mothership->obj.pos.y = 3240.0f; + mothership->obj.pos.z = 15000.0f; + mothership->obj.id = OBJ_BOSS_316; + Object_SetInfo(&mothership->info, mothership->obj.id); - boss[1].obj.status = OBJ_INIT; - boss[1].obj.pos.x = -15000.0f; - boss[1].obj.pos.y = 3240.0f; - boss[1].obj.pos.z = 15000.0f; - boss[1].obj.id = OBJ_BOSS_316; - Object_SetInfo(&boss[1].info, boss[1].obj.id); - - Boss_Initialize(&boss[0]); - - boss[0].obj.status = OBJ_INIT; - boss[0].obj.pos.x = 0.0f; - boss[0].obj.pos.y = 0.0f; - boss[0].obj.pos.z = 0.0f; - boss[0].obj.id = OBJ_BOSS_317; - Object_SetInfo(&boss[0].info, boss[0].obj.id); + Boss_Initialize(base); + base->obj.status = OBJ_INIT; + base->obj.pos.x = 0.0f; + base->obj.pos.y = 0.0f; + base->obj.pos.z = 0.0f; + base->obj.id = OBJ_BOSS_317; + Object_SetInfo(&base->info, base->obj.id); } -bool Katina_801989F4(Actor* boss, f32 posX, f32 posY) { - if ((fabsf(gBosses[0].obj.pos.x - (boss->obj.pos.x + (posX * 650.0f))) < 1500.0f) && - (fabsf(gBosses[0].obj.pos.z - (boss->obj.pos.z + (posY * 650.0f))) < 1500.0f) && - (fabsf(gBosses[0].obj.pos.y - boss->obj.pos.y) < 700.0f)) { +bool Katina_IsActorCloseToBase(Actor* this, f32 posX, f32 posY) { + if ((fabsf(gBosses[KA_BOSS_BASE].obj.pos.x - (this->obj.pos.x + (posX * 650.0f))) < 1500.0f) && + (fabsf(gBosses[KA_BOSS_BASE].obj.pos.z - (this->obj.pos.z + (posY * 650.0f))) < 1500.0f) && + (fabsf(gBosses[KA_BOSS_BASE].obj.pos.y - this->obj.pos.y) < 700.0f)) { return true; } else { return false; } } -void Katina_80198AA0(Actor* actor) { - s32 isClose; +void Katina_EnemyUpdate(ActorAllRange* this) { + bool actorCloseToBase; s32 state; s32 pad; f32 xVel; @@ -1945,63 +2407,73 @@ void Katina_80198AA0(Actor* actor) { zPos = 0.0f; yPos = 0.0f; xPos = 0.0f; - Math_SmoothStepToF(&actor->fwork[10], 0.0f, 0.1f, 0.2f, 0.1f); - Math_SmoothStepToF(&actor->fwork[9], actor->fwork[10], 0.1f, 2.0f, 0.1f); + + Math_SmoothStepToF(&this->fwork[KA_ACTOR_FWORK_10], 0.0f, 0.1f, 0.2f, 0.1f); + Math_SmoothStepToF(&this->fwork[KA_ACTOR_FWORK_9], this->fwork[KA_ACTOR_FWORK_10], 0.1f, 2.0f, 0.1f); + state = 0; - actor->iwork[5] = 0; - switch (actor->state) { + + this->iwork[KA_ACTOR_IWORK_5] = 0; + + switch (this->state) { case 1: - actor->fwork[1] = 40.0f; - if (actor->timer_0BC == 0) { - actor->state = 3; + this->fwork[KA_ACTOR_FWORK_1] = 40.0f; + if (this->timer_0BC == 0) { + this->state = 3; } break; case 2: state = 1; - xDist = fabsf(actor->fwork[4] - actor->obj.pos.x); - yDist = fabsf(actor->fwork[6] - actor->obj.pos.z); - if (actor->aiIndex <= -1) { - actor->state = 3; + xDist = fabsf(this->fwork[KA_ACTOR_FWORK_4] - this->obj.pos.x); + yDist = fabsf(this->fwork[KA_ACTOR_FWORK_6] - this->obj.pos.z); + + if (this->aiIndex <= -1) { + this->state = 3; } else { - if (actor->aiType >= AI360_10) { - xPos = SIN_DEG((actor->index * 45) + gGameFrameCount) * 200.0f; - yPos = COS_DEG((actor->index * 45) + (gGameFrameCount * 2)) * 200.0f; - zPos = SIN_DEG((actor->index * 45) + gGameFrameCount) * 200.0f; + if (this->aiType >= AI360_10) { + xPos = SIN_DEG((this->index * 45) + gGameFrameCount) * 200.0f; + yPos = COS_DEG((this->index * 45) + (gGameFrameCount * 2)) * 200.0f; + zPos = SIN_DEG((this->index * 45) + gGameFrameCount) * 200.0f; } - actor->fwork[4] = gActors[actor->aiIndex].obj.pos.x + xPos; - actor->fwork[5] = gActors[actor->aiIndex].obj.pos.y + yPos; - actor->fwork[6] = gActors[actor->aiIndex].obj.pos.z + zPos; - actor->fwork[1] = gActors[actor->aiIndex].fwork[0] + 10.0f; - if (actor->fwork[1] < 30.0f) { - actor->fwork[1] = 30.0f; + + this->fwork[KA_ACTOR_FWORK_4] = gActors[this->aiIndex].obj.pos.x + xPos; + this->fwork[KA_ACTOR_FWORK_5] = gActors[this->aiIndex].obj.pos.y + yPos; + this->fwork[KA_ACTOR_FWORK_6] = gActors[this->aiIndex].obj.pos.z + zPos; + this->fwork[KA_ACTOR_FWORK_1] = gActors[this->aiIndex].fwork[0] + 10.0f; + + if (this->fwork[KA_ACTOR_FWORK_1] < 30.0f) { + this->fwork[KA_ACTOR_FWORK_1] = 30.0f; } - actor->fwork[3] = 1.4f; - if (actor->aiIndex > -1) { + + this->fwork[KA_ACTOR_FWORK_3] = 1.4f; + + if (this->aiIndex > -1) { if (yDist < 800.0f) { if (xDist < 800.0f) { - actor->fwork[1] = gActors[actor->aiIndex].fwork[0] - 5.0f; + this->fwork[KA_ACTOR_FWORK_1] = gActors[this->aiIndex].fwork[0] - 5.0f; } - } else if (actor->timer_0C0 == 0) { - actor->timer_0C0 = RAND_INT(200.0f) + 200; - actor->fwork[10] = 20.0f; + } else if (this->timer_0C0 == 0) { + this->timer_0C0 = RAND_INT(200.0f) + 200; + this->fwork[KA_ACTOR_FWORK_10] = 20.0f; } - if ((yDist < 1500.0f) && (xDist < 1500.0f)) { - actor->iwork[4] += 1; - actor->iwork[5] = 1; - if ((((actor->index + gGameFrameCount) & 0xB) == 0) && (Rand_ZeroOne() < 0.1f) && - func_360_80031900(actor) && (gActors[0].state == 2)) { - actor->iwork[0] = 1; + if ((yDist < 1500.0f) && (xDist < 1500.0f)) { + this->iwork[KA_ACTOR_IWORK_4] += 1; + this->iwork[KA_ACTOR_IWORK_5] = 1; + + if ((((this->index + gGameFrameCount) & 11) == 0) && (Rand_ZeroOne() < 0.1f) && + func_360_80031900(this) && (gActors[0].state == 2)) { + this->iwork[KA_ACTOR_IWORK_0] = true; } } else { - actor->iwork[4] = 0; + this->iwork[KA_ACTOR_IWORK_4] = 0; } - if ((actor->aiIndex >= AI360_FALCO) && - ((gActors[actor->aiIndex].obj.status == OBJ_DYING) || (gActors[actor->aiIndex].state == 6) || - gActors[actor->aiIndex].obj.status == OBJ_FREE)) { - actor->state = 3; + if ((this->aiIndex >= AI360_FALCO) && + ((gActors[this->aiIndex].obj.status == OBJ_DYING) || (gActors[this->aiIndex].state == 6) || + gActors[this->aiIndex].obj.status == OBJ_FREE)) { + this->state = 3; } } } @@ -2009,10 +2481,12 @@ void Katina_80198AA0(Actor* actor) { case 3: state = 1; - if (actor->timer_0BC == 0) { - actor->fwork[3] = 1.2f; - actor->fwork[1] = 40.0f; + + if (this->timer_0BC == 0) { + this->fwork[KA_ACTOR_FWORK_3] = 1.2f; + this->fwork[KA_ACTOR_FWORK_1] = 40.0f; yRand = RAND_FLOAT(1000.0f); + if (gPlayer[0].state_1C8 == PLAYERSTATE_1C8_STANDBY) { xRand = RAND_FLOAT_CENTERED(5000.0f); zRand = RAND_FLOAT_CENTERED(5000.0f); @@ -2020,42 +2494,47 @@ void Katina_80198AA0(Actor* actor) { xRand = RAND_FLOAT_CENTERED(10000.0f); zRand = RAND_FLOAT_CENTERED(10000.0f); } - actor->fwork[4] = xRand; - actor->fwork[5] = yRand; - actor->fwork[6] = zRand; - actor->timer_0BC = RAND_INT(20.0f) + 10; + + this->fwork[KA_ACTOR_FWORK_4] = xRand; + this->fwork[KA_ACTOR_FWORK_5] = yRand; + this->fwork[KA_ACTOR_FWORK_6] = zRand; + this->timer_0BC = RAND_INT(20.0f) + 10; } - if (actor->timer_0C0 == 0) { - actor->timer_0C0 = RAND_INT(200.0f) + 200; - actor->fwork[10] = 30.0f; + if (this->timer_0C0 == 0) { + this->timer_0C0 = RAND_INT(200.0f) + 200; + this->fwork[KA_ACTOR_FWORK_10] = 30.0f; } - if ((actor->aiIndex >= AI360_FALCO) && (gActors[actor->aiIndex].obj.status == OBJ_ACTIVE)) { - actor->state = 2; - actor->iwork[2] = AI360_FOX; + if ((this->aiIndex >= AI360_FALCO) && (gActors[this->aiIndex].obj.status == OBJ_ACTIVE)) { + this->state = 2; + this->iwork[KA_ACTOR_IWORK_2] = AI360_FOX; } break; } - xSin = SIN_DEG(actor->obj.rot.x); - xCos = COS_DEG(actor->obj.rot.x); - ySin = SIN_DEG(actor->obj.rot.y); - yCos = COS_DEG(actor->obj.rot.y); + xSin = SIN_DEG(this->obj.rot.x); + xCos = COS_DEG(this->obj.rot.x); + ySin = SIN_DEG(this->obj.rot.y); + yCos = COS_DEG(this->obj.rot.y); if (state != 0) { - xRand = actor->fwork[4] - actor->obj.pos.x; - yRand = actor->fwork[5] - actor->obj.pos.y; - zRand = actor->fwork[6] - actor->obj.pos.z; - if (((actor->index + gGameFrameCount) % 8) == 0) { - actor->fwork[19] = Math_RadToDeg(Math_Atan2F(xRand, zRand)); + xRand = this->fwork[KA_ACTOR_FWORK_4] - this->obj.pos.x; + yRand = this->fwork[KA_ACTOR_FWORK_5] - this->obj.pos.y; + zRand = this->fwork[KA_ACTOR_FWORK_6] - this->obj.pos.z; + + if (((this->index + gGameFrameCount) % 8) == 0) { + this->fwork[KA_ACTOR_FWORK_19] = Math_RadToDeg(Math_Atan2F(xRand, zRand)); xAngle = sqrtf(SQ(xRand) + SQ(zRand)); - actor->fwork[20] = Math_RadToDeg(Math_Atan2F(yRand, xAngle)); + this->fwork[KA_ACTOR_FWORK_20] = Math_RadToDeg(Math_Atan2F(yRand, xAngle)); } - xAngle = actor->fwork[20]; - isClose = Katina_801989F4(actor, ySin, yCos); - if (isClose != 0) { - xAngle += 40.0f * isClose; + + xAngle = this->fwork[KA_ACTOR_FWORK_20]; + + actorCloseToBase = Katina_IsActorCloseToBase(this, ySin, yCos); + + if (actorCloseToBase) { + xAngle += 40.0f * actorCloseToBase; if (xAngle >= 360.0f) { xAngle -= 360.0f; } @@ -2063,108 +2542,122 @@ void Katina_80198AA0(Actor* actor) { if (xAngle < 0.0f) { xAngle += 360.0f; } - } else if ((actor->obj.pos.y < (gGroundHeight + 50.0f)) && (xAngle > 180.0f)) { + } else if ((this->obj.pos.y < (gGroundHeight + 50.0f)) && (xAngle > 180.0f)) { xAngle = 0.0f; - actor->unk_0F4.x = 0.0f; + this->unk_0F4.x = 0.0f; } - Math_SmoothStepToAngle(&actor->unk_0F4.x, xAngle, 0.5f, actor->fwork[2], 0.0001f); - yAngle = Math_SmoothStepToAngle(&actor->unk_0F4.y, actor->fwork[19], 0.5f, actor->fwork[2], 0.0001f) * 30.0f; + + Math_SmoothStepToAngle(&this->unk_0F4.x, xAngle, 0.5f, this->fwork[KA_ACTOR_FWORK_2], 0.0001f); + + yAngle = Math_SmoothStepToAngle(&this->unk_0F4.y, this->fwork[KA_ACTOR_FWORK_19], 0.5f, + this->fwork[KA_ACTOR_FWORK_2], 0.0001f) * + 30.0f; + if (yAngle < 0.0f) { zAngle = yAngle * -1.0f; } else { zAngle = 360.0f - yAngle; } - Math_SmoothStepToAngle(&actor->obj.rot.z, zAngle, 0.1f, 3.0f, 0.01f); + Math_SmoothStepToAngle(&this->obj.rot.z, zAngle, 0.1f, 3.0f, 0.01f); } - actor->obj.rot.x = -actor->unk_0F4.x; - actor->obj.rot.y = actor->unk_0F4.y; + this->obj.rot.x = -this->unk_0F4.x; + this->obj.rot.y = this->unk_0F4.y; - Math_SmoothStepToF(&actor->fwork[0], actor->fwork[1], 0.2f, 1.0f, 0.1f); - Math_SmoothStepToF(&actor->fwork[2], actor->fwork[3], 1.0f, 0.1f, 0.1f); - zVel = (actor->fwork[0] + actor->fwork[9]) * xCos; - yVel = (actor->fwork[0] + actor->fwork[9]) * -xSin; + Math_SmoothStepToF(&this->fwork[KA_ACTOR_FWORK_0], this->fwork[KA_ACTOR_FWORK_1], 0.2f, 1.0f, 0.1f); + Math_SmoothStepToF(&this->fwork[KA_ACTOR_FWORK_2], this->fwork[KA_ACTOR_FWORK_3], 1.0f, 0.1f, 0.1f); + + zVel = (this->fwork[KA_ACTOR_FWORK_0] + this->fwork[KA_ACTOR_FWORK_9]) * xCos; + yVel = (this->fwork[KA_ACTOR_FWORK_0] + this->fwork[KA_ACTOR_FWORK_9]) * -xSin; xVel = ySin * zVel; zVel = yCos * zVel; - actor->vel.x = actor->fwork[13] + xVel; - actor->vel.y = actor->fwork[14] + yVel; - actor->vel.z = actor->fwork[12] + zVel; + this->vel.x = this->fwork[KA_ACTOR_FWORK_13] + xVel; + this->vel.y = this->fwork[KA_ACTOR_FWORK_14] + yVel; + this->vel.z = this->fwork[KA_ACTOR_FWORK_12] + zVel; - actor->fwork[13] -= actor->fwork[13] * 0.1f; - actor->fwork[14] -= actor->fwork[14] * 0.1f; - actor->fwork[12] -= actor->fwork[12] * 0.1f; + this->fwork[KA_ACTOR_FWORK_13] -= this->fwork[KA_ACTOR_FWORK_13] * 0.1f; + this->fwork[KA_ACTOR_FWORK_14] -= this->fwork[KA_ACTOR_FWORK_14] * 0.1f; + this->fwork[KA_ACTOR_FWORK_12] -= this->fwork[KA_ACTOR_FWORK_12] * 0.1f; - if ((actor->obj.pos.y < gGroundHeight + 40.0f) && (actor->vel.y < 0.0f)) { - actor->obj.pos.y = gGroundHeight + 40.0f; - actor->vel.y = 0.0f; + if ((this->obj.pos.y < gGroundHeight + 40.0f) && (this->vel.y < 0.0f)) { + this->obj.pos.y = gGroundHeight + 40.0f; + this->vel.y = 0.0f; } - if (actor->iwork[0] != 0) { - actor->iwork[0] = 0; - yVel = (-xSin * 200.0f * 0.5f); - xVel = (xCos * 200.0f * 0.5f); - zVel = (xCos * 200.0f * 0.5f); - Actor_SpawnPlayerLaser(actor->aiType, actor->obj.pos.x + ((ySin * xVel) * 1.5f), - actor->obj.pos.y + (yVel * 1.5f), actor->obj.pos.z + ((yCos * zVel) * 1.5f), - (ySin * (xCos * 200.0f * 0.5f)), (-xSin * 200.0f * 0.5f), - (yCos * (xCos * 200.0f * 0.5f)), actor->obj.rot.x, actor->obj.rot.y, actor->obj.rot.z); + if (this->iwork[KA_ACTOR_IWORK_0]) { + this->iwork[KA_ACTOR_IWORK_0] = false; + + yVel = -xSin * 200.0f * 0.5f; + xVel = +xCos * 200.0f * 0.5f; + zVel = +xCos * 200.0f * 0.5f; + + Actor_SpawnPlayerLaser(this->aiType, this->obj.pos.x + (ySin * xVel * 1.5f), this->obj.pos.y + (yVel * 1.5f), + this->obj.pos.z + (yCos * zVel * 1.5f), ySin * (xCos * 200.0f * 0.5f), + -xSin * 200.0f * 0.5f, yCos * (xCos * 200.0f * 0.5f), this->obj.rot.x, this->obj.rot.y, + this->obj.rot.z); } - ActorAllRange_ApplyDamage(actor); - radarMark = &gRadarMarks[actor->index]; + + ActorAllRange_ApplyDamage(this); + + radarMark = &gRadarMarks[this->index]; radarMark->status = 1; - radarMark->type = actor->aiType; - radarMark->pos.x = actor->obj.pos.x; - radarMark->pos.y = actor->obj.pos.y; - radarMark->pos.z = actor->obj.pos.z; - radarMark->yRot = actor->unk_0F4.y + 180.0f; - if (actor->iwork[8] != 0) { - actor->iwork[8]--; + radarMark->type = this->aiType; + radarMark->pos.x = this->obj.pos.x; + radarMark->pos.y = this->obj.pos.y; + radarMark->pos.z = this->obj.pos.z; + radarMark->yRot = this->unk_0F4.y + 180.0f; + + if (this->iwork[KA_ACTOR_IWORK_8] != 0) { + this->iwork[KA_ACTOR_IWORK_8]--; } } -void Katina_801995B4(Actor* actor) { +void Katina_EnemyDraw(ActorAllRange* this) { s32 pad3[3]; f32 angle; Vec3f D_i4_8019F4A8 = { 0.0f, 0.0f, 0.0f }; Vec3f pad[30]; - if (((actor->index + gSysFrameCount) % 8) == 0) { - actor->iwork[23] = 1; - if ((fabsf(actor->obj.pos.x - gPlayer[0].cam.eye.x) < 4500.0f) && - (fabsf(actor->obj.pos.z - gPlayer[0].cam.eye.z) < 4500.0f)) { - actor->iwork[23] = 0; + if (((this->index + gSysFrameCount) % 8) == 0) { + this->iwork[KA_ACTOR_LOW_POLY] = true; + if ((fabsf(this->obj.pos.x - gPlayer[0].cam.eye.x) < 4500.0f) && + (fabsf(this->obj.pos.z - gPlayer[0].cam.eye.z) < 4500.0f)) { + this->iwork[KA_ACTOR_LOW_POLY] = false; } } - if ((actor->iwork[8] != 0) && (actor->aiType < AI360_GREAT_FOX)) { - angle = SIN_DEG(actor->iwork[8] * 400.0f) * actor->iwork[8]; + if ((this->iwork[KA_ACTOR_IWORK_8] != 0) && (this->aiType < AI360_GREAT_FOX)) { + angle = SIN_DEG(this->iwork[KA_ACTOR_IWORK_8] * 400.0f) * this->iwork[KA_ACTOR_IWORK_8]; Matrix_RotateY(gGfxMatrix, M_DTOR * angle, MTXF_APPLY); Matrix_RotateX(gGfxMatrix, M_DTOR * angle, MTXF_APPLY); Matrix_RotateZ(gGfxMatrix, M_DTOR * angle, MTXF_APPLY); Matrix_SetGfxMtx(&gMasterDisp); } - if (actor->iwork[23] != 0) { + + if (this->iwork[KA_ACTOR_LOW_POLY]) { RCP_SetupDL(&gMasterDisp, 34); gDPSetPrimColor(gMasterDisp++, 0, 0, 80, 64, 64, 255); } else { RCP_SetupDL(&gMasterDisp, 29); } - if ((actor->timer_0C6 % 2) == 0) { + + if ((this->timer_0C6 % 2) == 0) { gSPFogPosition(gMasterDisp++, gFogNear, 1005); } - switch (actor->unk_0B6) { + + switch (this->unk_0B6) { case 0: - if (actor->iwork[23] != 0) { - gSPDisplayList(gMasterDisp++, D_KA_600EFF0); + if (this->iwork[KA_ACTOR_LOW_POLY]) { + gSPDisplayList(gMasterDisp++, aKaEnemy1LowPolyDL); } else { - gSPDisplayList(gMasterDisp++, D_KA_6001530); + gSPDisplayList(gMasterDisp++, aKaEnemy1DL); } break; case 1: - gSPDisplayList(gMasterDisp++, D_KA_600E050); + gSPDisplayList(gMasterDisp++, aKaCornerianFighterDL); Matrix_Translate(gGfxMatrix, 0.0f, 0.0f, -60.0f, MTXF_APPLY); - Actor_DrawEngineGlow(actor, 0); + Actor_DrawEngineGlow(this, 0); break; } } diff --git a/src/overlays/ovl_i4/fox_sz.c b/src/overlays/ovl_i4/fox_sz.c index 5484f7d1..e8d68048 100644 --- a/src/overlays/ovl_i4/fox_sz.c +++ b/src/overlays/ovl_i4/fox_sz.c @@ -67,7 +67,7 @@ void SectorZ_80199900(Actor* actor, s32 arg1) { void SectorZ_80199B18(Effect* effect, f32 xPos, f32 yPos, f32 zPos, f32 xVel, f32 yVel, f32 zVel, f32 scale) { Effect_Initialize(effect); effect->obj.status = OBJ_INIT; - effect->obj.id = OBJ_EFFECT_339; + effect->obj.id = OBJ_EFFECT_FIRE_SMOKE; effect->obj.pos.x = xPos; effect->obj.pos.y = yPos; @@ -1240,7 +1240,7 @@ void SectorZ_LevelComplete(Player* player) { player->csState = 10; player->csTimer = 1000; - Audio_StopPlayerNoise(0U); + Audio_StopPlayerNoise(0); Audio_KillSfxBySource(player->sfxSource); Play_ClearObjectData(); diff --git a/src/overlays/ovl_i5/fox_ma.c b/src/overlays/ovl_i5/fox_ma.c index 3ae62ac3..c43b4fb9 100644 --- a/src/overlays/ovl_i5/fox_ma.c +++ b/src/overlays/ovl_i5/fox_ma.c @@ -6265,6 +6265,7 @@ void Macbeth_LevelComplete2(Player* player) { Math_SmoothStepToF(&gCsCamEyeX, player->pos.x - 2000.0f, 0.1f, D_ctx_80177A48[8], 0.0f); gCsCamEyeZ -= 1.0f; } + //! @BUG: The following condition is always true: if ((gCsFrameCount >= 2120) || (gCsFrameCount < 2175)) { Math_SmoothStepToF(&gCsCamAtY, player->pos.y + 70.0f, 0.1f, 8.0f, 0.0f); } diff --git a/src/sys/sys_fault.c b/src/sys/sys_fault.c index b0240169..000304a5 100644 --- a/src/sys/sys_fault.c +++ b/src/sys/sys_fault.c @@ -243,7 +243,7 @@ void Fault_ThreadEntry(void* arg0) { func_8000762C(300, 10, "-"); gControllerPlugged[0] = 1; -#if MODS_AUTO_DEBUGGER == 0 // Turn this off for instant crash debugger (no button combination needed) +#if MODS_AUTO_DEBUGGER == 0 // Instant crash debugger (no button combination needed) while (var_s5 == 0) { osSendMesg(&gSerialThreadMesgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_NOBLOCK); MQ_WAIT_FOR_MESG(&gControllerMesgQueue, NULL); diff --git a/tools/Torch b/tools/Torch index f24e7ec6..45e6853e 160000 --- a/tools/Torch +++ b/tools/Torch @@ -1 +1 @@ -Subproject commit f24e7ec63b81bfe24e4daa795cc1e1d690e789cd +Subproject commit 45e6853e315933d57a0e7213a2d5590fb74f628a