diff --git a/include/functions.h b/include/functions.h index f0a96080a5..dbe7d1de13 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1263,7 +1263,7 @@ void SoundSource_InitAll(PlayState* play); void SoundSource_UpdateAll(PlayState* play); void SoundSource_PlaySfxAtFixedWorldPos(PlayState* play, Vec3f* worldPos, u32 duration, u16 sfxId); void SoundSource_PlaySfxEachFrameAtFixedWorldPos(PlayState* play, Vec3f* worldPos, u32 duration, u16 sfxId); -u16 ElfMessage_GetFirstCycleHint(PlayState* play); +u16 QuestHint_GetTatlTextId(PlayState* play); u16 Text_GetFaceReaction(PlayState* play, u32 reactionSet); void EnvFlags_UnsetAll(PlayState* play); diff --git a/include/z64.h b/include/z64.h index 7552cbe660..2daea1d77e 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1067,7 +1067,7 @@ struct PlayState { /* 0x1885C */ EntranceEntry* setupEntranceList; /* 0x18860 */ u16* setupExitList; /* 0x18864 */ Path* setupPathList; - /* 0x18868 */ void* unk_18868; + /* 0x18868 */ void* naviQuestHints; // leftover from OoT, system which processes this is removed /* 0x1886C */ AnimatedMaterial* sceneMaterialAnims; /* 0x18870 */ void* specialEffects; /* 0x18874 */ u8 skyboxId; diff --git a/include/z64scene.h b/include/z64scene.h index 3af90e02ce..088565c0c9 100644 --- a/include/z64scene.h +++ b/include/z64scene.h @@ -67,7 +67,7 @@ typedef struct { typedef struct { /* 0x0 */ u8 code; - /* 0x1 */ u8 cUpElfMsgNum; + /* 0x1 */ u8 naviQuestHintFileId; /* 0x4 */ u32 subKeepIndex; } SCmdSpecialFiles; // size = 0x8 @@ -825,6 +825,14 @@ typedef enum { /* 7 */ SCENE_DRAW_CFG_MAT_ANIM_MANUAL_STEP } SceneDrawConfigIds; +// TODO: make ZAPD use this enum for `SCENE_CMD_SPECIAL_FILES` +// Leftover from OoT +typedef enum { + /* 0 */ NAVI_QUEST_HINTS_NONE, + /* 1 */ NAVI_QUEST_HINTS_OVERWORLD, + /* 2 */ NAVI_QUEST_HINTS_DUNGEON +} NaviQuestHintFileId; + // SceneTableEntry commands typedef enum { /* 0x00 */ SCENE_CMD_ID_SPAWN_LIST, @@ -882,8 +890,8 @@ typedef enum { #define SCENE_CMD_ENTRANCE_LIST(entranceList) \ { SCENE_CMD_ID_ENTRANCE_LIST, 0, CMD_PTR(entranceList) } -#define SCENE_CMD_SPECIAL_FILES(elfMessageFile, keepObjectId) \ - { SCENE_CMD_ID_SPECIAL_FILES, elfMessageFile, CMD_W(keepObjectId) } +#define SCENE_CMD_SPECIAL_FILES(naviQuestHintFileId, keepObjectId) \ + { SCENE_CMD_ID_SPECIAL_FILES, naviQuestHintFileId, CMD_W(keepObjectId) } #define SCENE_CMD_ROOM_BEHAVIOR(curRoomUnk3, curRoomUnk2, curRoomUnk5, msgCtxunk12044, enablePosLights, \ kankyoContextUnkE2) \ diff --git a/src/code/z_elf_message.c b/src/code/z_elf_message.c index 11e4a2743c..a5a4890a79 100644 --- a/src/code/z_elf_message.c +++ b/src/code/z_elf_message.c @@ -1,62 +1,93 @@ +/** + * @file z_elf_message.c + * + * This file provides quest hints through Tatl. + * + * In Ocarina of Time, this was a more elaborate system that determined + * which hint to give based on a script. + * That system has been replaced with a single function that hardcodes the checks. + */ #include "global.h" -u16 ElfMessage_GetFirstCycleHint(PlayState* play) { +/** + * Gets the relevant text ID for Tatl hints in first cycle. + */ +u16 QuestHint_GetTatlTextId(PlayState* play) { if (INV_CONTENT(ITEM_OCARINA) == ITEM_OCARINA) { return 0; } + if (CURRENT_DAY <= 0) { return 0; } + if (gSaveContext.save.weekEventReg[88] & 0x20) { return 0; } + if (gSaveContext.save.weekEventReg[79] & 0x10) { if (gSaveContext.save.weekEventReg[8] & 0x40) { return 0; } + return 0x224; } + if (!(gSaveContext.save.weekEventReg[8] & 0x80)) { if (gSaveContext.save.weekEventReg[9] & 1) { return 0x21E; } + if (play->sceneId == SCENE_YOUSEI_IZUMI) { return 0; } + return 0x21D; } + if (gSaveContext.save.playerData.isMagicAcquired != true) { return 0x21F; } + if (INV_CONTENT(ITEM_DEED_LAND) == ITEM_DEED_LAND) { if (play->sceneId != SCENE_OKUJOU) { return 0x244; } + return 0; } + if (INV_CONTENT(ITEM_MOON_TEAR) == ITEM_MOON_TEAR) { if (gSaveContext.save.weekEventReg[86] & 4) { return 0x242; } + return 0x243; } + if (gSaveContext.save.weekEventReg[74] & 0x20) { return 0x223; } + if (gSaveContext.save.weekEventReg[73] & 0x80) { return 0x222; } + if (gSaveContext.save.weekEventReg[73] & 0x20) { return 0x221; } + if (gSaveContext.save.weekEventReg[77] & 2) { if (gSaveContext.save.weekEventReg[73] & 0x10) { return 0x240; } + return 0x241; } + if ((gSaveContext.save.weekEventReg[86] & 2) || (gSaveContext.save.weekEventReg[73] & 0x40)) { return 0x23F; } + return 0x220; } diff --git a/src/code/z_scene.c b/src/code/z_scene.c index 1167f14abf..7cb180b803 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -216,7 +216,9 @@ void Scene_HeaderCmdEntranceList(PlayState* play, SceneCmd* cmd) { // SceneTableEntry Header Command 0x07: Special Files void Scene_HeaderCmdSpecialFiles(PlayState* play, SceneCmd* cmd) { - static RomFile tatlMessageFiles[2] = { + // @note These quest hint files are identical to OoT's. + // They are not relevant in this game and the system to process these scripts has been removed. + static RomFile naviQuestHintFiles[2] = { { SEGMENT_ROM_START(elf_message_field), SEGMENT_ROM_END(elf_message_field) }, { SEGMENT_ROM_START(elf_message_ydan), SEGMENT_ROM_END(elf_message_ydan) }, }; @@ -227,8 +229,8 @@ void Scene_HeaderCmdSpecialFiles(PlayState* play, SceneCmd* cmd) { gSegments[0x05] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[play->objectCtx.subKeepIndex].segment); } - if (cmd->specialFiles.cUpElfMsgNum != 0) { - play->unk_18868 = Play_LoadScene(play, &tatlMessageFiles[cmd->specialFiles.cUpElfMsgNum - 1]); + if (cmd->specialFiles.naviQuestHintFileId != NAVI_QUEST_HINTS_NONE) { + play->naviQuestHints = Play_LoadScene(play, &naviQuestHintFiles[cmd->specialFiles.naviQuestHintFileId - 1]); } } diff --git a/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/src/overlays/actors/ovl_En_Elf/z_en_elf.c index f00963f121..27f619816d 100644 --- a/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -358,7 +358,7 @@ void EnElf_Init(Actor* thisx, PlayState* play2) { if ((gSaveContext.save.playerData.tatlTimer >= 25800) || (gSaveContext.save.playerData.tatlTimer < 3000)) { gSaveContext.save.playerData.tatlTimer = 0; } - this->unk_266 = ElfMessage_GetFirstCycleHint(play); + this->unk_266 = QuestHint_GetTatlTextId(play); break; case 1: @@ -1449,7 +1449,7 @@ void func_8089010C(Actor* thisx, PlayState* play) { s32 pad; EnElf* this = THIS; Player* player = GET_PLAYER(play); - u16 temp_v0 = ElfMessage_GetFirstCycleHint(play); + u16 temp_v0 = QuestHint_GetTatlTextId(play); if (temp_v0 != this->unk_266) { this->unk_266 = temp_v0; @@ -1458,7 +1458,7 @@ void func_8089010C(Actor* thisx, PlayState* play) { if ((player->tatlTextId == 0) && (player->unk_730 == NULL)) { if ((gSaveContext.save.playerData.tatlTimer >= 600) && (gSaveContext.save.playerData.tatlTimer <= 3000)) { - player->tatlTextId = ElfMessage_GetFirstCycleHint(play); + player->tatlTextId = QuestHint_GetTatlTextId(play); } } @@ -1470,7 +1470,7 @@ void func_8089010C(Actor* thisx, PlayState* play) { func_8019FDC8(&gSfxDefaultPos, NA_SE_VO_NA_LISTEN, 0x20); thisx->focus.pos = thisx->world.pos; - if (thisx->textId == ElfMessage_GetFirstCycleHint(play)) { + if (thisx->textId == QuestHint_GetTatlTextId(play)) { this->fairyFlags |= 0x80; gSaveContext.save.playerData.tatlTimer = 3001; } diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 8e074c5096..276694be75 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -1615,7 +1615,7 @@ 0x800F048C:("SoundSource_Add",), 0x800F0568:("SoundSource_PlaySfxAtFixedWorldPos",), 0x800F0590:("SoundSource_PlaySfxEachFrameAtFixedWorldPos",), - 0x800F05C0:("ElfMessage_GetFirstCycleHint",), + 0x800F05C0:("QuestHint_GetTatlTextId",), 0x800F07C0:("EnHy_ChangeAnim",), 0x800F0888:("EnHy_FindNearestDoor",), 0x800F0944:("EnHy_ChangeObjectAndAnim",),