forked from HarbourMasters/Shipwright
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request HarbourMasters#831 from leggettc18/custom-messages
System for Creating and Storing Custom Messages
- Loading branch information
Showing
11 changed files
with
572 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
soh/soh/Enhancements/custom-message/CustomMessageManager.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#include "CustomMessageManager.h" | ||
#include <algorithm> | ||
|
||
using namespace std::literals::string_literals; | ||
|
||
CustomMessageManager::CustomMessageManager() { | ||
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 } }; | ||
} | ||
|
||
CustomMessageManager::~CustomMessageManager() { | ||
this->textBoxSpecialCharacters.clear(); | ||
this->colors.clear(); | ||
this->messageTables.clear(); | ||
} | ||
|
||
void CustomMessageManager::ReplaceSpecialCharacters(std::string& string) { | ||
// add special characters | ||
for (auto specialCharacterPair : this->textBoxSpecialCharacters) { | ||
size_t start_pos = 0; | ||
std::string textBoxSpecialCharacterString = ""s; | ||
textBoxSpecialCharacterString += specialCharacterPair.second; | ||
while ((start_pos = string.find(specialCharacterPair.first, 0)) != std::string::npos) { | ||
string.replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString); | ||
start_pos += textBoxSpecialCharacterString.length(); | ||
} | ||
} | ||
} | ||
|
||
void CustomMessageManager::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 CustomMessageManager::FormatCustomMessage(std::string& message, ItemID iid) { | ||
message.insert(0, ITEM_OBTAINED(iid)); | ||
size_t start_pos = 0; | ||
std::replace(message.begin(), message.end(), '&', NEWLINE()[0]); | ||
while ((start_pos = message.find('^', start_pos)) != std::string::npos) { | ||
message.replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid)); | ||
start_pos += 3; | ||
} | ||
std::replace(message.begin(), message.end(), '@', PLAYER_NAME()[0]); | ||
ReplaceSpecialCharacters(message); | ||
ReplaceColors(message); | ||
message += MESSAGE_END(); | ||
} | ||
|
||
void CustomMessageManager::FormatCustomMessage(std::string& message) { | ||
size_t start_pos = 0; | ||
std::replace(message.begin(), message.end(), '&', NEWLINE()[0]); | ||
std::replace(message.begin(), message.end(), '^', WAIT_FOR_INPUT()[0]); | ||
std::replace(message.begin(), message.end(), '@', PLAYER_NAME()[0]); | ||
ReplaceSpecialCharacters(message); | ||
ReplaceColors(message); | ||
message += MESSAGE_END(); | ||
} | ||
|
||
bool CustomMessageManager::InsertCustomMessage(std::string tableID, uint16_t textID, CustomMessageEntry messages) { | ||
auto foundMessageTable = messageTables.find(tableID); | ||
if (foundMessageTable == messageTables.end()) { | ||
return false; | ||
} | ||
auto& messageTable = foundMessageTable->second; | ||
auto messageInsertResult = messageTable.emplace(textID, messages); | ||
return messageInsertResult.second; | ||
} | ||
|
||
|
||
|
||
bool CustomMessageManager::CreateGetItemMessage(std::string tableID, GetItemID giid, ItemID iid, CustomMessageEntry messageEntry) { | ||
FormatCustomMessage(messageEntry.english, iid); | ||
FormatCustomMessage(messageEntry.german, iid); | ||
FormatCustomMessage(messageEntry.french, iid); | ||
const uint16_t textID = giid; | ||
return InsertCustomMessage(tableID, textID, messageEntry); | ||
} | ||
|
||
bool CustomMessageManager::CreateMessage(std::string tableID, uint16_t textID, CustomMessageEntry messageEntry) { | ||
FormatCustomMessage(messageEntry.english); | ||
FormatCustomMessage(messageEntry.german); | ||
FormatCustomMessage(messageEntry.french); | ||
return InsertCustomMessage(tableID, textID, messageEntry); | ||
} | ||
|
||
CustomMessageEntry CustomMessageManager::RetrieveMessage(std::string tableID, uint16_t textID) { | ||
std::unordered_map<std::string, CustomMessageTable>::const_iterator foundMessageTable = messageTables.find(tableID); | ||
if (foundMessageTable == messageTables.end()) { | ||
return NULL_CUSTOM_MESSAGE; | ||
} | ||
CustomMessageTable messageTable = foundMessageTable->second; | ||
std::unordered_map<uint16_t, CustomMessageEntry>::const_iterator foundMessage = messageTable.find(textID); | ||
if (foundMessage == messageTable.end()) { | ||
return NULL_CUSTOM_MESSAGE; | ||
} | ||
CustomMessageEntry message = foundMessage->second; | ||
return message; | ||
} | ||
|
||
bool CustomMessageManager::ClearMessageTable(std::string tableID) { | ||
auto foundMessageTable = messageTables.find(tableID); | ||
if (foundMessageTable == messageTables.end()) { | ||
return false; | ||
} | ||
auto& messageTable = foundMessageTable->second; | ||
messageTable.clear(); | ||
} | ||
|
||
bool CustomMessageManager::AddCustomMessageTable(std::string tableID) { | ||
CustomMessageTable newMessageTable; | ||
return messageTables.emplace(tableID, newMessageTable).second; | ||
} | ||
|
||
std::string CustomMessageManager::MESSAGE_END() { | ||
return "\x02"s; | ||
} | ||
|
||
std::string CustomMessageManager::ITEM_OBTAINED(uint8_t x) { | ||
return "\x13"s + char(x); | ||
} | ||
|
||
std::string CustomMessageManager::NEWLINE() { | ||
return "\x01"s; | ||
} | ||
|
||
std::string CustomMessageManager::COLOR(uint8_t x) { | ||
return "\x05"s + char(x); | ||
} | ||
|
||
std::string CustomMessageManager::WAIT_FOR_INPUT() { | ||
return "\x04"s; | ||
} | ||
|
||
std::string CustomMessageManager::PLAYER_NAME() { | ||
return "\x0F"s; | ||
} |
133 changes: 133 additions & 0 deletions
133
soh/soh/Enhancements/custom-message/CustomMessageManager.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
#pragma once | ||
#include <string> | ||
#include <unordered_map> | ||
#include "../../../include/z64item.h" | ||
|
||
#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 | ||
|
||
#ifndef MESSAGE_DATA_STATIC_H | ||
|
||
typedef enum { | ||
/* 0 */ TEXTBOX_TYPE_BLACK, | ||
/* 1 */ TEXTBOX_TYPE_WOODEN, | ||
/* 2 */ TEXTBOX_TYPE_BLUE, | ||
/* 3 */ TEXTBOX_TYPE_OCARINA, | ||
/* 4 */ TEXTBOX_TYPE_NONE_BOTTOM, | ||
/* 5 */ TEXTBOX_TYPE_NONE_NO_SHADOW, | ||
/* 11 */ TEXTBOX_TYPE_CREDITS = 11 | ||
} TextBoxType; | ||
|
||
typedef enum { | ||
/* 0 */ TEXTBOX_BG_CROSS | ||
} TextBoxBackground; | ||
|
||
typedef enum { | ||
/* 0 */ TEXTBOX_POS_VARIABLE, | ||
/* 1 */ TEXTBOX_POS_TOP, | ||
/* 2 */ TEXTBOX_POS_MIDDLE, | ||
/* 3 */ TEXTBOX_POS_BOTTOM | ||
} TextBoxPosition; | ||
|
||
#endif | ||
|
||
typedef struct { | ||
TextBoxType textBoxType; | ||
TextBoxPosition textBoxPos; | ||
std::string english; | ||
std::string german; | ||
std::string french; | ||
} CustomMessageEntry; | ||
|
||
// Message Entry without the text type and position, useful for when | ||
// you need an array of these to loop over for registration | ||
// that will all have the same textbox type and position. | ||
typedef struct { | ||
std::string english; | ||
std::string german; | ||
std::string french; | ||
} CustomMessageMinimal; | ||
|
||
#define NULL_CUSTOM_MESSAGE \ | ||
{ (TextBoxType)(-1), (TextBoxPosition)(-1), "", "", "" } | ||
|
||
typedef std::unordered_map<uint16_t, CustomMessageEntry> CustomMessageTable; | ||
|
||
class CustomMessageManager { | ||
private: | ||
std::unordered_map<std::string, char> textBoxSpecialCharacters; | ||
std::unordered_map<std::string, char> colors; | ||
std::unordered_map<std::string, CustomMessageTable> messageTables; | ||
|
||
void ReplaceSpecialCharacters(std::string &string); | ||
void ReplaceColors(std::string& string); | ||
bool InsertCustomMessage(std::string tableID, uint16_t textID, CustomMessageEntry messages); | ||
|
||
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 CustomMessageManager* Instance; | ||
|
||
CustomMessageManager(); | ||
~CustomMessageManager(); | ||
|
||
/* | ||
Formats the provided Custom Message Entry and inserts it into the table with the provided tableID, | ||
with the provided giid (getItemID) as its key. This function also inserts the icon corresponding to | ||
the provided iid (itemID) at the beginning of each page of the textbox. | ||
*/ | ||
bool CreateGetItemMessage(std::string tableID, GetItemID giid, ItemID iid, CustomMessageEntry messages); | ||
|
||
/* | ||
Formats the provided Custom Message Entry and inserts it into the table with the provided tableID, | ||
with the provided textID as its key. | ||
*/ | ||
bool CreateMessage(std::string tableID, uint16_t textID, CustomMessageEntry messages); | ||
|
||
/* | ||
Retrieves a message from the table with id tableID with the provided textID. | ||
Returns a NULL_CUSTOM_MESSAGE if the message or table does not exist. | ||
*/ | ||
CustomMessageEntry RetrieveMessage(std::string tableID, uint16_t textID); | ||
|
||
/* | ||
Empties out the message table identified by tableID. | ||
Returns true if successful and false if not (for instance | ||
if a table with the provided tableID does not exist). | ||
*/ | ||
bool ClearMessageTable(std::string tableID); | ||
|
||
/* | ||
Creates an empty CustomMessageTable accessible at the provided | ||
tableID, returns true if creation was successful and false | ||
if not. | ||
*/ | ||
bool AddCustomMessageTable(std::string tableID); | ||
|
||
/* | ||
Replaces special characters and certain symbols with control codes | ||
& for newline, ^ for wait-for-input, and @ for the player name, | ||
as well as %<letter> for colors (i.e. %r for red and %w for white). | ||
*/ | ||
void FormatCustomMessage(std::string& message, ItemID iid); | ||
|
||
/* | ||
Replaces special characters and certain symbols with control codes | ||
& for newline, ^ for wait-for-input, and @ for the player name, | ||
as well as %<letter> for colors (i.e. %r for red and %w for white). | ||
*/ | ||
void FormatCustomMessage(std::string& message); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#pragma once | ||
|
||
typedef enum { | ||
TEXT_GS_NO_FREEZE = 0xB4, | ||
TEXT_GS_FREEZE = 0xB5, | ||
TEXT_RANDOMIZER_CUSTOM_ITEM = 0xF8, | ||
TEXT_SCRUB_POH = 0x10A2, | ||
TEXT_SCRUB_STICK_UPGRADE = 0x10DC, | ||
TEXT_SCRUB_NUT_UPGRADE = 0x10DD, | ||
TEXT_RANDOMIZER_GOSSIP_STONE_HINTS = 0x2053, | ||
TEXT_ALTAR_CHILD = 0x7040, | ||
TEXT_ALTAR_ADULT = 0x7088, | ||
TEXT_GANONDORF = 0x70CC, | ||
TEXT_GANONDORF_NOHINT = 0x70CD | ||
} TextIDs; | ||
|
||
#ifdef __cplusplus | ||
|
||
typedef struct { | ||
GetItemID giid; | ||
ItemID iid; | ||
std::string english; | ||
std::string german; | ||
std::string french; | ||
} GetItemMessage; | ||
|
||
#define GIMESSAGE(giid, iid, english, german, french) \ | ||
{ giid, iid, english, german, french } | ||
|
||
#define GIMESSAGE_UNTRANSLATED(giid, iid, message) \ | ||
{ giid, iid, message, message, message } | ||
|
||
#endif |
Oops, something went wrong.