diff --git a/assets/xml/objects/object_big_fwall.xml b/assets/xml/objects/object_big_fwall.xml
index bb8b838be..f1becbe8e 100644
--- a/assets/xml/objects/object_big_fwall.xml
+++ b/assets/xml/objects/object_big_fwall.xml
@@ -1,6 +1,7 @@
+
-
-
+
+
diff --git a/assets/xml/objects/object_po.xml b/assets/xml/objects/object_po.xml
index 98dbc61b1..a430d178b 100644
--- a/assets/xml/objects/object_po.xml
+++ b/assets/xml/objects/object_po.xml
@@ -1,53 +1,65 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_visiblock.xml b/assets/xml/objects/object_visiblock.xml
index d714338fc..cae048322 100644
--- a/assets/xml/objects/object_visiblock.xml
+++ b/assets/xml/objects/object_visiblock.xml
@@ -1,8 +1,9 @@
+
-
-
-
-
+
+
+
+
diff --git a/assets/xml/objects/object_zoraegg.xml b/assets/xml/objects/object_zoraegg.xml
index 175c6aeb2..0fd05641d 100644
--- a/assets/xml/objects/object_zoraegg.xml
+++ b/assets/xml/objects/object_zoraegg.xml
@@ -1,34 +1,48 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/functions.h b/include/functions.h
index 74b593152..829291c25 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -1292,21 +1292,13 @@ void Audio_SetBgmVolumeOn(void);
void func_801A0204(s8 seqId);
void Audio_SetMainBgmVolume(u8 targetVolume, u8 volumeFadeTimer);
void AudioSfx_SetChannelIO(Vec3f* pos, u16 sfxId, u8 ioData);
-// void func_801A1290(void);
-// void func_801A1348(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7);
-// void func_801A13BC(void);
-// void func_801A153C(void);
-// void func_801A17F4(void);
-// void func_801A1904(void);
-// void func_801A1A10(void);
-// void func_801A1A8C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6);
-void func_801A1D44(Vec3f* vec, u8 seqId, f32 arg2);
-void func_801A1DB8(Vec3f* vec, u8 seqId, f32 arg2);
-// void func_801A1E0C(void);
-void func_801A1F00(u8 arg0, u16 seqId);
-void func_801A1F88(void);
-void func_801A1FB4(u8 playerIndex, Vec3f* pos, u16 seqId, f32 maxDist);
-// void func_801A2090(void);
+void Audio_PlayObjSoundBgm(Vec3f* pos, s8 seqId);
+void Audio_PlayObjSoundFanfare(Vec3f* pos, s8 seqId);
+void Audio_PlaySubBgmAtPos(Vec3f* pos, u8 seqId, f32 maxDist);
+void Audio_PlaySubBgmAtPosWithFilter(Vec3f* pos, u8 seqId, f32 arg2);
+void Audio_PlaySequenceAtDefaultPos(u8 seqPlayerIndex, u16 seqId);
+void Audio_StopSequenceAtDefaultPos(void);
+void Audio_PlaySequenceAtPos(u8 seqPlayerIndex, Vec3f* pos, u16 seqId, f32 maxDist);
void func_801A246C(u8 param_1, u8 param_2);
void Audio_PlayMorningSceneSequence(u16 seqId, u8 dayMinusOne);
void Audio_PlaySceneSequence(u16 seqId, u8 dayMinusOne);
diff --git a/include/z64actor.h b/include/z64actor.h
index b3e1fe77e..5d072d253 100644
--- a/include/z64actor.h
+++ b/include/z64actor.h
@@ -370,6 +370,8 @@ typedef struct ActorSharedMemoryEntry {
/* 0x4 */ void* ptr;
} ActorSharedMemoryEntry; // size = 0x8
+#define SWITCH_FLAG_NONE -1
+
typedef struct ActorContextSceneFlags {
/* 0x00 */ u32 switches[4]; // First 0x40 are permanent, second 0x40 are temporary
/* 0x10 */ u32 chest;
diff --git a/spec b/spec
index 7f92b1c4d..b8d6431f5 100644
--- a/spec
+++ b/spec
@@ -2000,8 +2000,7 @@ beginseg
name "ovl_Obj_Sound"
compress
include "build/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.o"
- include "build/data/ovl_Obj_Sound/ovl_Obj_Sound.data.o"
- include "build/data/ovl_Obj_Sound/ovl_Obj_Sound.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Sound/ovl_Obj_Sound_reloc.o"
endseg
beginseg
@@ -2079,8 +2078,7 @@ beginseg
name "ovl_Door_Spiral"
compress
include "build/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.o"
- include "build/data/ovl_Door_Spiral/ovl_Door_Spiral.data.o"
- include "build/data/ovl_Door_Spiral/ovl_Door_Spiral.reloc.o"
+ include "build/src/overlays/actors/ovl_Door_Spiral/ovl_Door_Spiral_reloc.o"
endseg
beginseg
@@ -2108,8 +2106,7 @@ beginseg
name "ovl_Obj_Boyo"
compress
include "build/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.o"
- include "build/data/ovl_Obj_Boyo/ovl_Obj_Boyo.data.o"
- include "build/data/ovl_Obj_Boyo/ovl_Obj_Boyo.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Boyo/ovl_Obj_Boyo_reloc.o"
endseg
beginseg
@@ -2165,8 +2162,7 @@ beginseg
name "ovl_En_Jso"
compress
include "build/src/overlays/actors/ovl_En_Jso/z_en_jso.o"
- include "build/data/ovl_En_Jso/ovl_En_Jso.data.o"
- include "build/data/ovl_En_Jso/ovl_En_Jso.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Jso/ovl_En_Jso_reloc.o"
endseg
beginseg
diff --git a/src/audio/code_8019AF00.c b/src/audio/code_8019AF00.c
index dcefd2eae..5fb24860f 100644
--- a/src/audio/code_8019AF00.c
+++ b/src/audio/code_8019AF00.c
@@ -77,10 +77,10 @@ void Audio_PlayAmbience(u8 ambienceId);
void Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(u8 volume);
void Audio_UpdateRiverSoundVolumes(void);
-void func_801A1290(void);
-void func_801A1904(void);
-void func_801A1E0C(void);
-void func_801A2090(void);
+void Audio_UpdateObjSoundProperties(void);
+void Audio_UpdateObjSoundFanfare(void);
+void Audio_UpdateSubBgmAtPos(void);
+void Audio_UpdateSequenceAtPos(void);
void Audio_UpdateSceneSequenceResumePoint(void);
void func_801A312C(void);
void func_801A3AC0(void);
@@ -116,7 +116,14 @@ u8 sRiverSoundBgmTimer;
u8 sFanfareState;
u16 sFanfareSeqId;
u8 sMuteOnlySfxAndAmbienceSeq;
-u8 sAllPlayersMutedExceptOcaAndSys;
+u8 sAllPlayersMutedExceptSystemAndOcarina;
+
+typedef enum {
+ /* 0 */ AUDIO_PAUSE_STATE_CLOSED,
+ /* 1 */ AUDIO_PAUSE_STATE_CLOSING,
+ /* 2 */ AUDIO_PAUSE_STATE_OPEN
+} AudioPauseState;
+
u8 sAudioPauseState;
u8 sSpatialSeqIsActive[4];
u8 sSequenceFilter[8 * 4];
@@ -237,6 +244,10 @@ Vec3f* sRiverSoundBgmPos = NULL;
f32 sRiverSoundXZDistToPlayer = 2000.0f;
u8 sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX;
+// Weights distance strongest by depth (z), weaker by left/right screen (x), and weakest by top/bottom screen (y)
+#define SEQ_SCREEN_WEIGHTED_DIST(projectedPos) \
+ (sqrtf(SQ((projectedPos)->z) + ((SQ((projectedPos)->x) / 4.0f) + (SQ((projectedPos)->y) / 6.0f))))
+
// Allows enemy bgm
#define SEQ_FLAG_ENEMY (1 << 0)
@@ -3639,11 +3650,11 @@ void Audio_Update(void) {
Audio_UpdateSceneSequenceResumePoint();
func_801A312C();
Audio_UpdateSfxVolumeTransition();
- func_801A1E0C();
- func_801A1904();
- func_801A2090();
+ Audio_UpdateSubBgmAtPos();
+ Audio_UpdateObjSoundFanfare();
+ Audio_UpdateSequenceAtPos();
func_801A3AC0();
- func_801A1290();
+ Audio_UpdateObjSoundProperties();
Audio_ResetRequestedSceneSeqId();
AudioSfx_ProcessRequests();
AudioSeq_ProcessSeqCmds();
@@ -4870,37 +4881,455 @@ void Audio_SplitBgmChannels(s8 volumeSplit) {
}
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0E44.s")
+void Audio_SetSequenceProperties(u8 seqPlayerIndex, Vec3f* projectedPos, s16 flags, f32 minDist, f32 maxDist,
+ f32 maxVolume, f32 minVolume) {
+ f32 dist;
+ f32 volume;
+ s8 surroundEffectIndex;
+ s8 pan;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1290.s")
+ // calculating surround sound effect from screen depth
+ if (projectedPos->z > 0.0f) {
+ if (projectedPos->z > 100.0f) {
+ surroundEffectIndex = 0;
+ } else {
+ surroundEffectIndex = ((100.0f - projectedPos->z) / 100.0f) * 64.0f;
+ }
+ } else {
+ if (projectedPos->z < -100.0f) {
+ surroundEffectIndex = 0x7F;
+ } else {
+ surroundEffectIndex = (s8)((-projectedPos->z / 100.0f) * 64.0f) + 0x3F;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1348.s")
+ // calculating pan from left-right screen position
+ if (projectedPos->x > 0.0f) {
+ if (projectedPos->x > 200.0f) {
+ pan = 0x6C;
+ } else {
+ pan = (s8)((projectedPos->x / 200.0f) * 45.0f) + 0x3F;
+ }
+ } else {
+ if (projectedPos->x < -200.0f) {
+ pan = 0x14;
+ } else {
+ pan = (s8)(((projectedPos->x + 200.0f) / 200.0f) * 44.0f) + 0x14;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A13BC.s")
+ // Calculate weighted volume
+ dist = SEQ_SCREEN_WEIGHTED_DIST(projectedPos);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A153C.s")
+ if (dist > maxDist) {
+ volume = minVolume;
+ } else if (dist < minDist) {
+ volume = 1.0f;
+ } else {
+ volume = (((maxDist - dist) / (maxDist - minDist)) * (1.0f - minVolume)) + minVolume;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A17F4.s")
+ AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(seqPlayerIndex, 0xFFFF);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1904.s")
+ if (flags & 1) {
+ AUDIOCMD_CHANNEL_SET_SURROUND_EFFECT_INDEX(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, surroundEffectIndex);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A10.s")
+ if (flags & 2) {
+ AUDIOCMD_CHANNEL_SET_PAN(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, pan);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A8C.s")
+ if (flags & 4) {
+ AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x7F);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1D44.s")
+ // applies filter, stores result in sSequenceFilter
+ if (flags & 8) {
+ // Uses new filter gBandPassFilterData
+ AUDIOCMD_CHANNEL_SET_FILTER(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x54,
+ ((u32)&sSequenceFilter[0] & ~0xF) + 0x10);
+ } else {
+ // Identity Filter
+ AUDIOCMD_CHANNEL_SET_FILTER(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0, ((u32)&sSequenceFilter[0] & ~0xF) + 0x10);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1DB8.s")
+ if (flags & 0x10) {
+ AUDIOCMD_CHANNEL_SET_GAIN(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x7F);
+ } else {
+ AUDIOCMD_CHANNEL_SET_GAIN(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1E0C.s")
+ if (flags & 0x20) {
+ AUDIOCMD_CHANNEL_SET_VOL_SCALE(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, maxVolume * volume);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F00.s")
+ if (flags & 0x40) {
+ AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 0x40);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F88.s")
+ if (flags & 0x80) {
+ AUDIOCMD_CHANNEL_SET_REVERB_INDEX(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 1);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1FB4.s")
+ if (flags & 0x100) {
+ AUDIOCMD_CHANNEL_SET_REVERB_VOLUME(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, 55);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2090.s")
+// ======== BEGIN Z_OBJ_SOUND FUNCTIONS ========
+
+/**
+ * Used for Main Bgm and Fanfares
+ */
+void Audio_UpdateObjSoundProperties(void) {
+ if (sObjSoundPlayerIndex != SEQ_PLAYER_INVALID) {
+ if ((AudioSeq_GetActiveSeqId(sObjSoundPlayerIndex) != NA_BGM_FINAL_HOURS) &&
+ AudioSeq_IsSeqCmdNotQueued((sObjSoundPlayerIndex << 24) + NA_BGM_FINAL_HOURS,
+ SEQCMD_OP_MASK | SEQCMD_ASYNC_ACTIVE | SEQCMD_SEQPLAYER_MASK |
+ SEQCMD_SEQID_MASK) &&
+ !sIsFinalHoursOrSoaring) {
+ Audio_SetSequenceProperties(sObjSoundPlayerIndex, &sObjSoundPos, sObjSoundFlags, sObjSoundMinDist,
+ sObjSoundMaxDist, sObjSoundMaxVol, sObjSoundMinVol);
+ }
+ sObjSoundPlayerIndex = SEQ_PLAYER_INVALID;
+ }
+}
+
+/**
+ * Used for Main Bgm and Fanfares
+ */
+void Audio_SetObjSoundProperties(u8 seqPlayerIndex, Vec3f* pos, s16 flags, f32 minDist, f32 maxDist, f32 maxVolume,
+ f32 minVolume) {
+ sObjSoundPlayerIndex = seqPlayerIndex;
+ sObjSoundPos.x = pos->x;
+ sObjSoundPos.y = pos->y;
+ sObjSoundPos.z = pos->z;
+ sObjSoundFlags = flags;
+ sObjSoundMinDist = minDist;
+ sObjSoundMaxDist = maxDist;
+ sObjSoundMaxVol = maxVolume;
+ sObjSoundMinVol = minVolume;
+}
+
+void Audio_StartObjSoundFanfare(u8 seqPlayerIndex, Vec3f* pos, s8 seqId, u16 seqIdOffset) {
+ s32 pad[3];
+ u32 mask;
+
+ if ((AudioSeq_GetActiveSeqId(seqPlayerIndex) == NA_BGM_FINAL_HOURS) ||
+ !AudioSeq_IsSeqCmdNotQueued((seqPlayerIndex << 0x18) + NA_BGM_FINAL_HOURS,
+ SEQCMD_OP_MASK | SEQCMD_ASYNC_ACTIVE | SEQCMD_SEQPLAYER_MASK | SEQCMD_SEQID_MASK) ||
+ sIsFinalHoursOrSoaring) {
+ sIsFinalHoursOrSoaring = true;
+ } else if (pos != NULL) {
+ if ((seqId != (s8)(AudioSeq_GetActiveSeqId(seqPlayerIndex) & 0xFFFF)) &&
+ !gAudioCtx.seqPlayers[seqPlayerIndex].enabled && (sObjSoundMainBgmSeqId == NA_BGM_GENERAL_SFX)) {
+
+ mask = 0xFFFF;
+
+ SEQCMD_PLAY_SEQUENCE(seqPlayerIndex, ((((AudioThread_NextRandom() % 30) & 0xFF) + 1)),
+ ((seqId & mask) + seqIdOffset));
+ sObjSoundMainBgmSeqId = seqId;
+ }
+
+ Audio_SetObjSoundProperties(seqPlayerIndex, pos, 0x7F, 320.0f, 1280.0f, 1.0f, 0.0f);
+ } else {
+ SEQCMD_STOP_SEQUENCE(seqPlayerIndex, 5);
+ }
+}
+
+void Audio_PlayObjSoundBgm(Vec3f* pos, s8 seqId) {
+ s32 pad[2];
+ u16 sp36;
+ s32 sp2C;
+ u16 seqId0 = AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN);
+ u32 temp_a0;
+
+ if ((seqId0 == NA_BGM_FINAL_HOURS) ||
+ !AudioSeq_IsSeqCmdNotQueued(NA_BGM_FINAL_HOURS,
+ SEQCMD_OP_MASK | SEQCMD_ASYNC_ACTIVE | SEQCMD_SEQPLAYER_MASK | SEQCMD_SEQID_MASK) ||
+ sIsFinalHoursOrSoaring) {
+ sIsFinalHoursOrSoaring = true;
+ return;
+ }
+
+ if (seqId0 == NA_BGM_SONG_OF_SOARING) {
+ sIsFinalHoursOrSoaring = true;
+ }
+
+ if (pos != NULL) {
+ if (seqId == NA_BGM_ASTRAL_OBSERVATORY) {
+
+ if ((seqId != (u8)(seqId0 & 0xFF)) && !sAllPlayersMutedExceptSystemAndOcarina) {
+ SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, (u16)seqId);
+ sObjSoundMainBgmSeqId = seqId;
+ } else if ((seqId == (u8)(seqId0 & 0xFF)) && (sObjSoundMainBgmSeqId == NA_BGM_GENERAL_SFX)) {
+ sObjSoundMainBgmSeqId = seqId;
+ }
+
+ Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x20, 100.0f, 1500.0f, 0.9f, 0.0f);
+ } else {
+ if (sObjSoundMainBgmSeqId == NA_BGM_GENERAL_SFX) {
+ temp_a0 = ((((AudioThread_NextRandom() % 30) & 0xFF) + 1) << 0x10) | ((u16)seqId + 0x7F00);
+ SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, temp_a0);
+ sObjSoundMainBgmSeqId = seqId;
+ }
+
+ if (seqId == NA_BGM_MILK_BAR_DUPLICATE) {
+ Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x1E3, 0.0f, 600.0f, 0.9f, 0.55f);
+ } else if (seqId == NA_BGM_MILK_BAR) {
+ Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x1FF, 0.0f, 600.0f, 0.9f, 0.55f);
+ } else {
+ Audio_SetObjSoundProperties(SEQ_PLAYER_BGM_MAIN, pos, 0x3F, 0.0f, 600.0f, 0.9f, 0.55f);
+ }
+ }
+ } else {
+ if (sObjSoundMainBgmSeqId == NA_BGM_ASTRAL_OBSERVATORY) {
+ AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(SEQ_PLAYER_BGM_MAIN, 0xFFFF);
+ AUDIOCMD_CHANNEL_SET_VOL_SCALE(SEQ_PLAYER_BGM_MAIN, AUDIOCMD_ALL_CHANNELS, 1.0f);
+ SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 10, NA_BGM_CAVERN);
+ } else {
+ SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 5);
+ }
+
+ sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX;
+ }
+}
+
+void Audio_PlayObjSoundFanfare(Vec3f* pos, s8 seqId) {
+ s32 requestFanfare = false;
+ s32 pad;
+
+ if (sObjSoundFanfareSeqId == NA_BGM_GENERAL_SFX) {
+ // No spatial fanfare is currently playing
+ requestFanfare = true;
+ } else if (SEQ_SCREEN_WEIGHTED_DIST(pos) < SEQ_SCREEN_WEIGHTED_DIST(&sObjSoundFanfarePos)) {
+ // The spatial fanfare requested is closer than the spatial fanfare currently playing
+ requestFanfare = true;
+ }
+
+ if (requestFanfare) {
+ sObjSoundFanfarePos.x = pos->x;
+ sObjSoundFanfarePos.y = pos->y;
+ sObjSoundFanfarePos.z = pos->z;
+ sObjSoundFanfareSeqId = seqId;
+ sObjSoundFanfareRequested = true;
+ }
+}
+
+void Audio_UpdateObjSoundFanfare(void) {
+ if (sObjSoundFanfareRequested && (sAudioPauseState == AUDIO_PAUSE_STATE_CLOSED)) {
+ if (sObjSoundFanfareSeqId != NA_BGM_GENERAL_SFX) {
+ Audio_StartObjSoundFanfare(SEQ_PLAYER_FANFARE, &sObjSoundFanfarePos, sObjSoundFanfareSeqId, 0);
+
+ if (AudioSeq_GetActiveSeqId(SEQ_PLAYER_FANFARE) == NA_BGM_DISABLED) {
+ func_801A3038();
+ }
+
+ if ((AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) &&
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_AMBIENCE) == NA_BGM_DISABLED)) {
+ Audio_PlayAmbience(AMBIENCE_ID_09);
+ }
+
+ sAudioCutsceneFlag = true;
+ } else {
+ Audio_StartObjSoundFanfare(SEQ_PLAYER_FANFARE, NULL, sObjSoundFanfareSeqId, 0);
+ if (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) {
+ SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, 0);
+ }
+ sObjSoundFanfareRequested = false;
+ sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX;
+ sAudioCutsceneFlag = false;
+ }
+ sObjSoundFanfareSeqId = NA_BGM_GENERAL_SFX;
+ }
+}
+
+// ======== END Z_OBJ_SOUND FUNCTIONS ========
+
+void Audio_StopSequenceAtPos(u8 seqPlayerIndex, u8 volumeFadeTimer) {
+ SEQCMD_STOP_SEQUENCE((u32)seqPlayerIndex, 20);
+ if ((seqPlayerIndex == SEQ_PLAYER_BGM_SUB) && (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED)) {
+ AudioSeq_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, 0x7F, volumeFadeTimer);
+ Audio_SplitBgmChannels(0);
+ }
+}
+
+void Audio_StartSubBgmAtPos(u8 seqPlayerIndex, Vec3f* projectedPos, u8 seqId, u8 flags, f32 minDist, f32 maxDist,
+ f32 arg6) {
+ f32 dist = SEQ_SCREEN_WEIGHTED_DIST(projectedPos);
+ u8 targetVolume;
+ u16 seqId0 = AudioSeq_GetActiveSeqId(seqPlayerIndex);
+ f32 relVolume;
+ s32 pad;
+
+ if (dist > maxDist) {
+ if ((u8)seqId0 == seqId) {
+ Audio_StopSequenceAtPos(seqPlayerIndex, 10);
+ sSpatialSeqIsActive[seqPlayerIndex] = false;
+ }
+ return;
+ }
+
+ if ((!gAudioCtx.seqPlayers[seqPlayerIndex].enabled && !sAllPlayersMutedExceptSystemAndOcarina) ||
+ (seqId0 == (NA_BGM_ENEMY | 0x800))) {
+ if (seqPlayerIndex == SEQ_PLAYER_BGM_SUB) {
+ AudioSeq_SetVolumeScale(seqPlayerIndex, VOL_SCALE_INDEX_BGM_SUB, 0x7F, 1);
+ }
+
+ SEQCMD_PLAY_SEQUENCE((u32)seqPlayerIndex, 1, seqId);
+
+ sSpatialSeqIsActive[seqPlayerIndex] = true;
+ }
+
+ Audio_SetSequenceProperties(seqPlayerIndex, projectedPos, flags, minDist, maxDist, 1.0, 0.05f);
+
+ if ((seqPlayerIndex == SEQ_PLAYER_BGM_SUB) && (gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].enabled == true)) {
+
+ if (dist > maxDist) {
+ relVolume = 1.0f;
+ } else if (dist < minDist) {
+ relVolume = 0.0f;
+ } else {
+ relVolume = 1.0f - ((maxDist - dist) / (maxDist - minDist));
+ }
+
+ targetVolume = (u8)(relVolume * 127.0f);
+
+ AudioSeq_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, targetVolume, 10);
+ Audio_SplitBgmChannels(0x7F - targetVolume);
+ }
+}
+
+/**
+ * sSpatialSeqNoFilterPos takes priority over sSpatialSeqFilterPos
+ * Used only by guru guru for song of storms
+ */
+void Audio_PlaySubBgmAtPos(Vec3f* pos, u8 seqId, f32 maxDist) {
+ if (gAudioSpecId != 0xC) {
+ sSpatialSeqNoFilterPos.x = pos->x;
+ sSpatialSeqNoFilterPos.y = pos->y;
+ sSpatialSeqNoFilterPos.z = pos->z;
+ sSpatialSeqSeqId = seqId;
+ sSpatialSeqMaxDist = maxDist;
+ sSpatialSeqFlags |= 2; // Only update volume
+ sSpatialSubBgmFadeTimer = 4;
+ }
+}
+
+// Used only by guru guru for song of storms in stock pot from hallway or neighboring room
+void Audio_PlaySubBgmAtPosWithFilter(Vec3f* pos, u8 seqId, f32 maxDist) {
+ sSpatialSeqFilterPos.x = pos->x;
+ sSpatialSeqFilterPos.y = pos->y;
+ sSpatialSeqFilterPos.z = pos->z;
+ sSpatialSeqSeqId = seqId;
+ //! @bug Did not set sSpatialSeqMaxDist = maxDist; This will use the previously set value of sSpatialSeqMaxDist
+ sSpatialSeqFlags |= 1; // Update with volume and filter
+ sSpatialSubBgmFadeTimer = 4;
+}
+
+// Another bgm by pos, less customization
+void Audio_UpdateSubBgmAtPos(void) {
+ if (sSpatialSubBgmFadeTimer != 0) {
+ if (sSpatialSeqFlags & 2) {
+ // Affects only volume
+ Audio_StartSubBgmAtPos(SEQ_PLAYER_BGM_SUB, &sSpatialSeqNoFilterPos, sSpatialSeqSeqId, 0x20, 100.0f,
+ sSpatialSeqMaxDist, 1.0f);
+ } else {
+ // Set volume with band-pass filter
+ Audio_StartSubBgmAtPos(SEQ_PLAYER_BGM_SUB, &sSpatialSeqFilterPos, sSpatialSeqSeqId, 0x28, 100.0f,
+ sSpatialSeqMaxDist, 1.0f);
+ }
+
+ sSpatialSubBgmFadeTimer--;
+ if (sSpatialSubBgmFadeTimer == 0) {
+ Audio_StopSequenceAtPos(SEQ_PLAYER_BGM_SUB, 10);
+ }
+
+ sSpatialSeqFlags = 0;
+ }
+}
+
+/**
+ * Play sequence at the default center of the screen. Does not check for final hours or soaring bgms playing
+ * Used only by minifrog for the frog song
+ */
+void Audio_PlaySequenceAtDefaultPos(u8 seqPlayerIndex, u16 seqId) {
+ if (!sAudioCutsceneFlag && (gAudioSpecId != 0xC)) {
+ sSpatialSeqFilterPos.x = gSfxDefaultPos.x;
+ sSpatialSeqFilterPos.y = gSfxDefaultPos.y;
+ sSpatialSeqFilterPos.z = gSfxDefaultPos.z;
+ sSpatialSeqMaxDist = 10000.0f;
+ sSpatialSeqFadeTimer = 128;
+ sSpatialSeqSeqId = seqId;
+ sSpatialSeqPlayerIndex = seqPlayerIndex;
+ }
+}
+
+// Used only by minifrog
+void Audio_StopSequenceAtDefaultPos(void) {
+ if (gAudioSpecId != 0xC) {
+ sSpatialSeqFadeTimer = 1;
+ sSpatialSeqSeqId = NA_BGM_GENERAL_SFX;
+ }
+}
+
+/**
+ * Play the requested sequence at a position. Valid for sequences on players 0 - 3
+ */
+void Audio_PlaySequenceAtPos(u8 seqPlayerIndex, Vec3f* pos, u16 seqId, f32 maxDist) {
+ if ((!sAudioCutsceneFlag) && ((AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) & 0xFF) != NA_BGM_SONG_OF_SOARING) &&
+ (gAudioSpecId != 0xC) && (pos != NULL) &&
+ ((sSpatialSeqPlayerIndex != SEQ_PLAYER_BGM_MAIN) ||
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_FINAL_HOURS))) {
+ sSpatialSeqFilterPos.x = pos->x;
+ sSpatialSeqFilterPos.y = pos->y;
+ sSpatialSeqFilterPos.z = pos->z;
+ sSpatialSeqMaxDist = maxDist;
+ sSpatialSeqFadeTimer = 2;
+ sSpatialSeqSeqId = seqId & 0xFF;
+ sSpatialSeqPlayerIndex = seqPlayerIndex;
+ }
+}
+
+void Audio_UpdateSequenceAtPos(void) {
+ u16 mainBgmSeqId = AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN);
+ u8 volumeFadeTimer;
+
+ if ((sSpatialSeqFadeTimer != 0) && (sAudioPauseState == AUDIO_PAUSE_STATE_CLOSED)) {
+ if ((sSpatialSeqSeqId == NA_BGM_GENERAL_SFX) || (mainBgmSeqId == NA_BGM_SONG_OF_SOARING)) {
+ volumeFadeTimer = 10;
+
+ if (mainBgmSeqId == NA_BGM_SONG_OF_SOARING) {
+ sSpatialSeqFadeTimer = 0;
+ volumeFadeTimer = 1;
+ } else if (sSpatialSeqFadeTimer < 128) {
+ sSpatialSeqFadeTimer--;
+ }
+
+ if (sSpatialSeqFadeTimer == 0) {
+ Audio_StopSequenceAtPos(sSpatialSeqPlayerIndex, volumeFadeTimer);
+ sSpatialSeqIsActive[sSpatialSeqPlayerIndex] = false;
+ }
+ } else {
+ if ((sSpatialSeqPlayerIndex == SEQ_PLAYER_BGM_MAIN) && (mainBgmSeqId == NA_BGM_FINAL_HOURS)) {
+ Audio_StopSequenceAtPos(sSpatialSeqPlayerIndex, 10);
+ sSpatialSeqIsActive[sSpatialSeqPlayerIndex] = false;
+ return;
+ }
+
+ Audio_StartSubBgmAtPos(sSpatialSeqPlayerIndex, &sSpatialSeqFilterPos, sSpatialSeqSeqId, 0x20, 200.0f,
+ sSpatialSeqMaxDist, 1.0f);
+ if (!sSpatialSeqIsActive[sSpatialSeqPlayerIndex]) {
+ sSpatialSeqFadeTimer = 0;
+ }
+ }
+
+ if (sSpatialSeqFadeTimer < 128) {
+ sSpatialSeqSeqId = NA_BGM_GENERAL_SFX;
+ }
+ }
+}
/**
* Unused remnant of OoT's EnRiverSound
@@ -5408,7 +5837,7 @@ void Audio_StartSfxPlayer(void) {
void Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(u8 volume) {
u8 channelIndex;
- if (!sAllPlayersMutedExceptOcaAndSys) {
+ if (!sAllPlayersMutedExceptSystemAndOcarina) {
for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) {
switch (channelIndex) {
case SFX_CHANNEL_SYSTEM0:
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index eb5ba018d..b48484687 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -728,7 +728,7 @@ void Target_Update(TargetContext* targetCtx, Player* player, Actor* lockOnActor,
* Tests if a current scene switch flag is set.
*/
s32 Flags_GetSwitch(PlayState* play, s32 flag) {
- if ((flag >= 0) && (flag < 0x80)) {
+ if ((flag > SWITCH_FLAG_NONE) && (flag < 0x80)) {
return play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F));
}
return 0;
@@ -738,7 +738,7 @@ s32 Flags_GetSwitch(PlayState* play, s32 flag) {
* Sets a current scene switch flag.
*/
void Flags_SetSwitch(PlayState* play, s32 flag) {
- if ((flag >= 0) && (flag < 0x80)) {
+ if ((flag > SWITCH_FLAG_NONE) && (flag < 0x80)) {
play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F);
}
}
@@ -747,7 +747,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) {
* Unsets a current scene switch flag.
*/
void Flags_UnsetSwitch(PlayState* play, s32 flag) {
- if ((flag >= 0) && (flag < 0x80)) {
+ if ((flag > SWITCH_FLAG_NONE) && (flag < 0x80)) {
play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] &= ~(1 << (flag & 0x1F));
}
}
@@ -2767,11 +2767,11 @@ void Actor_UpdateFlaggedAudio(Actor* actor) {
if (sfxId != NA_SE_NONE) {}
if (actor->audioFlags & ACTOR_AUDIO_FLAG_SEQ_MUSIC_BOX_HOUSE) {
- func_801A1FB4(SEQ_PLAYER_BGM_SUB, &actor->projectedPos, NA_BGM_MUSIC_BOX_HOUSE, 1500.0f);
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &actor->projectedPos, NA_BGM_MUSIC_BOX_HOUSE, 1500.0f);
}
if (actor->audioFlags & ACTOR_AUDIO_FLAG_SEQ_KAMARO_DANCE) {
- func_801A1FB4(SEQ_PLAYER_BGM_MAIN, &actor->projectedPos, NA_BGM_KAMARO_DANCE, 900.0f);
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_MAIN, &actor->projectedPos, NA_BGM_KAMARO_DANCE, 900.0f);
}
}
diff --git a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c
index 18063efce..cbeea4911 100644
--- a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c
+++ b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c
@@ -74,7 +74,7 @@ void BgF40Switch_CheckAll(BgF40Switch* this, PlayState* play) {
}
if (actorAsSwitch->isPressed) {
switchFlag = BGF40SWITCH_GET_SWITCH_FLAG(&actorAsSwitch->dyna.actor);
- if ((switchFlag >= 0) && (switchFlag < 0x80)) {
+ if ((switchFlag > SWITCH_FLAG_NONE) && (switchFlag < 0x80)) {
pressedSwitchFlags[(switchFlag & ~0x1F) >> 5] |= 1 << (switchFlag & 0x1F);
if (!actorAsSwitch->wasPressed && (actorAsSwitch->actionFunc == BgF40Switch_IdleUnpressed) &&
!Flags_GetSwitch(play, switchFlag)) {
@@ -88,7 +88,7 @@ void BgF40Switch_CheckAll(BgF40Switch* this, PlayState* play) {
if ((actor->id == ACTOR_BG_F40_SWITCH) && (actor->room == this->dyna.actor.room) &&
(actor->update != NULL)) {
switchFlag = BGF40SWITCH_GET_SWITCH_FLAG(actor);
- if ((switchFlag >= 0) && (switchFlag < 0x80) && Flags_GetSwitch(play, switchFlag) &&
+ if ((switchFlag > SWITCH_FLAG_NONE) && (switchFlag < 0x80) && Flags_GetSwitch(play, switchFlag) &&
!(pressedSwitchFlags[(switchFlag & ~0x1F) >> 5] & (1 << (switchFlag & 0x1F)))) {
Flags_UnsetSwitch(play, switchFlag);
}
diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c
index 6c7d32152..0370023a8 100644
--- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c
+++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c
@@ -21,8 +21,17 @@ void DoorSpiral_Destroy(Actor* thisx, PlayState* play);
void DoorSpiral_Update(Actor* thisx, PlayState* play);
void DoorSpiral_Draw(Actor* thisx, PlayState* play);
-/*
-const ActorInit Door_Spiral_InitVars = {
+void DoorSpiral_SetupAction(DoorSpiral* this, DoorSpiralActionFunc actionFunc);
+s32 func_809A2B70(DoorSpiral* this, PlayState* play);
+u8 func_809A2BF8(PlayState* play);
+f32 func_809A2E08(PlayState* play, DoorSpiral* this, f32 arg2, f32 arg3, f32 arg4);
+void func_809A2DB0(DoorSpiral* this, PlayState* play);
+void func_809A2FF8(DoorSpiral* this, PlayState* play);
+void func_809A2DB0(DoorSpiral* this, PlayState* play);
+void func_809A3098(DoorSpiral* this, PlayState* play);
+s32 func_809A2EA0(DoorSpiral* this, PlayState* play);
+
+ActorInit Door_Spiral_InitVars = {
ACTOR_DOOR_SPIRAL,
ACTORCAT_DOOR,
FLAGS,
@@ -31,30 +40,223 @@ const ActorInit Door_Spiral_InitVars = {
(ActorFunc)DoorSpiral_Init,
(ActorFunc)DoorSpiral_Destroy,
(ActorFunc)DoorSpiral_Update,
- (ActorFunc)DoorSpiral_Draw
+ (ActorFunc)DoorSpiral_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2B60.s")
+typedef struct {
+ /* 0x0 */ Gfx* dLists[2]; // represents a staircase up or down
+ /* 0x8 */ u32 unk_08;
+ /* 0x9 */ u8 unk_09;
+ /* 0xA */ u8 translateZ;
+ /* 0xB */ u8 unk_0B;
+ /* 0xC */ u8 unk_0C;
+} SpiralInfo; // size = 0x10
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2B70.s")
+SpiralInfo sSpiralInfoTable[] = {
+ { { NULL, NULL }, 0, 130, 12, 50, 15 },
+ { { gameplay_dangeon_keep_DL_0219E0, gameplay_dangeon_keep_DL_01D980 }, 0, 130, 12, 50, 15 },
+ { { object_numa_obj_DL_004448, object_numa_obj_DL_0007A8 }, 0, 130, 12, 50, 15 },
+ { { object_numa_obj_DL_0051B8, object_numa_obj_DL_0014C8 }, 0, 130, 12, 50, 15 },
+ { { object_hakugin_obj_DL_009278, object_hakugin_obj_DL_006128 }, 0, 130, 12, 50, 15 },
+ { { object_ikana_obj_DL_013EA8, object_ikana_obj_DL_012B70 }, 0, 130, 12, 50, 15 },
+ { { object_ikninside_obj_DL_000EA0, object_ikninside_obj_DL_000590 }, 0, 130, 12, 50, 15 },
+ { { object_danpei_object_DL_002110, object_danpei_object_DL_0012C0 }, 0, 130, 12, 50, 15 },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2BF8.s")
+typedef struct {
+ /* 0x0 */ s16 objectId;
+ /* 0x2 */ u8 index;
+} SpiralObjectInfo; // size = 0x4
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Init.s")
+SpiralObjectInfo sSpiralObjectInfoTable[] = {
+ { GAMEPLAY_KEEP, 0 }, { GAMEPLAY_DANGEON_KEEP, 1 }, { OBJECT_NUMA_OBJ, 2 }, { OBJECT_HAKUGIN_OBJ, 4 },
+ { OBJECT_IKANA_OBJ, 5 }, { OBJECT_DANPEI_OBJECT, 7 }, { OBJECT_IKNINSIDE_OBJ, 6 },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Destroy.s")
+typedef struct {
+ /* 0x0 */ s16 sceneId;
+ /* 0x2 */ u8 index;
+} SpiralSceneInfo; // size = 0x4
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2DB0.s")
+SpiralSceneInfo sSpiralSceneInfoTable[] = {
+ { SCENE_MITURIN, 2 }, { SCENE_HAKUGIN, 3 }, { SCENE_INISIE_N, 4 }, { SCENE_INISIE_R, 4 },
+ { SCENE_DANPEI2TEST, 5 }, { SCENE_IKNINSIDE, 6 }, { SCENE_CASTLE, 6 },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2E08.s")
+static InitChainEntry sInitChain[] = {
+ ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2EA0.s")
+void DoorSpiral_SetupAction(DoorSpiral* this, DoorSpiralActionFunc actionFunc) {
+ this->actionFunc = actionFunc;
+ this->unk14A = 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A2FF8.s")
+s32 func_809A2B70(DoorSpiral* this, PlayState* play) {
+ SpiralObjectInfo* spiralObjectInfo = &sSpiralObjectInfoTable[this->unk147];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/func_809A3098.s")
+ this->unk148 = spiralObjectInfo->index;
+ if ((this->unk148 == 7) || ((this->unk148 == 2) && play->roomCtx.curRoom.enablePosLights)) {
+ if (this->unk148 == 2) {
+ this->unk148 = 3;
+ }
+ this->actor.flags |= ACTOR_FLAG_10000000;
+ }
+ DoorSpiral_SetupAction(this, func_809A2FF8);
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Update.s")
+u8 func_809A2BF8(PlayState* play) {
+ SpiralSceneInfo* spiralSceneInfo = sSpiralSceneInfoTable;
+ s32 i;
+ u8 var_v1;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Spiral/DoorSpiral_Draw.s")
+ for (i = 0; i < ARRAY_COUNT(sSpiralSceneInfoTable); i++) {
+ if (play->sceneId == spiralSceneInfo->sceneId) {
+ break;
+ }
+ spiralSceneInfo++;
+ }
+ if (i < ARRAY_COUNT(sSpiralSceneInfoTable)) {
+ var_v1 = spiralSceneInfo->index;
+ } else {
+ var_v1 = (Object_GetSlot(&play->objectCtx, GAMEPLAY_DANGEON_KEEP) > OBJECT_SLOT_NONE) ? 1 : 0;
+ }
+ return var_v1;
+}
+
+void DoorSpiral_Init(Actor* thisx, PlayState* play) {
+ DoorSpiral* this = THIS;
+ s32 transitionId = DOOR_GET_TRANSITION_ID(thisx);
+ s8 objectSlot;
+
+ if (this->actor.room != play->doorCtx.transitionActorList[transitionId].sides[0].room) {
+ Actor_Kill(&this->actor);
+ return;
+ }
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ this->type = DOORSPIRAL_GET_TYPE(thisx);
+ this->direction = DOORSPIRAL_GET_DIRECTION(thisx);
+ this->unk147 = func_809A2BF8(play);
+ objectSlot = Object_GetSlot(&play->objectCtx, sSpiralObjectInfoTable[this->unk147].objectId);
+ this->objectSlot = objectSlot;
+ if (objectSlot <= OBJECT_SLOT_NONE) {
+ Actor_Kill(&this->actor);
+ return;
+ }
+ DoorSpiral_SetupAction(this, func_809A2DB0);
+ Actor_SetFocus(&this->actor, 60.0f);
+}
+
+void DoorSpiral_Destroy(Actor* thisx, PlayState* play) {
+ s32 transitionId = DOOR_GET_TRANSITION_ID(thisx);
+
+ play->doorCtx.transitionActorList[transitionId].id = -play->doorCtx.transitionActorList[transitionId].id;
+}
+
+void func_809A2DB0(DoorSpiral* this, PlayState* play) {
+ if (Object_IsLoaded(&play->objectCtx, this->objectSlot)) {
+ this->actor.objectSlot = this->objectSlot;
+ func_809A2B70(this, play);
+ }
+}
+
+f32 func_809A2E08(PlayState* play, DoorSpiral* this, f32 arg2, f32 arg3, f32 arg4) {
+ Player* player = GET_PLAYER(play);
+ Vec3f point;
+ Vec3f offset;
+
+ point.x = player->actor.world.pos.x;
+ point.y = player->actor.world.pos.y + arg2;
+ point.z = player->actor.world.pos.z;
+
+ Actor_OffsetOfPointInActorCoords(&this->actor, &offset, &point);
+
+ if ((arg3 < fabsf(offset.x)) || (arg4 < fabsf(offset.y))) {
+ return FLT_MAX;
+ } else {
+ return offset.z;
+ }
+}
+
+s32 func_809A2EA0(DoorSpiral* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ if (!Player_InCsMode(play)) {
+ SpiralInfo* spiralInfo = &sSpiralInfoTable[this->unk148];
+ f32 temp_fv0 = func_809A2E08(play, this, 0.0f, spiralInfo->unk_0B, spiralInfo->unk_0C);
+
+ if (fabsf(temp_fv0) < 64.0f) {
+ s16 var_v0 = player->actor.shape.rot.y - this->actor.shape.rot.y;
+
+ if (temp_fv0 > 0.0f) {
+ var_v0 = 0x8000 - var_v0;
+ }
+ if (ABS_ALT(var_v0) < 0x3000) {
+ return (temp_fv0 >= 0.0f) ? 1.0f : -1.0f;
+ }
+ }
+ }
+ return 0;
+}
+
+void func_809A2FF8(DoorSpiral* this, PlayState* play) {
+ Player* player;
+ u32 transitionId;
+
+ if (this->shouldClimb) {
+ DoorSpiral_SetupAction(this, func_809A3098);
+ } else if (func_809A2EA0(this, play) != 0) {
+ player = GET_PLAYER(play);
+ player->doorType = PLAYER_DOORTYPE_STAIRCASE;
+ player->doorDirection = this->direction;
+ player->doorActor = &this->actor;
+ transitionId = DOOR_GET_TRANSITION_ID(&this->actor);
+ player->doorNext = (play->doorCtx.transitionActorList[transitionId].params >> 0xA);
+ func_80122F28(player);
+ }
+}
+
+void func_809A3098(DoorSpiral* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ if (!(player->stateFlags1 & PLAYER_STATE1_20000000)) {
+ DoorSpiral_SetupAction(this, func_809A2DB0);
+ this->shouldClimb = false;
+ }
+}
+
+void DoorSpiral_Update(Actor* thisx, PlayState* play) {
+ DoorSpiral* this = THIS;
+ Player* player = GET_PLAYER(play);
+
+ if (!(player->stateFlags1 & (PLAYER_STATE1_40 | PLAYER_STATE1_80 | PLAYER_STATE1_400 | PLAYER_STATE1_10000000)) ||
+ (this->actionFunc == func_809A2DB0)) {
+ this->actionFunc(this, play);
+ }
+}
+
+void DoorSpiral_Draw(Actor* thisx, PlayState* play) {
+ s32 pad;
+ DoorSpiral* this = THIS;
+
+ if (this->actor.objectSlot == this->objectSlot) {
+ SpiralInfo* spiralInfo = &sSpiralInfoTable[this->unk148];
+ Gfx* dList = spiralInfo->dLists[this->direction];
+
+ if (dList != NULL) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL25_Opa(play->state.gfxCtx);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_OPA_DISP++, spiralInfo->dLists[this->direction]);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+}
diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h
index af4f27aea..6d9aac7e6 100644
--- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h
+++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h
@@ -2,13 +2,25 @@
#define Z_DOOR_SPIRAL_H
#include "global.h"
+#include "z64door.h"
struct DoorSpiral;
+typedef void (*DoorSpiralActionFunc)(struct DoorSpiral*, PlayState*);
+
+#define DOORSPIRAL_GET_TYPE(thisx) (((thisx)->params >> 8) & 0x3)
+#define DOORSPIRAL_GET_DIRECTION(thisx) (((thisx)->params >> 7) & 0x1)
+
typedef struct DoorSpiral {
/* 0x000 */ Actor actor;
/* 0x144 */ u8 shouldClimb;
- /* 0x145 */ UNK_TYPE1 unk_145[0xB];
+ /* 0x145 */ s8 type;
+ /* 0x146 */ u8 direction; // represents a staircase up or down
+ /* 0x147 */ u8 unk147;
+ /* 0x148 */ u8 unk148;
+ /* 0x149 */ s8 objectSlot;
+ /* 0x14A */ s8 unk14A;
+ /* 0x14C */ DoorSpiralActionFunc actionFunc;
} DoorSpiral; // size = 0x150
#endif // Z_DOOR_SPIRAL_H
diff --git a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c
index f2089ca03..eb1d5761e 100644
--- a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c
+++ b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c
@@ -40,8 +40,8 @@ void ElfMsg_SetupAction(ElfMsg* this, ElfMsgActionFunc actionFunc) {
}
s32 func_8092DF9C(ElfMsg* this, PlayState* play) {
- if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) &&
- (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) {
+ if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) &&
+ Flags_GetSwitch(play, this->actor.home.rot.y - 1)) {
(void)"共倒れ"; // "Collapse together"
if (ELFMSG_GET_SWITCH_FLAG(&this->actor) != 0x7F) {
Flags_SetSwitch(play, ELFMSG_GET_SWITCH_FLAG(&this->actor));
@@ -144,7 +144,7 @@ void ElfMsg_Update(Actor* thisx, PlayState* play) {
}
if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) ||
- (Flags_GetSwitch(play, -1 - this->actor.home.rot.y))) {
+ Flags_GetSwitch(play, -1 - this->actor.home.rot.y)) {
this->actionFunc(this, play);
}
}
diff --git a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c
index 552478ace..409202468 100644
--- a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c
+++ b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c
@@ -40,8 +40,8 @@ void ElfMsg2_SetupAction(ElfMsg2* this, ElfMsg2ActionFunc actionFunc) {
}
s32 func_8096EC4C(ElfMsg2* this, PlayState* play) {
- if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) &&
- (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) {
+ if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) &&
+ Flags_GetSwitch(play, this->actor.home.rot.y - 1)) {
(void)"共倒れ"; // "Collapse together"
if (ELFMSG2_GET_SWITCH_FLAG(&this->actor) != 0x7F) {
Flags_SetSwitch(play, ELFMSG2_GET_SWITCH_FLAG(&this->actor));
@@ -135,7 +135,7 @@ void func_8096EF98(ElfMsg2* this, PlayState* play) {
void func_8096EFD0(ElfMsg2* this, PlayState* play) {
if ((this->actor.home.rot.y < 0) && (this->actor.home.rot.y >= -0x80) &&
- (Flags_GetSwitch(play, -this->actor.home.rot.y - 1))) {
+ Flags_GetSwitch(play, -this->actor.home.rot.y - 1)) {
ElfMsg2_SetupAction(this, func_8096EF98);
this->actor.flags |= (ACTOR_FLAG_40000 | ACTOR_FLAG_TARGETABLE);
this->actor.textId = func_8096EE50(this);
diff --git a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c
index b7b349dfe..ba8256361 100644
--- a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c
+++ b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c
@@ -39,8 +39,8 @@ void ElfMsg3_SetupAction(ElfMsg3* this, ElfMsg3ActionFunc actionFunc) {
}
s32 func_80A2CD1C(ElfMsg3* this, PlayState* play) {
- if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) &&
- (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) {
+ if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) &&
+ Flags_GetSwitch(play, this->actor.home.rot.y - 1)) {
(void)"共倒れ"; // "Collapse together"
if (ELFMSG3_GET_SWITCH_FLAG(&this->actor) != 0x7F) {
Flags_SetSwitch(play, ELFMSG3_GET_SWITCH_FLAG(&this->actor));
@@ -142,7 +142,7 @@ void ElfMsg3_Update(Actor* thisx, PlayState* play) {
}
if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) ||
- (Flags_GetSwitch(play, -1 - this->actor.home.rot.y))) {
+ Flags_GetSwitch(play, -1 - this->actor.home.rot.y)) {
this->actionFunc(this, play);
}
}
diff --git a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c
index 423f8c351..5f1f0d3dc 100644
--- a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c
+++ b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c
@@ -40,8 +40,8 @@ static InitChainEntry sInitChain[] = {
};
s32 func_80AFD380(ElfMsg4* this, PlayState* play) {
- if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) &&
- (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) {
+ if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) &&
+ Flags_GetSwitch(play, this->actor.home.rot.y - 1)) {
(void)"共倒れ"; // "Collapse together"
if (ELFMSG4_GET_SWITCH_FLAG(&this->actor) != 0x7F) {
Flags_SetSwitch(play, ELFMSG4_GET_SWITCH_FLAG(&this->actor));
@@ -169,7 +169,7 @@ void ElfMsg4_Update(Actor* thisx, PlayState* play) {
}
if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) ||
- (Flags_GetSwitch(play, -1 - this->actor.home.rot.y))) {
+ Flags_GetSwitch(play, -1 - this->actor.home.rot.y)) {
this->actionFunc(this, play);
}
}
diff --git a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c
index c44ab8e0a..236933fc9 100644
--- a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c
+++ b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c
@@ -35,8 +35,8 @@ static InitChainEntry sInitChainsInitChain[] = {
};
s32 func_80AFD990(ElfMsg5* this, PlayState* play) {
- if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y < 0x81) &&
- (Flags_GetSwitch(play, this->actor.home.rot.y - 1))) {
+ if ((this->actor.home.rot.y > 0) && (this->actor.home.rot.y <= 0x80) &&
+ Flags_GetSwitch(play, this->actor.home.rot.y - 1)) {
(void)"共倒れ"; // Collapse together
if (ELFMSG5_GET_SWITCH_FLAG(&this->actor) != 0x7F) {
Flags_SetSwitch(play, ELFMSG5_GET_SWITCH_FLAG(&this->actor));
@@ -87,7 +87,7 @@ void ElfMsg5_Update(Actor* thisx, PlayState* play) {
ElfMsg5* this = THIS;
if ((this->actor.home.rot.y >= 0) || (this->actor.home.rot.y < -0x80) ||
- (Flags_GetSwitch(play, -this->actor.home.rot.y - 1))) {
+ Flags_GetSwitch(play, -this->actor.home.rot.y - 1)) {
this->actionFunc(this, play);
}
}
diff --git a/src/overlays/actors/ovl_En_Bal/z_en_bal.c b/src/overlays/actors/ovl_En_Bal/z_en_bal.c
index 490517e09..95b495124 100644
--- a/src/overlays/actors/ovl_En_Bal/z_en_bal.c
+++ b/src/overlays/actors/ovl_En_Bal/z_en_bal.c
@@ -864,7 +864,7 @@ void EnBal_TryPurchaseMap(EnBal* this, PlayState* play) {
void EnBal_HandleConversation(EnBal* this, PlayState* play) {
if (((this->textId != 0x1D07) || Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) &&
- (Message_ShouldAdvance(play))) {
+ Message_ShouldAdvance(play)) {
switch (this->textId) {
case 0x1D00:
Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, TINGLE_ANIM_TALK);
diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c
index e754ff5b8..4fa521de3 100644
--- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c
+++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c
@@ -222,7 +222,7 @@ void EnBigpo_Init(Actor* thisx, PlayState* play2) {
this->mainColor.b = 210;
this->mainColor.a = 0; // fully invisible
- if ((this->switchFlag != 0xFF) && (Flags_GetSwitch(play, this->switchFlag))) {
+ if ((this->switchFlag != BIG_POE_SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
}
@@ -756,7 +756,7 @@ void EnBigpo_SetupLanternDrop(EnBigpo* this, PlayState* play) {
void EnBigpo_LanternFalling(EnBigpo* this, PlayState* play) {
if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND || this->actor.floorHeight == BGCHECK_Y_MIN) {
- if (this->switchFlag != 0xFF) {
+ if (this->switchFlag != BIG_POE_SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h
index d5bdaf1e8..6fd0db8a3 100644
--- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h
+++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h
@@ -8,6 +8,10 @@ struct EnBigpo;
typedef void (*EnBigPoActionFunc)(struct EnBigpo*, PlayState*);
+#define BIG_POE_GET_SWITCH_FLAG(thisx) (u8)((thisx)->params >> 0x8)
+
+#define BIG_POE_SWITCH_FLAG_NONE 0xFF
+
typedef enum BigPoeBodyPart {
/* 0 */ BIG_POE_BODYPART_0,
/* 1 */ BIG_POE_BODYPART_1,
@@ -75,6 +79,4 @@ typedef enum EnBigpoType {
/* 5 */ BIG_POE_TYPE_UNK5
} EnBigpoType;
-#define BIG_POE_GET_SWITCH_FLAG(thisx) (u8)((thisx)->params >> 0x8)
-
#endif // Z_EN_BIGPO_H
diff --git a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c
index 1e322650e..90d8673f6 100644
--- a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c
+++ b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c
@@ -97,8 +97,8 @@ void EnDaiku2_Init(Actor* thisx, PlayState* play) {
return;
}
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == ENDAIKU2_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
} else if (Flags_GetSwitch(play, this->switchFlag)) {
this->unk_25C = this->path->count - 1;
func_80BE61D0(this);
@@ -185,7 +185,7 @@ s32 func_80BE64C0(EnDaiku2* this, PlayState* play) {
Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos);
bomb = (EnBom*)Actor_FindNearby(play, &this->actor, -1, ACTORCAT_EXPLOSIVES, BREG(7) + 240.0f);
Math_Vec3f_Copy(&this->actor.world.pos, &sp30);
- if ((this->switchFlag >= 0) && !Flags_GetSwitch(play, this->switchFlag) && (bomb != NULL) &&
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && !Flags_GetSwitch(play, this->switchFlag) && (bomb != NULL) &&
(bomb->actor.id == ACTOR_EN_BOM)) {
if (!bomb->isPowderKeg) {
this->actor.textId = 0x32D3;
@@ -228,7 +228,7 @@ void func_80BE65B4(EnDaiku2* this, PlayState* play) {
}
this->unk_264 = 1.0f;
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->unk_28A = 5;
if (this->animIndex != ENDAIKU2_ANIM_10) {
EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_10);
@@ -251,7 +251,7 @@ void func_80BE66E4(EnDaiku2* this, PlayState* play) {
Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.home.rot.y, 1, 0xBB8, 0x0);
if (sp98 != 2) {
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->unk_28A = 5;
if (this->animIndex != ENDAIKU2_ANIM_10) {
EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_10);
@@ -433,7 +433,7 @@ void func_80BE6EF0(EnDaiku2* this, PlayState* play) {
EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_3);
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->unk_28A = 5;
if (this->animIndex != ENDAIKU2_ANIM_10) {
EnDaiku2_ChangeAnim(this, ENDAIKU2_ANIM_10);
diff --git a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h
index c047b6577..a462d854f 100644
--- a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h
+++ b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.h
@@ -12,6 +12,7 @@ typedef void (*EnDaiku2ActionFunc)(struct EnDaiku2*, PlayState*);
#define ENDAIKU2_GET_PATH_INDEX(thisx) (((thisx)->params >> 7) & 0x3F)
#define ENDAIKU2_GET_8000(thisx) (((thisx)->params >> 15) & 0x1)
+#define ENDAIKU2_SWITCH_FLAG_NONE 0x7F
#define ENDAIKU2_PATH_INDEX_NONE 0x3F
typedef struct EnDaiku2Effect {
diff --git a/src/overlays/actors/ovl_En_Egol/z_en_egol.c b/src/overlays/actors/ovl_En_Egol/z_en_egol.c
index 775a14eb5..9d5c148f9 100644
--- a/src/overlays/actors/ovl_En_Egol/z_en_egol.c
+++ b/src/overlays/actors/ovl_En_Egol/z_en_egol.c
@@ -482,10 +482,10 @@ void EnEgol_Init(Actor* thisx, PlayState* play) {
EYEGORE_SET_SPH_DIM(this->bodyCollider.elements[5], 2100, -300, 0, 37, 1.0f);
this->switchFlag = EYEGORE_GET_SWITCH_FLAG(&this->actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == EYEGORE_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag > -1) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
@@ -1096,7 +1096,7 @@ void EnEgol_Death(EnEgol* this, PlayState* play) {
Play_SetCameraAtEye(play, this->subCamId, &this->subCamEye, &this->subCamAt);
Play_SetCameraFov(play, this->subCamId, this->subCamFov);
if ((this->action == EYEGORE_ACTION_DEAD) && (this->waitTimer == 1)) {
- if (this->switchFlag > -1) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
CutsceneManager_Stop(this->actor.csId);
diff --git a/src/overlays/actors/ovl_En_Egol/z_en_egol.h b/src/overlays/actors/ovl_En_Egol/z_en_egol.h
index 0861ce580..66c828922 100644
--- a/src/overlays/actors/ovl_En_Egol/z_en_egol.h
+++ b/src/overlays/actors/ovl_En_Egol/z_en_egol.h
@@ -12,6 +12,7 @@ typedef void (*EnEgolActionFunc)(struct EnEgol*, PlayState*);
#define EYEGORE_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 6) & 0x7F)
#define EYEGORE_PATH_INDEX_NONE 0x3F
+#define EYEGORE_SWITCH_FLAG_NONE 0x7F
#define EYEGORE_PARAMS(switch, pathIndex) ((((switch) & 0x7F) << 6) | ((pathIndex) & 0x3F))
diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c
index c840c33e1..e56252b43 100644
--- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c
+++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c
@@ -117,11 +117,11 @@ void EnEncount2_Init(Actor* thisx, PlayState* play) {
this->scale = 0.1f;
this->switchFlag = ENCOUNT2_GET_SWITCH_FLAG(&this->dyna.actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == ENCOUNT2_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->dyna.actor);
return;
}
@@ -180,7 +180,7 @@ void EnEncount2_Popped(EnEncount2* this, PlayState* play) {
void EnEncount2_Die(EnEncount2* this, PlayState* play) {
if (this->deathTimer == 0) {
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
Actor_Kill(&this->dyna.actor);
diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h
index 0a9cb1394..12eb62428 100644
--- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h
+++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h
@@ -7,6 +7,10 @@ struct EnEncount2;
typedef void (*EnEncount2ActionFunc)(struct EnEncount2*, PlayState*);
+#define ENCOUNT2_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
+
+#define ENCOUNT2_SWITCH_FLAG_NONE 0x7F
+
typedef struct EnEncount2Effect{
/* 0x00 */ u8 isEnabled;
/* 0x04 */ Vec3f pos;
@@ -33,6 +37,4 @@ typedef struct EnEncount2 {
/* 0x01D0 */ EnEncount2Effect effects[EN_ENCOUNT2_EFFECT_COUNT];
} EnEncount2; // size = 0x2A70
-#define ENCOUNT2_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
-
#endif // Z_EN_ENCOUNT2_H
diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c
index 931e8c6d4..61ff3039f 100644
--- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c
+++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c
@@ -49,10 +49,10 @@ void EnEncount3_Init(Actor* thisx, PlayState* play) {
} else if (this->unk16C > 1000.0f) {
this->unk16C = 1000.0f;
}
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == ENCOUNT3_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
}
this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
@@ -71,7 +71,7 @@ void func_809AD058(EnEncount3* this) {
}
void func_809AD084(EnEncount3* this, PlayState* play) {
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
@@ -94,7 +94,7 @@ void func_809AD084(EnEncount3* this, PlayState* play) {
void func_809AD194(EnEncount3* this, PlayState* play) {
if (this->unk14E == 0) {
this->unk178 = 0.0f;
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
this->actionFunc = func_809AD1EC;
@@ -199,7 +199,7 @@ void EnEncount3_Draw(Actor* thisx, PlayState* play) {
Matrix_Scale(this->unk168, this->unk174, this->unk168, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(POLY_XLU_DISP++, object_big_fwall_DL_0009A0);
+ gSPDisplayList(POLY_XLU_DISP++, gRingOfFireDL);
Matrix_Pop();
CLOSE_DISPS(play->state.gfxCtx);
diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h
index 9e8bd01ad..cd1df694b 100644
--- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h
+++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h
@@ -13,6 +13,8 @@ typedef void (*EnEncount3ActionFunc)(struct EnEncount3*, PlayState*);
#define ENCOUNT3_GET_ROTZ(thisx) ((thisx)->world.rot.z)
+#define ENCOUNT3_SWITCH_FLAG_NONE 0x7F
+
typedef struct EnEncount3 {
/* 0x000 */ Actor actor;
/* 0x144 */ EnEncount3ActionFunc actionFunc;
diff --git a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c
index 077273309..376401ae4 100644
--- a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c
+++ b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c
@@ -43,12 +43,12 @@ void EnEncount4_Init(Actor* thisx, PlayState* play) {
s32 pad;
EnEncount4* this = THIS;
- this->unk_148 = ENENCOUNT4_GET_F000(thisx);
- this->switchFlag = ENENCOUNT4_GET_FLAG(thisx);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ this->unk_148 = ENCOUNT4_GET_F000(thisx);
+ this->switchFlag = ENCOUNT4_GET_SWITCH_FLAG(thisx);
+ if (this->switchFlag == ENCOUNT4_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
@@ -64,7 +64,7 @@ void func_809C3FD8(EnEncount4* this, PlayState* play) {
Actor* actor;
this->unk_14E = 0;
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->timer = 100;
this->actionFunc = func_809C464C;
} else {
@@ -89,7 +89,7 @@ void func_809C4078(EnEncount4* this, PlayState* play) {
s32 i;
EnBsb* captainKeeta = this->captainKeeta;
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->timer = 100;
this->actionFunc = func_809C464C;
} else if (BREG(1) == 0) {
@@ -135,7 +135,7 @@ void func_809C42A8(EnEncount4* this, PlayState* play) {
CollisionPoly* colPoly;
s32 bgId;
- if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->timer = 100;
this->actionFunc = func_809C464C;
@@ -185,12 +185,12 @@ void func_809C42A8(EnEncount4* this, PlayState* play) {
}
void func_809C4598(EnEncount4* this, PlayState* play) {
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
this->timer = 100;
this->actionFunc = func_809C464C;
} else if (this->unk_14E >= 2) {
this->timer = 100;
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
this->actionFunc = func_809C464C;
diff --git a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h
index a692f796a..64dfdff92 100644
--- a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h
+++ b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.h
@@ -10,8 +10,10 @@ struct EnEncount4;
typedef void (*EnEncount4ActionFunc)(struct EnEncount4*, PlayState*);
-#define ENENCOUNT4_GET_FLAG(thisx) ((thisx)->params & 0x7F)
-#define ENENCOUNT4_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF)
+#define ENCOUNT4_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
+#define ENCOUNT4_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF)
+
+#define ENCOUNT4_SWITCH_FLAG_NONE 0x7F
typedef struct EnEncount4 {
/* 0x000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c b/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c
index 92afb3083..b3ae6bbeb 100644
--- a/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c
+++ b/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c
@@ -350,12 +350,12 @@ void EnGuruguru_Update(Actor* thisx, PlayState* play) {
if (this->actor.params == 2) {
if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 100.0f) {
- func_801A1DB8(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f);
+ Audio_PlaySubBgmAtPosWithFilter(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f);
}
return;
}
if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 200.0f) {
- func_801A1D44(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f);
+ Audio_PlaySubBgmAtPos(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f);
}
if (this->unusedTimer != 0) {
this->unusedTimer--;
diff --git a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c
index 48f75aa68..ef88474f8 100644
--- a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c
+++ b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c
@@ -115,11 +115,11 @@ void EnHiddenNuts_Init(Actor* thisx, PlayState* play) {
this->pathIndex = ENHIDDENNUTS_GET_PATH_INDEX(&this->actor);
this->switchFlag = ENHIDDENNUTS_GET_SWITCH_FLAG(&this->actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == ENHIDDENNUTS_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
@@ -411,7 +411,7 @@ void func_80BDBB48(EnHiddenNuts* this, PlayState* play) {
}
void func_80BDBE70(EnHiddenNuts* this, PlayState* play) {
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
EnHiddenNuts_ChangeAnim(this, ENHIDDENNUTS_ANIM_8);
diff --git a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h
index 7df4b5f01..517ade964 100644
--- a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h
+++ b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h
@@ -11,6 +11,7 @@ typedef void (*EnHiddenNutsActionFunc)(struct EnHiddenNuts*, PlayState*);
#define ENHIDDENNUTS_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
#define ENHIDDENNUTS_GET_PATH_INDEX(thisx) (((thisx)->params >> 7) & 0x1F)
+#define ENHIDDENNUTS_SWITCH_FLAG_NONE 0x7F
#define ENHIDDENNUTS_PATH_INDEX_NONE 0x1F
#define ENHIDDENNUTS_PATH_INDEX_NONE_ALT 0x3F
diff --git a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c
index 86cb7235d..e62be0095 100644
--- a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c
+++ b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c
@@ -5,6 +5,7 @@
*/
#include "z_en_hint_skb.h"
+#include "overlays/actors/ovl_En_Part/z_en_part.h"
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10)
@@ -903,12 +904,12 @@ void EnHintSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
Collider_UpdateSpheres(limbIndex, &this->collider);
if ((limbIndex == STALCHILD_LIMB_HEAD) && (this->unk_3E8 & 1) && !(this->unk_3E8 & 2)) {
- Actor_SpawnBodyParts(&this->actor, play, 1, dList);
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList);
this->unk_3E8 |= 2;
} else if ((this->unk_3E8 & 4) && !(this->unk_3E8 & 8) &&
((limbIndex != STALCHILD_LIMB_HEAD) || !(this->unk_3E8 & 1)) &&
(limbIndex != STALCHILD_LIMB_LOWER_JAW)) {
- Actor_SpawnBodyParts(&this->actor, play, 1, dList);
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList);
}
if (this->drawDmgEffTimer != 0) {
diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c
index dcecdac43..a9cf2e351 100644
--- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c
+++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c
@@ -80,7 +80,7 @@ void func_80C2590C(EnInvisibleRuppe* this, PlayState* play) {
break;
}
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
@@ -98,11 +98,11 @@ void EnInvisibleRuppe_Init(Actor* thisx, PlayState* play) {
this->switchFlag = INVISIBLERUPPE_GET_SWITCH_FLAG(&this->actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == INVISIBLERUPPE_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h
index 2257a649a..1e6ae328e 100644
--- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h
+++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h
@@ -10,6 +10,8 @@ typedef void (*EnInvisibleRuppeActionFunc)(struct EnInvisibleRuppe*, PlayState*)
#define INVISIBLERUPPE_GET_3(thisx) ((thisx)->params & 3)
#define INVISIBLERUPPE_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0x1FC) >> 2)
+#define INVISIBLERUPPE_SWITCH_FLAG_NONE 0x7F
+
typedef struct EnInvisibleRuppe {
/* 0x000 */ Actor actor;
/* 0x144 */ ColliderCylinder collider;
diff --git a/src/overlays/actors/ovl_En_Jso/z_en_jso.c b/src/overlays/actors/ovl_En_Jso/z_en_jso.c
index 43a27759f..5d083246a 100644
--- a/src/overlays/actors/ovl_En_Jso/z_en_jso.c
+++ b/src/overlays/actors/ovl_En_Jso/z_en_jso.c
@@ -5,6 +5,9 @@
*/
#include "z_en_jso.h"
+#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
+#include "overlays/actors/ovl_En_Encount3/z_en_encount3.h"
+#include "overlays/actors/ovl_En_Part/z_en_part.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10)
@@ -13,60 +16,135 @@
void EnJso_Init(Actor* thisx, PlayState* play);
void EnJso_Destroy(Actor* thisx, PlayState* play);
void EnJso_Update(Actor* thisx, PlayState* play);
+void EnJso_Draw(Actor* thisx, PlayState* play);
-void func_809ADCB8(EnJso* this, PlayState* play);
-void func_809AE87C(EnJso* this, PlayState* play);
-void func_809AEA08(EnJso* this, PlayState* play);
-void func_809AED00(EnJso* this, PlayState* play);
-void func_809AEDAC(EnJso* this, PlayState* play);
-void func_809AEEC0(EnJso* this, PlayState* play);
-void func_809AF110(EnJso* this, PlayState* play);
-void func_809AF2F8(EnJso* this, PlayState* play);
-void func_809AF3C0(EnJso* this, PlayState* play);
-void func_809AF440(EnJso* this, PlayState* play);
-void func_809AF53C(EnJso* this, PlayState* play);
-void func_809AF714(EnJso* this, PlayState* play);
-void func_809AF7F4(EnJso* this, PlayState* play);
-void func_809AF99C(EnJso* this, PlayState* play);
-void func_809AFAF4(EnJso* this, PlayState* play);
-void func_809AFC10(EnJso* this, PlayState* play);
-void func_809AFE38(EnJso* this, PlayState* play);
+void EnJso_SetupHandleIntroCutscene(EnJso* this);
+void EnJso_HandleIntroCutscene(EnJso* this, PlayState* play);
+void EnJso_Reappear(EnJso* this, PlayState* play);
+void EnJso_SetupCirclePlayer(EnJso* this, PlayState* play);
+void EnJso_CirclePlayer(EnJso* this, PlayState* play);
+void EnJso_Guard(EnJso* this, PlayState* play);
+void EnJso_SetupSpinBeforeAttack(EnJso* this);
+void EnJso_SpinBeforeAttack(EnJso* this, PlayState* play);
+void EnJso_SetupDashAttack(EnJso* this);
+void EnJso_DashAttack(EnJso* this, PlayState* play);
+void EnJso_SetupSlash(EnJso* this, PlayState* play);
+void EnJso_Slash(EnJso* this, PlayState* play);
+void EnJso_SetupWaitAfterSlash(EnJso* this);
+void EnJso_WaitAfterSlash(EnJso* this, PlayState* play);
+void EnJso_SetupKnockedBack(EnJso* this);
+void EnJso_KnockedBack(EnJso* this, PlayState* play);
+void EnJso_SetupCower(EnJso* this);
+void EnJso_Cower(EnJso* this, PlayState* play);
+void EnJso_Stunned(EnJso* this, PlayState* play);
+void EnJso_Damaged(EnJso* this, PlayState* play);
+void EnJso_SetupJumpBack(EnJso* this);
+void EnJso_JumpBack(EnJso* this, PlayState* play);
+void EnJso_Dead(EnJso* this, PlayState* play);
+void EnJso_SetupFallDownAndTalk(EnJso* this, PlayState* play);
+void EnJso_FallDownAndTalk(EnJso* this, PlayState* play);
+void EnJso_TellHint(EnJso* this, PlayState* play);
+void EnJso_BurstIntoFlames(EnJso* this, PlayState* play);
-#if 0
-// static DamageTable sDamageTable = {
-static DamageTable D_809B0F48 = {
- /* Deku Nut */ DMG_ENTRY(0, 0x1),
- /* Deku Stick */ DMG_ENTRY(1, 0xF),
- /* Horse trample */ DMG_ENTRY(0, 0x0),
- /* Explosives */ DMG_ENTRY(1, 0xF),
- /* Zora boomerang */ DMG_ENTRY(1, 0xF),
- /* Normal arrow */ DMG_ENTRY(1, 0xF),
- /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
- /* Hookshot */ DMG_ENTRY(0, 0x1),
- /* Goron punch */ DMG_ENTRY(1, 0xF),
- /* Sword */ DMG_ENTRY(1, 0xF),
- /* Goron pound */ DMG_ENTRY(1, 0xF),
- /* Fire arrow */ DMG_ENTRY(2, 0x2),
- /* Ice arrow */ DMG_ENTRY(2, 0x3),
- /* Light arrow */ DMG_ENTRY(2, 0x4),
- /* Goron spikes */ DMG_ENTRY(1, 0xF),
- /* Deku spin */ DMG_ENTRY(0, 0x1),
- /* Deku bubble */ DMG_ENTRY(1, 0xF),
- /* Deku launch */ DMG_ENTRY(2, 0xF),
- /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1),
- /* Zora barrier */ DMG_ENTRY(0, 0x5),
- /* Normal shield */ DMG_ENTRY(0, 0x0),
- /* Light ray */ DMG_ENTRY(0, 0x0),
- /* Thrown object */ DMG_ENTRY(1, 0xF),
- /* Zora punch */ DMG_ENTRY(1, 0xF),
- /* Spin attack */ DMG_ENTRY(1, 0xF),
- /* Sword beam */ DMG_ENTRY(0, 0x0),
- /* Normal Roll */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
- /* Unblockable */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
- /* Powder Keg */ DMG_ENTRY(1, 0xF),
+typedef enum {
+ /* 0 */ EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE,
+ /* 1 */ EN_JSO_ACTION_REAPPEAR,
+ /* 2 */ EN_JSO_ACTION_CIRCLE_PLAYER,
+ /* 3 */ EN_JSO_ACTION_GUARD,
+ /* 4 */ EN_JSO_ACTION_SPIN_BEFORE_ATTACK,
+ /* 5 */ EN_JSO_ACTION_DASH_ATTACK,
+ /* 6 */ EN_JSO_ACTION_SLASH,
+ /* 7 */ EN_JSO_ACTION_WAIT_AFTER_SLASH,
+ /* 8 */ EN_JSO_ACTION_STUNNED,
+ /* 9 */ EN_JSO_ACTION_KNOCKED_BACK,
+ /* 10 */ EN_JSO_ACTION_COWER,
+ /* 11 */ EN_JSO_ACTION_DAMAGED,
+ /* 12 */ EN_JSO_ACTION_JUMP_BACK,
+ /* 13 */ EN_JSO_ACTION_DEAD,
+ /* 14 */ EN_JSO_ACTION_FALL_DOWN_AND_TALK,
+ /* 15 */ EN_JSO_ACTION_UNK_15 // Checked in EnJso_Update, but never actually used
+} EnJsoAction;
+
+typedef enum {
+ /* 0 */ EN_JSO_INTRO_SPIN_UP_FROM_GROUND,
+ /* 1 */ EN_JSO_INTRO_JUMP_OUT_FROM_GROUND,
+ /* 2 */ EN_JSO_INTRO_LAND_FROM_ABOVE,
+ /* 3 */ EN_JSO_INTRO_SCALE_UP
+} EnJsoIntroType;
+
+typedef enum {
+ // Either the cutscene started (in which case, we'll transition to the next state on the next frame) or it's done.
+ /* 0 */ EN_JSO_INTRO_CS_STATE_DONE_OR_STARTED,
+ // Waits for the Garo to finish their intro animation and open the first textbox.
+ /* 1 */ EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_APPEAR,
+ // Waits for the player to press a button to continue on from the Garo's first textbox.
+ /* 2 */ EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_CONTINUE,
+ // Lifts the Garo's right arm such that, when they draw their sword, it's pointed at the player. Waits until the
+ // player has finished reading all of the Garo's dialogue before continuing.
+ /* 3 */ EN_JSO_INTRO_CS_STATE_RAISE_ARM_AND_DRAW_RIGHT_SWORD,
+ // Waits 10 frames, then the Garo draws its left sword and continues to the next state.
+ /* 4 */ EN_JSO_INTRO_CS_STATE_DRAW_LEFT_SWORD,
+ // Waits 10 frames, then the Garo jumps back and the cutscene ends.
+ /* 5 */ EN_JSO_INTRO_CS_STATE_ENDING
+} EnJsoIntroCsState;
+
+typedef enum {
+ /* 0 */ EN_JSO_SWORD_STATE_BOTH_DRAWN,
+ /* 1 */ EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS,
+ /* 2 */ EN_JSO_SWORD_STATE_RIGHT_DRAWN,
+ /* 3 */ EN_JSO_SWORD_STATE_LEFT_DRAWN,
+ /* 5 */ EN_JSO_SWORD_STATE_NONE_DRAWN = 5
+} EnJsoSwordState;
+
+// Seemingly a duplicate of the isAttacking instance variable. Its purpose is unknown.
+static s32 sIsAttacking = false;
+
+// Seemingly a duplicate of the isPlayerLockedOn instance variable. Its purpose is unknown.
+static s32 sIsPlayerLockedOn = false;
+
+typedef enum {
+ /* 0x0 */ EN_JSO_DMGEFF_IMMUNE, // Deals no damage and has no special effect
+ /* 0x1 */ EN_JSO_DMGEFF_STUN, // Deals no damage but stuns the Garo
+ /* 0x2 */ EN_JSO_DMGEFF_FIRE, // Damages and sets the Garo on fire
+ /* 0x3 */ EN_JSO_DMGEFF_FREEZE, // Damages and surrounds the Garo with ice
+ /* 0x4 */ EN_JSO_DMGEFF_LIGHT_ORB, // Damages and surrounds the Garo with light orbs
+ /* 0x5 */ EN_JSO_DMGEFF_ELECTRIC_STUN, // Deals no damage but stuns the Garo and surrounds them with electric sparks
+ /* 0xF */ EN_JSO_DMGEFF_NONE = 0xF // Damages the Garo and has no special effect
+} EnJsoDamageEffect;
+
+static DamageTable sDamageTable = {
+ /* Deku Nut */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN),
+ /* Deku Stick */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Horse trample */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Explosives */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Zora boomerang */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Normal arrow */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Hookshot */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN),
+ /* Goron punch */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Sword */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Goron pound */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Fire arrow */ DMG_ENTRY(2, EN_JSO_DMGEFF_FIRE),
+ /* Ice arrow */ DMG_ENTRY(2, EN_JSO_DMGEFF_FREEZE),
+ /* Light arrow */ DMG_ENTRY(2, EN_JSO_DMGEFF_LIGHT_ORB),
+ /* Goron spikes */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Deku spin */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN),
+ /* Deku bubble */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Deku launch */ DMG_ENTRY(2, EN_JSO_DMGEFF_NONE),
+ /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_JSO_DMGEFF_STUN),
+ /* Zora barrier */ DMG_ENTRY(0, EN_JSO_DMGEFF_ELECTRIC_STUN),
+ /* Normal shield */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Light ray */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Thrown object */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Zora punch */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Spin attack */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
+ /* Sword beam */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Normal Roll */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Unblockable */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_JSO_DMGEFF_IMMUNE),
+ /* Powder Keg */ DMG_ENTRY(1, EN_JSO_DMGEFF_NONE),
};
ActorInit En_Jso_InitVars = {
@@ -81,106 +159,1560 @@ ActorInit En_Jso_InitVars = {
(ActorFunc)NULL,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_809B0F88 = {
- { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x08, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_ON | AC_HARD | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x08, 0x04 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 22, 55, 0, { 0, 0, 0 } },
};
-// static ColliderQuadInit sQuadInit = {
-static ColliderQuadInit D_809B0FB4 = {
- { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_QUAD, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x08 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7, BUMP_NONE, OCELEM_NONE, },
+static ColliderQuadInit sQuadInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_NONE,
+ OC1_NONE,
+ OC2_NONE,
+ COLSHAPE_QUAD,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x04, 0x08 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL | TOUCH_UNK7,
+ BUMP_NONE,
+ OCELEM_NONE,
+ },
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
};
-#endif
+// These text IDs are the ones common to all Garos, regardless of which hint they provide. This includes their dialogue
+// during their intro cutscene, as well as most of their dialogue when they are defeated.
+static u16 sTextIds[] = {
+ 0x1396,
+ 0x1397,
+ 0x1398,
+ 0x1399,
+};
-extern DamageTable D_809B0F48;
-extern ColliderCylinderInit D_809B0F88;
-extern ColliderQuadInit D_809B0FB4;
+typedef enum {
+ /* 0 */ EN_JSO_ANIM_APPEAR,
+ /* 1 */ EN_JSO_ANIM_IDLE,
+ /* 2 */ EN_JSO_ANIM_BOUNCE,
+ /* 3 */ EN_JSO_ANIM_GUARD,
+ /* 4 */ EN_JSO_ANIM_DASH_ATTACK,
+ /* 5 */ EN_JSO_ANIM_SLASH_START,
+ /* 6 */ EN_JSO_ANIM_SLASH_LOOP,
+ /* 7 */ EN_JSO_ANIM_KNOCKED_BACK,
+ /* 8 */ EN_JSO_ANIM_COWER,
+ /* 9 */ EN_JSO_ANIM_DAMAGED,
+ /* 10 */ EN_JSO_ANIM_JUMP_BACK,
+ /* 11 */ EN_JSO_ANIM_FALL_DOWN,
+ /* 12 */ EN_JSO_ANIM_MAX
+} EnJsoAnimation;
-extern UNK_TYPE D_060081F4;
+static AnimationHeader* sAnimations[EN_JSO_ANIM_MAX] = {
+ &gGaroAppearAnim, // EN_JSO_ANIM_APPEAR
+ &gGaroIdleAnim, // EN_JSO_ANIM_IDLE
+ &gGaroBounceAnim, // EN_JSO_ANIM_BOUNCE
+ &gGaroGuardAnim, // EN_JSO_ANIM_GUARD
+ &gGaroDashAttackAnim, // EN_JSO_ANIM_DASH_ATTACK
+ &gGaroSlashStartAnim, // EN_JSO_ANIM_SLASH_START
+ &gGaroSlashLoopAnim, // EN_JSO_ANIM_SLASH_LOOP
+ &gGaroKnockedBackAnim, // EN_JSO_ANIM_KNOCKED_BACK
+ &gGaroCowerAnim, // EN_JSO_ANIM_COWER
+ &gGaroDamagedAnim, // EN_JSO_ANIM_DAMAGED
+ &gGaroJumpBackAnim, // EN_JSO_ANIM_JUMP_BACK
+ &gGaroFallDownAnim, // EN_JSO_ANIM_FALL_DOWN
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/EnJso_Init.s")
+static u8 sAnimationModes[EN_JSO_ANIM_MAX] = {
+ ANIMMODE_ONCE, // EN_JSO_ANIM_APPEAR
+ ANIMMODE_LOOP, // EN_JSO_ANIM_IDLE
+ ANIMMODE_LOOP, // EN_JSO_ANIM_BOUNCE
+ ANIMMODE_ONCE, // EN_JSO_ANIM_GUARD
+ ANIMMODE_ONCE, // EN_JSO_ANIM_DASH_ATTACK
+ ANIMMODE_ONCE, // EN_JSO_ANIM_SLASH_START
+ ANIMMODE_LOOP, // EN_JSO_ANIM_SLASH_LOOP
+ ANIMMODE_ONCE, // EN_JSO_ANIM_KNOCKED_BACK
+ ANIMMODE_LOOP, // EN_JSO_ANIM_COWER
+ ANIMMODE_LOOP, // EN_JSO_ANIM_DAMAGED
+ ANIMMODE_ONCE, // EN_JSO_ANIM_JUMP_BACK
+ ANIMMODE_ONCE, // EN_JSO_ANIM_FALL_DOWN
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/EnJso_Destroy.s")
+void EnJso_Init(Actor* thisx, PlayState* play) {
+ EnJso* this = THIS;
+ EffectBlureInit1 rightSwordBlureInit;
+ EffectBlureInit1 leftSwordBlureInit;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809ADBC8.s")
+ this->actor.hintId = TATL_HINT_ID_GARO;
+ this->actor.targetMode = TARGET_MODE_5;
+ this->actor.colChkInfo.mass = 80;
+ this->actor.colChkInfo.health = 3;
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f);
+ this->actor.colChkInfo.damageTable = &sDamageTable;
+ this->actor.shape.shadowScale = 0.0f;
+ SkelAnime_InitFlex(play, &this->skelAnime, &gGaroSkel, &gGaroAppearAnim, this->jointTable, this->morphTable,
+ GARO_LIMB_MAX);
+ this->actor.focus.pos = this->actor.world.pos;
+ Collider_InitAndSetCylinder(play, &this->bodyCollider, &this->actor, &sCylinderInit);
+ Collider_InitAndSetQuad(play, &this->rightSwordCollider, &this->actor, &sQuadInit);
+ Collider_InitAndSetQuad(play, &this->leftSwordCollider, &this->actor, &sQuadInit);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809ADC7C.s")
+ rightSwordBlureInit.p1StartColor[0] = leftSwordBlureInit.p1StartColor[0] = rightSwordBlureInit.p1StartColor[1] =
+ leftSwordBlureInit.p1StartColor[1] = rightSwordBlureInit.p1StartColor[2] = leftSwordBlureInit.p1StartColor[2] =
+ rightSwordBlureInit.p1StartColor[3] = leftSwordBlureInit.p1StartColor[3] =
+ rightSwordBlureInit.p2StartColor[0] = leftSwordBlureInit.p2StartColor[0] =
+ rightSwordBlureInit.p2StartColor[1] = leftSwordBlureInit.p2StartColor[1] =
+ rightSwordBlureInit.p2StartColor[2] = leftSwordBlureInit.p2StartColor[2] =
+ rightSwordBlureInit.p1EndColor[0] = leftSwordBlureInit.p1EndColor[0] =
+ rightSwordBlureInit.p1EndColor[1] = leftSwordBlureInit.p1EndColor[1] =
+ rightSwordBlureInit.p1EndColor[2] = leftSwordBlureInit.p1EndColor[2] =
+ rightSwordBlureInit.p2EndColor[0] = leftSwordBlureInit.p2EndColor[0] =
+ rightSwordBlureInit.p2EndColor[1] = leftSwordBlureInit.p2EndColor[1] =
+ rightSwordBlureInit.p2EndColor[2] = leftSwordBlureInit.p2EndColor[2] =
+ 255;
+ leftSwordBlureInit.p2StartColor[3] = rightSwordBlureInit.p2StartColor[3] = 64;
+ rightSwordBlureInit.p1EndColor[3] = leftSwordBlureInit.p1EndColor[3] = rightSwordBlureInit.p2EndColor[3] =
+ leftSwordBlureInit.p2EndColor[3] = 0;
+ rightSwordBlureInit.elemDuration = leftSwordBlureInit.elemDuration = 8;
+ rightSwordBlureInit.unkFlag = leftSwordBlureInit.unkFlag = 0;
+ rightSwordBlureInit.calcMode = leftSwordBlureInit.calcMode = 2;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809ADCB8.s")
+ Effect_Add(play, &this->rightSwordBlureIndex, EFFECT_BLURE1, 0, 0, &rightSwordBlureInit);
+ Effect_Add(play, &this->leftSwordBlureIndex, EFFECT_BLURE1, 0, 0, &leftSwordBlureInit);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AE754.s")
+ this->actor.gravity = -3.0f;
+ this->scale = 0.035f;
+ this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
+ this->hintType = EN_JSO_GET_HINT_TYPE(&this->actor);
+ this->introCsType = this->hintType & EN_JSO_INTRO_SCALE_UP;
+ EnJso_SetupHandleIntroCutscene(this);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AE87C.s")
+void EnJso_Destroy(Actor* thisx, PlayState* play) {
+ EnJso* this = THIS;
+ EnEncount3* parent;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AE9B0.s")
+ Collider_DestroyCylinder(play, &this->bodyCollider);
+ Collider_DestroyQuad(play, &this->rightSwordCollider);
+ Collider_DestroyQuad(play, &this->leftSwordCollider);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEA08.s")
+ if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) {
+ parent = (EnEncount3*)this->actor.parent;
+ if (parent->actor.update != NULL) {
+ parent->child = NULL;
+ if (parent->unk14E > 0) {
+ parent->unk14E--;
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AECA8.s")
+ Effect_Destroy(play, this->rightSwordBlureIndex);
+ Effect_Destroy(play, this->leftSwordBlureIndex);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AED00.s")
+void EnJso_ChangeAnim(EnJso* this, s32 animIndex) {
+ f32 morphFrames = -4.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AED54.s")
+ this->animEndFrame = Animation_GetLastFrame(sAnimations[animIndex]);
+ if ((animIndex == EN_JSO_ANIM_GUARD) || (animIndex == EN_JSO_ANIM_DAMAGED)) {
+ morphFrames = 0.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEDAC.s")
+ Animation_Change(&this->skelAnime, sAnimations[animIndex], 1.0f, 0.0f, this->animEndFrame,
+ sAnimationModes[animIndex], morphFrames);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEE44.s")
+void EnJso_SetupHandleIntroCutscene(EnJso* this) {
+ EnEncount3* parent = (EnEncount3*)this->actor.parent;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AEEC0.s")
+ this->csId = parent->csId;
+ this->swordState = EN_JSO_SWORD_STATE_NONE_DRAWN;
+ this->action = EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE;
+ this->actor.flags |= ACTOR_FLAG_100000;
+ this->actionFunc = EnJso_HandleIntroCutscene;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF064.s")
+/**
+ * Responsible for handling all aspects of the intro cutscene, including manipulating the sub-camera, making the Garo
+ * appear in one of four different ways, activating the ring of fire, etc. When the cutscene is over, the Garo will
+ * jump back to start the fight.
+ */
+void EnJso_HandleIntroCutscene(EnJso* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+ f32 curFrame = this->skelAnime.curFrame;
+ s16 showTextbox;
+ s16 diffToTargetRobeRightRot;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF110.s")
+ switch (this->introCsState) {
+ case EN_JSO_INTRO_CS_STATE_DONE_OR_STARTED:
+ if (!CutsceneManager_IsNext(this->csId)) {
+ CutsceneManager_Queue(this->csId);
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF28C.s")
+ CutsceneManager_StartWithPlayerCs(this->csId, &this->actor);
+ func_800B7298(play, &this->actor, PLAYER_CSMODE_21);
+ this->subCamId = CutsceneManager_GetCurrentSubCamId(this->actor.csId);
+ player->actor.world.pos.x = this->actor.home.pos.x + 30.0f;
+ player->actor.world.pos.z = this->actor.home.pos.z + 30.0f;
+ this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
+ this->subCamEyeNext.x = player->actor.world.pos.x;
+ this->subCamEyeNext.y = player->actor.world.pos.y;
+ this->subCamEyeNext.z = player->actor.world.pos.z;
+ this->subCamAtNext.x = player->actor.world.pos.x;
+ this->subCamAtNext.y = player->actor.world.pos.y;
+ this->subCamAtNext.z = player->actor.world.pos.z;
+ player->actor.shape.rot.y = player->actor.world.rot.y =
+ Math_Vec3f_Yaw(&player->actor.world.pos, &this->actor.world.pos);
+ Math_Vec3f_Copy(&this->subCamEye, &this->subCamEyeNext);
+ Math_Vec3f_Copy(&this->subCamAt, &this->subCamAtNext);
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_IDLE);
+ this->actor.draw = EnJso_Draw;
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_ENTRY);
+ this->actor.shape.yOffset = 970.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF2F8.s")
+ switch (this->introCsType) {
+ case EN_JSO_INTRO_SPIN_UP_FROM_GROUND:
+ this->actor.shape.yOffset = -300.0f;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF368.s")
+ case EN_JSO_INTRO_JUMP_OUT_FROM_GROUND:
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_APPEAR);
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale,
+ 1, 8.0f, 500, 10, true);
+ this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF3C0.s")
+ case EN_JSO_INTRO_LAND_FROM_ABOVE:
+ this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ this->actor.world.pos.y = this->actor.home.pos.y + 200.0f;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF3FC.s")
+ case EN_JSO_INTRO_SCALE_UP:
+ this->scale = 0.0f;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF440.s")
+ default:
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF470.s")
+ this->introCsTimer = 0;
+ this->introCsState++;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF53C.s")
+ case EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_APPEAR:
+ player->actor.world.pos.x = this->actor.home.pos.x + 30.0f;
+ player->actor.world.pos.z = this->actor.home.pos.z + 90.0f;
+ this->subCamEyeNext.x = player->actor.world.pos.x - 170.0f;
+ this->subCamEyeNext.y = player->actor.world.pos.y + 30.0f;
+ this->subCamEyeNext.z = player->actor.world.pos.z - 80.0f;
+ this->subCamAtNext.x = player->actor.world.pos.x + 200.0f;
+ this->subCamAtNext.y = player->actor.world.pos.y + 10.0f;
+ this->subCamAtNext.z = player->actor.world.pos.z;
+ Math_ApproachF(&this->actor.shape.shadowScale, 16.0f, 0.4f, 4.0f);
+ showTextbox = false;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF5F8.s")
+ switch (this->introCsType) {
+ case EN_JSO_INTRO_SPIN_UP_FROM_GROUND:
+ Math_ApproachF(&this->actor.shape.yOffset, 970.0f, 0.5f, 100.0f);
+ this->actor.shape.rot.y += 0x1770;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF714.s")
+ if (this->actor.shape.yOffset >= 969.0f) {
+ showTextbox = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF76C.s")
+ if ((play->gameplayFrames % 4) == 0) {
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos,
+ this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true);
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF7F4.s")
+ case EN_JSO_INTRO_JUMP_OUT_FROM_GROUND:
+ if (curFrame >= this->animEndFrame) {
+ showTextbox = true;
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos,
+ this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true);
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF8D0.s")
+ case EN_JSO_INTRO_LAND_FROM_ABOVE:
+ if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
+ showTextbox = true;
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos,
+ this->actor.shape.shadowScale, 1, 8.0f, 500, 10, true);
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AF99C.s")
+ case EN_JSO_INTRO_SCALE_UP:
+ Math_ApproachF(&this->scale, 0.035f, 0.2f, 0.03f);
+ if (this->scale >= 0.034f) {
+ this->scale = 0.035f;
+ showTextbox = true;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFA58.s")
+ default:
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFAF4.s")
+ if (showTextbox) {
+ func_800B7298(play, &this->actor, PLAYER_CSMODE_4);
+ Message_StartTextbox(play, sTextIds[this->textIndex], &this->actor);
+ this->textIndex++;
+ this->actor.shape.yOffset = 970.0f;
+ this->introCsTimer = 0;
+ this->introCsState++;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFC10.s")
+ case EN_JSO_INTRO_CS_STATE_WAITING_FOR_TEXTBOX_TO_CONTINUE:
+ this->subCamEyeNext.x = player->actor.world.pos.x - 30.0f;
+ this->subCamEyeNext.y = player->actor.world.pos.y + 30.0f;
+ this->subCamEyeNext.z = player->actor.world.pos.z + 70.0f;
+ this->subCamAtNext.x = player->actor.world.pos.x - 20.0f;
+ this->subCamAtNext.y = player->actor.world.pos.y + 20.0f;
+ this->subCamAtNext.z = player->actor.world.pos.z;
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809AFE38.s")
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) {
+ Message_CloseTextbox(play);
+ Message_ContinueTextbox(play, sTextIds[this->textIndex]);
+ this->introCsTimer = 0;
+ this->textIndex++;
+ this->introCsState++;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0034.s")
+ case EN_JSO_INTRO_CS_STATE_RAISE_ARM_AND_DRAW_RIGHT_SWORD:
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/EnJso_Update.s")
+ if (Message_GetState(&play->msgCtx) == TEXT_STATE_10) {
+ this->targetRobeRightRot.x = -0x2710;
+ this->targetRobeRightRot.z = -0x2710;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0734.s")
+ diffToTargetRobeRightRot = this->targetRobeRightRot.x - this->robeRightRot.x;
+ diffToTargetRobeRightRot = ABS_ALT(diffToTargetRobeRightRot);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0820.s")
+ if (this->targetRobeRightRot.x != 0) {
+ if ((ABS_ALT(diffToTargetRobeRightRot) < 0x64) && (this->swordState == EN_JSO_SWORD_STATE_NONE_DRAWN)) {
+ this->swordState = EN_JSO_SWORD_STATE_RIGHT_DRAWN;
+ this->targetRightArmRot.x = -0x32C8;
+ this->targetRightArmRot.y = -0xBB8;
+ this->rightArmRot.z = this->targetRightArmRot.z = -0x32C8;
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SWORD);
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0B70.s")
+ this->subCamEyeNext.x = player->actor.world.pos.x + 100.0f;
+ this->subCamEyeNext.y = player->actor.world.pos.y + 60.0f;
+ this->subCamEyeNext.z = player->actor.world.pos.z - 30.0f;
+ this->subCamAtNext.x = player->actor.world.pos.x - 35.0f;
+ this->subCamAtNext.y = player->actor.world.pos.y + 30.0f;
+ this->subCamAtNext.z = player->actor.world.pos.z - 40.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jso/func_809B0BB0.s")
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) {
+ Message_CloseTextbox(play);
+ this->targetRightArmRot.x = this->targetRightArmRot.y = this->targetRightArmRot.z =
+ this->targetRobeRightRot.x = this->targetRobeRightRot.y = this->targetRobeRightRot.z = 0;
+ this->introCsTimer = 0;
+ this->introCsState++;
+ }
+ break;
+
+ case EN_JSO_INTRO_CS_STATE_DRAW_LEFT_SWORD:
+ this->subCamEyeNext.x = player->actor.world.pos.x - 40.0f;
+ this->subCamEyeNext.y = player->actor.world.pos.y + 20.0f;
+ this->subCamEyeNext.z = player->actor.world.pos.z;
+ this->subCamAtNext.x = player->actor.world.pos.x - 30.0f;
+ this->subCamAtNext.y = player->actor.world.pos.y + 40.0f;
+ this->subCamAtNext.z = player->actor.world.pos.z - 130.0f;
+ this->introCsTimer++;
+
+ if (this->introCsTimer >= 10) {
+ this->swordState = EN_JSO_SWORD_STATE_BOTH_DRAWN;
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SWORD);
+ if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) {
+ EnEncount3* parent = (EnEncount3*)this->actor.parent;
+
+ if (parent->actor.update != NULL) {
+ parent->unk148 = 1;
+ play->unk_18880 = 1;
+ }
+ }
+
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_IDLE);
+ this->introCsTimer = 0;
+ this->introCsState++;
+ }
+ break;
+
+ case EN_JSO_INTRO_CS_STATE_ENDING:
+ this->subCamEyeNext.x = player->actor.world.pos.x - 40.0f;
+ this->subCamEyeNext.y = player->actor.world.pos.y + 20.0f;
+ this->subCamEyeNext.z = player->actor.world.pos.z;
+ this->subCamAtNext.x = player->actor.world.pos.x - 30.0f;
+ this->subCamAtNext.y = player->actor.world.pos.y + 40.0f;
+ this->subCamAtNext.z = player->actor.world.pos.z - 130.0f;
+ this->introCsTimer++;
+
+ if (this->introCsTimer >= 10) {
+ func_800B7298(play, &this->actor, PLAYER_CSMODE_END);
+ CutsceneManager_Stop(this->csId);
+ this->rightArmRot.x = this->rightArmRot.y = this->rightArmRot.z = this->robeRightRot.x =
+ this->robeRightRot.y = this->robeRightRot.z = 0;
+ this->introCsState = EN_JSO_INTRO_CS_STATE_DONE_OR_STARTED;
+ this->subCamId = SUB_CAM_ID_DONE;
+ this->actor.flags &= ~ACTOR_FLAG_100000;
+ this->actor.flags &= ~ACTOR_FLAG_CANT_LOCK_ON;
+ this->actor.flags |= ACTOR_FLAG_TARGETABLE;
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ EnJso_SetupJumpBack(this);
+ }
+ break;
+ }
+
+ Math_SmoothStepToS(&this->rightArmRot.x, this->targetRightArmRot.x, 1, 0xBB8, 0);
+ Math_SmoothStepToS(&this->rightArmRot.y, this->targetRightArmRot.y, 1, 0xBB8, 0);
+ Math_SmoothStepToS(&this->rightArmRot.z, this->targetRightArmRot.z, 1, 0xBB8, 0);
+ Math_SmoothStepToS(&this->robeRightRot.x, this->targetRobeRightRot.x, 1, 0xBB8, 0);
+ Math_SmoothStepToS(&this->robeRightRot.y, this->targetRobeRightRot.y, 1, 0xBB8, 0);
+ Math_SmoothStepToS(&this->robeRightRot.z, this->targetRobeRightRot.z, 1, 0xBB8, 0);
+ Math_Vec3f_Copy(&this->subCamEye, &this->subCamEyeNext);
+ Math_Vec3f_Copy(&this->subCamAt, &this->subCamAtNext);
+
+ if (this->subCamId != SUB_CAM_ID_DONE) {
+ this->subCamUp.x = 0.0f;
+ this->subCamUp.y = 1.0f;
+ this->subCamUp.z = 0.0f;
+ Play_SetCameraAtEyeUp(play, this->subCamId, &this->subCamAt, &this->subCamEye, &this->subCamUp);
+ }
+}
+
+void EnJso_SetupReappear(EnJso* this, PlayState* play) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_APPEAR);
+ this->actor.speed = 0.0f;
+ this->actor.velocity.y = 0.0f;
+
+ if (this->isPlayerLockedOn) {
+ this->isPlayerLockedOn = false;
+ sIsPlayerLockedOn = false;
+ }
+
+ if (this->isAttacking) {
+ this->isAttacking = false;
+ sIsAttacking = false;
+ }
+
+ if (this->swordState != EN_JSO_SWORD_STATE_BOTH_DRAWN) {
+ this->swordState = EN_JSO_SWORD_STATE_BOTH_DRAWN;
+ }
+
+ this->actor.shape.rot.x = this->actor.world.rot.x = 0;
+ this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos);
+ this->actor.floorHeight = this->actor.home.pos.y;
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, 500,
+ 10, true);
+ this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_ENTRY);
+ this->afterimageCount = 0;
+ this->action = EN_JSO_ACTION_REAPPEAR;
+ this->actor.gravity = 0.0f;
+ this->actionFunc = EnJso_Reappear;
+}
+
+/**
+ * This function makes the Garo jump out of the ground from its home position. It's intended to be used if the Garo gets
+ * too far away from the player (for example, if the Garo's dash attack makes it fall off a ledge); this will ensure the
+ * Garo is back inside the ring of fire, so the player can interact with them again.
+ */
+void EnJso_Reappear(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ if (this->actor.colChkInfo.health <= 0) {
+ Player* player = GET_PLAYER(play);
+
+ player->actor.freezeTimer = 3;
+ }
+
+ Math_ApproachF(&this->actor.shape.shadowScale, 16.0f, 0.4f, 4.0f);
+ Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xBB8, 0x14);
+
+ if ((play->gameplayFrames % 8) == 0) {
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f,
+ 500, 10, true);
+ }
+
+ if (curFrame >= this->animEndFrame) {
+ this->actor.gravity = -3.0f;
+ if (this->actor.colChkInfo.health > 0) {
+ this->actor.flags &= ~ACTOR_FLAG_CANT_LOCK_ON;
+ EnJso_SetupCirclePlayer(this, play);
+ } else {
+ EnJso_SetupFallDownAndTalk(this, play);
+ }
+ }
+}
+
+void EnJso_SetupCirclePlayer(EnJso* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_BOUNCE);
+ this->circlingAngularVelocity = 0x258;
+ this->action = EN_JSO_ACTION_CIRCLE_PLAYER;
+ this->circlingAngle = player->actor.shape.rot.y;
+ this->actionFunc = EnJso_CirclePlayer;
+}
+
+/**
+ * Makes the Garo bounce in a circle around the player, sometimes randomly switching the direction it's traveling, until
+ * the attack wait timer reaches 0. Once it does, then the Garo will prepare to attack.
+ */
+void EnJso_CirclePlayer(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+ Player* player = GET_PLAYER(play);
+ Vec3f targetPos;
+ s32 pad;
+
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_MOVING - SFX_FLAG);
+ if ((this->action != EN_JSO_ACTION_REAPPEAR) && (this->action != EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE) &&
+ (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) > 60.0f)) {
+ EnJso_SetupReappear(this, play);
+ return;
+ }
+
+ if (curFrame < this->animEndFrame) {
+ SkelAnime_Update(&this->skelAnime);
+ } else if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
+ SkelAnime_Update(&this->skelAnime);
+ }
+
+ if (Animation_OnFrame(&this->skelAnime, 6.0f)) {
+ this->actor.velocity.y = 10.0f;
+ if ((play->gameplayFrames % 2) == 0) {
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_CRYING);
+ }
+ }
+
+ if (Animation_OnFrame(&this->skelAnime, 12.0f)) {
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SKIP);
+ this->actor.speed = 0.0f;
+ if (Rand_ZeroFloat(1.0f) < 0.5f) {
+ this->circlingAngularVelocity = -this->circlingAngularVelocity;
+ }
+ }
+
+ //! @note: Since sIsPlayerLockedOn always mirrors the value of this->isPlayerLockedOn, the last part of this
+ //! if-statement is always true and has no impact on the logic. In other words, the Garo doesn't care whether or not
+ //! the player is locked on; it will attack regardless as long as the other conditions are met.
+ if ((this->attackWaitTimer == 0) && !sIsAttacking && (!sIsPlayerLockedOn || this->isPlayerLockedOn)) {
+ sIsAttacking = true;
+ this->isAttacking = true;
+ this->action = EN_JSO_ACTION_SPIN_BEFORE_ATTACK;
+ this->actor.speed = 0.0f;
+ EnJso_SetupSpinBeforeAttack(this);
+ return;
+ }
+
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xFA0, 0x14);
+ Math_ApproachF(&this->actor.speed, 5.0f, 0.3f, 2.0f);
+ this->circlingAngle += this->circlingAngularVelocity;
+ targetPos.x = (Math_SinS(this->circlingAngle) * 200.0f) + player->actor.world.pos.x;
+ targetPos.y = this->actor.world.pos.y;
+ targetPos.z = (Math_CosS(this->circlingAngle) * 200.0f) + player->actor.world.pos.z;
+ Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &targetPos), 0xA, 0xFA0, 0x14);
+}
+
+void EnJso_SetupGuard(EnJso* this) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_GUARD);
+ this->action = EN_JSO_ACTION_GUARD;
+ this->actor.world.rot.y = this->actor.yawTowardsPlayer;
+ Actor_PlaySfx(&this->actor, NA_SE_IT_SHIELD_BOUND);
+ this->bodyCollider.base.acFlags |= AC_HARD;
+ this->actionFunc = EnJso_Guard;
+}
+
+/**
+ * Plays the guard animation to completion, then goes back to circling the player.
+ */
+void EnJso_Guard(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ if (curFrame >= this->animEndFrame) {
+ this->isGuarding = false;
+
+ if (this->isAttacking) {
+ this->isAttacking = false;
+ sIsAttacking = false;
+ }
+
+ EnJso_SetupCirclePlayer(this, play);
+ }
+}
+
+void EnJso_SetupSpinBeforeAttack(EnJso* this) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_DASH_ATTACK);
+ this->actor.world.rot.y = -this->actor.yawTowardsPlayer;
+ this->actor.speed = 10.0f;
+ this->actor.velocity.y = 20.0f;
+ this->actionFunc = EnJso_SpinBeforeAttack;
+}
+
+/**
+ * Leaps into the air while spinning forward. Once the Garo touches the ground, it will begin a dash attack.
+ */
+void EnJso_SpinBeforeAttack(EnJso* this, PlayState* play) {
+ this->actor.world.rot.x += 0x1770;
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xFA0, 0x14);
+
+ if (this->actor.velocity.y > 0.0f) {
+ return;
+ }
+
+ if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
+ this->actor.world.rot.x = 0;
+ this->actor.velocity.y = 0.0f;
+ this->actor.speed = 0.0f;
+ this->actor.world.rot.y = this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
+ EnJso_SetupDashAttack(this);
+ }
+}
+
+void EnJso_SetupDashAttack(EnJso* this) {
+ this->action = EN_JSO_ACTION_DASH_ATTACK;
+ this->dashAttackTimer = 40;
+ this->bodyCollider.base.colType = COLTYPE_HIT2;
+ this->bodyCollider.base.acFlags &= ~AC_HARD;
+ this->actor.speed = 15.0f;
+ this->actor.velocity.y = 13.0f;
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_ENTRY);
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_DASH_2);
+ this->actionFunc = EnJso_DashAttack;
+}
+
+/**
+ * Dashes toward the player with its swords out. If the player shields the attack, the Garo will be knocked back and
+ * drop its swords. The Garo will stop dashing and perform a slash if it's close enough to the player, if the difference
+ * between its y-rotation and the yaw towards the player is large enough (usually indicating that it has dashed past the
+ * player), or if 40 frames have passed, whichever comes first.
+ */
+void EnJso_DashAttack(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+ s16 yawDiff;
+ s16 absYawDiff;
+ Vec3f knockbackVelocity;
+
+ if ((this->rightSwordCollider.base.atFlags & AT_BOUNCED) || (this->leftSwordCollider.base.atFlags & AT_BOUNCED)) {
+ this->rightSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
+ this->leftSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
+ if (this->swordState == EN_JSO_SWORD_STATE_BOTH_DRAWN) {
+ Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW);
+ knockbackVelocity.x = 0.0f;
+ knockbackVelocity.y = 0.0f;
+ knockbackVelocity.z = -10.0f;
+ Matrix_MultVec3f(&knockbackVelocity, &this->knockbackVelocity);
+ this->swordState = EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS;
+ this->dashAttackTimer = 0;
+ this->disableBlure = true;
+ AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0);
+ EnJso_SetupKnockedBack(this);
+ return;
+ }
+ }
+
+ if ((this->actor.velocity.y < 0.0f) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) {
+ this->actor.velocity.y = 13.0f;
+ }
+
+ if (curFrame < this->animEndFrame) {
+ return;
+ }
+
+ yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
+ absYawDiff = ABS_ALT(yawDiff);
+
+ if ((this->dashAttackTimer == 0) || (this->actor.xzDistToPlayer < 100.0f) || (absYawDiff > 0x4300)) {
+ AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0);
+ Math_ApproachZeroF(&this->actor.speed, 0.3f, 3.0f);
+ EnJso_SetupSlash(this, play);
+ }
+}
+
+void EnJso_SetupSlash(EnJso* this, PlayState* play) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_SLASH_START);
+ this->action = EN_JSO_ACTION_SLASH;
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f, 500,
+ 10, true);
+ Math_ApproachZeroF(&this->actor.speed, 0.3f, 3.0f);
+ this->swordHitSomething = false;
+ Actor_PlaySfx(&this->actor, NA_SE_IT_SWORD_SWING_HARD);
+ this->actionFunc = EnJso_Slash;
+}
+
+/**
+ * Slash in place with both swords. If the player shields the attack, the Garo will be knocked back and drop its swords.
+ * Once the slash animation ends, this function will transition the Garo to a waiting state.
+ */
+void EnJso_Slash(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ Math_ApproachZeroF(&this->actor.speed, 0.5f, 5.0f);
+
+ if ((play->gameplayFrames % 8) == 0) {
+ Actor_SpawnFloorDustRing(play, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f,
+ 500, 10, true);
+ }
+
+ if ((this->rightSwordCollider.base.atFlags & AT_HIT) || (this->leftSwordCollider.base.atFlags & AT_HIT)) {
+ this->swordHitSomething = true;
+ this->rightSwordCollider.base.atFlags &= ~AT_HIT;
+ this->leftSwordCollider.base.atFlags &= ~AT_HIT;
+ }
+
+ if ((this->rightSwordCollider.base.atFlags & AT_BOUNCED) || (this->leftSwordCollider.base.atFlags & AT_BOUNCED)) {
+ this->rightSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
+ this->leftSwordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
+
+ if (this->swordState == EN_JSO_SWORD_STATE_BOTH_DRAWN) {
+ Vec3f knockbackVelocity;
+
+ Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW);
+ knockbackVelocity.x = 0.0f;
+ knockbackVelocity.y = 0.0f;
+ knockbackVelocity.z = -10.0f;
+ Matrix_MultVec3f(&knockbackVelocity, &this->knockbackVelocity);
+ this->swordState = EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS;
+ this->disableBlure = true;
+ EnJso_SetupKnockedBack(this);
+ return;
+ }
+ }
+
+ if (curFrame >= this->animEndFrame) {
+ this->actor.speed = 0.0f;
+ this->disableBlure = true;
+ EnJso_SetupWaitAfterSlash(this);
+ }
+}
+
+void EnJso_SetupWaitAfterSlash(EnJso* this) {
+ if (this->swordHitSomething) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_SLASH_LOOP);
+ this->timer = 20;
+ } else {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_SLASH_LOOP);
+ this->timer = 40;
+ }
+
+ this->action = EN_JSO_ACTION_WAIT_AFTER_SLASH;
+ this->actionFunc = EnJso_WaitAfterSlash;
+}
+
+/**
+ * Waits either 20 or 40 frames, depending on whether or not the Garo hit the player with its slash attack. Once this
+ * waiting period ends, the Garo starts circling the player again.
+ */
+void EnJso_WaitAfterSlash(EnJso* this, PlayState* play) {
+ if (this->timer == 0) {
+ this->attackWaitTimer = Rand_S16Offset(30, 30);
+ this->bodyCollider.base.colType = COLTYPE_NONE;
+ this->bodyCollider.base.acFlags |= AC_HARD;
+ this->swordHitSomething = false;
+ sIsAttacking = false;
+ this->isAttacking = false;
+ EnJso_SetupCirclePlayer(this, play);
+ }
+}
+
+void EnJso_SetupKnockedBack(EnJso* this) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_KNOCKED_BACK);
+ this->bodyCollider.base.acFlags &= ~AC_HARD;
+ this->timer = 30;
+ this->action = EN_JSO_ACTION_KNOCKED_BACK;
+ this->actor.speed = 0.0f;
+ this->actionFunc = EnJso_KnockedBack;
+}
+
+/**
+ * Plays the knocked back animation to completion, then transitions to cowering on the ground.
+ */
+void EnJso_KnockedBack(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ if (curFrame >= this->animEndFrame) {
+ EnJso_SetupCower(this);
+ }
+}
+
+void EnJso_SetupCower(EnJso* this) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_COWER);
+ this->action = EN_JSO_ACTION_COWER;
+ this->timer = 30;
+ this->actionFunc = EnJso_Cower;
+}
+
+/**
+ * Cower on the ground for 30 frames, then jump back.
+ */
+void EnJso_Cower(EnJso* this, PlayState* play) {
+ if (this->timer == 0) {
+ EnJso_SetupJumpBack(this);
+ }
+}
+
+/**
+ * Unlike most enemies, this will make the Garo play its damaged animation rather than stopping all animations.
+ */
+void EnJso_SetupStunned(EnJso* this) {
+ Vec3f knockbackVelocity;
+
+ AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0);
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_DAMAGED);
+
+ // This assignment is immediately overriden below.
+ this->timer = 30;
+ this->actor.speed = 0.0f;
+ if (((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) ||
+ (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) &&
+ (this->drawDmgEffAlpha == 0)) {
+ this->drawDmgEffAlpha = 0;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ }
+
+ this->timer = 40;
+ Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW);
+ Matrix_MultVecZ(-10.0f, &knockbackVelocity);
+ Math_Vec3f_Copy(&this->knockbackVelocity, &knockbackVelocity);
+ this->action = EN_JSO_ACTION_STUNNED;
+ this->bodyCollider.base.acFlags &= ~AC_HARD;
+ this->actionFunc = EnJso_Stunned;
+}
+
+/**
+ * Makes the Garo play its damaged animation and stop moving until 40 frames have passed, then it jumps back.
+ */
+void EnJso_Stunned(EnJso* this, PlayState* play) {
+ if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) {
+ if ((this->drawDmgEffAlpha != 0) && (this->drawDmgEffAlpha < 60)) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX;
+ }
+ }
+
+ if ((this->timer == 0) && (this->drawDmgEffAlpha == 0)) {
+ if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) ||
+ (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) {
+ Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, 2, 0.3f, 0.2f);
+ this->drawDmgEffAlpha = 0;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ }
+
+ EnJso_SetupJumpBack(this);
+ }
+}
+
+void EnJso_SetupDamaged(EnJso* this, PlayState* play) {
+ Vec3f knockbackVelocity;
+
+ AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0);
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_DAMAGED);
+ this->swordHitSomething = false;
+ this->actor.velocity.y = 10.0f;
+ this->actor.speed = 0.0f;
+ Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW);
+ Matrix_MultVecZ(-20.0f, &knockbackVelocity);
+ Math_Vec3f_Copy(&this->knockbackVelocity, &knockbackVelocity);
+
+ if (((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) ||
+ (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) &&
+ (this->drawDmgEffAlpha != 0)) {
+ Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, 2, 0.3f, 0.2f);
+ this->drawDmgEffAlpha = 0;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ }
+
+ Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA, 8);
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_DAMAGE);
+ this->action = EN_JSO_ACTION_DAMAGED;
+ this->actionFunc = EnJso_Damaged;
+}
+
+/**
+ * Plays the damaged animation until the Garo is touching the ground and no longer has its red color filter, at which
+ * point it will jump back.
+ */
+void EnJso_Damaged(EnJso* this, PlayState* play) {
+ if (this->actor.velocity.y > 0.0f) {
+ return;
+ }
+
+ if ((this->actor.colorFilterTimer == 0) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) {
+ EnJso_SetupJumpBack(this);
+ }
+}
+
+void EnJso_SetupJumpBack(EnJso* this) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_JUMP_BACK);
+ this->action = EN_JSO_ACTION_JUMP_BACK;
+ this->timer = 30;
+ this->actor.speed = 7.0f;
+ this->actor.velocity.y = 20.0f;
+
+ if (this->swordState != EN_JSO_SWORD_STATE_BOTH_DRAWN) {
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_SWORD);
+ this->swordState = EN_JSO_SWORD_STATE_BOTH_DRAWN;
+ }
+
+ this->actor.world.rot.y += 0x8000;
+ this->actionFunc = EnJso_JumpBack;
+}
+
+/**
+ * Jump backwards away from the player. After the Garo touches the ground, the jump back animation completes, and 30
+ * frames have passed, the Garo will transition to circling the player.
+ */
+void EnJso_JumpBack(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xBB8, 0x14);
+
+ if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
+ this->actor.speed = 0.0f;
+ }
+
+ if ((this->timer == 0) || ((curFrame >= this->animEndFrame) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND))) {
+ this->actor.world.rot.x = 0;
+ this->actor.velocity.y = 0.0f;
+ this->actor.speed = 0.0f;
+ this->timer = 0;
+ sIsAttacking = false;
+ this->isAttacking = false;
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ this->attackWaitTimer = Rand_S16Offset(10, 10);
+ EnJso_SetupCirclePlayer(this, play);
+ }
+}
+
+void EnJso_SetupDead(EnJso* this, PlayState* play) {
+ AudioSfx_SetChannelIO(&this->actor.projectedPos, NA_SE_EN_ANSATSUSYA_DASH_2, 0);
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_DAMAGED);
+
+ if (((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) ||
+ (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) &&
+ (this->drawDmgEffAlpha == 0)) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ }
+
+ this->actor.flags &= ~(ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY);
+ this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
+ this->actor.speed = 0.0f;
+ this->disableBlure = true;
+ this->timer = 30;
+ Enemy_StartFinishingBlow(play, &this->actor);
+ Actor_PlaySfx(&this->actor, NA_SE_EN_ANSATSUSYA_DEAD);
+ this->action = EN_JSO_ACTION_DEAD;
+ this->actionFunc = EnJso_Dead;
+}
+
+/**
+ * Plays the damaged animation for 30 frames, then the Garo falls down and starts talking to the player.
+ */
+void EnJso_Dead(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+
+ if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) ||
+ (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) {
+ if (this->drawDmgEffAlpha != 0) {
+ Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, 2, 0.3f, 0.2f);
+ this->drawDmgEffAlpha = 0;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ } else {
+ return;
+ }
+ }
+
+ if ((curFrame >= this->animEndFrame) && (this->timer == 0)) {
+ EnJso_SetupFallDownAndTalk(this, play);
+ }
+}
+
+void EnJso_SetupFallDownAndTalk(EnJso* this, PlayState* play) {
+ EnJso_ChangeAnim(this, EN_JSO_ANIM_FALL_DOWN);
+ this->textIndex = 2;
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ this->actor.flags |= (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY);
+ func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_NPC);
+ this->actor.flags &= ~ACTOR_FLAG_CANT_LOCK_ON;
+ this->actor.flags &= ~ACTOR_FLAG_100000;
+ this->action = EN_JSO_ACTION_FALL_DOWN_AND_TALK;
+ this->actionFunc = EnJso_FallDownAndTalk;
+}
+
+/**
+ * Handles the first part of the dialogue the Garo gives when defeated.
+ */
+void EnJso_FallDownAndTalk(EnJso* this, PlayState* play) {
+ f32 curFrame = this->skelAnime.curFrame;
+ Player* player = GET_PLAYER(play);
+
+ if (curFrame < this->animEndFrame) {
+ return;
+ }
+
+ if (!Play_InCsMode(play) && (play->msgCtx.msgLength == 0)) {
+ if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 60.0f) {
+ Player* player2 = GET_PLAYER(play);
+
+ this->actor.textId = sTextIds[this->textIndex];
+ Message_StartTextbox(play, this->actor.textId, &this->actor);
+ player2->stateFlags1 |= PLAYER_STATE1_10000000;
+ player2->actor.freezeTimer = 3;
+ this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
+ this->actionFunc = EnJso_TellHint;
+ } else {
+ EnJso_SetupReappear(this, play);
+ }
+ }
+}
+
+/**
+ * Handles the second part of the dialogue the Garo gives when defeated involving its specific hint. If the player has
+ * the Elegy of Emptiness, then the Garo ignore its specific hint and will instead always tell them that the Elegy can
+ * be used to climb Stone Tower. Once the Garo has given its hint, this function will have it say one final piece of
+ * dialogue and prepare for it to burst into flames.
+ */
+void EnJso_TellHint(EnJso* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ player->actor.freezeTimer = 3;
+
+ // Checking for Dawn of the Second Day, Night of the First Day, etc. messages
+ if ((play->msgCtx.currentTextId >= 0x1BB2) && (play->msgCtx.currentTextId < 0x1BB7)) {
+ this->actor.textId = sTextIds[this->textIndex];
+ Message_StartTextbox(play, this->actor.textId, &this->actor);
+ return;
+ }
+
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) {
+ Message_CloseTextbox(play);
+ if (this->textIndex == 2) {
+ u16 textId = 0x139C; // Hint about using Elegy to climb Stone Tower
+
+ switch (this->hintType) {
+ case EN_JSO_HINT_FREEZE_OCTOROKS:
+ textId = 0x139A; // Hint about freezing the Octoroks
+ break;
+
+ case EN_JSO_HINT_FLATS_LOCATION:
+ textId = 0x139B; // Hint about Flat being in the Graveyard
+ break;
+
+ case EN_JSO_HINT_VARIABLE_1:
+ textId = 0x139D; // Hint about Pamela's family being in the house with the waterwheel
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) {
+ textId = 0x13A1; // Hint about using the Song of Healing on Pamela's father
+ }
+ break;
+
+ case EN_JSO_HINT_VARIABLE_2:
+ textId = 0x139E; // Hint about Pamela leaving her house to check something
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) {
+ textId = 0x13A2; // Hint about the well being connected to Ikana Castle
+ }
+ break;
+
+ case EN_JSO_HINT_VARIABLE_3:
+ textId = 0x139F; // Hint about restoring the river by going into Sharp's cave
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) {
+ textId = 0x13A3; // Hint about the Gibdos in the well wanting items
+ }
+ break;
+
+ case EN_JSO_HINT_VARIABLE_4:
+ textId = 0x13A0; // Hint about needing the Song of Storms to pacify Sharp
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_14_04)) {
+ textId = 0x13A4; // Hint about the items the Gibdos want being in the well
+ }
+ break;
+
+ case EN_JSO_HINT_DANCING_REDEADS:
+ textId = 0x13A5; // Hint about the Redeads being able to dance
+ break;
+
+ case EN_JSO_HINT_DESTRUCTIBLE_CEILING_IN_CASTLE:
+ textId = 0x13A6; // Hint about the destructible ceiling in Ikana Castle
+ break;
+
+ case EN_JSO_HINT_SECOND_ENTRANCE_TO_CASTLE:
+ textId = 0x13A7; // Hint about the second entrance to Ikana Castle
+ break;
+
+ case EN_JSO_HINT_KING_WEAK_TO_MIRROR_SHIELD:
+ textId = 0x13A8; // Hint about using the Mirror Shield on Igos du Ikana
+ break;
+
+ default:
+ break;
+ }
+
+ if (CHECK_QUEST_ITEM(QUEST_SONG_ELEGY)) {
+ textId = 0x139C; // Hint about using Elegy to climb Stone Tower
+ }
+
+ Message_ContinueTextbox(play, textId);
+ this->textIndex++;
+ } else if (this->textIndex == 3) {
+ Message_ContinueTextbox(play, sTextIds[this->textIndex]);
+ this->actionFunc = EnJso_BurstIntoFlames;
+ }
+ }
+}
+
+/**
+ * Once the player closes the Garo's final textbox, this function will spawn nine green flames to obscure the Garo and
+ * kill the actor.
+ */
+void EnJso_BurstIntoFlames(EnJso* this, PlayState* play) {
+ Vec3f firePos;
+ Vec3f fireVelocityAndAccel[] = {
+ { 1.0f, 0.0f, 0.5f }, { 1.0f, 0.0f, -0.5f }, { -1.0f, 0.0f, 0.5f },
+ { -1.0f, 0.0f, -0.5f }, { 0.5f, 0.0f, 1.0f }, { -0.5f, 0.0f, 1.0f },
+ { 0.5f, 0.0f, -1.0f }, { -0.5f, 0.0f, -1.0f }, { 0.0f, 0.0f, 0.0f },
+ };
+ Player* player = GET_PLAYER(play);
+ f32 scale;
+ f32 scaleStep;
+ s32 i;
+
+ player->actor.freezeTimer = 3;
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) {
+ Player* player2 = GET_PLAYER(play);
+
+ Message_CloseTextbox(play);
+ for (i = 0; i < ARRAY_COUNT(fireVelocityAndAccel); i++) {
+ Math_Vec3f_Copy(&firePos, &this->actor.world.pos);
+ firePos.x += Rand_CenteredFloat(30.0f);
+ firePos.y = this->actor.floorHeight;
+ firePos.z += Rand_CenteredFloat(30.0f);
+ scale = (Rand_ZeroFloat(1.0f) * 100.0f) + 100.0f;
+ scaleStep = 20.0f;
+ func_800B3030(play, &firePos, &fireVelocityAndAccel[i], &fireVelocityAndAccel[i], scale, scaleStep, 1);
+ }
+
+ SoundSource_PlaySfxEachFrameAtFixedWorldPos(play, &this->actor.world.pos, 10,
+ NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG);
+
+ sIsAttacking = false;
+ this->isAttacking = false;
+ if (this->isPlayerLockedOn) {
+ this->isPlayerLockedOn = false;
+ sIsPlayerLockedOn = false;
+ }
+
+ player2->stateFlags1 &= ~PLAYER_STATE1_10000000;
+ Actor_Kill(&this->actor);
+ }
+}
+
+void EnJso_UpdateDamage(EnJso* this, PlayState* play) {
+ s32 attackDealsDamage = false;
+
+ if (this->bodyCollider.base.acFlags & AC_HIT) {
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
+ if ((this->actor.colChkInfo.damageEffect == EN_JSO_DMGEFF_STUN) ||
+ (this->actor.colChkInfo.damageEffect == EN_JSO_DMGEFF_ELECTRIC_STUN)) {
+ if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_SFX) &&
+ (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) ||
+ (this->drawDmgEffAlpha == 0)) {
+ Actor_PlaySfx(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_BLUE, 255, COLORFILTER_BUFFLAG_OPA, 40);
+ if (this->actor.colChkInfo.damageEffect == EN_JSO_DMGEFF_ELECTRIC_STUN) {
+ this->drawDmgEffAlpha = 40;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL;
+ }
+
+ EnJso_SetupStunned(this);
+ }
+ } else {
+ switch (this->action) {
+ case EN_JSO_ACTION_CIRCLE_PLAYER:
+ case EN_JSO_ACTION_GUARD:
+ this->actor.speed = 0.0f;
+ EnJso_SetupGuard(this);
+ attackDealsDamage = false;
+ break;
+
+ case EN_JSO_ACTION_DASH_ATTACK:
+ case EN_JSO_ACTION_SLASH:
+ case EN_JSO_ACTION_WAIT_AFTER_SLASH:
+ case EN_JSO_ACTION_STUNNED:
+ case EN_JSO_ACTION_COWER:
+ switch (this->actor.colChkInfo.damageEffect) {
+ case EN_JSO_DMGEFF_NONE:
+ attackDealsDamage = true;
+ break;
+
+ case EN_JSO_DMGEFF_FIRE:
+ this->drawDmgEffAlpha = 40;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ attackDealsDamage = true;
+ break;
+
+ case EN_JSO_DMGEFF_LIGHT_ORB:
+ if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_SFX) &&
+ (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) ||
+ (this->drawDmgEffAlpha == 0)) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->actor.focus.pos.x,
+ this->actor.focus.pos.y, this->actor.focus.pos.z, 0, 0, 0,
+ CLEAR_TAG_PARAMS(CLEAR_TAG_LARGE_LIGHT_RAYS));
+ this->drawDmgEffAlpha = 20;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS;
+ attackDealsDamage = true;
+ }
+ break;
+
+ case EN_JSO_DMGEFF_FREEZE:
+ if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_SFX) &&
+ (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) ||
+ (this->drawDmgEffAlpha == 0)) {
+ attackDealsDamage = false;
+ Actor_ApplyDamage(&this->actor);
+ this->drawDmgEffAlpha = 80;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX;
+ this->drawDmgEffScale = 0.0f;
+ this->drawDmgEffFrozenSteamScale = 1.5f;
+ }
+
+ if (this->actor.colChkInfo.health <= 0) {
+ EnJso_SetupDead(this, play);
+ attackDealsDamage = false;
+ } else {
+ EnJso_SetupStunned(this);
+ attackDealsDamage = false;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (attackDealsDamage) {
+ Actor_ApplyDamage(&this->actor);
+ this->bodyCollider.base.colType = COLTYPE_NONE;
+ this->bodyCollider.base.acFlags |= AC_HARD;
+ if (this->actor.colChkInfo.health > 0) {
+ EnJso_SetupDamaged(this, play);
+ } else {
+ EnJso_SetupDead(this, play);
+ }
+ }
+ }
+ }
+}
+
+void EnJso_Update(Actor* thisx, PlayState* play) {
+ EnJso* this = THIS;
+ s32 pad;
+
+ if ((this->action != EN_JSO_ACTION_CIRCLE_PLAYER) && !this->disableAnimations) {
+ SkelAnime_Update(&this->skelAnime);
+ }
+
+ EnJso_UpdateDamage(this, play);
+ if (this->actor.isLockedOn) {
+ sIsPlayerLockedOn = true;
+ this->isPlayerLockedOn = true;
+ } else if (this->isPlayerLockedOn) {
+ this->isPlayerLockedOn = false;
+ sIsPlayerLockedOn = false;
+ }
+
+ this->actionFunc(this, play);
+ DECR(this->dashAttackTimer);
+ DECR(this->attackWaitTimer);
+ DECR(this->timer);
+ DECR(this->drawDmgEffAlpha);
+
+ if (this->action != EN_JSO_ACTION_FALL_DOWN_AND_TALK) {
+ Actor_SetFocus(&this->actor, 50.0f);
+ } else {
+ Actor_SetFocus(&this->actor, 30.0f);
+ }
+
+ Actor_SetScale(&this->actor, this->scale);
+ Actor_MoveWithGravity(&this->actor);
+ this->actor.world.pos.x += this->knockbackVelocity.x;
+ this->actor.world.pos.z += this->knockbackVelocity.z;
+
+ if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
+ Math_ApproachZeroF(&this->knockbackVelocity.x, 1.0f, 2.0f);
+ Math_ApproachZeroF(&this->knockbackVelocity.z, 1.0f, 2.0f);
+ }
+
+ if (this->action != EN_JSO_ACTION_REAPPEAR) {
+ Actor_UpdateBgCheckInfo(play, &this->actor, 35.0f, 40.0f, 40.0f,
+ UPDBGCHECKINFO_FLAG_1 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_4 |
+ UPDBGCHECKINFO_FLAG_8 | UPDBGCHECKINFO_FLAG_10);
+ }
+
+ if ((this->action == EN_JSO_ACTION_SPIN_BEFORE_ATTACK) || (this->action == EN_JSO_ACTION_DASH_ATTACK)) {
+ this->afterimageIndex++;
+ if (this->afterimageIndex >= EN_JSO_AFTERIMAGE_COUNT) {
+ this->afterimageIndex = 0;
+ }
+
+ if (this->afterimageCount < EN_JSO_AFTERIMAGE_COUNT - 1) {
+ this->afterimageCount++;
+ }
+
+ this->afterimagePos[this->afterimageIndex] = this->actor.world.pos;
+ this->afterimagePos[this->afterimageIndex].y += 40.0f;
+ this->afterimageRot[this->afterimageIndex] = this->actor.world.rot;
+
+ {
+ s32 i;
+
+ for (i = 0; i < EN_JSO_AFTERIMAGE_COUNT; i++) {
+ this->afterimageJointTable[this->afterimageIndex][i] = this->jointTable[i];
+ }
+ }
+ } else {
+ this->afterimageCount = 0;
+ }
+
+ if ((this->action != EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE) && (this->action != EN_JSO_ACTION_CIRCLE_PLAYER) &&
+ (this->action != EN_JSO_ACTION_SPIN_BEFORE_ATTACK) && (this->action != EN_JSO_ACTION_DAMAGED) &&
+ (this->action != EN_JSO_ACTION_JUMP_BACK)) {
+ this->actor.shape.rot.y = this->actor.world.rot.y;
+ }
+
+ this->actor.shape.rot.x = this->actor.world.rot.x;
+ Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
+
+ if ((this->action != EN_JSO_ACTION_HANDLE_INTRO_CUTSCENE) && (this->action != EN_JSO_ACTION_REAPPEAR) &&
+ (this->action != EN_JSO_ACTION_DAMAGED) && (this->action != EN_JSO_ACTION_SPIN_BEFORE_ATTACK) &&
+ (this->action != EN_JSO_ACTION_DEAD) && (this->action != EN_JSO_ACTION_FALL_DOWN_AND_TALK) &&
+ (this->action != EN_JSO_ACTION_UNK_15)) {
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
+
+ if ((this->action == EN_JSO_ACTION_SLASH) && !this->swordHitSomething &&
+ (this->swordState == EN_JSO_SWORD_STATE_BOTH_DRAWN)) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->rightSwordCollider.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->leftSwordCollider.base);
+ }
+ }
+}
+
+s32 EnJso_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
+ EnJso* this = THIS;
+
+ if (limbIndex == GARO_LIMB_RIGHT_ARM) {
+ rot->x += this->rightArmRot.x;
+ rot->y += this->rightArmRot.y;
+ rot->z += this->rightArmRot.z;
+ }
+
+ if (limbIndex == GARO_LIMB_ROBE_RIGHT) {
+ rot->x += this->robeRightRot.x;
+ rot->y += this->robeRightRot.y;
+ rot->z += this->robeRightRot.z;
+ }
+
+ if ((limbIndex == GARO_LIMB_LEFT_SWORD) || (limbIndex == GARO_LIMB_RIGHT_SWORD)) {
+ if (this->swordState == EN_JSO_SWORD_STATE_NONE_DRAWN) {
+ *dList = NULL;
+ } else if (limbIndex == GARO_LIMB_LEFT_SWORD) {
+ if (this->swordState == EN_JSO_SWORD_STATE_RIGHT_DRAWN) {
+ *dList = NULL;
+ }
+ } else if ((limbIndex == GARO_LIMB_RIGHT_SWORD) && (this->swordState == EN_JSO_SWORD_STATE_LEFT_DRAWN)) {
+ *dList = NULL;
+ }
+ }
+
+ return false;
+}
+
+void EnJso_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
+ static Vec3f sSwordTipOffset = { 1600.0f, 0.0f, 0.0f };
+ static Vec3f sSwordBaseOffset = { 0.0f, 0.0f, 0.0f };
+ static Vec3f sSwordTipQuadOffset = { 1700.0f, 0.0f, 0.0f };
+ static Vec3f sSwordBaseQuadOffset = { 0.0f, 0.0f, 0.0f };
+ EnJso* this = THIS;
+ Vec3f swordTipPos;
+ Vec3f swordBasePos;
+
+ Matrix_Push();
+
+ if (limbIndex == GARO_LIMB_LEFT_SWORD) {
+ if (this->swordState == EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS) {
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_15), dList);
+ }
+
+ Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Math_Vec3f_Copy(&this->leftSwordCollider.dim.quad[3], &this->leftSwordCollider.dim.quad[1]);
+ Math_Vec3f_Copy(&this->leftSwordCollider.dim.quad[2], &this->leftSwordCollider.dim.quad[0]);
+ Matrix_MultVec3f(&sSwordTipQuadOffset, &this->leftSwordCollider.dim.quad[1]);
+ Matrix_MultVec3f(&sSwordBaseQuadOffset, &this->leftSwordCollider.dim.quad[0]);
+ Collider_SetQuadVertices(&this->leftSwordCollider, &this->leftSwordCollider.dim.quad[0],
+ &this->leftSwordCollider.dim.quad[1], &this->leftSwordCollider.dim.quad[2],
+ &this->leftSwordCollider.dim.quad[3]);
+ Matrix_MultVec3f(&sSwordTipOffset, &swordTipPos);
+ Matrix_MultVec3f(&sSwordBaseOffset, &swordBasePos);
+
+ if (((this->action == EN_JSO_ACTION_SLASH) || (this->action == EN_JSO_ACTION_DASH_ATTACK)) &&
+ !this->disableBlure) {
+ EffectBlure_AddVertex(Effect_GetByIndex(this->leftSwordBlureIndex), &swordTipPos, &swordBasePos);
+ } else if (this->disableBlure == true) {
+ EffectBlure_AddSpace(Effect_GetByIndex(this->leftSwordBlureIndex));
+ }
+ }
+
+ if (limbIndex == GARO_LIMB_RIGHT_SWORD) {
+ if (this->swordState == EN_JSO_SWORD_STATE_KNOCKED_OUT_OF_HANDS) {
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_15), dList);
+ this->swordState = EN_JSO_SWORD_STATE_NONE_DRAWN;
+ }
+
+ Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Math_Vec3f_Copy(&this->rightSwordCollider.dim.quad[3], &this->rightSwordCollider.dim.quad[1]);
+ Math_Vec3f_Copy(&this->rightSwordCollider.dim.quad[2], &this->rightSwordCollider.dim.quad[0]);
+ Matrix_MultVec3f(&sSwordTipQuadOffset, &this->rightSwordCollider.dim.quad[1]);
+ Matrix_MultVec3f(&sSwordBaseQuadOffset, &this->rightSwordCollider.dim.quad[0]);
+ Collider_SetQuadVertices(&this->rightSwordCollider, &this->rightSwordCollider.dim.quad[0],
+ &this->rightSwordCollider.dim.quad[1], &this->rightSwordCollider.dim.quad[2],
+ &this->rightSwordCollider.dim.quad[3]);
+ Matrix_MultVec3f(&sSwordTipOffset, &swordTipPos);
+ Matrix_MultVec3f(&sSwordBaseOffset, &swordBasePos);
+
+ if (((this->action == EN_JSO_ACTION_SLASH) || (this->action == EN_JSO_ACTION_DASH_ATTACK)) &&
+ !this->disableBlure) {
+ EffectBlure_AddVertex(Effect_GetByIndex(this->rightSwordBlureIndex), &swordTipPos, &swordBasePos);
+ } else if (this->disableBlure == true) {
+ EffectBlure_AddSpace(Effect_GetByIndex(this->rightSwordBlureIndex));
+ this->disableBlure = false;
+ }
+ }
+
+ if ((limbIndex == GARO_LIMB_LEFT_SWORD) || (limbIndex == GARO_LIMB_RIGHT_SWORD) ||
+ (limbIndex == GARO_LIMB_ROBE_TOP) || (limbIndex == GARO_LIMB_ROBE_BACK) || (limbIndex == GARO_LIMB_ROBE_LEFT) ||
+ (limbIndex == GARO_LIMB_ROBE_RIGHT) || (limbIndex == GARO_LIMB_ROBE_FRONT) || (limbIndex == GARO_LIMB_HEAD) ||
+ (limbIndex == GARO_LIMB_RIGHT_THIGH) || (limbIndex == GARO_LIMB_RIGHT_FOOT) ||
+ (limbIndex == GARO_LIMB_LEFT_THIGH) || (limbIndex == GARO_LIMB_LEFT_FOOT)) {
+ Matrix_MultZero(&this->bodyPartsPos[this->bodyPartIndex]);
+ this->bodyPartIndex++;
+ if (this->bodyPartIndex >= EN_JSO_BODYPART_MAX) {
+ this->bodyPartIndex = 0;
+ }
+ }
+
+ Matrix_Pop();
+}
+
+Gfx* EnJso_SetAfterimageRenderMode(GraphicsContext* gfxCtx) {
+ Gfx* gfxHead = GRAPH_ALLOC(gfxCtx, 2 * sizeof(Gfx));
+ Gfx* gfx = gfxHead;
+
+ gDPSetRenderMode(
+ gfx++, AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | G_RM_FOG_SHADE_A,
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL |
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA));
+ gSPEndDisplayList(gfx++);
+
+ return gfxHead;
+}
+
+void EnJso_Draw(Actor* thisx, PlayState* play) {
+ static s16 sAfterimageAlpha[EN_JSO_AFTERIMAGE_COUNT] = {
+ 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0, 0, 0, 0,
+ };
+ EnJso* this = THIS;
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL25_Xlu(play->state.gfxCtx);
+ Gfx_SetupDL25_Opa(play->state.gfxCtx);
+
+ gSPSegment(POLY_OPA_DISP++, 0x0C, D_801AEFA0);
+ SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
+ EnJso_OverrideLimbDraw, EnJso_PostLimbDraw, &this->actor);
+
+ if (this->afterimageCount > 0) {
+ s32 i;
+ s32 index = this->afterimageIndex;
+
+ for (i = 0; i < this->afterimageCount; i++) {
+ if (sAfterimageAlpha[i] == 0) {
+ continue;
+ }
+
+ Matrix_Translate(this->afterimagePos[index].x, this->afterimagePos[index].y, this->afterimagePos[index].z,
+ MTXMODE_NEW);
+ Matrix_Scale(this->scale, this->scale, this->scale, MTXMODE_APPLY);
+ //! @bug: These matrix rotation functions are supposed to be passed binangs, so using BINANG_TO_RAD here
+ //! is incorrect. Specifically, it results in rotation values far smaller than expected, since
+ //! BINANG_TO_RAD divides the angle by 0x8000. In-game, this bug manifests as the Garo's afterimages
+ //! looking the "wrong way", as they have a rotation close to (0, 0, 0) instead of matching the Garo's
+ //! rotation as intended. This bug can be fixed by using the correct matrix rotation functions (e.g.,
+ //! Matrix_RotateYF instead of Matrix_RotateYS) or by removing BINANG_TO_RAD entirely.
+ Matrix_RotateYS(BINANG_TO_RAD(this->afterimageRot[index].y), MTXMODE_APPLY);
+ Matrix_RotateXS(BINANG_TO_RAD(this->afterimageRot[index].x), MTXMODE_APPLY);
+ Matrix_RotateZS(BINANG_TO_RAD(this->afterimageRot[index].z), MTXMODE_APPLY);
+
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, sAfterimageAlpha[i]);
+ gSPSegment(POLY_XLU_DISP++, 0x0C, EnJso_SetAfterimageRenderMode(play->state.gfxCtx));
+ POLY_XLU_DISP = SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->afterimageJointTable[index],
+ this->skelAnime.dListCount, NULL, NULL, &this->actor, POLY_XLU_DISP);
+
+ index--;
+ if (index < 0) {
+ index = EN_JSO_AFTERIMAGE_COUNT - 1;
+ }
+ }
+ }
+
+ if (this->drawDmgEffAlpha != 0) {
+ f32 drawDmgEffAlpha = this->drawDmgEffAlpha * 0.05f;
+
+ if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) ||
+ (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) {
+ this->drawDmgEffScale += 0.3f;
+ if (this->drawDmgEffScale > 0.5f) {
+ this->drawDmgEffScale = 0.5f;
+ }
+
+ Math_ApproachF(&this->drawDmgEffFrozenSteamScale, this->drawDmgEffScale, 0.1f, 0.04f);
+ } else {
+ this->drawDmgEffScale = 0.8f;
+ this->drawDmgEffFrozenSteamScale = 0.8f;
+ }
+
+ Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, EN_JSO_BODYPART_MAX, this->drawDmgEffScale,
+ this->drawDmgEffFrozenSteamScale, drawDmgEffAlpha, this->drawDmgEffType);
+ }
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Jso/z_en_jso.h b/src/overlays/actors/ovl_En_Jso/z_en_jso.h
index 7f5db0757..7f97e5008 100644
--- a/src/overlays/actors/ovl_En_Jso/z_en_jso.h
+++ b/src/overlays/actors/ovl_En_Jso/z_en_jso.h
@@ -2,16 +2,107 @@
#define Z_EN_JSO_H
#include "global.h"
+#include "assets/objects/object_jso/object_jso.h"
struct EnJso;
+#define EN_JSO_GET_HINT_TYPE(thisx) ((thisx)->params)
+
+#define EN_JSO_AFTERIMAGE_COUNT 20
+
typedef void (*EnJsoActionFunc)(struct EnJso*, PlayState*);
+// For the four `VARIABLE` hint types, the former hint is used if the player hasn't restored the river in
+// Ikana Canyon yet, and the latter hint is used if the player has. If the player has the Elegy of Emptiness,
+// then all hints will be replaced with a hint telling the player to use the song to climb Stone Tower.
+typedef enum {
+ /* 0 */ EN_JSO_HINT_FREEZE_OCTOROKS,
+ /* 1 */ EN_JSO_HINT_FLATS_LOCATION,
+ /* 2 */ EN_JSO_HINT_VARIABLE_1, // Hints that Pamela's family is in the house or that the Song of Healing can heal Pamela's father
+ /* 3 */ EN_JSO_HINT_VARIABLE_2, // Hints that Pamela leaves the house to check something or that the well is connected to Ikana Castle
+ /* 4 */ EN_JSO_HINT_VARIABLE_3, // Hints that they can restore the river by going to Sharp's cave or that the Gidbos in the well want items
+ /* 5 */ EN_JSO_HINT_VARIABLE_4, // Hints that they need to Song of Storms to stop Sharp or that the items the Gibdos want can be found in the well
+ /* 6 */ EN_JSO_HINT_DANCING_REDEADS,
+ /* 7 */ EN_JSO_HINT_DESTRUCTIBLE_CEILING_IN_CASTLE,
+ /* 8 */ EN_JSO_HINT_SECOND_ENTRANCE_TO_CASTLE,
+ /* 9 */ EN_JSO_HINT_KING_WEAK_TO_MIRROR_SHIELD
+} EnJsoHintType;
+
+typedef enum {
+ /* 0 */ EN_JSO_BODYPART_LEFT_SWORD,
+ /* 1 */ EN_JSO_BODYPART_RIGHT_SWORD,
+ /* 2 */ EN_JSO_BODYPART_ROBE_TOP,
+ /* 3 */ EN_JSO_BODYPART_ROBE_BACK,
+ /* 4 */ EN_JSO_BODYPART_ROBE_LEFT,
+ /* 5 */ EN_JSO_BODYPART_ROBE_RIGHT,
+ /* 6 */ EN_JSO_BODYPART_ROBE_FRONT,
+ /* 7 */ EN_JSO_BODYPART_HEAD,
+ /* 8 */ EN_JSO_BODYPART_RIGHT_THIGH,
+ /* 9 */ EN_JSO_BODYPART_RIGHT_FOOT,
+ /* 10 */ EN_JSO_BODYPART_LEFT_THIGH,
+ /* 11 */ EN_JSO_BODYPART_LEFT_FOOT,
+ /* 12 */ EN_JSO_BODYPART_MAX
+} EnJsoBodyPart;
+
+
typedef struct EnJso {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x134];
+ /* 0x144 */ SkelAnime skelAnime;
+ /* 0x188 */ Vec3s jointTable[GARO_LIMB_MAX];
+ /* 0x200 */ Vec3s morphTable[GARO_LIMB_MAX];
/* 0x278 */ EnJsoActionFunc actionFunc;
- /* 0x27C */ char unk_27C[0xD70];
+ /* 0x27C */ s16 action;
+ /* 0x27E */ s16 circlingAngle;
+ /* 0x280 */ s16 circlingAngularVelocity;
+ /* 0x282 */ s16 dashAttackTimer;
+ /* 0x284 */ UNK_TYPE1 unk_284[0x2];
+ /* 0x286 */ s16 attackWaitTimer; // while bouncing, the Garo cannot start an attack until this reaches 0
+ /* 0x288 */ s16 timer;
+ /* 0x28A */ s16 isGuarding; // Set to false when the guard animation ends, never checked or set otherwise. Name is inferred based on how it's being set.
+ /* 0x28C */ s16 isPlayerLockedOn;
+ /* 0x28E */ s16 isAttacking;
+ /* 0x290 */ Vec3s robeRightRot;
+ /* 0x296 */ Vec3s targetRobeRightRot;
+ /* 0x29C */ Vec3s rightArmRot;
+ /* 0x2A2 */ Vec3s targetRightArmRot;
+ /* 0x2A8 */ s16 drawDmgEffAlpha;
+ /* 0x2AA */ s16 drawDmgEffType;
+ /* 0x2AC */ f32 drawDmgEffScale;
+ /* 0x2B0 */ f32 drawDmgEffFrozenSteamScale;
+ /* 0x2B4 */ Vec3f bodyPartsPos[EN_JSO_BODYPART_MAX];
+ /* 0x344 */ s16 bodyPartIndex;
+ /* 0x346 */ s16 disableAnimations; // Checked but never set, so it's implicitly always false. Name is inferred based on how it's being checked.
+ /* 0x348 */ s16 textIndex;
+ /* 0x34A */ s16 hintType;
+ /* 0x34C */ u8 disableBlure;
+ /* 0x34D */ u8 swordState;
+ /* 0x34E */ u8 swordHitSomething;
+ /* 0x350 */ f32 animEndFrame;
+ /* 0x354 */ f32 scale;
+ /* 0x358 */ UNK_TYPE1 unk_358[0x4];
+ /* 0x35C */ ColliderCylinder bodyCollider;
+ /* 0x3A8 */ ColliderQuad rightSwordCollider;
+ /* 0x428 */ ColliderQuad leftSwordCollider;
+ /* 0x4A8 */ s32 rightSwordBlureIndex;
+ /* 0x4AC */ s32 leftSwordBlureIndex;
+ /* 0x4B0 */ s16 afterimageIndex;
+ /* 0x4B4 */ s32 afterimageCount;
+ /* 0x4B8 */ s16 csId;
+ /* 0x4BC */ u32 introCsTimer;
+ /* 0x4C0 */ s16 introCsState;
+ /* 0x4C2 */ s16 subCamId;
+ /* 0x4C4 */ UNK_TYPE1 unk_4C4[0x4];
+ /* 0x4C8 */ Vec3f subCamEye;
+ /* 0x4D4 */ Vec3f subCamAt;
+ /* 0x4E0 */ Vec3f subCamUp;
+ /* 0x4EC */ Vec3f subCamEyeNext;
+ /* 0x4F8 */ Vec3f subCamAtNext;
+ /* 0x504 */ UNK_TYPE1 unk_504[0x10];
+ /* 0x514 */ s16 introCsType;
+ /* 0x518 */ Vec3f afterimagePos[EN_JSO_AFTERIMAGE_COUNT];
+ /* 0x608 */ Vec3s afterimageRot[EN_JSO_AFTERIMAGE_COUNT];
+ /* 0x680 */ Vec3s afterimageJointTable[EN_JSO_AFTERIMAGE_COUNT][GARO_LIMB_MAX];
+ /* 0xFE0 */ Vec3f knockbackVelocity; // Adds a little push backwards when the Garo is bounced off the player's shield, damaged, or stunned
} EnJso; // size = 0xFEC
#endif // Z_EN_JSO_H
diff --git a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c
index abba3efac..59ba5feb4 100644
--- a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c
+++ b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c
@@ -287,11 +287,11 @@ void EnKaizoku_Init(Actor* thisx, PlayState* play) {
Actor_SetScale(&this->picto.actor, 0.0125f);
this->picto.actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
this->picto.actor.flags &= ~ACTOR_FLAG_TARGETABLE;
- if (this->switchFlag == 127) {
- this->switchFlag = -1;
+ if (this->switchFlag == KAIZOKU_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->picto.actor);
return;
}
@@ -867,7 +867,7 @@ void func_80B86B74(EnKaizoku* this, PlayState* play) {
this->subCamId = SUB_CAM_ID_DONE;
func_800B7298(play, &this->picto.actor, PLAYER_CSMODE_END);
CutsceneManager_Stop(this->csId);
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
Actor_Kill(&this->picto.actor);
diff --git a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h
index 423819eb3..15562ee2e 100644
--- a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h
+++ b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h
@@ -5,13 +5,15 @@
#include "z64snap.h"
#include "objects/object_kz/object_kz.h"
-#define KAIZOKU_GET_EXIT_INDEX(thisx) ((thisx)->params & 0x3F)
-#define KAIZOKU_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 6) & 0x7F)
-
struct EnKaizoku;
typedef void (*EnKaizokuActionFunc)(struct EnKaizoku*, PlayState*);
+#define KAIZOKU_GET_EXIT_INDEX(thisx) ((thisx)->params & 0x3F)
+#define KAIZOKU_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 6) & 0x7F)
+
+#define KAIZOKU_SWITCH_FLAG_NONE 0x7F
+
typedef enum EnKaizokuAnimation {
/* 0 */ EN_KAIZOKU_ANIM_0,
/* 1 */ EN_KAIZOKU_ANIM_1,
diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c
index 880f48e82..09358e034 100644
--- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c
+++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c
@@ -113,13 +113,13 @@ void EnLookNuts_Init(Actor* thisx, PlayState* play) {
Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
this->pathIndex = LOOKNUTS_GET_PATH_INDEX(&this->actor);
- this->switchFlag = LOOKNUTS_GET_SCENE_FLAG(&this->actor);
+ this->switchFlag = LOOKNUTS_GET_SWITCH_FLAG(&this->actor);
this->spawnIndex = LOOKNUTS_GET_SPAWN_INDEX(&this->actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == LOOKNUTS_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h
index 92c24cfbd..1cce177d4 100644
--- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h
+++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h
@@ -9,9 +9,10 @@ struct EnLookNuts;
typedef void (*EnLookNutsActionFunc)(struct EnLookNuts*, PlayState*);
#define LOOKNUTS_GET_SPAWN_INDEX(thisx) (((thisx)->params >> 0xC) & 0xF)
-#define LOOKNUTS_GET_SCENE_FLAG(thisx) ((thisx)->params & 0x7F)
+#define LOOKNUTS_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
#define LOOKNUTS_GET_PATH_INDEX(thisx) (((thisx)->params >> 0x7) & 0x1F)
+#define LOOKNUTS_SWITCH_FLAG_NONE 0x7F
#define LOOKNUTS_PATH_INDEX_NONE 0x1F
typedef struct EnLookNuts {
diff --git a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c
index 8495411d5..ce3beaa2a 100644
--- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c
+++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c
@@ -150,7 +150,7 @@ void EnMinifrog_Destroy(Actor* thisx, PlayState* play) {
Collider_DestroyCylinder(play, &this->collider);
if (this->flags & 0x100) {
- func_801A1F88();
+ Audio_StopSequenceAtDefaultPos();
}
}
@@ -438,7 +438,7 @@ void EnMinifrog_SetupNextFrogChoir(EnMinifrog* this, PlayState* play) {
this->actionFunc = EnMinifrog_NextFrogMissing;
this->timer = 60;
this->actor.home.rot.y = Actor_WorldYawTowardActor(&this->actor, &this->frog->actor);
- func_801A1F88();
+ Audio_StopSequenceAtDefaultPos();
this->flags &= ~0x100;
this->flags &=
~(0x2 << FROG_YELLOW | 0x2 << FROG_CYAN | 0x2 << FROG_PINK | 0x2 << FROG_BLUE | 0x2 << FROG_WHITE);
@@ -460,7 +460,7 @@ void EnMinifrog_BeginChoirCutscene(EnMinifrog* this, PlayState* play) {
CutsceneManager_Start(this->actor.csId, &this->actor);
this->actionFunc = EnMinifrog_SetupNextFrogChoir;
this->timer = 5;
- func_801A1F00(3, NA_BGM_FROG_SONG);
+ Audio_PlaySequenceAtDefaultPos(SEQ_PLAYER_BGM_SUB, NA_BGM_FROG_SONG);
this->flags |= 0x100;
play->setPlayerTalkAnim(play, &gPlayerAnim_pn_gakkiplay, ANIMMODE_LOOP);
} else {
diff --git a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c
index 82e25a95d..1a2925f65 100644
--- a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c
+++ b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c
@@ -897,7 +897,7 @@ void EnMnk_Monkey_Run(EnMnk* this, PlayState* play) {
this->picto.actor.speed = 0.0f;
if (MONKEY_GET_TYPE(&this->picto.actor) == MONKEY_OUTSIDECHAMBER) {
switchFlag = MONKEY_GET_SWITCH_FLAG(&this->picto.actor);
- if (switchFlag != 0x7F) {
+ if (switchFlag != MONKEY_SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, switchFlag + 1);
}
Actor_Kill(&this->picto.actor);
diff --git a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h
index a9493208f..42a23f99c 100644
--- a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h
+++ b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.h
@@ -14,6 +14,7 @@ typedef void (*EnMnkFunc)(PlayState*, struct EnMnk*);
#define MONKEY_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
#define MONKEY_GET_PATH_INDEX(thisx) (((thisx)->params & 0xF800) >> 11)
+#define MONKEY_SWITCH_FLAG_NONE 0x7F
#define MONKEY_PATH_INDEX_NONE 0x1F
typedef enum {
diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c
index 9119e0609..4b225880b 100644
--- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c
+++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c
@@ -50,8 +50,8 @@ void EnOkarinaTag_Init(Actor* thisx, PlayState* play) {
}
this->unk154 = zRot * 50.0f;
this->unk158 = i * 50.0f;
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == ENOKARINATAG_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
if (this->unk14A == 0xF) {
this->unk14A = -1;
@@ -66,7 +66,7 @@ void func_8093E518(EnOkarinaTag* this, PlayState* play) {
s16 yDiff;
u16 var_v1;
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
if (this->unk148 == 0) {
if (Flags_GetSwitch(play, this->switchFlag)) {
return;
@@ -122,7 +122,7 @@ void func_8093E68C(EnOkarinaTag* this, PlayState* play) {
(play->msgCtx.ocarinaMode == OCARINA_MODE_PLAYED_SUNS) ||
(play->msgCtx.ocarinaMode == OCARINA_MODE_PLAYED_STORMS) ||
(play->msgCtx.ocarinaMode == OCARINA_MODE_F)))) {
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
switch (this->unk148) {
case 0:
Flags_SetSwitch(play, this->switchFlag);
diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h
index 4c968b362..649f3b3da 100644
--- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h
+++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h
@@ -11,6 +11,8 @@ typedef void (*EnOkarinaTagActionFunc)(struct EnOkarinaTag*, PlayState*);
#define ENOKARINATAG_GET_780(thisx) (((thisx)->params >> 0x7) & 0xF)
#define ENOKARINATAG_GET_F800(thisx) (((thisx)->params >> 0xB) & 0x1F)
+#define ENOKARINATAG_SWITCH_FLAG_NONE 0x7F
+
typedef struct EnOkarinaTag {
/* 0x000 */ Actor actor;
/* 0x144 */ EnOkarinaTagActionFunc actionFunc;
diff --git a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c
index 4e666ed5c..eb6907c7c 100644
--- a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c
+++ b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c
@@ -102,7 +102,7 @@ void func_80B11F78(EnOnpuman* this, PlayState* play) {
void func_80B1202C(EnOnpuman* this, PlayState* play2) {
PlayState* play = play2;
- if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && (Message_ShouldAdvance(play))) {
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) {
switch (play->msgCtx.currentTextId) {
case 0x8D4:
this->unk_2A4 |= 1;
@@ -138,7 +138,7 @@ void func_80B1202C(EnOnpuman* this, PlayState* play2) {
}
void func_80B1217C(EnOnpuman* this, PlayState* play) {
- if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && (Message_ShouldAdvance(play))) {
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) {
this->actionFunc = func_80B121D8;
Message_CloseTextbox(play);
}
diff --git a/src/overlays/actors/ovl_En_Part/z_en_part.h b/src/overlays/actors/ovl_En_Part/z_en_part.h
index 5bd4de503..4a766276d 100644
--- a/src/overlays/actors/ovl_En_Part/z_en_part.h
+++ b/src/overlays/actors/ovl_En_Part/z_en_part.h
@@ -5,6 +5,8 @@
struct EnPart;
+#define ENPART_PARAMS(type) (type)
+
typedef void (*EnPartActionFunc)(struct EnPart*, PlayState*);
typedef enum {
diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
index 1c301a8bf..f0109b40a 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
@@ -7,7 +7,6 @@
#include "prevent_bss_reordering.h"
#include "z_en_poh.h"
#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
-#include "objects/object_po/object_po.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_200 | ACTOR_FLAG_IGNORE_QUAKE)
@@ -167,8 +166,7 @@ void EnPoh_Init(Actor* thisx, PlayState* play) {
this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo);
Lights_PointGlowSetInfo(&this->lightInfo, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z,
255, 255, 255, 0);
- SkelAnime_Init(play, &this->skelAnime, &object_po_Skel_0050D0, &object_po_Anim_000A60, this->jointTable,
- this->morphTable, 21);
+ SkelAnime_Init(play, &this->skelAnime, &gPoeSkel, &gPoeFloatAnim, this->jointTable, this->morphTable, POE_LIMB_MAX);
this->actor.bgCheckFlags |= BGCHECKFLAG_PLAYER_400;
func_80B2D0E8(this);
}
@@ -215,7 +213,7 @@ void func_80B2C9B8(EnPoh* this, PlayState* play) {
}
void func_80B2CA4C(EnPoh* this) {
- Animation_PlayLoop(&this->skelAnime, &object_po_Anim_0015B0);
+ Animation_PlayLoop(&this->skelAnime, &gPoeDisappearAnim);
this->unk_18E = Rand_S16Offset(2, 3);
this->actionFunc = func_80B2CAA4;
this->actor.speed = 0.0f;
@@ -241,7 +239,7 @@ void func_80B2CAA4(EnPoh* this, PlayState* play) {
}
void func_80B2CB60(EnPoh* this) {
- Animation_PlayLoop(&this->skelAnime, &object_po_Anim_000A60);
+ Animation_PlayLoop(&this->skelAnime, &gPoeFloatAnim);
this->unk_18E = Rand_S16Offset(15, 3);
this->colliderCylinder.base.acFlags |= AC_ON;
this->actionFunc = func_80B2CBBC;
@@ -276,7 +274,7 @@ void func_80B2CBBC(EnPoh* this, PlayState* play) {
}
void func_80B2CD14(EnPoh* this) {
- Animation_PlayLoop(&this->skelAnime, &object_po_Anim_000A60);
+ Animation_PlayLoop(&this->skelAnime, &gPoeFloatAnim);
this->actionFunc = func_80B2CD64;
this->unk_18E = 0;
this->actor.speed = 2.0f;
@@ -315,7 +313,7 @@ void func_80B2CD64(EnPoh* this, PlayState* play) {
}
void func_80B2CEC8(EnPoh* this) {
- Animation_MorphToLoop(&this->skelAnime, &object_po_Anim_0001A8, -6.0f);
+ Animation_MorphToLoop(&this->skelAnime, &gPoeAttackAnim, -6.0f);
this->unk_18E = 12;
this->actor.speed = 0.0f;
Actor_PlaySfx(&this->actor, NA_SE_EN_PO_LAUGH);
@@ -344,7 +342,7 @@ void func_80B2CF28(EnPoh* this, PlayState* play) {
}
void func_80B2CFF8(EnPoh* this) {
- Animation_MorphToPlayOnce(&this->skelAnime, &object_po_Anim_0004EC, -6.0f);
+ Animation_MorphToPlayOnce(&this->skelAnime, &gPoeDamagedAnim, -6.0f);
func_800BE504(&this->actor, &this->colliderCylinder);
this->colliderCylinder.base.acFlags &= ~AC_ON;
this->actor.speed = 5.0f;
@@ -366,7 +364,7 @@ void func_80B2D07C(EnPoh* this, PlayState* play) {
void func_80B2D0E8(EnPoh* this) {
this->unk_197 = 0;
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
- Animation_PlayOnceSetSpeed(&this->skelAnime, &object_po_Anim_0011C4, 0.0f);
+ Animation_PlayOnceSetSpeed(&this->skelAnime, &gPoeAppearAnim, 0.0f);
this->actionFunc = func_80B2D140;
}
@@ -445,7 +443,7 @@ void func_80B2D300(EnPoh* this, PlayState* play) {
}
void func_80B2D5DC(EnPoh* this) {
- Animation_PlayOnce(&this->skelAnime, &object_po_Anim_000A60);
+ Animation_PlayOnce(&this->skelAnime, &gPoeFloatAnim);
this->actionFunc = func_80B2D628;
this->actor.speed = -5.0f;
}
@@ -462,7 +460,7 @@ void func_80B2D628(EnPoh* this, PlayState* play) {
}
void func_80B2D694(EnPoh* this) {
- Animation_PlayLoop(&this->skelAnime, &object_po_Anim_0015B0);
+ Animation_PlayLoop(&this->skelAnime, &gPoeDisappearAnim);
this->unk_192 = BINANG_ROT180(this->actor.world.rot.y);
this->actionFunc = func_80B2D6EC;
this->actor.speed = 0.0f;
@@ -540,7 +538,7 @@ void func_80B2D980(EnPoh* this, PlayState* play) {
}
void func_80B2DAD0(EnPoh* this) {
- Animation_MorphToLoop(&this->skelAnime, &object_po_Anim_0006E0, -5.0f);
+ Animation_MorphToLoop(&this->skelAnime, &gPoeFleeAnim, -5.0f);
this->actor.speed = 5.0f;
this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y);
this->colliderCylinder.base.acFlags |= AC_ON;
@@ -585,7 +583,7 @@ void func_80B2DC50(EnPoh* this, PlayState* play) {
void func_80B2DD2C(EnPoh* this, PlayState* play) {
if ((this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) || (this->actor.floorHeight <= BGCHECK_Y_MIN)) {
- EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO, 10, object_po_DL_002D28);
+ EffectSsHahen_SpawnBurst(play, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO, 10, gPoeLanternDL);
func_80B2E0B0(this);
}
@@ -864,34 +862,34 @@ s32 EnPoh_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p
return false;
}
-static s8 sLimbToBodyParts[OBJECT_PO_LIMB_MAX] = {
- BODYPART_NONE, // OBJECT_PO_LIMB_NONE
- BODYPART_NONE, // OBJECT_PO_LIMB_01
- BODYPART_NONE, // OBJECT_PO_LIMB_02
- BODYPART_NONE, // OBJECT_PO_LIMB_03
- ENPOH_BODYPART_4, // OBJECT_PO_LIMB_04
- ENPOH_BODYPART_5, // OBJECT_PO_LIMB_05
- BODYPART_NONE, // OBJECT_PO_LIMB_06
- BODYPART_NONE, // OBJECT_PO_LIMB_07
- BODYPART_NONE, // OBJECT_PO_LIMB_08
- ENPOH_BODYPART_0, // OBJECT_PO_LIMB_09
- ENPOH_BODYPART_1, // OBJECT_PO_LIMB_0A
- BODYPART_NONE, // OBJECT_PO_LIMB_0B
- BODYPART_NONE, // OBJECT_PO_LIMB_0C
- BODYPART_NONE, // OBJECT_PO_LIMB_0D
- BODYPART_NONE, // OBJECT_PO_LIMB_0E
- BODYPART_NONE, // OBJECT_PO_LIMB_0F
- ENPOH_BODYPART_2, // OBJECT_PO_LIMB_10
- BODYPART_NONE, // OBJECT_PO_LIMB_11
- BODYPART_NONE, // OBJECT_PO_LIMB_12
- ENPOH_BODYPART_3, // OBJECT_PO_LIMB_13
- BODYPART_NONE, // OBJECT_PO_LIMB_14
+static s8 sLimbToBodyParts[POE_LIMB_MAX] = {
+ BODYPART_NONE, // POE_LIMB_NONE
+ BODYPART_NONE, // POE_LIMB_ROOT
+ BODYPART_NONE, // POE_LIMB_ROOT_WRAPPER
+ BODYPART_NONE, // POE_LIMB_BOTTOM_CLOAK_ROOT
+ POE_BODYPART_BOTTOM_CLOAK, // POE_LIMB_BOTTOM_CLOAK
+ POE_BODYPART_TOP_CLOAK, // POE_LIMB_TOP_CLOAK
+ BODYPART_NONE, // POE_LIMB_LEFT_ARM_ROOT
+ BODYPART_NONE, // POE_LIMB_LEFT_ARM_WRAPPER
+ BODYPART_NONE, // POE_LIMB_LEFT_FOREARM_ROOT
+ POE_BODYPART_LEFT_FOREARM, // POE_LIMB_LEFT_FOREARM
+ POE_BODYPART_LEFT_UPPER_ARM, // POE_LIMB_LEFT_UPPER_ARM
+ BODYPART_NONE, // POE_LIMB_FACE
+ BODYPART_NONE, // POE_LIMB_RIGHT_ARM_ROOT
+ BODYPART_NONE, // POE_LIMB_RIGHT_ARM_WRAPPER
+ BODYPART_NONE, // POE_LIMB_RIGHT_FOREARM_ROOT
+ BODYPART_NONE, // POE_LIMB_RIGHT_ARM_HAND_ROOT
+ POE_BODYPART_RIGHT_ARM_HAND, // POE_LIMB_RIGHT_ARM_HAND
+ BODYPART_NONE, // POE_LIMB_LANTERN_ROOT
+ BODYPART_NONE, // POE_LIMB_LANTERN
+ POE_BODYPART_RIGHT_FOREARM, // POE_LIMB_RIGHT_FOREARM
+ BODYPART_NONE, // POE_LIMB_RIGHT_UPPER_ARM
};
static Vec3f D_80B2F734[] = {
- { -600.0f, 500.0f, 1700.0f }, // ENPOH_BODYPART_7
- { -600.0f, 500.0f, -1700.0f }, // ENPOH_BODYPART_8
- { 1000.0f, 1700.0f, 0.0f }, // ENPOH_BODYPART_9
+ { -600.0f, 500.0f, 1700.0f }, // POE_BODYPART_7
+ { -600.0f, 500.0f, -1700.0f }, // POE_BODYPART_8
+ { 1000.0f, 1700.0f, 0.0f }, // POE_BODYPART_9
};
void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) {
@@ -903,7 +901,7 @@ void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
Collider_UpdateSpheres(limbIndex, &this->colliderSph);
if ((this->actionFunc == func_80B2D300) && (this->unk_18E >= 2) && (limbIndex == 5)) {
gSPMatrix((*gfx)++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList((*gfx)++, object_po_DL_002608);
+ gSPDisplayList((*gfx)++, gPoeBurnDL);
}
if (limbIndex == 18) {
@@ -921,19 +919,19 @@ void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
bodyPartIndex = sLimbToBodyParts[limbIndex];
if (bodyPartIndex != BODYPART_NONE) {
- if (bodyPartIndex <= ENPOH_BODYPART_3) {
+ if (bodyPartIndex <= POE_BODYPART_RIGHT_FOREARM) {
Matrix_MultZero(&this->bodyPartsPos[bodyPartIndex]);
- } else if (bodyPartIndex == ENPOH_BODYPART_4) {
+ } else if (bodyPartIndex == POE_BODYPART_BOTTOM_CLOAK) {
Matrix_MultVecX(2000.0f, &this->bodyPartsPos[bodyPartIndex]);
} else {
s32 i;
Vec3f* vec = &this->bodyPartsPos[bodyPartIndex + 2];
Vec3f* vec2 = &D_80B2F734[0];
- Matrix_MultVecX(-2000.0f, &this->bodyPartsPos[bodyPartIndex]); // ENPOH_BODYPART_5
- Matrix_MultVecY(-2000.0f, &this->bodyPartsPos[bodyPartIndex + 1]); // ENPOH_BODYPART_6
+ Matrix_MultVecX(-2000.0f, &this->bodyPartsPos[bodyPartIndex]); // POE_BODYPART_TOP_CLOAK
+ Matrix_MultVecY(-2000.0f, &this->bodyPartsPos[bodyPartIndex + 1]); // POE_BODYPART_6
- for (i = bodyPartIndex + 2; i < ENPOH_BODYPART_MAX; i++, vec++, vec2++) {
+ for (i = bodyPartIndex + 2; i < POE_BODYPART_MAX; i++, vec++, vec2++) {
Matrix_MultVec3f(vec2, vec);
}
}
@@ -978,10 +976,10 @@ void EnPoh_Draw(Actor* thisx, PlayState* play) {
Matrix_Put(&this->unk_3D8);
gSPMatrix(&gfx[2], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(&gfx[3], object_po_DL_002D28);
+ gSPDisplayList(&gfx[3], gPoeLanternDL);
POLY_OPA_DISP = &gfx[4];
- Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, ENPOH_BODYPART_MAX,
+ Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, POE_BODYPART_MAX,
this->actor.scale.x * 100.0f * this->drawDmgEffScale, 0.0f, this->drawDmgEffAlpha,
ACTOR_DRAW_DMGEFF_LIGHT_ORBS);
@@ -1018,7 +1016,7 @@ void func_80B2F37C(Actor* thisx, PlayState* play) {
this->actor.world.pos.z + sp7C.z, this->unk_198, this->unk_199, this->unk_19A, 200);
gSPMatrix(&gfx[2], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(&gfx[3], object_po_DL_002D28);
+ gSPDisplayList(&gfx[3], gPoeLanternDL);
POLY_OPA_DISP = &gfx[4];
} else {
@@ -1033,7 +1031,7 @@ void func_80B2F37C(Actor* thisx, PlayState* play) {
Matrix_RotateYF(BINANG_TO_RAD(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000), MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(POLY_XLU_DISP++, object_po_DL_003850);
+ gSPDisplayList(POLY_XLU_DISP++, gPoeSoulDL);
}
CLOSE_DISPS(play->state.gfxCtx);
diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.h b/src/overlays/actors/ovl_En_Poh/z_en_poh.h
index 5f7439e4a..7c3e47eed 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.h
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.h
@@ -2,23 +2,24 @@
#define Z_EN_POH_H
#include "global.h"
+#include "objects/object_po/object_po.h"
struct EnPoh;
typedef void (*EnPohActionFunc)(struct EnPoh*, PlayState*);
typedef enum EnPohBodyPart {
- /* 0 */ ENPOH_BODYPART_0,
- /* 1 */ ENPOH_BODYPART_1,
- /* 2 */ ENPOH_BODYPART_2,
- /* 3 */ ENPOH_BODYPART_3,
- /* 4 */ ENPOH_BODYPART_4,
- /* 5 */ ENPOH_BODYPART_5,
- /* 6 */ ENPOH_BODYPART_6,
- /* 7 */ ENPOH_BODYPART_7,
- /* 8 */ ENPOH_BODYPART_8,
- /* 9 */ ENPOH_BODYPART_9,
- /* 10 */ ENPOH_BODYPART_MAX
+ /* 0 */ POE_BODYPART_LEFT_FOREARM,
+ /* 1 */ POE_BODYPART_LEFT_UPPER_ARM,
+ /* 2 */ POE_BODYPART_RIGHT_ARM_HAND,
+ /* 3 */ POE_BODYPART_RIGHT_FOREARM,
+ /* 4 */ POE_BODYPART_BOTTOM_CLOAK,
+ /* 5 */ POE_BODYPART_TOP_CLOAK,
+ /* 6 */ POE_BODYPART_6,
+ /* 7 */ POE_BODYPART_7,
+ /* 8 */ POE_BODYPART_8,
+ /* 9 */ POE_BODYPART_9,
+ /* 10 */ POE_BODYPART_MAX
} EnPohBodyPart;
typedef struct EnPoh {
@@ -38,11 +39,11 @@ typedef struct EnPoh {
/* 0x199 */ u8 unk_199;
/* 0x19A */ u8 unk_19A;
/* 0x19B */ u8 unk_19B;
- /* 0x19C */ Vec3s jointTable[21];
- /* 0x21A */ Vec3s morphTable[21];
+ /* 0x19C */ Vec3s jointTable[POE_LIMB_MAX];
+ /* 0x21A */ Vec3s morphTable[POE_LIMB_MAX];
/* 0x298 */ f32 drawDmgEffAlpha;
/* 0x29C */ f32 drawDmgEffScale;
- /* 0x2A0 */ Vec3f bodyPartsPos[ENPOH_BODYPART_MAX];
+ /* 0x2A0 */ Vec3f bodyPartsPos[POE_BODYPART_MAX];
/* 0x318 */ LightNode* lightNode;
/* 0x31C */ LightInfo lightInfo;
/* 0x32C */ ColliderCylinder colliderCylinder;
diff --git a/src/overlays/actors/ovl_En_Raf/z_en_raf.c b/src/overlays/actors/ovl_En_Raf/z_en_raf.c
index 1c6a669a2..a7b7d9c13 100644
--- a/src/overlays/actors/ovl_En_Raf/z_en_raf.c
+++ b/src/overlays/actors/ovl_En_Raf/z_en_raf.c
@@ -225,8 +225,8 @@ void EnRaf_Init(Actor* thisx, PlayState* play) {
this->mainType = EN_RAF_GET_TYPE(&this->dyna.actor);
this->reviveTimer = EN_RAF_GET_REVIVE_TIMER(&this->dyna.actor);
this->switchFlag = EN_RAF_GET_SWITCH_FLAG(&this->dyna.actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == EN_RAF_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
if (this->reviveTimer == 31) {
@@ -235,7 +235,7 @@ void EnRaf_Init(Actor* thisx, PlayState* play) {
this->reviveTimer = 30;
}
- if (((this->switchFlag >= 0) || (this->mainType == EN_RAF_TYPE_DORMANT) ||
+ if (((this->switchFlag > SWITCH_FLAG_NONE) || (this->mainType == EN_RAF_TYPE_DORMANT) ||
CHECK_WEEKEVENTREG(WEEKEVENTREG_12_01)) &&
(Flags_GetSwitch(play, this->switchFlag) || (this->mainType == EN_RAF_TYPE_DORMANT))) {
s32 i;
@@ -515,7 +515,7 @@ void EnRaf_Explode(EnRaf* this, PlayState* play) {
CLEAR_TAG_PARAMS(CLEAR_TAG_SMALL_EXPLOSION));
Actor_PlaySfx(&this->dyna.actor, NA_SE_IT_BOMB_EXPLOSION);
Actor_PlaySfx(&this->dyna.actor, NA_SE_EN_SUISEN_DEAD);
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
@@ -579,7 +579,7 @@ void EnRaf_Convulse(EnRaf* this, PlayState* play) {
if (this->endFrame <= curFrame) {
this->chewCount++;
if (this->chewCount > (BREG(2) + 2)) {
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
diff --git a/src/overlays/actors/ovl_En_Raf/z_en_raf.h b/src/overlays/actors/ovl_En_Raf/z_en_raf.h
index a025046ab..ca6091233 100644
--- a/src/overlays/actors/ovl_En_Raf/z_en_raf.h
+++ b/src/overlays/actors/ovl_En_Raf/z_en_raf.h
@@ -8,6 +8,8 @@
#define EN_RAF_GET_REVIVE_TIMER(thisx) (((thisx)->params >> 7) & 0x1F)
#define EN_RAF_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
+#define EN_RAF_SWITCH_FLAG_NONE 0x7F
+
typedef enum {
/* 0 */ EN_RAF_TYPE_NORMAL,
/* 1 */ EN_RAF_TYPE_DORMANT, // Spawns without trap, so it can't eat bombs/player
diff --git a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c
index 226aec92b..fdda7ed14 100644
--- a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c
+++ b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c
@@ -5,8 +5,9 @@
*/
#include "z_en_rail_skb.h"
-#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "objects/object_skb/object_skb.h"
+#include "overlays/actors/ovl_En_Part/z_en_part.h"
+#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10)
@@ -1119,10 +1120,10 @@ void EnRailSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
Collider_UpdateSpheres(limbIndex, &this->collider);
if ((limbIndex == 11) && (this->unk_402 & 1) && !(this->unk_402 & 2)) {
- Actor_SpawnBodyParts(&this->actor, play, 1, dList);
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList);
this->unk_402 |= 2;
} else if ((this->unk_402 & 0x40) && ((limbIndex != 11) || !(this->unk_402 & 1)) && (limbIndex != 12)) {
- Actor_SpawnBodyParts(&this->actor, play, 1, dList);
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList);
}
if (this->drawDmgEffTimer != 0) {
diff --git a/src/overlays/actors/ovl_En_Rz/z_en_rz.c b/src/overlays/actors/ovl_En_Rz/z_en_rz.c
index a7bfd13f0..a1ed46868 100644
--- a/src/overlays/actors/ovl_En_Rz/z_en_rz.c
+++ b/src/overlays/actors/ovl_En_Rz/z_en_rz.c
@@ -417,7 +417,7 @@ void func_80BFC058(EnRz* this, PlayState* play) {
void func_80BFC078(EnRz* this, PlayState* play) {
s32 pad;
- Vec3f sp28;
+ Vec3f seqPos;
EnRz_UpdateSkelAnime(this, play);
@@ -443,10 +443,10 @@ void func_80BFC078(EnRz* this, PlayState* play) {
}
if (EN_RZ_GET_SISTER(&this->actor) == EN_RZ_JUDO) {
- sp28.x = this->actor.projectedPos.x;
- sp28.y = this->actor.projectedPos.y;
- sp28.z = this->actor.projectedPos.z;
- func_801A1FB4(SEQ_PLAYER_BGM_SUB, &sp28, NA_BGM_ROSA_SISTERS, 900.0f);
+ seqPos.x = this->actor.projectedPos.x;
+ seqPos.y = this->actor.projectedPos.y;
+ seqPos.z = this->actor.projectedPos.z;
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_ROSA_SISTERS, 900.0f);
}
}
@@ -504,7 +504,7 @@ void func_80BFC36C(EnRz* this, PlayState* play) {
void func_80BFC3F8(EnRz* this, PlayState* play) {
s32 pad;
- Vec3f bgmPos;
+ Vec3f seqPos;
EnRz_UpdateSkelAnime(this, play);
@@ -544,10 +544,10 @@ void func_80BFC3F8(EnRz* this, PlayState* play) {
}
if (EN_RZ_GET_SISTER(&this->actor) == EN_RZ_JUDO) {
- bgmPos.x = this->actor.projectedPos.x;
- bgmPos.y = this->actor.projectedPos.y;
- bgmPos.z = this->actor.projectedPos.z;
- func_801A1FB4(SEQ_PLAYER_BGM_SUB, &bgmPos, NA_BGM_ROSA_SISTERS, 900.0f);
+ seqPos.x = this->actor.projectedPos.x;
+ seqPos.y = this->actor.projectedPos.y;
+ seqPos.z = this->actor.projectedPos.z;
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_ROSA_SISTERS, 900.0f);
}
}
}
diff --git a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c
index f7ec8f509..cd2b36634 100644
--- a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c
+++ b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c
@@ -1122,7 +1122,7 @@ void EnSGoro_WinterShrineGoron_Idle(EnSGoro* this, PlayState* play) {
}
void EnSGoro_WinterShrineGoron_Talk(EnSGoro* this, PlayState* play) {
- if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && (Message_ShouldAdvance(play))) {
+ if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
if (this->actionFlags & EN_S_GORO_ACTIONFLAG_LASTMESSAGE) {
this->actionFlags &= ~EN_S_GORO_ACTIONFLAG_LASTMESSAGE;
this->actionFlags &= ~EN_S_GORO_ACTIONFLAG_ENGAGED;
@@ -1230,7 +1230,7 @@ void EnSGoro_ShopGoron_Talk(EnSGoro* this, PlayState* play) {
this->textId = EnSGoro_BombshopGoron_NextTextId(this, play);
Message_StartTextbox(play, this->textId, &this->actor);
}
- } else if ((talkState == TEXT_STATE_CHOICE) && (Message_ShouldAdvance(play))) {
+ } else if ((talkState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) {
switch (play->msgCtx.choiceIndex) {
case 0:
this->bombbuyFlags |= EN_S_GORO_BOMBBUYFLAG_YESBUY;
diff --git a/src/overlays/actors/ovl_En_Sb/z_en_sb.c b/src/overlays/actors/ovl_En_Sb/z_en_sb.c
index 08b1ad240..eaf5b88d3 100644
--- a/src/overlays/actors/ovl_En_Sb/z_en_sb.c
+++ b/src/overlays/actors/ovl_En_Sb/z_en_sb.c
@@ -6,6 +6,7 @@
#include "z_en_sb.h"
#include "objects/object_sb/object_sb.h"
+#include "overlays/actors/ovl_En_Part/z_en_part.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY)
@@ -388,13 +389,13 @@ void EnSb_Update(Actor* thisx, PlayState* play) {
}
void EnSb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
- s8 phi_a2;
+ s8 partParams;
EnSb* this = THIS;
if (this->isDrawn) {
if (limbIndex < 7) {
- phi_a2 = (this->actor.depthInWater > 0) ? 4 : 1;
- Actor_SpawnBodyParts(thisx, play, phi_a2, dList);
+ partParams = (this->actor.depthInWater > 0) ? ENPART_PARAMS(ENPART_TYPE_4) : ENPART_PARAMS(ENPART_TYPE_1);
+ Actor_SpawnBodyParts(thisx, play, partParams, dList);
}
if (limbIndex == 6) {
this->isDrawn = false;
diff --git a/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/src/overlays/actors/ovl_En_Skb/z_en_skb.c
index 98223faea..e2f40f35c 100644
--- a/src/overlays/actors/ovl_En_Skb/z_en_skb.c
+++ b/src/overlays/actors/ovl_En_Skb/z_en_skb.c
@@ -5,9 +5,10 @@
*/
#include "z_en_skb.h"
-#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
-#include "overlays/actors/ovl_En_Encount4/z_en_encount4.h"
#include "objects/object_skb/object_skb.h"
+#include "overlays/actors/ovl_En_Encount4/z_en_encount4.h"
+#include "overlays/actors/ovl_En_Part/z_en_part.h"
+#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY)
@@ -1106,12 +1107,12 @@ void EnSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
Collider_UpdateSpheres(limbIndex, &this->collider);
if ((this->unk_3D8 & 1) && !(this->unk_3D8 & 2)) {
if (limbIndex == 11) {
- Actor_SpawnBodyParts(&this->actor, play, 1, dList);
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList);
this->unk_3D8 |= 2;
}
} else if ((this->unk_3D8 & 0x40) && !(this->unk_3D8 & 0x80) && ((limbIndex != 11) || !(this->unk_3D8 & 1)) &&
(limbIndex != 12)) {
- Actor_SpawnBodyParts(&this->actor, play, 1, dList);
+ Actor_SpawnBodyParts(&this->actor, play, ENPART_PARAMS(ENPART_TYPE_1), dList);
}
if (this->drawDmgEffTimer != 0) {
diff --git a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c
index 6a1b68bbc..99c5441a6 100644
--- a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c
+++ b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c
@@ -107,10 +107,10 @@ void EnStopheishi_Init(Actor* thisx, PlayState* play) {
this->switchFlag = ENSTOPHEISHI_GET_SWITCH_FLAG(&this->actor);
this->unk_288 = (this->actor.world.rot.z * 40.0f) + 50.0f;
this->actor.world.rot.z = 0;
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == ENSTOPHEISHI_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag >= 0) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
diff --git a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h
index 651a66496..34cb9bf56 100644
--- a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h
+++ b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.h
@@ -11,6 +11,8 @@ typedef void (*EnStopheishiActionFunc)(struct EnStopheishi*, PlayState*);
#define ENSTOPHEISHI_GET_SWITCH_FLAG(thisx) (((thisx)->params) & 0x3F)
#define ENSTOPHEISHI_GET_F000(thisx) ((((thisx)->params) >> 0xC) & 0xF)
+#define ENSTOPHEISHI_SWITCH_FLAG_NONE 0x7F
+
typedef struct EnStopheishi {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelAnime;
diff --git a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c
index 34ebe1d80..667f5d8c4 100644
--- a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c
+++ b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c
@@ -264,11 +264,11 @@ void EnTalkGibud_Init(Actor* thisx, PlayState* play) {
this->requestedItemIndex = EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK;
}
- if (this->switchFlag == 0xFF) {
- this->switchFlag = -1;
+ if (this->switchFlag == EN_TALK_GIBUD_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag != -1) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag != SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
}
@@ -880,7 +880,7 @@ void EnTalkGibud_Disappear(EnTalkGibud* this, PlayState* play) {
player->stateFlags1 |= PLAYER_STATE1_20000000;
this->disappearanceTimer--;
} else {
- if (this->switchFlag != -1) {
+ if (this->switchFlag != SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
player->stateFlags1 &= ~PLAYER_STATE1_20;
diff --git a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h
index 06ccd3914..eb1121801 100644
--- a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h
+++ b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h
@@ -7,6 +7,8 @@
#define EN_TALK_GIBUD_REQUESTED_ITEM_INDEX(thisx) ((thisx)->params & 0xF)
#define EN_TALK_GIBUD_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0xFF0) >> 4)
+#define EN_TALK_GIBUD_SWITCH_FLAG_NONE 0xFF
+
struct EnTalkGibud;
typedef void (*EnTalkGibudActionFunc)(struct EnTalkGibud*, PlayState*);
diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c
index 8ae7b0de4..c44ec1442 100644
--- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c
+++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c
@@ -339,8 +339,8 @@ void EnWiz_Init(Actor* thisx, PlayState* play) {
this->switchFlag = EN_WIZ_GET_SWITCH_FLAG(&this->actor);
this->type = EN_WIZ_GET_TYPE(&this->actor);
- if (this->switchFlag == 0x7F) {
- this->switchFlag = -1;
+ if (this->switchFlag == EN_WIZ_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
if ((this->type == EN_WIZ_TYPE_FIRE) || (this->type == EN_WIZ_TYPE_FIRE_NO_BGM)) {
@@ -352,7 +352,7 @@ void EnWiz_Init(Actor* thisx, PlayState* play) {
this->actor.colChkInfo.health = 6;
}
- if ((this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))) {
+ if ((this->switchFlag > SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->actor);
return;
}
@@ -1201,7 +1201,7 @@ void EnWiz_Dead(EnWiz* this, PlayState* play) {
EnWiz_SelectPlatform(this, play);
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 50, NA_SE_EN_EXTINCT);
Actor_Kill(&this->actor);
- if (this->switchFlag >= 0) {
+ if (this->switchFlag > SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
}
diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h
index fa7156fc5..ea17a254d 100644
--- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h
+++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h
@@ -7,6 +7,8 @@
#define EN_WIZ_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
#define EN_WIZ_GET_TYPE(thisx) (((thisx)->params >> 8) & 0xFF)
+#define EN_WIZ_SWITCH_FLAG_NONE 0x7F
+
typedef enum {
/* 0 */ EN_WIZ_TYPE_FIRE,
/* 1 */ EN_WIZ_TYPE_ICE,
diff --git a/src/overlays/actors/ovl_En_Zob/z_en_zob.c b/src/overlays/actors/ovl_En_Zob/z_en_zob.c
index 9e6310a71..68dbd0e48 100644
--- a/src/overlays/actors/ovl_En_Zob/z_en_zob.c
+++ b/src/overlays/actors/ovl_En_Zob/z_en_zob.c
@@ -558,7 +558,7 @@ void func_80BA06BC(EnZob* this, PlayState* play) {
void func_80BA0728(EnZob* this, PlayState* play) {
s32 pad;
- Vec3f sp28;
+ Vec3f seqPos;
func_80B9F86C(this);
@@ -585,10 +585,10 @@ void func_80BA0728(EnZob* this, PlayState* play) {
func_800B874C(&this->actor, play, 200.0f, 150.0f);
}
- sp28.x = this->actor.projectedPos.x;
- sp28.y = this->actor.projectedPos.y;
- sp28.z = this->actor.projectedPos.z;
- func_801A1FB4(SEQ_PLAYER_BGM_SUB, &sp28, NA_BGM_BASS_PLAY, 1000.0f);
+ seqPos.x = this->actor.projectedPos.x;
+ seqPos.y = this->actor.projectedPos.y;
+ seqPos.z = this->actor.projectedPos.z;
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_BASS_PLAY, 1000.0f);
}
void func_80BA08E8(EnZob* this, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_Zod/z_en_zod.c b/src/overlays/actors/ovl_En_Zod/z_en_zod.c
index ab1f940ce..f30aa51b8 100644
--- a/src/overlays/actors/ovl_En_Zod/z_en_zod.c
+++ b/src/overlays/actors/ovl_En_Zod/z_en_zod.c
@@ -387,7 +387,7 @@ void EnZod_PlayDrumsSequence(EnZod* this, PlayState* play) {
seqPos.y = this->actor.projectedPos.y;
seqPos.z = this->actor.projectedPos.z;
- func_801A1FB4(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_DRUMS_PLAY, 700.0f);
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_DRUMS_PLAY, 700.0f);
}
void func_80BAFA44(EnZod* this, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c
index 6440493cf..099f75a57 100644
--- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c
+++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c
@@ -6,7 +6,6 @@
#include "z_en_zoraegg.h"
#include "objects/gameplay_keep/gameplay_keep.h"
-#include "objects/object_zoraegg/object_zoraegg.h"
#define FLAGS (ACTOR_FLAG_10)
@@ -81,9 +80,9 @@ void EnZoraegg_Init(Actor* thisx, PlayState* play) {
};
Actor_SetScale(&this->actor, 0.006f);
- SkelAnime_InitFlex(play, &this->skelAnime, &object_zoraegg_Skel_004C90, &object_zoraegg_Anim_005098,
- this->jointTable, this->morphTable, 7);
- Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_005098);
+ SkelAnime_InitFlex(play, &this->skelAnime, &gZoraBabySkel, &gZoraBabySwimAnim, this->jointTable, this->morphTable,
+ ZORA_BABY_LIMB_MAX);
+ Animation_PlayLoop(&this->skelAnime, &gZoraBabySwimAnim);
ActorShape_Init(&this->actor.shape, 1100.0f, NULL, 0.0f);
this->actionFunc = func_80B32084;
@@ -166,7 +165,7 @@ void EnZoraegg_Init(Actor* thisx, PlayState* play) {
case ZORA_EGG_TYPE_08:
case ZORA_EGG_TYPE_09:
this->cueType = cueTypes[ZORA_EGG_GET_TYPE(&this->actor) - ZORA_EGG_TYPE_03];
- Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_001E08);
+ Animation_PlayOnce(&this->skelAnime, &gZoraBabyHatchAnim);
this->unk_1EC = 1;
this->unk_1EE = 0;
this->unk_1EF = 0;
@@ -187,7 +186,7 @@ void EnZoraegg_Init(Actor* thisx, PlayState* play) {
this->cueType = cueTypes[ZORA_EGG_GET_TYPE(&this->actor) - ZORA_EGG_TYPE_0A];
this->unk_1EC = 2;
this->actionFunc = func_80B324B0;
- Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4);
+ Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim);
this->unk_1EE = 0;
this->unk_1ED = 0;
this->unk_1EA |= 3;
@@ -426,13 +425,13 @@ void func_80B324B0(EnZoraegg* this, PlayState* play) {
if (this->unk_1EA & 4) {
if (Cutscene_IsCueInChannel(play, this->cueType) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id == 3)) {
- Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4);
+ Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim);
this->unk_1EA &= ~4;
}
} else {
if (Cutscene_IsCueInChannel(play, this->cueType) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id == 4)) {
- Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004E04);
+ Animation_PlayLoop(&this->skelAnime, &gZoraBabySongLearnedAnim);
this->unk_1EA |= 4;
}
}
@@ -444,14 +443,14 @@ void func_80B324B0(EnZoraegg* this, PlayState* play) {
this->unk_1E4 = Rand_ZeroFloat(5.0f);
}
} else if (this->unk_1EA & 4) {
- Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4);
+ Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim);
this->unk_1EA &= ~4;
}
}
void func_80B32644(EnZoraegg* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
- Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4);
+ Animation_PlayLoop(&this->skelAnime, &gZoraBabyNoteAnim);
this->unk_1EE = 0;
this->unk_1EA |= 2;
}
@@ -474,8 +473,8 @@ void func_80B326F4(EnZoraegg* this, PlayState* play) {
if (Cutscene_IsCueInChannel(play, this->cueType) &&
(play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id == 3)) {
- Animation_Change(&this->skelAnime, &object_zoraegg_Anim_004D20, 1.0f, 0.0f,
- Animation_GetLastFrame(&object_zoraegg_Anim_004D20), ANIMMODE_ONCE, 5.0f);
+ Animation_Change(&this->skelAnime, &gZoraBabyFormNoteAnim, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gZoraBabyFormNoteAnim), ANIMMODE_ONCE, 5.0f);
this->unk_1E8 = 0;
this->actionFunc = func_80B32644;
SET_WEEKEVENTREG(WEEKEVENTREG_19_40);
@@ -495,14 +494,14 @@ void func_80B32820(EnZoraegg* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
if (this->unk_1E8 >= 2) {
this->actionFunc = func_80B326F4;
- Animation_Change(&this->skelAnime, &object_zoraegg_Anim_005098, 1.0f, 0.0f,
- Animation_GetLastFrame(&object_zoraegg_Anim_005098), ANIMMODE_LOOP, 10.0f);
+ Animation_Change(&this->skelAnime, &gZoraBabySwimAnim, 1.0f, 0.0f,
+ Animation_GetLastFrame(&gZoraBabySwimAnim), ANIMMODE_LOOP, 10.0f);
this->unk_1E8 = 0;
SkelAnime_Update(&this->skelAnime);
return;
}
- Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_0005D4);
+ Animation_PlayOnce(&this->skelAnime, &gZoraBabySwimUpAnim);
this->unk_1E8 += 1;
SkelAnime_Update(&this->skelAnime);
}
@@ -520,7 +519,7 @@ void func_80B32928(EnZoraegg* this, PlayState* play) {
}
if (SkelAnime_Update(&this->skelAnime)) {
- Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_0005D4);
+ Animation_PlayOnce(&this->skelAnime, &gZoraBabySwimUpAnim);
this->unk_1EA |= 1;
this->actionFunc = func_80B32820;
this->unk_1E8 = 0;
@@ -653,13 +652,13 @@ void EnZoraegg_Update(Actor* thisx, PlayState* play) {
this->actionFunc(this, play);
- if (DECR(this->unk_1F4) == 0) {
- this->unk_1F4 = Rand_S16Offset(60, 60);
+ if (DECR(this->blinkTimer) == 0) {
+ this->blinkTimer = Rand_S16Offset(60, 60);
}
- this->unk_1F2 = this->unk_1F4;
- if (this->unk_1F2 >= 3) {
- this->unk_1F2 = 0;
+ this->eyeIndex = this->blinkTimer;
+ if (this->eyeIndex >= 3) {
+ this->eyeIndex = 0;
}
}
@@ -730,14 +729,14 @@ void func_80B331C8(Actor* thisx, PlayState* play) {
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2);
- gSPDisplayList(POLY_OPA_DISP++, object_zoraegg_DL_005250);
+ gSPDisplayList(POLY_OPA_DISP++, gZoraEggDL);
} else {
Gfx_SetupDL72(POLY_XLU_DISP++);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2);
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1ED);
- gSPDisplayList(POLY_XLU_DISP++, object_zoraegg_DL_005250);
+ gSPDisplayList(POLY_XLU_DISP++, gZoraEggDL);
}
Matrix_Pop();
@@ -856,16 +855,15 @@ void EnZoraegg_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
}
}
-TexturePtr D_80B33950[] = { object_zoraegg_Tex_003430, object_zoraegg_Tex_004430, object_zoraegg_Tex_004830 };
-
void func_80B33818(Actor* thisx, PlayState* play) {
+ static TexturePtr sZoraBabyEyeTextures[] = { gZoraBabyEyeOpenTex, gZoraBabyEyeHalfTex, gZoraBabyEyeClosedTex };
EnZoraegg* this = THIS;
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL25_Opa(play->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B33950[this->unk_1F2]));
+ gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sZoraBabyEyeTextures[this->eyeIndex]));
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnZoraegg_OverrideLimbDraw, EnZoraegg_PostLimbDraw, &this->actor);
diff --git a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h
index 84fce59df..a74c5a4c8 100644
--- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h
+++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h
@@ -2,6 +2,7 @@
#define Z_EN_ZORAEGG_H
#include "global.h"
+#include "objects/object_zoraegg/object_zoraegg.h"
struct EnZoraegg;
@@ -44,8 +45,8 @@ typedef enum {
typedef struct EnZoraegg {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelAnime;
- /* 0x188 */ Vec3s jointTable[7];
- /* 0x1B2 */ Vec3s morphTable[7];
+ /* 0x188 */ Vec3s jointTable[ZORA_BABY_LIMB_MAX];
+ /* 0x1B2 */ Vec3s morphTable[ZORA_BABY_LIMB_MAX];
/* 0x1DC */ Actor* unk_1DC;
/* 0x1E0 */ f32 unk_1E0;
/* 0x1E4 */ f32 unk_1E4;
@@ -56,8 +57,8 @@ typedef struct EnZoraegg {
/* 0x1EE */ u8 unk_1EE;
/* 0x1EF */ u8 unk_1EF;
/* 0x1F0 */ u16 cueType;
- /* 0x1F2 */ s16 unk_1F2;
- /* 0x1F4 */ s16 unk_1F4;
+ /* 0x1F2 */ s16 eyeIndex;
+ /* 0x1F4 */ s16 blinkTimer;
/* 0x1F8 */ EnZoraeggActionFunc actionFunc;
} EnZoraegg; // size = 0x1FC
diff --git a/src/overlays/actors/ovl_En_Zos/z_en_zos.c b/src/overlays/actors/ovl_En_Zos/z_en_zos.c
index 8a942ce17..249b8f6bb 100644
--- a/src/overlays/actors/ovl_En_Zos/z_en_zos.c
+++ b/src/overlays/actors/ovl_En_Zos/z_en_zos.c
@@ -542,7 +542,7 @@ void func_80BBBD5C(EnZos* this, PlayState* play) {
void func_80BBBDE0(EnZos* this, PlayState* play) {
Actor* thisx = &this->actor;
- Vec3f sp28;
+ Vec3f seqPos;
if (this->unk_2B6 & 1) {
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x1000, 0x200);
@@ -578,10 +578,10 @@ void func_80BBBDE0(EnZos* this, PlayState* play) {
CLEAR_WEEKEVENTREG(WEEKEVENTREG_52_10);
}
- sp28.x = this->actor.projectedPos.x;
- sp28.y = this->actor.projectedPos.y;
- sp28.z = this->actor.projectedPos.z;
- func_801A1FB4(SEQ_PLAYER_BGM_SUB, &sp28, NA_BGM_PIANO_PLAY, 1000.0f);
+ seqPos.x = this->actor.projectedPos.x;
+ seqPos.y = this->actor.projectedPos.y;
+ seqPos.z = this->actor.projectedPos.z;
+ Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &seqPos, NA_BGM_PIANO_PLAY, 1000.0f);
}
void func_80BBBFBC(EnZos* this, PlayState* play) {
diff --git a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c
index e5e53000a..9e791f7ae 100644
--- a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c
+++ b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c
@@ -1,4 +1,7 @@
#include "z_obj_boyo.h"
+#include "overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h"
+#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+#include "objects/object_boyo/object_boyo.h"
#define FLAGS (ACTOR_FLAG_10)
@@ -9,7 +12,11 @@ void ObjBoyo_Destroy(Actor* thisx, PlayState* play2);
void ObjBoyo_Update(Actor* thisx, PlayState* play2);
void ObjBoyo_Draw(Actor* thisx, PlayState* play);
-/*
+void ObjBoyo_PushPlayer(ObjBoyo* this, Actor* actor);
+void ObjBoyo_PushPirate(ObjBoyo* this, Actor* actor);
+void ObjBoyo_ExplodeBomb(ObjBoyo* this, Actor* actor);
+Actor* ObjBoyo_FindCollidedActor(ObjBoyo* this, PlayState* play, s32* index);
+
const ActorInit Obj_Boyo_InitVars = {
ACTOR_OBJ_BOYO,
ACTORCAT_PROP,
@@ -19,22 +26,184 @@ const ActorInit Obj_Boyo_InitVars = {
(ActorFunc)ObjBoyo_Init,
(ActorFunc)ObjBoyo_Destroy,
(ActorFunc)ObjBoyo_Update,
- (ActorFunc)ObjBoyo_Draw
+ (ActorFunc)ObjBoyo_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Init.s")
+typedef void (*ObjBoyoCollisionHandler)(ObjBoyo* this, Actor* actor);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Destroy.s")
+typedef struct ObjBoyoUnkStruct {
+ /* 0x0 */ s16 id;
+ /* 0x4 */ ObjBoyoCollisionHandler colHandler;
+} ObjBoyoUnkStruct; // size = 0x8
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5DC0.s")
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_TYPE_PLAYER | AC_HARD | AC_ON,
+ OC1_TYPE_2 | OC1_TYPE_1 | OC1_TYPE_PLAYER | OC1_ON,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x01CBFFBE, 0x00, 0x00 },
+ TOUCH_NONE,
+ BUMP_ON,
+ OCELEM_ON,
+ },
+ {
+ 60,
+ 140,
+ 0,
+ { 0, 0, 0 },
+ },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5DE0.s")
+static InitChainEntry sInitChain[] = {
+ ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 300, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_CONTINUE),
+ ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5E14.s")
+static ObjBoyoUnkStruct sCollisionHandlers[] = {
+ { ACTOR_PLAYER, ObjBoyo_PushPlayer },
+ { ACTOR_EN_KAIZOKU, ObjBoyo_PushPirate },
+ { ACTOR_EN_BOM, ObjBoyo_ExplodeBomb },
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/func_809A5E24.s")
+void ObjBoyo_Init(Actor* thisx, PlayState* play) {
+ ObjBoyo* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Update.s")
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ Collider_InitCylinder(play, &this->collider);
+ Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ this->actor.colChkInfo.mass = MASS_IMMOVABLE;
+ this->animatedMaterial = Lib_SegmentedToVirtual(&object_boyo_Matanimheader_000E88);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Boyo/ObjBoyo_Draw.s")
+void ObjBoyo_Destroy(Actor* thisx, PlayState* play2) {
+ PlayState* play = play2;
+ ObjBoyo* this = THIS;
+
+ Collider_DestroyCylinder(play, &this->collider);
+}
+
+void ObjBoyo_PushPlayer(ObjBoyo* this, Actor* actor) {
+ Player* player = (Player*)actor;
+
+ player->pushedSpeed = 30.0f;
+ player->pushedYaw = this->actor.yawTowardsPlayer;
+}
+
+void ObjBoyo_PushPirate(ObjBoyo* this, Actor* actor) {
+ EnKaizoku* kaizoku = (EnKaizoku*)actor;
+
+ kaizoku->unk_2F0 = 30.0f;
+ kaizoku->unk_2F4 = Actor_WorldYawTowardActor(&this->actor, &kaizoku->picto.actor);
+}
+
+void ObjBoyo_ExplodeBomb(ObjBoyo* this, Actor* actor) {
+ EnBom* bom = (EnBom*)actor;
+
+ bom->timer = 0;
+}
+
+/*
+ * Find the Actor we collided with.
+ */
+Actor* ObjBoyo_FindCollidedActor(ObjBoyo* this, PlayState* play, s32* index) {
+ Actor* collidedActor;
+ ObjBoyoUnkStruct* iter;
+ s32 i;
+
+ if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) {
+ *index = 0;
+ return &GET_PLAYER(play)->actor;
+ }
+ iter = sCollisionHandlers + 1;
+ if (this->collider.base.ocFlags1 & OC1_HIT) {
+ collidedActor = this->collider.base.oc;
+ for (i = 1; i < 3; i++) {
+ if (iter->id == collidedActor->id) {
+ *index = i;
+ return collidedActor;
+ }
+ iter++;
+ }
+ }
+ return NULL;
+}
+
+void ObjBoyo_Update(Actor* thisx, PlayState* play2) {
+ PlayState* play = play2;
+ ObjBoyo* this = THIS;
+ Actor* collidedActor;
+ s32 index;
+
+ collidedActor = ObjBoyo_FindCollidedActor(this, play, &index);
+
+ if (collidedActor != NULL) {
+ sCollisionHandlers[index].colHandler(this, collidedActor);
+ // TODO: find out what all of these are.
+
+ this->unk194 = 0x64;
+ this->unk196 = 3;
+ this->unk198 = 0.01f;
+ this->unk19C = 0.03f;
+ this->unk1A4 = 0x3F40;
+ this->unk1A6 = 0x7D0;
+ this->unk1A8 = 0;
+ this->unk1A0 = 0.03f;
+ this->unk1AA = 0x2DF7;
+ this->unk1AC = 0x258;
+ }
+
+ if (this->unk194 > 0) {
+ // compute new scaling
+ // this computation might help finding what those values are.
+
+ this->unk194 -= this->unk196;
+ this->unk1AA += this->unk1AC;
+ this->unk1A8 += this->unk1AA;
+
+ this->actor.scale.x = this->actor.scale.z =
+ (Math_CosS(this->unk1A8 + this->unk1A4) * (f32)this->unk194 * this->unk19C * this->unk198) + 0.1f;
+
+ this->actor.scale.y =
+ (Math_CosS(this->unk1A8 + this->unk1A6) * (f32)this->unk194 * this->unk1A0 * this->unk198) + 0.1f;
+ } else {
+ Actor_SetScale(&this->actor, 0.1f);
+ if (this->collider.base.acFlags & AC_HIT) {
+ // TODO: find out what all of these are.
+
+ this->unk194 = 0x1E;
+ this->unk196 = 2;
+ this->unk198 = 0.033333335f;
+ this->unk19C = 0.012f;
+ this->unk1A0 = 0.006f;
+ this->unk1A4 = 0x3F40;
+ this->unk1A6 = 0x7D0;
+ this->unk1A8 = 0;
+ this->unk1AA = 0x3A98;
+ this->unk1AC = 0x640;
+ }
+ }
+ this->collider.base.acFlags &= ~AC_HIT;
+ this->collider.base.ocFlags1 &= ~OC1_HIT;
+ this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER;
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
+ if (this->actor.xzDistToPlayer < 2000.0f) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
+ }
+}
+
+void ObjBoyo_Draw(Actor* thisx, PlayState* play) {
+ ObjBoyo* this = THIS;
+
+ AnimatedMat_Draw(play, this->animatedMaterial);
+ Gfx_DrawDListOpa(play, object_boyo_DL_000300);
+}
diff --git a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h
index feb95dcd1..eb1184a40 100644
--- a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h
+++ b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.h
@@ -3,11 +3,21 @@
#include "global.h"
-struct ObjBoyo;
-
typedef struct ObjBoyo {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x6C];
+ /* 0x144 */ ColliderCylinder collider;
+ /* 0x190 */ AnimatedMaterial* animatedMaterial;
+ /* 0x194 */ s16 unk194;
+ /* 0x196 */ s16 unk196;
+ /* 0x198 */ f32 unk198;
+ /* 0x19C */ f32 unk19C;
+ /* 0x1A0 */ f32 unk1A0;
+ /* 0x1A4 */ s16 unk1A4;
+ /* 0x1A6 */ s16 unk1A6;
+ /* 0x1A8 */ s16 unk1A8;
+ /* 0x1AA */ s16 unk1AA;
+ /* 0x1AC */ s16 unk1AC;
+ /* 0x1AE */ s16 unk1AE;
} ObjBoyo; // size = 0x1B0
#endif // Z_OBJ_BOYO_H
diff --git a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c
index a809da57a..ba4782d02 100644
--- a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c
+++ b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c
@@ -33,7 +33,7 @@ void ObjDemo_Init(Actor* thisx, PlayState* play) {
ObjDemo* this = THIS;
thisx->params = OBJDEMO_GET_SWITCH_FLAG_MASK(thisx);
- if ((OBJDEMO_GET_SWITCH_FLAG(thisx) != 0xFF) && (Flags_GetSwitch(play, OBJDEMO_GET_SWITCH_FLAG(thisx)))) {
+ if ((OBJDEMO_GET_SWITCH_FLAG(thisx) != 0xFF) && Flags_GetSwitch(play, OBJDEMO_GET_SWITCH_FLAG(thisx))) {
Actor_Kill(&this->actor);
return;
}
diff --git a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c
index 8802a257d..a76476bde 100644
--- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c
+++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c
@@ -115,11 +115,11 @@ void ObjHakaisi_Init(Actor* thisx, PlayState* play) {
this->switchFlag = OBJHAKAISI_GET_SWITCH_FLAG(thisx);
this->csId = this->dyna.actor.csId;
- if (this->switchFlag == 0xFF) {
- this->switchFlag = -1;
+ if (this->switchFlag == OBJHAKAISI_SWITCH_FLAG_NONE) {
+ this->switchFlag = SWITCH_FLAG_NONE;
}
- if ((this->switchFlag != -1) && Flags_GetSwitch(play, this->switchFlag)) {
+ if ((this->switchFlag != SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
Actor_Kill(&this->dyna.actor);
}
diff --git a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h
index 7ee84768a..937b3d64e 100644
--- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h
+++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h
@@ -10,6 +10,8 @@ typedef void (*ObjHakaisiActionFunc)(struct ObjHakaisi*, PlayState*);
#define OBJHAKAISI_GET_FF(thisx) ((thisx)->params & 0xFF)
#define OBJHAKAISI_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0xFF00) >> 8)
+#define OBJHAKAISI_SWITCH_FLAG_NONE 0xFF
+
typedef struct ObjHakaisi {
/* 0x000 */ DynaPolyActor dyna;
/* 0x15C */ ObjHakaisiActionFunc actionFunc;
diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c
index 8df527f37..c98645d17 100644
--- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c
+++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c
@@ -115,7 +115,7 @@ void ObjIcePoly_Init(Actor* thisx, PlayState* play) {
thisx->shape.rot.x = 0x500;
thisx->shape.rot.z = -0x500;
- if (((this->switchFlag != 0xFF) && Flags_GetSwitch(play, this->switchFlag)) ||
+ if (((this->switchFlag != OBJICEPOLY_SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) ||
((play->sceneId == SCENE_KAJIYA) && CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE))) {
Actor_Kill(thisx);
return;
@@ -219,7 +219,7 @@ void func_80931A38(ObjIcePoly* this, PlayState* play) {
}
} while (actor != NULL);
}
- } else if ((this->switchFlag != 0xFF) && Flags_GetSwitch(play, this->switchFlag)) {
+ } else if ((this->switchFlag != OBJICEPOLY_SWITCH_FLAG_NONE) && Flags_GetSwitch(play, this->switchFlag)) {
CutsceneManager_Queue(this->actor.csId);
this->unk_14A = 1;
this->actionFunc = func_80931E58;
@@ -328,7 +328,7 @@ void func_80931EEC(ObjIcePoly* this, PlayState* play) {
if (this->unk_14A == 0) {
CutsceneManager_Stop(this->actor.csId);
- if (this->switchFlag != 0xFF) {
+ if (this->switchFlag != OBJICEPOLY_SWITCH_FLAG_NONE) {
Flags_SetSwitch(play, this->switchFlag);
}
Actor_Kill(&this->actor);
diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h
index 3e59cd92e..acf62bb91 100644
--- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h
+++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h
@@ -9,6 +9,8 @@ typedef void (*ObjIcePolyActionFunc)(struct ObjIcePoly*, PlayState*);
#define OBJICEPOLY_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 8) & 0xFF)
+#define OBJICEPOLY_SWITCH_FLAG_NONE 0xFF
+
typedef struct ObjIcePoly {
/* 0x000 */ Actor actor;
/* 0x144 */ ObjIcePolyActionFunc actionFunc;
diff --git a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c
index 9e92dcb11..61822bde7 100644
--- a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c
+++ b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c
@@ -101,7 +101,7 @@ void ObjLift_Init(Actor* thisx, PlayState* play) {
this->unk_178 = this->dyna.actor.home.rot.z;
this->dyna.actor.home.rot.z = this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z;
DynaPolyActor_Init(&this->dyna, DYNA_TRANSFORM_POS);
- if ((this->unk_178 <= 0) && (Flags_GetSwitch(play, OBJLIFT_GET_SWITCH_FLAG(&this->dyna.actor)))) {
+ if ((this->unk_178 <= 0) && Flags_GetSwitch(play, OBJLIFT_GET_SWITCH_FLAG(&this->dyna.actor))) {
Actor_Kill(&this->dyna.actor);
return;
}
diff --git a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c
index b5ba51418..569a6e6f2 100644
--- a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c
+++ b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c
@@ -75,7 +75,7 @@ void ObjOcarinalift_Init(Actor* thisx, PlayState* play) {
this->unk170 = Lib_SegmentedToVirtual(path->points);
func_80AC94C0(this, this->unk168);
if ((OBJOCARINALIFT_GET_C(&this->dyna.actor) != OBJOCARINALIFT_PARAM_1) &&
- (Flags_GetSwitch(play, OBJOCARINALIFT_GET_SWITCH_FLAG(&this->dyna.actor)))) {
+ Flags_GetSwitch(play, OBJOCARINALIFT_GET_SWITCH_FLAG(&this->dyna.actor))) {
func_80AC96B4(this);
} else {
func_80AC9AB8(this);
diff --git a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c
index 42c2bcc95..1bcfd0ab5 100644
--- a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c
+++ b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c
@@ -1,7 +1,7 @@
/*
* File: z_obj_sound.c
* Overlay: ovl_Obj_Sound
- * Description: Plays certain sounds (e.g., swamp waterfall noise)
+ * Description: An invisible point-source to play sounds, including sfx and sequences.
*/
#include "z_obj_sound.h"
@@ -13,8 +13,8 @@
void ObjSound_Init(Actor* thisx, PlayState* play);
void ObjSound_Destroy(Actor* thisx, PlayState* play);
void ObjSound_Update(Actor* thisx, PlayState* play);
+void ObjSound_Draw(Actor* thisx, PlayState* play);
-#if 0
ActorInit Obj_Sound_InitVars = {
ACTOR_OBJ_SOUND,
ACTORCAT_ITEMACTION,
@@ -27,12 +27,50 @@ ActorInit Obj_Sound_InitVars = {
(ActorFunc)NULL,
};
-#endif
+void ObjSound_Init(Actor* thisx, PlayState* play) {
+ ObjSound* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/ObjSound_Init.s")
+ this->unk_144 = false;
+ this->soundType = OBJ_SOUND_GET_TYPE(&this->actor);
+ this->sfxType = OBJ_SOUND_GET_SFX_TYPE(&this->actor);
+ this->actor.params &= OBJ_SOUND_ID_MASK;
+ if (this->soundType == OBJ_SOUND_TYPE_FANFARE) {
+ this->actor.draw = ObjSound_Draw;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/ObjSound_Destroy.s")
+void ObjSound_Destroy(Actor* thisx, PlayState* play) {
+ ObjSound* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/ObjSound_Update.s")
+ if (this->soundType == OBJ_SOUND_TYPE_BGM) {
+ Audio_PlayObjSoundBgm(NULL, NA_BGM_GENERAL_SFX);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Sound/func_8099AA84.s")
+void ObjSound_Update(Actor* thisx, PlayState* play) {
+ ObjSound* this = THIS;
+
+ if (this->soundType == OBJ_SOUND_TYPE_SFX) {
+ if (this->sfxType != 0) {
+ Actor_PlaySfx_Flagged(&this->actor, gAudioEnvironmentalSfx[this->actor.params]);
+ } else {
+ Actor_PlaySfx_FlaggedCentered3(&this->actor, gAudioEnvironmentalSfx[this->actor.params]);
+ }
+ } else if (this->unk_144) {
+ if (this->soundType == OBJ_SOUND_TYPE_BGM) {
+ Audio_PlayObjSoundBgm(&this->actor.projectedPos, this->actor.params);
+ } else if (this->soundType == OBJ_SOUND_TYPE_FIXED_SFX) {
+ Audio_PlaySfx_AtFixedPos(&this->actor.projectedPos, gAudioEnvironmentalSfx[this->actor.params]);
+ }
+ } else {
+ this->unk_144 = true;
+ }
+}
+
+void ObjSound_Draw(Actor* thisx, PlayState* play) {
+ ObjSound* this = THIS;
+
+ if (CHECK_EVENTINF(EVENTINF_41) || CHECK_EVENTINF(EVENTINF_35)) {
+ Audio_PlayObjSoundFanfare(&this->actor.projectedPos, this->actor.params);
+ }
+}
diff --git a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h
index a83aa840b..f9ec7fa8f 100644
--- a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h
+++ b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.h
@@ -5,9 +5,22 @@
struct ObjSound;
+#define OBJ_SOUND_GET_TYPE(thisx) (((thisx)->params >> 8) & 0xFF)
+#define OBJ_SOUND_GET_SFX_TYPE(thisx) (((thisx)->params >> 7) & 1)
+#define OBJ_SOUND_ID_MASK 0x7F
+
+typedef enum {
+ /* 0 */ OBJ_SOUND_TYPE_SFX,
+ /* 1 */ OBJ_SOUND_TYPE_BGM,
+ /* 2 */ OBJ_SOUND_TYPE_FIXED_SFX,
+ /* 3 */ OBJ_SOUND_TYPE_FANFARE
+} ObjSoundType;
+
typedef struct ObjSound {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x4];
+ /* 0x144 */ u8 unk_144;
+ /* 0x145 */ u8 sfxType;
+ /* 0x146 */ s16 soundType;
} ObjSound; // size = 0x148
#endif // Z_OBJ_SOUND_H
diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c
index cbd94d808..43bf3cb21 100644
--- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c
+++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c
@@ -105,8 +105,8 @@ void ObjSyokudai_Init(Actor* thisx, PlayState* play) {
this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo);
if (OBJ_SYOKUDAI_GET_START_LIT(thisx) ||
- ((type != OBJ_SYOKUDAI_TYPE_NO_SWITCH || switchFlag != 0x7F) && Flags_GetSwitch(play, switchFlag))) {
-
+ (((type != OBJ_SYOKUDAI_TYPE_NO_SWITCH) || (switchFlag != OBJ_SYOKUDAI_SWITCH_FLAG_NONE)) &&
+ Flags_GetSwitch(play, switchFlag))) {
s32 groupSize = OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx);
this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER;
@@ -239,7 +239,7 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) {
player->unk_B28 = 0xC8;
}
if (groupSize == 0) {
- if ((type == OBJ_SYOKUDAI_TYPE_NO_SWITCH) && (switchFlag == 0x7F)) {
+ if ((type == OBJ_SYOKUDAI_TYPE_NO_SWITCH) && (switchFlag == OBJ_SYOKUDAI_SWITCH_FLAG_NONE)) {
this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER;
} else if (thisx->csId >= 0) {
this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH;
@@ -267,9 +267,11 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->standCollider.base);
Collider_UpdateCylinder(thisx, &this->flameCollider);
CollisionCheck_SetAC(play, &play->colChkCtx, &this->flameCollider.base);
- if ((this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) && (--this->snuffTimer == OBJ_SYOKUDAI_SNUFF_OUT) &&
- (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME)) {
- sNumLitTorchesInGroup--;
+ if (this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) {
+ this->snuffTimer--;
+ if ((this->snuffTimer == OBJ_SYOKUDAI_SNUFF_OUT) && (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME)) {
+ sNumLitTorchesInGroup--;
+ }
}
if (this->snuffTimer != OBJ_SYOKUDAI_SNUFF_OUT) {
s32 pad2;
diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h
index d49f38289..2ea8dc2fc 100644
--- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h
+++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h
@@ -5,6 +5,13 @@
struct ObjSyokudai;
+#define OBJ_SYOKUDAI_GET_TYPE(thisx) ((thisx)->params >> 0xC)
+#define OBJ_SYOKUDAI_GET_START_LIT(thisx) ((thisx)->params & 0x800)
+#define OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx) (((thisx)->params >> 7) & 0xF)
+#define OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
+
+#define OBJ_SYOKUDAI_SWITCH_FLAG_NONE 0x7F
+
typedef struct ObjSyokudai {
/* 0x000 */ Actor actor;
/* 0x144 */ ColliderCylinder standCollider;
@@ -48,11 +55,6 @@ typedef enum {
#define OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS 10
#define OBJ_SYOKUDAI_LIGHT_RADIUS_MAX 250
-#define OBJ_SYOKUDAI_GET_TYPE(thisx) ((thisx)->params >> 0xC)
-#define OBJ_SYOKUDAI_GET_START_LIT(thisx) ((thisx)->params & 0x800)
-#define OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx) (((thisx)->params >> 7) & 0xF)
-#define OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
-
#define OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize) ((groupSize * 50) + 100)
#endif // Z_OBJ_SYOKUDAI_H
diff --git a/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c b/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c
index 9859d9c0f..c685f2836 100644
--- a/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c
+++ b/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c
@@ -39,7 +39,7 @@ void ObjVisiblock_Init(Actor* thisx, PlayState* play) {
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
DynaPolyActor_Init(&this->dyna, 0);
- DynaPolyActor_LoadMesh(play, &this->dyna, &object_visiblock_Colheader_000AD0);
+ DynaPolyActor_LoadMesh(play, &this->dyna, &gLensOfTruthPlatformCol);
}
void ObjVisiblock_Destroy(Actor* thisx, PlayState* play) {
@@ -49,5 +49,5 @@ void ObjVisiblock_Destroy(Actor* thisx, PlayState* play) {
}
void ObjVisiblock_Draw(Actor* thisx, PlayState* play) {
- Gfx_DrawDListXlu(play, object_visiblock_DL_000140);
+ Gfx_DrawDListXlu(play, gLensOfTruthPlatformDL);
}
diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c
index 6e19ae832..43021a023 100644
--- a/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/src/overlays/actors/ovl_player_actor/z_player.c
@@ -4,6 +4,7 @@
* Description: Player
*/
+#include "prevent_bss_reordering.h"
#include "global.h"
#include "z64horse.h"
#include "z64quake.h"
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 6576fc761..c75ca4a8e 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -3919,22 +3919,22 @@
0x801A0C70:("Audio_ClearSariaBgm",),
0x801A0C90:("Audio_ClearSariaBgmAtPos",),
0x801A0CB0:("Audio_SplitBgmChannels",),
- 0x801A0E44:("func_801A0E44",),
- 0x801A1290:("func_801A1290",),
- 0x801A1348:("func_801A1348",),
- 0x801A13BC:("func_801A13BC",),
- 0x801A153C:("func_801A153C",),
- 0x801A17F4:("func_801A17F4",),
- 0x801A1904:("func_801A1904",),
- 0x801A1A10:("func_801A1A10",),
- 0x801A1A8C:("func_801A1A8C",),
- 0x801A1D44:("func_801A1D44",),
- 0x801A1DB8:("func_801A1DB8",),
- 0x801A1E0C:("func_801A1E0C",),
- 0x801A1F00:("func_801A1F00",),
- 0x801A1F88:("func_801A1F88",),
- 0x801A1FB4:("func_801A1FB4",),
- 0x801A2090:("func_801A2090",),
+ 0x801A0E44:("Audio_SetSequenceProperties",),
+ 0x801A1290:("Audio_UpdateObjSoundProperties",),
+ 0x801A1348:("Audio_SetObjSoundProperties",),
+ 0x801A13BC:("Audio_StartObjSoundFanfare",),
+ 0x801A153C:("Audio_PlayObjSoundBgm",),
+ 0x801A17F4:("Audio_PlayObjSoundFanfare",),
+ 0x801A1904:("Audio_UpdateObjSoundFanfare",),
+ 0x801A1A10:("Audio_StopSequenceAtPos",),
+ 0x801A1A8C:("Audio_StartSubBgmAtPos",),
+ 0x801A1D44:("Audio_PlaySubBgmAtPos",),
+ 0x801A1DB8:("Audio_PlaySubBgmAtPosWithFilter",),
+ 0x801A1E0C:("Audio_UpdateSubBgmAtPos",),
+ 0x801A1F00:("Audio_PlaySequenceAtDefaultPos",),
+ 0x801A1F88:("Audio_StopSequenceAtDefaultPos",),
+ 0x801A1FB4:("Audio_PlaySequenceAtPos",),
+ 0x801A2090:("Audio_UpdateSequenceAtPos",),
0x801A21FC:("Audio_PlaySariaBgm",),
0x801A2460:("Audio_ClearSariaBgm2",),
0x801A246C:("func_801A246C",),
@@ -8743,10 +8743,10 @@
0x809A5B50:("ObjArmos_Draw",),
0x809A5D10:("ObjBoyo_Init",),
0x809A5D94:("ObjBoyo_Destroy",),
- 0x809A5DC0:("func_809A5DC0",),
- 0x809A5DE0:("func_809A5DE0",),
- 0x809A5E14:("func_809A5E14",),
- 0x809A5E24:("func_809A5E24",),
+ 0x809A5DC0:("ObjBoyo_PushPlayer",),
+ 0x809A5DE0:("ObjBoyo_PushPirate",),
+ 0x809A5E14:("ObjBoyo_ExplodeBomb",),
+ 0x809A5E24:("ObjBoyo_FindCollidedActor",),
0x809A5E98:("ObjBoyo_Update",),
0x809A610C:("ObjBoyo_Draw",),
0x809A6280:("EnGrasshopper_Init",),
@@ -8846,45 +8846,45 @@
0x809AD614:("EnEncount3_Draw",),
0x809AD8E0:("EnJso_Init",),
0x809ADB24:("EnJso_Destroy",),
- 0x809ADBC8:("func_809ADBC8",),
- 0x809ADC7C:("func_809ADC7C",),
- 0x809ADCB8:("func_809ADCB8",),
- 0x809AE754:("func_809AE754",),
- 0x809AE87C:("func_809AE87C",),
- 0x809AE9B0:("func_809AE9B0",),
- 0x809AEA08:("func_809AEA08",),
- 0x809AECA8:("func_809AECA8",),
- 0x809AED00:("func_809AED00",),
- 0x809AED54:("func_809AED54",),
- 0x809AEDAC:("func_809AEDAC",),
- 0x809AEE44:("func_809AEE44",),
- 0x809AEEC0:("func_809AEEC0",),
- 0x809AF064:("func_809AF064",),
- 0x809AF110:("func_809AF110",),
- 0x809AF28C:("func_809AF28C",),
- 0x809AF2F8:("func_809AF2F8",),
- 0x809AF368:("func_809AF368",),
- 0x809AF3C0:("func_809AF3C0",),
- 0x809AF3FC:("func_809AF3FC",),
- 0x809AF440:("func_809AF440",),
- 0x809AF470:("func_809AF470",),
- 0x809AF53C:("func_809AF53C",),
- 0x809AF5F8:("func_809AF5F8",),
- 0x809AF714:("func_809AF714",),
- 0x809AF76C:("func_809AF76C",),
- 0x809AF7F4:("func_809AF7F4",),
- 0x809AF8D0:("func_809AF8D0",),
- 0x809AF99C:("func_809AF99C",),
- 0x809AFA58:("func_809AFA58",),
- 0x809AFAF4:("func_809AFAF4",),
- 0x809AFC10:("func_809AFC10",),
- 0x809AFE38:("func_809AFE38",),
- 0x809B0034:("func_809B0034",),
+ 0x809ADBC8:("EnJso_ChangeAnim",),
+ 0x809ADC7C:("EnJso_SetupHandleIntroCutscene",),
+ 0x809ADCB8:("EnJso_HandleIntroCutscene",),
+ 0x809AE754:("EnJso_SetupReappear",),
+ 0x809AE87C:("EnJso_Reappear",),
+ 0x809AE9B0:("EnJso_SetupCirclePlayer",),
+ 0x809AEA08:("EnJso_CirclePlayer",),
+ 0x809AECA8:("EnJso_SetupGuard",),
+ 0x809AED00:("EnJso_Guard",),
+ 0x809AED54:("EnJso_SetupSpinBeforeAttack",),
+ 0x809AEDAC:("EnJso_SpinBeforeAttack",),
+ 0x809AEE44:("EnJso_SetupDashAttack",),
+ 0x809AEEC0:("EnJso_DashAttack",),
+ 0x809AF064:("EnJso_SetupSlash",),
+ 0x809AF110:("EnJso_Slash",),
+ 0x809AF28C:("EnJso_SetupWaitAfterSlash",),
+ 0x809AF2F8:("EnJso_WaitAfterSlash",),
+ 0x809AF368:("EnJso_SetupKnockedBack",),
+ 0x809AF3C0:("EnJso_KnockedBack",),
+ 0x809AF3FC:("EnJso_SetupCower",),
+ 0x809AF440:("EnJso_Cower",),
+ 0x809AF470:("EnJso_SetupStunned",),
+ 0x809AF53C:("EnJso_Stunned",),
+ 0x809AF5F8:("EnJso_SetupDamaged",),
+ 0x809AF714:("EnJso_Damaged",),
+ 0x809AF76C:("EnJso_SetupJumpBack",),
+ 0x809AF7F4:("EnJso_JumpBack",),
+ 0x809AF8D0:("EnJso_SetupDead",),
+ 0x809AF99C:("EnJso_Dead",),
+ 0x809AFA58:("EnJso_SetupFallDownAndTalk",),
+ 0x809AFAF4:("EnJso_FallDownAndTalk",),
+ 0x809AFC10:("EnJso_TellHint",),
+ 0x809AFE38:("EnJso_BurstIntoFlames",),
+ 0x809B0034:("EnJso_UpdateDamage",),
0x809B02CC:("EnJso_Update",),
- 0x809B0734:("func_809B0734",),
- 0x809B0820:("func_809B0820",),
- 0x809B0B70:("func_809B0B70",),
- 0x809B0BB0:("func_809B0BB0",),
+ 0x809B0734:("EnJso_OverrideLimbDraw",),
+ 0x809B0820:("EnJso_PostLimbDraw",),
+ 0x809B0B70:("EnJso_SetAfterimageRenderMode",),
+ 0x809B0BB0:("EnJso_Draw",),
0x809B1550:("func_809B1550",),
0x809B162C:("ObjChikuwa_Init",),
0x809B179C:("ObjChikuwa_Destroy",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index a3d433fd4..234967f2b 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -4181,7 +4181,7 @@
0x801FD3AB:("sFanfareState","UNK_TYPE1","",0x1),
0x801FD3AC:("sFanfareSeqId","UNK_TYPE1","",0x1),
0x801FD3AE:("sMuteOnlySfxAndAmbienceSeq","UNK_TYPE1","",0x1),
- 0x801FD3AF:("sAllPlayersMutedExceptOcaAndSys","UNK_TYPE1","",0x1),
+ 0x801FD3AF:("sAllPlayersMutedExceptSystemAndOcarina","UNK_TYPE1","",0x1),
0x801FD3B0:("sAudioPauseState","UNK_TYPE1","",0x1),
0x801FD3B4:("sSpatialSeqIsActive","u8","[4]",0x4),
0x801FD3B8:("sSequenceFilter","UNK_TYPE1","",0x1),
@@ -9366,10 +9366,9 @@
0x809A5BF0:("D_809A5BF0","f32","",0x4),
0x809A5BF4:("D_809A5BF4","f32","",0x4),
0x809A6150:("Obj_Boyo_InitVars","UNK_TYPE1","",0x1),
- 0x809A6170:("D_809A6170","UNK_TYPE1","",0x1),
- 0x809A619C:("D_809A619C","UNK_TYPE1","",0x1),
- 0x809A61B0:("D_809A61B0","UNK_TYPE1","",0x1),
- 0x809A61B4:("D_809A61B4","UNK_TYPE2","",0x2),
+ 0x809A6170:("sCylinderInit","ColliderCylinderInit","",0x1),
+ 0x809A619C:("sInitChain","InitChainEntry","[]",0x4),
+ 0x809A61AC:("gCollisionHandling","ObjBoyoUnkStruct","[]",0x20),
0x809A61D0:("D_809A61D0","f32","",0x4),
0x809A61D4:("D_809A61D4","f32","",0x4),
0x809A61D8:("D_809A61D8","f32","",0x4),
@@ -9488,21 +9487,21 @@
0x809AD82C:("D_809AD82C","f32","",0x4),
0x809AD830:("D_809AD830","f32","",0x4),
0x809AD834:("D_809AD834","f32","",0x4),
- 0x809B0F40:("D_809B0F40","UNK_TYPE4","",0x4),
- 0x809B0F44:("D_809B0F44","UNK_TYPE4","",0x4),
- 0x809B0F48:("D_809B0F48","UNK_TYPE1","",0x1),
- 0x809B0F68:("En_Jso_InitVars","UNK_TYPE1","",0x1),
- 0x809B0F88:("D_809B0F88","UNK_TYPE1","",0x1),
- 0x809B0FB4:("D_809B0FB4","UNK_TYPE1","",0x1),
- 0x809B1004:("D_809B1004","UNK_TYPE1","",0x1),
- 0x809B100C:("D_809B100C","UNK_TYPE1","",0x1),
- 0x809B103C:("D_809B103C","UNK_TYPE1","",0x1),
- 0x809B1048:("D_809B1048","UNK_TYPE4","",0x4),
- 0x809B10B4:("D_809B10B4","UNK_TYPE1","",0x1),
- 0x809B10C0:("D_809B10C0","UNK_TYPE1","",0x1),
- 0x809B10CC:("D_809B10CC","UNK_TYPE1","",0x1),
- 0x809B10D8:("D_809B10D8","UNK_TYPE1","",0x1),
- 0x809B10E4:("D_809B10E4","UNK_TYPE2","",0x2),
+ 0x809B0F40:("sIsAttacking","s32","",0x4),
+ 0x809B0F44:("sIsPlayerLockedOn","s32","",0x4),
+ 0x809B0F48:("sDamageTable","DamageTable","",0x20),
+ 0x809B0F68:("En_Jso_InitVars","ActorInit","",0x20),
+ 0x809B0F88:("sCylinderInit","ColliderCylinderInit","",0x2C),
+ 0x809B0FB4:("sQuadInit","ColliderQuadInit","",0x50),
+ 0x809B1004:("sTextIds","u16","[4]",0x8),
+ 0x809B100C:("sAnimations","AnimationHeader*","[12]",0x30),
+ 0x809B103C:("sAnimationModes","u8","[12]",0xC),
+ 0x809B1048:("fireVelocityAndAccel","Vec3f","[9]",0x6C),
+ 0x809B10B4:("sSwordTipOffset","Vec3f","",0xC),
+ 0x809B10C0:("sSwordBaseOffset","Vec3f","",0xC),
+ 0x809B10CC:("sSwordTipQuadOffset","Vec3f","",0xC),
+ 0x809B10D8:("sSwordBaseQuadOffset","Vec3f","",0xC),
+ 0x809B10E4:("sAfterimageAlpha","s16","[20]",0x28),
0x809B1110:("D_809B1110","f32","",0x4),
0x809B1114:("jtbl_809B1114","UNK_PTR","",0x4),
0x809B112C:("D_809B112C","f32","",0x4),
diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv
index 240f6a0b1..54ec93503 100644
--- a/tools/sizes/code_functions.csv
+++ b/tools/sizes/code_functions.csv
@@ -3436,22 +3436,22 @@ asm/non_matchings/code/code_8019AF00/func_801A09D4.s,func_801A09D4,0x801A09D4,0x
asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgm.s,Audio_ClearSariaBgm,0x801A0C70,0x8
asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgmAtPos.s,Audio_ClearSariaBgmAtPos,0x801A0C90,0x8
asm/non_matchings/code/code_8019AF00/Audio_SplitBgmChannels.s,Audio_SplitBgmChannels,0x801A0CB0,0x65
-asm/non_matchings/code/code_8019AF00/func_801A0E44.s,func_801A0E44,0x801A0E44,0x113
-asm/non_matchings/code/code_8019AF00/func_801A1290.s,func_801A1290,0x801A1290,0x2E
-asm/non_matchings/code/code_8019AF00/func_801A1348.s,func_801A1348,0x801A1348,0x1D
-asm/non_matchings/code/code_8019AF00/func_801A13BC.s,func_801A13BC,0x801A13BC,0x60
-asm/non_matchings/code/code_8019AF00/func_801A153C.s,func_801A153C,0x801A153C,0xAE
-asm/non_matchings/code/code_8019AF00/func_801A17F4.s,func_801A17F4,0x801A17F4,0x44
-asm/non_matchings/code/code_8019AF00/func_801A1904.s,func_801A1904,0x801A1904,0x43
-asm/non_matchings/code/code_8019AF00/func_801A1A10.s,func_801A1A10,0x801A1A10,0x1F
-asm/non_matchings/code/code_8019AF00/func_801A1A8C.s,func_801A1A8C,0x801A1A8C,0xAE
-asm/non_matchings/code/code_8019AF00/func_801A1D44.s,func_801A1D44,0x801A1D44,0x1D
-asm/non_matchings/code/code_8019AF00/func_801A1DB8.s,func_801A1DB8,0x801A1DB8,0x15
-asm/non_matchings/code/code_8019AF00/func_801A1E0C.s,func_801A1E0C,0x801A1E0C,0x3D
-asm/non_matchings/code/code_8019AF00/func_801A1F00.s,func_801A1F00,0x801A1F00,0x22
-asm/non_matchings/code/code_8019AF00/func_801A1F88.s,func_801A1F88,0x801A1F88,0xB
-asm/non_matchings/code/code_8019AF00/func_801A1FB4.s,func_801A1FB4,0x801A1FB4,0x37
-asm/non_matchings/code/code_8019AF00/func_801A2090.s,func_801A2090,0x801A2090,0x5B
+asm/non_matchings/code/code_8019AF00/Audio_SetSequenceProperties.s,Audio_SetSequenceProperties,0x801A0E44,0x113
+asm/non_matchings/code/code_8019AF00/Audio_UpdateObjSoundProperties.s,Audio_UpdateObjSoundProperties,0x801A1290,0x2E
+asm/non_matchings/code/code_8019AF00/Audio_SetObjSoundProperties.s,Audio_SetObjSoundProperties,0x801A1348,0x1D
+asm/non_matchings/code/code_8019AF00/Audio_StartObjSoundFanfare.s,Audio_StartObjSoundFanfare,0x801A13BC,0x60
+asm/non_matchings/code/code_8019AF00/Audio_PlayObjSoundBgm.s,Audio_PlayObjSoundBgm,0x801A153C,0xAE
+asm/non_matchings/code/code_8019AF00/Audio_PlayObjSoundFanfare.s,Audio_PlayObjSoundFanfare,0x801A17F4,0x44
+asm/non_matchings/code/code_8019AF00/Audio_UpdateObjSoundFanfare.s,Audio_UpdateObjSoundFanfare,0x801A1904,0x43
+asm/non_matchings/code/code_8019AF00/Audio_StopSequenceAtPos.s,Audio_StopSequenceAtPos,0x801A1A10,0x1F
+asm/non_matchings/code/code_8019AF00/Audio_StartSubBgmAtPos.s,Audio_StartSubBgmAtPos,0x801A1A8C,0xAE
+asm/non_matchings/code/code_8019AF00/Audio_PlaySubBgmAtPos.s,Audio_PlaySubBgmAtPos,0x801A1D44,0x1D
+asm/non_matchings/code/code_8019AF00/Audio_PlaySubBgmAtPosWithFilter.s,Audio_PlaySubBgmAtPosWithFilter,0x801A1DB8,0x15
+asm/non_matchings/code/code_8019AF00/Audio_UpdateSubBgmAtPos.s,Audio_UpdateSubBgmAtPos,0x801A1E0C,0x3D
+asm/non_matchings/code/code_8019AF00/Audio_PlaySequenceAtDefaultPos.s,Audio_PlaySequenceAtDefaultPos,0x801A1F00,0x22
+asm/non_matchings/code/code_8019AF00/Audio_StopSequenceAtDefaultPos.s,Audio_StopSequenceAtDefaultPos,0x801A1F88,0xB
+asm/non_matchings/code/code_8019AF00/Audio_PlaySequenceAtPos.s,Audio_PlaySequenceAtPos,0x801A1FB4,0x37
+asm/non_matchings/code/code_8019AF00/Audio_UpdateSequenceAtPos.s,Audio_UpdateSequenceAtPos,0x801A2090,0x5B
asm/non_matchings/code/code_8019AF00/Audio_PlaySariaBgm.s,Audio_PlaySariaBgm,0x801A21FC,0x99
asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgm2.s,Audio_ClearSariaBgm2,0x801A2460,0x3
asm/non_matchings/code/code_8019AF00/func_801A246C.s,func_801A246C,0x801A246C,0x36
diff --git a/undefined_syms.txt b/undefined_syms.txt
index cd89ee677..07f8f2b85 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -453,11 +453,6 @@ D_06015C28 = 0x06015C28;
D_060156D8 = 0x060156D8;
D_06016720 = 0x06016720;
-// ovl_En_Jso
-
-D_060081F4 = 0x060081F4;
-D_0600AA00 = 0x0600AA00;
-
// ovl_En_Jso2
D_06002ED8 = 0x06002ED8;