summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Asenjo Nitti <96613413+sonicdcer@users.noreply.github.com>2024-05-05 17:23:49 -0300
committerGitHub <noreply@github.com>2024-05-05 17:23:49 -0300
commit455aa0aa2c35da2dfca64c24a5cc2c36f488c110 (patch)
tree73c06ff09b7a42f443c964bdf49e35768787acc3
parent9303fba359a28d809246e4a2ea007a81d01f7686 (diff)
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
-rw-r--r--Makefile2
-rw-r--r--assets/yaml/us/ast_katina.yaml46
-rw-r--r--include/i4.h18
-rw-r--r--include/sf64object.h8
-rw-r--r--include/variables.h2
-rw-r--r--linker_scripts/us/symbol_addrs_overlays.txt4
-rw-r--r--src/engine/fox_360.c11
-rw-r--r--src/engine/fox_demo.c6
-rw-r--r--src/engine/fox_edata_info.c10
-rw-r--r--src/engine/fox_effect.c6
-rw-r--r--src/engine/fox_enmy.c6
-rw-r--r--src/engine/fox_hud.c6
-rw-r--r--src/engine/fox_play.c2
-rw-r--r--src/overlays/ovl_i4/fox_ka.c1965
-rw-r--r--src/overlays/ovl_i4/fox_sz.c4
-rw-r--r--src/overlays/ovl_i5/fox_ma.c1
-rw-r--r--src/sys/sys_fault.c2
m---------tools/Torch0
18 files changed, 1299 insertions, 800 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);
+
+ this->obj.status = OBJ_INIT;
+ this->obj.id = OBJ_EFFECT_FIRE_SMOKE;
+
+ this->obj.pos.x = x;
+ this->obj.pos.y = y;
+ this->obj.pos.z = z;
+
+ this->vel.x = xVel;
+ this->vel.y = yVel;
+ this->vel.z = zVel;
- effect->obj.status = OBJ_INIT;
- effect->obj.id = OBJ_EFFECT_339;
+ this->scale2 = scale;
+ this->scale1 = 0.5f;
- effect->obj.pos.x = x;
- effect->obj.pos.y = y;
- effect->obj.pos.z = z;
+ this->unk_4C = 2;
+ this->obj.rot.z = RAND_FLOAT(360.0f);
- effect->vel.x = xVel;
- effect->vel.y = yVel;
- effect->vel.z = zVel;
+ Object_SetInfo(&this->info, this->obj.id);
- 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->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 (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);
- }
- 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;
+ if (this->timer_052 == 1) {
+ AUDIO_PLAY_SFX(0x19034042, this->sfxSource, 0);
+ }
+
+ 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(&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;
-
- boss->fwork[12] = 0.0f;
- boss->fwork[10] = 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;
+
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);
- }
-
- 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;
+ 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 (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];
-
- Boss_Initialize(&boss[1]);
-
- 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);
+void Katina_BossInit(void) {
+ Frontlinebase* base = &gBosses[KA_BOSS_BASE];
+ Saucerer* mothership = &gBosses[KA_BOSS_MOTHERSHIP];
+
+ 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_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;
+ this->iwork[KA_ACTOR_IWORK_4] += 1;
+ this->iwork[KA_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 ((((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(&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);
- 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;
+ 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
-Subproject f24e7ec63b81bfe24e4daa795cc1e1d690e789c
+Subproject 45e6853e315933d57a0e7213a2d5590fb74f628