2020-10-03 15:22:44 +00:00
|
|
|
#include "global.h"
|
2022-10-15 17:24:13 +00:00
|
|
|
#include "z64quest_hint_commands.h"
|
|
|
|
|
|
|
|
QuestHintCmd sChildSariaQuestHints[] = {
|
|
|
|
QUEST_HINT_STRENGTH_UPG(SKIP, 0, false, 3),
|
|
|
|
QUEST_HINT_FLAG(CHECK, EVENTCHKINF_37, false, 0x61),
|
|
|
|
QUEST_HINT_END(0x64),
|
|
|
|
|
|
|
|
QUEST_HINT_FLAG(CHECK, EVENTCHKINF_25, false, 0x62),
|
|
|
|
QUEST_HINT_FLAG(CHECK, EVENTCHKINF_37, false, 0x63),
|
|
|
|
QUEST_HINT_FLAG(CHECK, EVENTCHKINF_43, false, 0x65),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_FOREST, false, 0x66),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_FIRE, false, 0x66),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_WATER, false, 0x66),
|
|
|
|
QUEST_HINT_SONG(CHECK, ITEM_SONG_STORMS, false, 0x67),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_SPIRIT, false, 0x68),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_SHADOW, false, 0x68),
|
|
|
|
QUEST_HINT_END(0x69),
|
2020-03-30 20:29:51 +00:00
|
|
|
};
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
QuestHintCmd sAdultSariaQuestHints[] = {
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_FOREST, false, 0x6A),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_FIRE, false, 0x6B),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_WATER, false, 0x6B),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_SPIRIT, false, 0x6C),
|
|
|
|
QUEST_HINT_MEDALLION(CHECK, ITEM_MEDALLION_SHADOW, false, 0x6C),
|
|
|
|
QUEST_HINT_END(0x6D),
|
2020-03-30 20:29:51 +00:00
|
|
|
};
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
u32 QuestHint_CheckCondition(QuestHintCmd* hintCmd) {
|
|
|
|
s32 type = hintCmd->byte0 & 0x1E;
|
2020-08-30 16:51:46 +00:00
|
|
|
u16 flag;
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2020-08-30 16:51:46 +00:00
|
|
|
switch (type) {
|
2022-10-15 17:24:13 +00:00
|
|
|
case (QUEST_HINT_CONDITION_FLAG << 1):
|
|
|
|
flag = 1 << (hintCmd->byte1 & 0x0F);
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) ==
|
|
|
|
((flag & gSaveContext.eventChkInf[(hintCmd->byte1 & 0xF0) >> 4]) != 0);
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_DUNGEON_ITEM << 1):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) ==
|
|
|
|
(CHECK_DUNGEON_ITEM(hintCmd->byte1 - ITEM_KEY_BOSS, gSaveContext.mapIndex) != 0);
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_ITEM << 1):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) == (hintCmd->byte3 == INV_CONTENT(hintCmd->byte1));
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_OTHER << 1):
|
|
|
|
switch (hintCmd->byte1 & 0xF0) {
|
|
|
|
case (QUEST_HINT_CONDITION_STRENGTH_UPG << 4):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) == ((hintCmd->byte1 & 0x0F) == CUR_UPG_VALUE(UPG_STRENGTH));
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_BOOTS << 4):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) ==
|
2022-04-30 16:18:56 +00:00
|
|
|
(CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS,
|
2022-10-15 17:24:13 +00:00
|
|
|
hintCmd->byte3 - ITEM_BOOTS_KOKIRI + EQUIP_INV_BOOTS_KOKIRI) != 0);
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_SONG << 4):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) ==
|
|
|
|
(CHECK_QUEST_ITEM(hintCmd->byte3 - ITEM_SONG_MINUET + QUEST_SONG_MINUET) != 0);
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_MEDALLION << 4):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) ==
|
|
|
|
(CHECK_QUEST_ITEM(hintCmd->byte3 - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST) != 0);
|
|
|
|
|
|
|
|
case (QUEST_HINT_CONDITION_MAGIC << 4):
|
|
|
|
return ((hintCmd->byte0 & 1) == 1) == (((void)0, gSaveContext.isMagicAcquired) != 0);
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2021-09-04 13:33:19 +00:00
|
|
|
LOG_STRING("企画外 条件", "../z_elf_message.c", 156); // "Unplanned conditions"
|
2021-04-29 18:39:46 +00:00
|
|
|
ASSERT(0, "0", "../z_elf_message.c", 157);
|
2020-03-17 04:31:30 +00:00
|
|
|
|
2020-03-30 20:29:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
u32 QuestHint_CheckConditionChain(QuestHintCmd** hintCmdPtr) {
|
|
|
|
u32 allConditionsMet = true;
|
2020-03-30 20:29:51 +00:00
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
while (((*hintCmdPtr)->byte0 & 0xE0) == (QUEST_HINT_TYPE_CHAIN << 5)) {
|
|
|
|
// if any of the conditions checked in the chain are not met,
|
|
|
|
// the whole chain is considered false
|
|
|
|
if (!QuestHint_CheckCondition(*hintCmdPtr)) {
|
|
|
|
allConditionsMet = false;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
*hintCmdPtr += 1;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
if (allConditionsMet) {
|
|
|
|
return QuestHint_CheckCondition(*hintCmdPtr);
|
2020-03-30 20:29:51 +00:00
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
u32 QuestHint_CheckRandomCondition(QuestHintCmd** hintCmdPtr) {
|
|
|
|
QuestHintCmd* hintCmd = *hintCmdPtr;
|
|
|
|
u32 conditions[10];
|
|
|
|
s32 i = 0;
|
|
|
|
s32 totalChecked = 0;
|
|
|
|
s32 rand;
|
2020-03-30 20:29:51 +00:00
|
|
|
|
|
|
|
do {
|
2022-10-15 17:24:13 +00:00
|
|
|
conditions[totalChecked] = QuestHint_CheckCondition(hintCmd);
|
|
|
|
// i is incremented if the condition was met
|
|
|
|
i += conditions[totalChecked];
|
|
|
|
totalChecked++;
|
|
|
|
hintCmd++;
|
|
|
|
} while ((hintCmd->byte0 & 0xE0) == (QUEST_HINT_TYPE_RANDOM << 5));
|
|
|
|
|
|
|
|
// if none of the conditions checked were satisfied, there are none to use
|
|
|
|
if (i == 0) {
|
2020-03-30 20:29:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
// choose a random number between 0 and the total amount of conditions met
|
|
|
|
rand = Rand_ZeroFloat(i);
|
|
|
|
|
|
|
|
for (i = 0; i < totalChecked; i++) {
|
|
|
|
// keep decrementing the random number until it reaches 0 then use that hint
|
|
|
|
if (conditions[i]) {
|
|
|
|
if (rand > 0) {
|
|
|
|
rand--;
|
2020-03-30 20:29:51 +00:00
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
*hintCmdPtr += 1;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
u16 QuestHint_GetTextIdFromScript(QuestHintCmd* hintCmd) {
|
2020-03-30 20:29:51 +00:00
|
|
|
while (true) {
|
2022-10-15 17:24:13 +00:00
|
|
|
switch (hintCmd->byte0 & 0xE0) {
|
|
|
|
case (QUEST_HINT_TYPE_CHECK << 5):
|
|
|
|
if (QuestHint_CheckCondition(hintCmd)) {
|
|
|
|
return hintCmd->byte2 | 0x100;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
break;
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
case (QUEST_HINT_TYPE_CHAIN << 5):
|
|
|
|
if (QuestHint_CheckConditionChain(&hintCmd)) {
|
|
|
|
return hintCmd->byte2 | 0x100;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
break;
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
case (QUEST_HINT_TYPE_RANDOM << 5):
|
|
|
|
if (QuestHint_CheckRandomCondition(&hintCmd)) {
|
|
|
|
return hintCmd->byte2 | 0x100;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
break;
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
case (QUEST_HINT_TYPE_SKIP << 5):
|
|
|
|
if (QuestHint_CheckCondition(hintCmd)) {
|
|
|
|
hintCmd += hintCmd->byte2; // skip the specified amount
|
|
|
|
hintCmd--; // decrement by 1 because it will be incremented again below
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
break;
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
case (QUEST_HINT_TYPE_END << 5):
|
|
|
|
return hintCmd->byte2 | 0x100;
|
|
|
|
|
2020-03-30 20:29:51 +00:00
|
|
|
default:
|
2021-09-04 13:33:19 +00:00
|
|
|
LOG_STRING("企画外 条件", "../z_elf_message.c", 281); // "Unplanned conditions"
|
2021-04-29 18:39:46 +00:00
|
|
|
ASSERT(0, "0", "../z_elf_message.c", 282);
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
2022-10-15 17:24:13 +00:00
|
|
|
|
|
|
|
hintCmd++;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
u16 QuestHint_GetSariaTextId(PlayState* play) {
|
2022-05-21 18:23:43 +00:00
|
|
|
Player* player = GET_PLAYER(play);
|
2022-10-15 17:24:13 +00:00
|
|
|
QuestHintCmd* sariaQuestHints;
|
2020-03-30 20:29:51 +00:00
|
|
|
|
2021-08-21 23:12:57 +00:00
|
|
|
if (!LINK_IS_ADULT) {
|
2022-05-21 18:23:43 +00:00
|
|
|
if (Actor_FindNearby(play, &player->actor, ACTOR_EN_SA, 4, 800.0f) == NULL) {
|
2022-10-15 17:24:13 +00:00
|
|
|
sariaQuestHints = sChildSariaQuestHints;
|
2020-03-30 20:29:51 +00:00
|
|
|
} else {
|
|
|
|
return 0x0160; // Special text about Saria preferring to talk to you face-to-face
|
|
|
|
}
|
|
|
|
} else {
|
2022-10-15 17:24:13 +00:00
|
|
|
sariaQuestHints = sAdultSariaQuestHints;
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
return QuestHint_GetTextIdFromScript(sariaQuestHints);
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 17:24:13 +00:00
|
|
|
u16 QuestHint_GetNaviTextId(PlayState* play) {
|
|
|
|
if (play->naviQuestHints == NULL) {
|
2020-03-30 20:29:51 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
2022-10-15 17:24:13 +00:00
|
|
|
return QuestHint_GetTextIdFromScript(play->naviQuestHints);
|
2020-03-30 20:29:51 +00:00
|
|
|
}
|
|
|
|
}
|