Skip to content

Commit

Permalink
Real time Hint Assembly, Hint object refactor, and expansion of Custo…
Browse files Browse the repository at this point in the history
…mMessage (#4078)

* Hint text refactor WIP DOES NOT BUILD

* Update to show people DOES NOT BUILD

* stuck on wierd errors

* forgot to add

* expression error does not name a type

* commit in case anyone looks

* static assertion failed: T must be an integral type or an enum.

* fail without error, complaining about unrefernced things

* fix some issues, still linker bs

* restructure some trials, conditionalAlwaysHints and hint_list stuff

* builds and does not crash, but there's text issues

* fix text issues

* commit to push, halfway through trimming down log

* finish trimming spoiler logging

* post merge clean up

* plando mode seems to work, looking into song text wierdness

* push for debugging crash on HBA sign

* fix num and anju issues

* fix the damn sign

* Fix Windows build

Renames GetMessage to GetHintMessage (a different name could be chosen, but GetMessage conflicts with a macro in winuser.h)
Changes uint to size_t, uint does not seem to exist on Windows.

* fix biggoron

* remove some manual formatting that autoformat doesn't like

* fix some altar text

* fix more altar text

* last cleanup

---------

Co-authored-by: Christopher Leggett <chris@leggett.dev>
  • Loading branch information
Pepper0ni and leggettc18 authored Apr 29, 2024
1 parent 65c5806 commit d69814e
Show file tree
Hide file tree
Showing 51 changed files with 11,182 additions and 11,290 deletions.
474 changes: 377 additions & 97 deletions soh/soh/Enhancements/custom-message/CustomMessageManager.cpp

Large diffs are not rendered by default.

120 changes: 95 additions & 25 deletions soh/soh/Enhancements/custom-message/CustomMessageManager.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
#pragma once
#include <string>
#include <unordered_map>
#include <cstdint>
#include <exception>
#include <vector>
#include <string>

#include "../../../include/z64item.h"
#include "../../../include/message_data_textbox_types.h"
#include "../randomizer/3drando/text.hpp"

#undef MESSAGE_END

#define QM_WHITE 0x00
#define QM_RED 0x41
#define QM_GREEN 0x42
#define QM_BLUE 0x43
#define QM_LBLUE 0x44
#define QM_PINK 0x45
#define QM_YELLOW 0x46
#define QM_BLACK 0x47
#define QM_WHITE "\x00"s
#define QM_RED "\x41"
#define QM_GREEN "\x42"
#define QM_BLUE "\x43"
#define QM_LBLUE "\x44"
#define QM_PINK "\x45"
#define QM_YELLOW "\x46"
#define QM_BLACK "\x47"

#define HS_HORSE_ARCHERY "\x00"s //HS_HBA is an enum already

typedef enum {
MF_FORMATTED,
MF_CLEAN,
MF_RAW,
MF_AUTO_FORMAT
} MessageFormat;

/**
* @brief Encapsulates logic surrounding languages, and formatting strings for OoT's textboxes and
Expand All @@ -30,25 +40,41 @@ class CustomMessage {
CustomMessage() = default;
CustomMessage(std::string english_, std::string german_, std::string french_,
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(std::string english_, std::string german_, std::string french_, std::vector<std::string> colors_, std::vector<bool> capital_ = {},
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(std::string english_, std::vector<std::string> colors_, std::vector<bool> capital_ = {}, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);

static std::string MESSAGE_END() ;
static std::string ITEM_OBTAINED(uint8_t x) ;
static std::string NEWLINE() ;
static std::string COLOR(uint8_t x) ;
static std::string COLOR(std::string x) ;
static std::string POINTS(std::string x) ;//HIGH_SCORE is also a macro
static std::string WAIT_FOR_INPUT() ;
static std::string PLAYER_NAME() ;

const std::string& GetEnglish() const;
const std::string& GetFrench() const;
const std::string& GetGerman() const;
const std::string GetEnglish(MessageFormat format = MF_FORMATTED) const;
const std::string GetFrench(MessageFormat format = MF_FORMATTED) const;
const std::string GetGerman(MessageFormat format = MF_FORMATTED) const;
const std::string GetForCurrentLanguage(MessageFormat format = MF_FORMATTED) const;
const std::string GetForLanguage(uint8_t language, MessageFormat format = MF_FORMATTED) const;
const std::vector<std::string> GetAllMessages(MessageFormat format = MF_FORMATTED) const;
void ProcessMessageFormat(std::string& str, MessageFormat format) const;
const std::vector<std::string>& GetColors() const;
void SetColors(std::vector<std::string> colors_);
const std::vector<bool>& GetCapital() const;
void SetCapital(std::vector<bool> capital_);
const TextBoxType& GetTextBoxType() const;
void SetTextBoxType(TextBoxType boxType);
const TextBoxPosition& GetTextBoxPosition() const;

CustomMessage operator+(const CustomMessage& right) const;
CustomMessage operator+(const std::string& right) const;
void operator+=(const std::string& right);
bool operator==(const CustomMessage& right) const;
void operator+=(const CustomMessage& right);
bool operator==(const CustomMessage& operand) const;
bool operator==(const std::string& operand) const;
bool operator!=(const CustomMessage& right) const;

/**
Expand All @@ -63,15 +89,13 @@ class CustomMessage {

/**
* @brief Finds an instance of oldStr in each language of the CustomMessage,
* and replaces it with the corresponding new string provided for each language.
* and replaces it with the corresponding string in the provided CustomMessage.
* Typically used for dynamic variable replacement (i.e. gameplay stats, skulltula count)
*
* @param oldStr the string to be replaced
* @param newEnglish the new string for the English message
* @param newGerman the new string for the German message
* @param newFrench the new string for the French message
* @param newMessage the message containing the new strings.
*/
void Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman, std::string&& newFrench);
void Replace(std::string&& oldStr, CustomMessage newMessage);

/**
* @brief Capitalizes the first letter of the string for each language.
Expand All @@ -82,17 +106,22 @@ class CustomMessage {
* @brief Replaces special characters (things like diacritics for non-english langugages)
* with the control codes used to display them in OoT's textboxes.
*/
void ReplaceSpecialCharacters();
void ReplaceSpecialCharacters(std::string& str) const;

/**
* @brief Replaces our color variable strings with the OoT control codes.
*/
void ReplaceColors();
void ReplaceColors(std::string& str) const;

/**
* @brief Replaces `$<char>` variable strings with OoT control codes.
*/
void ReplaceAltarIcons();
void ReplaceAltarIcons(std::string& str) const;

/**
* @brief Replaces [[1]] style variable strings with the provided vector of customMessages
*/
void InsertNames(std::vector<CustomMessage> toInsert);

/**
* @brief Replaces various symbols with the control codes necessary to
Expand All @@ -103,19 +132,60 @@ class CustomMessage {
*/
void Format(ItemID iid);

/**
* @brief Replaces [[d]] in text with the supplied number, and if plural
* options exist (2 blocks of text surrounded by |) choose the former if it 1,
* and the latter otherwise, deleting the other and the |'s.
*
* @param num the number to insert.
*/
void InsertNumber(uint8_t num);

/**
* @brief Replaces various symbols with the control codes necessary to
* display them in OoT's textboxes. i.e. special characters, colors, newlines,
* wait for input, etc.
*/
void Format();

/**
* @brief formats the message specifically to fit in OoT's
* textboxes, and use it's formatting.
*/
void AutoFormat();

/**
* @brief Removes all OoT formatting from the message,
* making it a good form for writing into spoiler logs.
*/
void Clean();

/**
* @brief Replaces various symbols with the control codes necessary to
* display them in OoT's textboxes for a single string
* . i.e. special characters, colors, newlines, wait for input, etc.
*/
void FormatString(std::string& str) const;

/**
* @brief formats the string specifically to fit in OoT's
* textboxes, and use it's formatting.
* RANDOTODO whoever knows exactly what this does check my adaption
*/
void AutoFormatString(std::string& str) const;

/**
* @brief Removes symbols used for control codes from the string,
* leaving raw text
*/
void CleanString(std::string& str) const;

private:
std::string english = "";
std::string french = "";
std::string german = "";
std::vector<std::string> messages = {"","",""};
TextBoxType type = TEXTBOX_TYPE_BLACK;
TextBoxPosition position = TEXTBOX_POS_BOTTOM;
std::vector<std::string> colors = {};
std::vector<bool> capital = {};
};

typedef std::unordered_map<uint16_t, CustomMessage> CustomMessageTable;
Expand Down
1 change: 1 addition & 0 deletions soh/soh/Enhancements/custom-message/CustomMessageTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ typedef enum {
TEXT_MALON_LINK_HAS_TIME_BUT_NO_RECORD = 0x2090,
TEXT_MALON_LINK_HAS_RECORD = 0x2091,
TEXT_MALON_FIRST_BEAT_THIS_RECORD = 0x2092,
TEXT_BIGGORON_I_MAAAADE_THISSSS = 0x3002,
TEXT_MEDIGORON = 0x304C,
TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME = 0x3052,
TEXT_BIGGORON_BETTER_AT_SMITHING = 0x3053,
Expand Down
11 changes: 1 addition & 10 deletions soh/soh/Enhancements/debugger/MessageViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,7 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan
const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId);
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
switch (language) {
case LANGUAGE_FRA:
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetFrench(), maxBufferSize);
break;
case LANGUAGE_GER:
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetGerman(), maxBufferSize);
break;
case LANGUAGE_ENG:
default:
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetEnglish(), maxBufferSize);
break;
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize);
}
msgCtx->msgLength = static_cast<int32_t>(font->msgLength);
}
Expand Down
4 changes: 1 addition & 3 deletions soh/soh/Enhancements/mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1161,9 +1161,7 @@ void RegisterAltTrapTypes() {
void RegisterRandomizerSheikSpawn() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
if (!gPlayState) return;
bool canSheik = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIAL_COUNT) != 0 &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LIGHT_ARROWS_HINT));
if (!IS_RANDO || !LINK_IS_ADULT || !canSheik) return;
if (!IS_RANDO || !LINK_IS_ADULT || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHEIK_LA_HINT)) return;
switch (gPlayState->sceneNum) {
case SCENE_TEMPLE_OF_TIME:
if (gPlayState->roomCtx.curRoom.num == 1) {
Expand Down
3 changes: 2 additions & 1 deletion soh/soh/Enhancements/presets.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ const std::vector<const char*> randomizerCvars = {
"gRandomizeLacsRewardOptions",
"gRandomizeLacsStoneCount",
"gRandomizeLacsTokenCount",
"gRandomizeLAHint",
"gRandomizeGanondorfHint",
"gRandomizeSheikLAHint",
"gRandomizeLinksPocket",
"gRandomizeLogicRules",
"gRandomizeMedallionCount",
Expand Down
6 changes: 3 additions & 3 deletions soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ constexpr std::array DungeonColors = {
CreateMessage(textId, unk_04, textBoxType, textBoxPosition, text.GetEnglish(), text.GetFrench(), text.GetSpanish());
}

Text AddColorsAndFormat(Text text, const std::vector<uint8_t>& colors /*= {}*/) {
Text AddColorsAndFormat(Text text, const std::vector<std::string>& colors /*= {}*/) {

//for each language
for (std::string* textStr : {&text.english, &text.french, &text.spanish}) {
Expand Down Expand Up @@ -280,12 +280,12 @@ constexpr std::array DungeonColors = {
std::string SET_SPEED(uint8_t x) {
return "\x7F\x10"s + char(x);
}
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; }
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } //RANDOTODO just refernce the versions in CustomMessage
std::string CURRENT_TIME() { return "\x7F\x17"s; }
std::string UNSKIPPABLE() { return "\x7F\x19"s; }
std::string TWO_WAY_CHOICE() { return "\x1B"s; }
std::string NEWLINE() { return "\x7F\x1C"s; }
std::string COLOR(uint8_t x) { return "\x7F\x1D"s + char(x); }
std::string COLOR(std::string x) { return "\x7F\x1D"s + x; }
std::string CENTER_TEXT() { return "\x7F\x1E"s; }
std::string IF_NOT_MQ() { return "\x7F\x29"s; }
std::string MQ_ELSE() { return "\x7F\x2A"s; }
Expand Down
11 changes: 1 addition & 10 deletions soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,6 @@

#include "text.hpp"

#define QM_WHITE 0x00
#define QM_RED 0x41
#define QM_GREEN 0x42
#define QM_BLUE 0x43
#define QM_LBLUE 0x44
#define QM_PINK 0x45
#define QM_YELLOW 0x46
#define QM_BLACK 0x47

namespace CustomMessages {
typedef struct {
// In the true file format, offset is the offset into the QM file.
Expand Down Expand Up @@ -73,7 +64,7 @@ typedef struct {
std::string UNSKIPPABLE();
std::string TWO_WAY_CHOICE();
std::string NEWLINE();
std::string COLOR(uint8_t x);
std::string COLOR(std::string x);
std::string CENTER_TEXT();
std::string IF_NOT_MQ();
std::string MQ_ELSE();
Expand Down
8 changes: 0 additions & 8 deletions soh/soh/Enhancements/randomizer/3drando/fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "spoiler_log.hpp"
#include "starting_inventory.hpp"
#include "hints.hpp"
#include "hint_list.hpp"
#include "../entrance.h"
#include "shops.hpp"
#include "pool_functions.hpp"
Expand Down Expand Up @@ -1145,13 +1144,6 @@ int Fill() {
ctx->CreateItemOverrides();
ctx->GetEntranceShuffler()->CreateEntranceOverrides();

SPDLOG_INFO("Creating Other Hint Texts...");
//funny ganon line
Text ganonText = RandomElement(GetHintCategory(HintCategory::GanonLine)).GetText();
CreateMessageFromTextObject(0x70CB, 0, 2, 3, AddColorsAndFormat(ganonText));
SetGanonText(ganonText);
SPDLOG_INFO("Creating Other Hint Texts Done");

CreateAllHints();
CreateWarpSongTexts();
return 1;
Expand Down
Loading

0 comments on commit d69814e

Please sign in to comment.