diff --git a/soh/soh.vcxproj b/soh/soh.vcxproj
index 037539b2a..43054c711 100644
--- a/soh/soh.vcxproj
+++ b/soh/soh.vcxproj
@@ -179,6 +179,7 @@
+
@@ -942,9 +943,9 @@
-
+
@@ -985,7 +986,6 @@
-
diff --git a/soh/soh/Enhancements/custom_message/CustomMessage.cpp b/soh/soh/Enhancements/custom_message/CustomMessage.cpp
new file mode 100644
index 000000000..1985a2bbc
--- /dev/null
+++ b/soh/soh/Enhancements/custom_message/CustomMessage.cpp
@@ -0,0 +1,108 @@
+#include "CustomMessage.h"
+#include
+
+using namespace std::literals::string_literals;
+
+CustomMessage::CustomMessage() {
+ this->textBoxSpecialCharacters = { { "À", 0x80 }, { "î", 0x81 }, { "Â", 0x82 }, { "Ä", 0x83 }, { "Ç", 0x84 },
+ { "È", 0x85 }, { "É", 0x86 }, { "Ê", 0x87 }, { "Ë", 0x88 }, { "Ï", 0x89 },
+ { "Ô", 0x8A }, { "Ö", 0x8B }, { "Ù", 0x8C }, { "Û", 0x8D }, { "Ü", 0x8E },
+ { "ß", 0x8F }, { "à", 0x90 }, { "á", 0x91 }, { "â", 0x92 }, { "ä", 0x93 },
+ { "ç", 0x94 }, { "è", 0x95 }, { "é", 0x96 }, { "ê", 0x97 }, { "ë", 0x98 },
+ { "ï", 0x99 }, { "ô", 0x9A }, { "ö", 0x9B }, { "ù", 0x9C }, { "û", 0x9D },
+ { "ü", 0x9E } };
+ this->colors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN }, { "b", QM_BLUE },
+ { "c", QM_LBLUE }, { "p", QM_PINK }, { "y", QM_YELLOW }, { "B", QM_BLACK } };
+}
+
+CustomMessage::~CustomMessage() {
+ this->textBoxSpecialCharacters.clear();
+}
+
+void CustomMessage::ReplaceSpecialCharacters(std::string& string) {
+ // add special characters
+ for (auto specialCharacterPair : textBoxSpecialCharacters) {
+ size_t start_pos = 0;
+ std::string textBoxSpecialCharacterString = "";
+ textBoxSpecialCharacterString += specialCharacterPair.second;
+ while ((start_pos = string.find(specialCharacterPair.first, start_pos)) != std::string::npos) {
+ string.replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString);
+ start_pos += textBoxSpecialCharacterString.length();
+ }
+ }
+}
+
+void CustomMessage::ReplaceColors(std::string& string) {
+ for (auto colorPair : colors) {
+ std::string textToReplace = "%";
+ textToReplace += colorPair.first;
+ size_t start_pos = 0;
+ while ((start_pos = string.find(textToReplace)) != std::string::npos) {
+ string.replace(start_pos, textToReplace.length(), COLOR(colorPair.second));
+ start_pos += textToReplace.length();
+ }
+ }
+}
+
+void CustomMessage::CreateGetItemMessage(GetItemID giid, ItemID iid, std::string messages[LANGUAGE_MAX]) {
+ for (int i = 0; i < LANGUAGE_MAX; i++) {
+ if (!(messages[i].empty())) {
+ std::string message = messages[i];
+ std::string formattedMessage = ITEM_OBTAINED(iid) + message;
+ size_t start_pos = 0;
+ std::replace(formattedMessage.begin(), formattedMessage.end(), '&', NEWLINE()[0]);
+ while ((start_pos = formattedMessage.find('^', start_pos)) != std::string::npos) {
+ formattedMessage.replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid));
+ start_pos += 3;
+ }
+ std::replace(formattedMessage.begin(), formattedMessage.end(), '@', PLAYER_NAME()[0]);
+ ReplaceSpecialCharacters(formattedMessage);
+ ReplaceColors(formattedMessage);
+ formattedMessage += MESSAGE_END();
+ this->getItemMessageTable[i].emplace(giid, formattedMessage);
+ } else {
+ this->getItemMessageTable[i].emplace(giid, MESSAGE_END());
+ }
+ }
+}
+
+std::string CustomMessage::RetrieveGetItemMessage(GetItemID giid) {
+ std::unordered_map::const_iterator result =
+ getItemMessageTable[gSaveContext.language].find(giid);
+ if (result == getItemMessageTable[gSaveContext.language].end()) {
+ switch (gSaveContext.language) {
+ case LANGUAGE_FRA:
+ return "Il n'y a pas de message personnalisé pour cet élément.";
+ case LANGUAGE_GER:
+ return "Für diesen Artikel gibt es keine benutzerdefinierte Nachricht.";
+ case LANGUAGE_ENG:
+ default:
+ return "There is no custom message for this item.";
+ }
+ }
+ return result->second;
+}
+
+std::string CustomMessage::MESSAGE_END() {
+ return "\x02"s;
+}
+
+std::string CustomMessage::ITEM_OBTAINED(uint8_t x) {
+ return "\x13"s + char(x);
+}
+
+std::string CustomMessage::NEWLINE() {
+ return "\x01"s;
+}
+
+std::string CustomMessage::COLOR(uint8_t x) {
+ return "\x05"s + char(x);
+}
+
+std::string CustomMessage::WAIT_FOR_INPUT() {
+ return "\x04"s;
+}
+
+std::string CustomMessage::PLAYER_NAME() {
+ return "\x0F"s;
+}
\ No newline at end of file
diff --git a/soh/soh/Enhancements/custom_message/CustomMessage.h b/soh/soh/Enhancements/custom_message/CustomMessage.h
new file mode 100644
index 000000000..d8cfd8e0d
--- /dev/null
+++ b/soh/soh/Enhancements/custom_message/CustomMessage.h
@@ -0,0 +1,39 @@
+#pragma once
+#include
+#include
+#include "variables.h"
+
+#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
+
+class CustomMessage {
+ private:
+ std::unordered_map textBoxSpecialCharacters;
+ std::unordered_map colors;
+ std::unordered_map getItemMessageTable[LANGUAGE_MAX];
+
+ void ReplaceSpecialCharacters(std::string &string);
+ void ReplaceColors(std::string& string);
+
+ std::string MESSAGE_END();
+ std::string ITEM_OBTAINED(uint8_t x);
+ std::string NEWLINE();
+ std::string COLOR(uint8_t x);
+ std::string WAIT_FOR_INPUT();
+ std::string PLAYER_NAME();
+
+ public:
+ static CustomMessage* Instance;
+
+ CustomMessage();
+ ~CustomMessage();
+
+ void CreateGetItemMessage(GetItemID giid, ItemID iid, std::string messages[LANGUAGE_MAX]);
+ std::string RetrieveGetItemMessage(GetItemID giid);
+};
\ No newline at end of file
diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp
index 09704e867..4c589ea48 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer.cpp
@@ -4748,6 +4748,7 @@ void DrawRandoEditor(bool& open) {
void InitRando() {
SohImGui::AddWindow("Randomizer", "Randomizer Settings", DrawRandoEditor);
+ Randomizer::CreateCustomMessages();
}
extern "C" {
diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h
index 180d91691..6f928bd66 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.h
+++ b/soh/soh/Enhancements/randomizer/randomizer.h
@@ -5,6 +5,7 @@
#include "../../../include/ultra64.h"
#include "../../../include/z64item.h"
#include
+#include
class Randomizer {
private:
@@ -42,6 +43,7 @@ class Randomizer {
GetItemID GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
GetItemID GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
std::string GetCustomGetItemMessage(GetItemID giid);
+ static void CreateCustomMessages();
};
#ifdef __cplusplus
diff --git a/soh/soh/Enhancements/randomizer/randomizer_custom_messages.cpp b/soh/soh/Enhancements/randomizer/randomizer_custom_messages.cpp
index 659e68fe8..a31edcbee 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_custom_messages.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_custom_messages.cpp
@@ -1,54 +1,33 @@
-#include "randomizer_custom_messages.h"
#include "randomizer.h"
-#include
+#include "soh/Enhancements/custom_message/CustomMessage.h"
using namespace std::literals::string_literals;
+#define MESSAGES(eng, ger, fra) (new std::string[]{eng, ger, fra})
+
+void Randomizer::CreateCustomMessages() {
+ CustomMessage* customMessage = CustomMessage::Instance;
+ customMessage->CreateGetItemMessage(
+ GI_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE,
+ MESSAGES("You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", "", ""));
+ customMessage->CreateGetItemMessage(
+ GI_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE,
+ MESSAGES("You got a %rBig Poe in a bottle%w!&Sell it to the Ghost Shop!", "", ""));
+ customMessage->CreateGetItemMessage(
+ GI_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE,
+ MESSAGES("You got a %rBottle of Blue Potion%w!&Drink it to replenish your&%ghealth%w and %bmagic%w!", "", ""));
+ customMessage->CreateGetItemMessage(
+ GI_BOTTLE_WITH_FISH, ITEM_FISH,
+ MESSAGES("You got a %rFish in a bottle%w!&It looks fresh and delicious!&They say Jabu-Jabu loves them!", "",
+ ""));
+
+
+}
+
std::string Randomizer::GetCustomGetItemMessage(GetItemID giid) {
if (!gSaveContext.n64ddFlag) {
return "Not Randomized.";
}
- switch (giid) {
- case GI_BOTTLE_WITH_BLUE_FIRE:
- switch (gSaveContext.language) {
- case LANGUAGE_FRA:
- case LANGUAGE_GER:
- case LANGUAGE_ENG:
- default:
- return ITEM_OBTAINED(ITEM_BLUE_FIRE) + "You got a " + COLOR(QM_RED) + "Bottle with Blue " +
- NEWLINE() + "Fire" + COLOR(QM_WHITE) + "! Use it to melt Red Ice!" +
- MESSAGE_END();
- }
- default:
- switch (gSaveContext.language) {
- case LANGUAGE_FRA:
- return "Il n'y a pas de message personnalisé pour cet élément.";
- case LANGUAGE_GER:
- return "Für diesen Artikel gibt es keine benutzerdefinierte Nachricht.";
- case LANGUAGE_ENG:
- default:
- return "There is no custom message for this item.";
- }
- }
-}
-
-std::string MESSAGE_END() {
- return "\x02"s;
-}
-
-std::string ITEM_OBTAINED(uint8_t x) {
- return "\x13"s + char(x);
-}
-
-std::string NEWLINE() {
- return "\x01"s;
-}
-
-std::string COLOR(uint8_t x) {
- return "\x05"s + char(x);
-}
-
-std::string WAIT_FOR_INPUT() {
- return "\x04"s;
+ return CustomMessage::Instance->RetrieveGetItemMessage(giid);
}
\ No newline at end of file
diff --git a/soh/soh/Enhancements/randomizer/randomizer_custom_messages.h b/soh/soh/Enhancements/randomizer/randomizer_custom_messages.h
deleted file mode 100644
index cae3c65b5..000000000
--- a/soh/soh/Enhancements/randomizer/randomizer_custom_messages.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include
-#include "../../../include/z64item.h"
-
-#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
-
-std::string MESSAGE_END();
-std::string ITEM_OBTAINED(uint8_t x);
-std::string NEWLINE();
-std::string COLOR(uint8_t x);
-std::string WAIT_FOR_INPUT();
\ No newline at end of file
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index 5ec051af0..6691127be 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -38,6 +38,7 @@
#include "Enhancements/debugger/debugger.h"
#include "Enhancements/randomizer/randomizer.h"
#include
+#include
#include "Enhancements/n64_weird_frame_data.inc"
#include "soh/frame_interpolation.h"
#include "Utils/BitConverter.h"
@@ -55,6 +56,7 @@
OTRGlobals* OTRGlobals::Instance;
SaveManager* SaveManager::Instance;
+CustomMessage* CustomMessage::Instance;
OTRGlobals::OTRGlobals() {
context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian");
@@ -106,6 +108,7 @@ extern "C" void OTRExtScanner() {
extern "C" void InitOTR() {
OTRGlobals::Instance = new OTRGlobals();
SaveManager::Instance = new SaveManager();
+ CustomMessage::Instance = new CustomMessage();
auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version");
if (!t->bHasLoadError)
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index 1cb90fc91..d999f1bda 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -9,7 +9,6 @@
#ifdef __cplusplus
#include "Enhancements/savestates.h"
#include "Enhancements/randomizer/randomizer.h"
-
class OTRGlobals
{
public:
diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c
index c27b78ee8..15ff2e7d8 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -654,13 +654,13 @@ static GetItemEntry sGetItemTable[] = {
GET_ITEM(ITEM_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG),
GET_ITEM(ITEM_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG),
- GET_ITEM(ITEM_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG),
+ GET_ITEM(ITEM_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0xF8, 0x80, CHEST_ANIM_LONG),
GET_ITEM(ITEM_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG),
- GET_ITEM(ITEM_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG),
+ GET_ITEM(ITEM_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, 0xF8, 0x80, CHEST_ANIM_LONG),
GET_ITEM(ITEM_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0xF8, 0x80, CHEST_ANIM_LONG),
GET_ITEM(ITEM_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG),
- GET_ITEM(ITEM_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG),
- GET_ITEM(ITEM_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, 0xF9, 0x80, CHEST_ANIM_LONG),
+ GET_ITEM(ITEM_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, 0xF8, 0x80, CHEST_ANIM_LONG),
+ GET_ITEM(ITEM_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, 0xF8, 0x80, CHEST_ANIM_LONG),
GET_ITEM_NONE,
GET_ITEM_NONE,