1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-10-20 13:40:02 +00:00

Document elf_message scripting system (#1398)

* `cUpElfMsgs` -> `cUpMsgs`

Motivation:
ElfMessage is the name of the system that handles c-up messages from navi, but also messages from child/adult saria
so it would make sense to name this after the system name like "ElfMsg"
but "cUpElf" primarily reads like (to me) "c up navi" since the actor implementing navi is EnElf

I think it'd be better to clear that confusion between "navi" and "elfmsg system" by just not using "elf" in the name

* Standardize c-up navi messages ElfMessage data to be named after "CUp"

* -> "Navi"

* Make symbols in `elf_message_` segments static

* new docs

* change commands, format

* introduce navi file id

* use enum

* remove concat

* add clarifying comment for skip

* concat cmd type

* Hints -> QuestHint

* rename command header

* s -> g

* missed enum name

* singular

* missed one

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
This commit is contained in:
fig02 2022-10-15 13:24:13 -04:00 committed by GitHub
commit fd24ad6e67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 343 additions and 290 deletions

View file

@ -797,8 +797,8 @@ void GetItem_Draw(PlayState* play, s16 drawId);
void SfxSource_InitAll(PlayState* play);
void SfxSource_UpdateAll(PlayState* play);
void SfxSource_PlaySfxAtFixedWorldPos(PlayState* play, Vec3f* worldPos, s32 duration, u16 sfxId);
u16 ElfMessage_GetSariaText(PlayState* play);
u16 ElfMessage_GetCUpText(PlayState* play);
u16 QuestHint_GetSariaTextId(PlayState* play);
u16 QuestHint_GetNaviTextId(PlayState* play);
u16 Text_GetFaceReaction(PlayState* play, u32 reactionSet);
void Flags_UnsetAllEnv(PlayState* play);
void Flags_SetEnv(PlayState* play, s16 flag);

View file

@ -1131,7 +1131,7 @@ typedef struct {
/* 0x01 */ u8 byte1;
/* 0x02 */ u8 byte2;
/* 0x03 */ u8 byte3;
} ElfMessage; // size = 0x4
} QuestHintCmd; // size = 0x4
typedef struct {
/* 0x00 */ u8 numActors;
@ -1193,7 +1193,7 @@ typedef struct PlayState {
/* 0x11E00 */ EntranceEntry* setupEntranceList;
/* 0x11E04 */ s16* setupExitList;
/* 0x11E08 */ Path* setupPathList;
/* 0x11E0C */ ElfMessage* cUpElfMsgs;
/* 0x11E0C */ QuestHintCmd* naviQuestHints;
/* 0x11E10 */ void* specialEffects;
/* 0x11E14 */ u8 skyboxId;
/* 0x11E15 */ s8 transitionTrigger; // "fade_direction"

View file

@ -1,129 +0,0 @@
#ifndef Z64ELF_MESSAGE_H
#define Z64ELF_MESSAGE_H
#include "ultra64.h"
// Checks the condition and exits the script if the check passes
#define ELF_MSG_TYPE_CHECK 0
// ? (unused)
#define ELF_MSG_TYPE_UNK_1 1
// ? (unused)
#define ELF_MSG_TYPE_UNK_2 2
// Checks the condition and skips forward by some number of commands if the check passes
#define ELF_MSG_TYPE_SKIP 3
// Always ends the script, returning the text id for this command
#define ELF_MSG_TYPE_END 7
// Check an eventChkInf flag
#define ELF_MSG_CONDITION_FLAG 0
// Check a dungeon item (map, compass, boss key)
#define ELF_MSG_CONDITION_DUNGEON_ITEM 1
// Check if an item is in an item slot
#define ELF_MSG_CONDITION_ITEM 2
// "Other" conditions described below
#define ELF_MSG_CONDITION_OTHER 3
// Check what strength upgrade has been obtained so far
#define ELF_MSG_CONDITION_STRENGTH_UPG 0
// Check if specific boots have been obtained so far
#define ELF_MSG_CONDITION_BOOTS 1
// Check if a particular song has been obtained
#define ELF_MSG_CONDITION_SONG 2
// Check if a particular medallion has been obtained
#define ELF_MSG_CONDITION_MEDALLION 3
// Check if the magic meter has been obtained
#define ELF_MSG_CONDITION_MAGIC 4
/*
* Bitpack byte 0
*/
#define ELF_MSG_B0(type, cond_type, tf) \
_SHIFTL(ELF_MSG_TYPE_##type, 5, 3) | \
_SHIFTL(ELF_MSG_CONDITION_##cond_type, 1, 4) | \
_SHIFTL(tf, 0, 1)
/*
* Bitpack byte 1
*/
#define ELF_MSG_B1(cond_type, data) \
_SHIFTL(ELF_MSG_CONDITION_##cond_type, 4, 4) | \
_SHIFTL(data, 0, 4)
/*
* Other bytes
*/
#define ELF_MSG_B(data) \
_SHIFTL(data, 0, 8)
/*
* Command macros
*/
#define ELF_MSG_FLAG(type, textId, tf, flag) \
{ \
ELF_MSG_B0(type, FLAG, tf), \
ELF_MSG_B(flag), \
ELF_MSG_B(textId), \
ELF_MSG_B(0), \
}
#define ELF_MSG_END(textId) \
ELF_MSG_FLAG(END, textId, false, 0)
#define ELF_MSG_DUNGEON_ITEM(type, textId, tf, itemId) \
{ \
ELF_MSG_B0(type, DUNGEON_ITEM, tf), \
ELF_MSG_B(itemId), \
ELF_MSG_B(textId), \
ELF_MSG_B(0), \
}
#define ELF_MSG_ITEM(type, textId, tf, slotItemId, itemId) \
{ \
ELF_MSG_B0(type, ITEM, tf), \
ELF_MSG_B(slotItemId), \
ELF_MSG_B(textId), \
ELF_MSG_B(itemId), \
}
#define ELF_MSG_STRENGTH_UPG(type, textId, tf, strUpg) \
{ \
ELF_MSG_B0(type, OTHER, tf), \
ELF_MSG_B1(STRENGTH_UPG, strUpg), \
ELF_MSG_B(textId), \
ELF_MSG_B(0), \
}
#define ELF_MSG_BOOTS(type, textId, tf, itemId) \
{ \
ELF_MSG_B0(type, OTHER, tf), \
ELF_MSG_B1(BOOTS, 0), \
ELF_MSG_B(textId), \
ELF_MSG_B(itemId), \
}
#define ELF_MSG_SONG(type, textId, tf, itemId) \
{ \
ELF_MSG_B0(type, OTHER, tf), \
ELF_MSG_B1(SONG, 0), \
ELF_MSG_B(textId), \
ELF_MSG_B(itemId), \
}
#define ELF_MSG_MEDALLION(type, textId, tf, itemId) \
{ \
ELF_MSG_B0(type, OTHER, tf), \
ELF_MSG_B1(MEDALLION, 0), \
ELF_MSG_B(textId), \
ELF_MSG_B(itemId), \
}
#define ELF_MSG_MAGIC(type, textId, tf) \
{ \
ELF_MSG_B0(type, OTHER, tf), \
ELF_MSG_B1(MAGIC, 0), \
ELF_MSG_B(textId), \
ELF_MSG_B(0), \
}
#endif

View file

@ -0,0 +1,150 @@
#ifndef Z64QUEST_HINT_COMMANDS_H
#define Z64QUEST_HINT_COMMANDS_H
#include "ultra64.h"
/*
* Hint Command Types
*/
// Checks the condition and exits the script if the check passes
#define QUEST_HINT_TYPE_CHECK 0
// Checks a chain of conditions and only evaluates the last entry
// if all conditions leading up to it were also true
#define QUEST_HINT_TYPE_CHAIN 1
// Checks a chain of conditionals and will return a randomly chosen entry among
// the conditions that evaluated to true
#define QUEST_HINT_TYPE_RANDOM 2
// Checks the condition and skips forward by specified number of commands if the check passes
// Note that the amount of entries to skip is specified in the field where the textId would usually go
#define QUEST_HINT_TYPE_SKIP 3
// Always ends the script, returning the text id for this command
#define QUEST_HINT_TYPE_END 7
/*
* Hint Condition Types
*/
// Check an eventChkInf flag
#define QUEST_HINT_CONDITION_FLAG 0
// Check a dungeon item (map, compass, boss key)
#define QUEST_HINT_CONDITION_DUNGEON_ITEM 1
// Check if an item is in an item slot
#define QUEST_HINT_CONDITION_ITEM 2
// "Other" conditions described below
#define QUEST_HINT_CONDITION_OTHER 3
/*
* "Other" Condition Types
*/
// Check what strength upgrade has been obtained so far
#define QUEST_HINT_CONDITION_STRENGTH_UPG 0
// Check if specific boots have been obtained so far
#define QUEST_HINT_CONDITION_BOOTS 1
// Check if a particular song has been obtained
#define QUEST_HINT_CONDITION_SONG 2
// Check if a particular medallion has been obtained
#define QUEST_HINT_CONDITION_MEDALLION 3
// Check if the magic meter has been obtained
#define QUEST_HINT_CONDITION_MAGIC 4
/*
* Byte pack macros
*/
#define HINT_B0(type, condType, tf) \
_SHIFTL(QUEST_HINT_TYPE_##type, 5, 3) | \
_SHIFTL(condType, 1, 4) | \
_SHIFTL(tf, 0, 1)
#define HINT_B1(condType, data) \
_SHIFTL(condType, 4, 4) | \
_SHIFTL(data, 0, 4)
#define HINT_B(data) \
_SHIFTL(data, 0, 8)
/*
* Command macros
*/
#define QUEST_HINT_FLAG(type, flag, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_FLAG, tf), \
HINT_B(flag), \
HINT_B(textId), \
HINT_B(0), \
}
#define QUEST_HINT_END(textId) \
QUEST_HINT_FLAG(END, 0, false, textId)
#define QUEST_HINT_DUNGEON_ITEM(type, itemId, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_DUNGEON_ITEM, tf), \
HINT_B(itemId), \
HINT_B(textId), \
HINT_B(0), \
}
#define QUEST_HINT_ITEM(type, slotItemId, itemId, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_ITEM, tf), \
HINT_B(slotItemId), \
HINT_B(textId), \
HINT_B(itemId), \
}
#define QUEST_HINT_STRENGTH_UPG(type, strUpg, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_OTHER, tf), \
HINT_B1(QUEST_HINT_CONDITION_STRENGTH_UPG, strUpg), \
HINT_B(textId), \
HINT_B(0), \
}
#define QUEST_HINT_BOOTS(type, itemId, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_OTHER, tf), \
HINT_B1(QUEST_HINT_CONDITION_BOOTS, 0), \
HINT_B(textId), \
HINT_B(itemId), \
}
#define QUEST_HINT_SONG(type, itemId, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_OTHER, tf), \
HINT_B1(QUEST_HINT_CONDITION_SONG, 0), \
HINT_B(textId), \
HINT_B(itemId), \
}
#define QUEST_HINT_MEDALLION(type, itemId, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_OTHER, tf), \
HINT_B1(QUEST_HINT_CONDITION_MEDALLION, 0), \
HINT_B(textId), \
HINT_B(itemId), \
}
#define QUEST_HINT_MAGIC(type, tf, textId) \
{ \
HINT_B0(type, QUEST_HINT_CONDITION_OTHER, tf), \
HINT_B1(QUEST_HINT_CONDITION_MAGIC, 0), \
HINT_B(textId), \
HINT_B(0), \
}
#endif

View file

@ -223,7 +223,7 @@ typedef struct {
typedef struct {
/* 0x00 */ u8 code;
/* 0x01 */ u8 cUpElfMsgNum;
/* 0x01 */ u8 naviQuestHintFileId;
/* 0x04 */ u32 keepObjectId;
} SCmdSpecialFiles;
@ -469,6 +469,14 @@ typedef enum {
#define SCENE_CAM_TYPE_FIXED_MARKET 0x40 // Camera exhibits fixed behaviors and delays textboxes by a small amount before they start to appear
#define SCENE_CAM_TYPE_SHOOTING_GALLERY 0x50 // Unreferenced in code, and used only by the main layer of the shooting gallery scene
// navi hints
// TODO: make ZAPD use this enum for `SCENE_CMD_SPECIAL_FILES`
typedef enum {
NAVI_QUEST_HINTS_NONE,
NAVI_QUEST_HINTS_OVERWORLD,
NAVI_QUEST_HINTS_DUNGEON
} NaviQuestHintFileId;
// Scene commands
typedef enum {
@ -522,8 +530,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, showInvisActors, disableWarpSongs) \
{ SCENE_CMD_ID_ROOM_BEHAVIOR, curRoomUnk3, \