mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 21:33:40 -07:00
Streamline hint generation (#3401)
* reimplement 3drando's hashtag color replacement system. Also generates merchant text at seed gen time instead of runtime. By merchants, I mean Bean Salesman, Medigoron, Granny, and Wasteland Bombchu guy. Scrubs and shops are still dynamic at runtime. * Improved auto-formatting and fixed altar text. * Gets hint text for spoiler direct from context. * Removal of now unused code. * Change warp song hint generation/retrieval Generates full warp location text instead of just location names and stores all six in the custom message tables for later retrieval as opposed to dynamically swapping in the location names every time the text is rendered. * Change Frog Ocarina Game Hint generation/retrieval Similar to previous changes, removes the on-the-fly generation aspect of it and just generates the full hint text once during seed generation. * Update soh/soh/Enhancements/randomizer/3drando/text.hpp Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> * Fix submodules appearing as changed files. * Fix WOTH/Foolish colors to match develop-macready. * Fixes backwards colors for area and item in some hints. --------- Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com>
This commit is contained in:
parent
467ee7ad12
commit
a196dd6b7e
17 changed files with 646 additions and 732 deletions
|
@ -42,7 +42,7 @@ Context::Context() {
|
|||
{ "Item Location", HINT_TYPE_ITEM_LOCATION },
|
||||
{ "Junk", HINT_TYPE_JUNK },
|
||||
};
|
||||
|
||||
|
||||
mSpoilerfileAreaNameToEnum = {
|
||||
{"No Hint", RA_NONE},
|
||||
{"Link's Pocket", RA_LINKS_POCKET},
|
||||
|
@ -423,187 +423,97 @@ void Context::ParseItemLocationsJson(nlohmann::json spoilerFileJson) {
|
|||
}
|
||||
}
|
||||
|
||||
std::string AltarIconString(const char iconChar) {
|
||||
std::string iconString;
|
||||
iconString += '\x13';
|
||||
switch (iconChar) {
|
||||
case '0':
|
||||
// Kokiri Emerald
|
||||
iconString += '\x6C';
|
||||
break;
|
||||
case '1':
|
||||
// Goron Ruby
|
||||
iconString += '\x6D';
|
||||
break;
|
||||
case '2':
|
||||
// Zora Sapphire
|
||||
iconString += '\x6E';
|
||||
break;
|
||||
case '3':
|
||||
// Forest Medallion
|
||||
iconString += '\x66';
|
||||
break;
|
||||
case '4':
|
||||
// Fire Medallion
|
||||
iconString += '\x67';
|
||||
break;
|
||||
case '5':
|
||||
// Water Medallion
|
||||
iconString += '\x68';
|
||||
break;
|
||||
case '6':
|
||||
// Spirit Medallion
|
||||
iconString += '\x69';
|
||||
break;
|
||||
case '7':
|
||||
// Shadow Medallion
|
||||
iconString += '\x6A';
|
||||
break;
|
||||
case '8':
|
||||
// Light Medallion
|
||||
iconString += '\x6B';
|
||||
break;
|
||||
case 'o':
|
||||
// Open DOT (master sword)
|
||||
iconString += '\x3C';
|
||||
break;
|
||||
case 'c':
|
||||
// Closed DOT (fairy ocarina)
|
||||
iconString += '\x07';
|
||||
break;
|
||||
case 'i':
|
||||
// Intended DOT (oot)
|
||||
iconString += '\x08';
|
||||
break;
|
||||
case 'l':
|
||||
// Light Arrow (for bridge reqs)
|
||||
iconString += '\x12';
|
||||
break;
|
||||
case 'b':
|
||||
// Boss Key (ganon boss key location)
|
||||
iconString += '\x74';
|
||||
break;
|
||||
case 'L':
|
||||
// Bow with Light Arrow
|
||||
iconString += '\x3A';
|
||||
break;
|
||||
case 'k':
|
||||
// Kokiri Tunic
|
||||
iconString += '\x41';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return iconString;
|
||||
}
|
||||
|
||||
std::string FormatJsonHintText(const std::string& jsonHint) {
|
||||
std::string formattedHintMessage = jsonHint;
|
||||
|
||||
// add icons to altar text
|
||||
for (const char iconChar : { '0', '1', '2', '3', '4', '5', '6', '7', '8', 'o', 'c', 'i', 'l', 'b', 'L', 'k' }) {
|
||||
std::string textToReplace = "$";
|
||||
textToReplace += iconChar;
|
||||
if (const size_t start_pos = formattedHintMessage.find(textToReplace); start_pos != std::string::npos) {
|
||||
std::string iconString = AltarIconString(iconChar);
|
||||
formattedHintMessage.replace(start_pos, textToReplace.length(), iconString);
|
||||
}
|
||||
}
|
||||
return formattedHintMessage;
|
||||
}
|
||||
|
||||
void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
|
||||
// Child Altar
|
||||
std::string childAltarJsonText = spoilerFileJson["childAltar"]["hintText"].get<std::string>();
|
||||
std::string formattedChildAltarText = FormatJsonHintText(childAltarJsonText);
|
||||
AddHint(RH_ALTAR_CHILD, Text(formattedChildAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
||||
std::string childAltarText = spoilerFileJson["childAltar"]["hintText"].get<std::string>();
|
||||
AddHint(RH_ALTAR_CHILD, Text(childAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", RA_NONE);
|
||||
mEmeraldLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["emeraldLoc"]];
|
||||
mRubyLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["rubyLoc"]];
|
||||
mSapphireLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["childAltar"]["rewards"]["sapphireLoc"]];
|
||||
|
||||
// Adult Altar
|
||||
std::string adultAltarJsonText = spoilerFileJson["adultAltar"]["hintText"].get<std::string>();
|
||||
std::string formattedAdultAltarText = FormatJsonHintText(adultAltarJsonText);
|
||||
AddHint(RH_ALTAR_ADULT, Text(formattedAdultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static");
|
||||
std::string adultAltarText = spoilerFileJson["adultAltar"]["hintText"].get<std::string>();
|
||||
AddHint(RH_ALTAR_ADULT, Text(adultAltarText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", RA_NONE);
|
||||
mForestMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["forestMedallionLoc"].get<std::string>()];
|
||||
mFireMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["fireMedallionLoc"].get<std::string>()];
|
||||
mWaterMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["waterMedallionLoc"].get<std::string>()];
|
||||
mShadowMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["shadowMedallionLoc"].get<std::string>()];
|
||||
mSpiritMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["spiritMedallionLoc"].get<std::string>()];
|
||||
mLightMedallionLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["adultAltar"]["rewards"]["lightMedallionLoc"].get<std::string>()];
|
||||
|
||||
|
||||
// Ganondorf and Sheik Light Arrow Hints
|
||||
std::string ganonHintText = FormatJsonHintText(spoilerFileJson["ganonHintText"].get<std::string>());
|
||||
std::string ganonHintText = spoilerFileJson["ganonHintText"].get<std::string>();
|
||||
RandomizerCheck lightArrowLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["lightArrowHintLoc"].get<std::string>()];
|
||||
std::string lightArrowRegion = spoilerFileJson["lightArrowArea"].get<std::string>();
|
||||
AddHint(RH_GANONDORF_HINT, Text(ganonHintText), lightArrowLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[lightArrowRegion]);
|
||||
if (spoilerFileJson.contains("sheikText")) {
|
||||
std::string sheikText = FormatJsonHintText(spoilerFileJson["sheikText"].get<std::string>());
|
||||
std::string sheikText = spoilerFileJson["sheikText"].get<std::string>();
|
||||
AddHint(RH_SHEIK_LIGHT_ARROWS, Text(sheikText), lightArrowLoc, HINT_TYPE_STATIC, lightArrowRegion);
|
||||
}
|
||||
std::string ganonText = FormatJsonHintText(spoilerFileJson["ganonText"].get<std::string>());
|
||||
std::string ganonText = spoilerFileJson["ganonText"].get<std::string>();
|
||||
AddHint(RH_GANONDORF_NOHINT, Text(ganonText), RC_UNKNOWN_CHECK, HINT_TYPE_JUNK, "Static", RA_GANONS_CASTLE);
|
||||
|
||||
|
||||
// Dampe Hookshot Hint
|
||||
if (spoilerFileJson.contains("dampeText")) {
|
||||
std::string dampeText = FormatJsonHintText(spoilerFileJson["dampeText"].get<std::string>());
|
||||
std::string dampeText = spoilerFileJson["dampeText"].get<std::string>();
|
||||
std::string dampeRegion = spoilerFileJson["dampeRegion"].get<std::string>();
|
||||
RandomizerCheck dampeHintLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["dampeHintLoc"].get<std::string>()];
|
||||
AddHint(RH_DAMPES_DIARY, Text(dampeText), dampeHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[dampeRegion]);
|
||||
}
|
||||
|
||||
|
||||
// Greg Hint
|
||||
if (spoilerFileJson.contains("gregText")) {
|
||||
std::string gregText = FormatJsonHintText(spoilerFileJson["gregText"].get<std::string>());
|
||||
std::string gregText = spoilerFileJson["gregText"].get<std::string>();
|
||||
std::string gregRegion = spoilerFileJson["gregRegion"].get<std::string>();
|
||||
RandomizerCheck gregLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["gregLoc"].get<std::string>()];
|
||||
AddHint(RH_GREG_RUPEE, Text(gregText), gregLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[gregRegion]);
|
||||
}
|
||||
|
||||
|
||||
// Saria Magic Hint
|
||||
if (spoilerFileJson.contains("sariaText")) {
|
||||
std::string sariaText = FormatJsonHintText(spoilerFileJson["sariaText"].get<std::string>());
|
||||
std::string sariaText = spoilerFileJson["sariaText"].get<std::string>();
|
||||
std::string sariaRegion = spoilerFileJson["sariaRegion"].get<std::string>();
|
||||
RandomizerCheck sariaHintLoc = mSpoilerfileCheckNameToEnum[spoilerFileJson["sariaHintLoc"].get<std::string>()];
|
||||
AddHint(RH_SARIA, Text(sariaText), sariaHintLoc, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[sariaRegion]);
|
||||
}
|
||||
|
||||
|
||||
// Warp Songs
|
||||
if (spoilerFileJson.contains("warpMinuetText")) {
|
||||
std::string warpMinuetText = FormatJsonHintText(spoilerFileJson["warpMinuetText"].get<std::string>()); //RANDOTODO fall back for if location is used
|
||||
std::string warpMinuetText = spoilerFileJson["warpMinuetText"].get<std::string>(); //RANDOTODO fall back for if location is used
|
||||
AddHint(RH_MINUET_WARP_LOC, Text(warpMinuetText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpMinuetText]);
|
||||
}
|
||||
if (spoilerFileJson.contains("warpBoleroText")) {
|
||||
std::string warpBoleroText = FormatJsonHintText(spoilerFileJson["warpBoleroText"].get<std::string>());
|
||||
std::string warpBoleroText = spoilerFileJson["warpBoleroText"].get<std::string>();
|
||||
AddHint(RH_BOLERO_WARP_LOC, Text(warpBoleroText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpBoleroText]);
|
||||
}
|
||||
if (spoilerFileJson.contains("warpSerenadeText")) {
|
||||
std::string warpSerenadeText = FormatJsonHintText(spoilerFileJson["warpSerenadeText"].get<std::string>());
|
||||
std::string warpSerenadeText = spoilerFileJson["warpSerenadeText"].get<std::string>();
|
||||
AddHint(RH_SERENADE_WARP_LOC, Text(warpSerenadeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpSerenadeText]);
|
||||
}
|
||||
if (spoilerFileJson.contains("warpRequiemText")) {
|
||||
std::string warpRequiemText = FormatJsonHintText(spoilerFileJson["warpRequiemText"].get<std::string>());
|
||||
std::string warpRequiemText = spoilerFileJson["warpRequiemText"].get<std::string>();
|
||||
AddHint(RH_REQUIEM_WARP_LOC, Text(warpRequiemText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpRequiemText]);
|
||||
}
|
||||
if (spoilerFileJson.contains("warpNocturneText")) {
|
||||
std::string warpNocturneText = FormatJsonHintText(spoilerFileJson["warpNocturneText"].get<std::string>());
|
||||
std::string warpNocturneText = spoilerFileJson["warpNocturneText"].get<std::string>();
|
||||
AddHint(RH_NOCTURNE_WARP_LOC, Text(warpNocturneText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpNocturneText]);
|
||||
}
|
||||
if (spoilerFileJson.contains("warpPreludeText")) {
|
||||
std::string warpPreludeText = FormatJsonHintText(spoilerFileJson["warpPreludeText"].get<std::string>());
|
||||
std::string warpPreludeText = spoilerFileJson["warpPreludeText"].get<std::string>();
|
||||
AddHint(RH_PRELUDE_WARP_LOC, Text(warpPreludeText), RC_UNKNOWN_CHECK, HINT_TYPE_STATIC, "Static", mSpoilerfileAreaNameToEnum[warpPreludeText]);
|
||||
}
|
||||
|
||||
|
||||
// Gossip Stones
|
||||
nlohmann::json hintsJson = spoilerFileJson["hints"];
|
||||
for (auto it = hintsJson.begin(); it != hintsJson.end(); ++it) {
|
||||
RandomizerCheck gossipStoneLoc = mSpoilerfileCheckNameToEnum[it.key()];
|
||||
nlohmann::json hintInfo = it.value();
|
||||
std::string hintText = FormatJsonHintText(hintInfo["hint"].get<std::string>());
|
||||
std::string hintText = hintInfo["hint"].get<std::string>();
|
||||
HintType hintType = mSpoilerfileHintTypeNameToEnum[hintInfo["type"].get<std::string>()];
|
||||
RandomizerCheck hintedLocation = hintInfo.contains("location") ? mSpoilerfileCheckNameToEnum[hintInfo["location"]] : RC_UNKNOWN_CHECK;
|
||||
std::string hintedArea = hintInfo.contains("area") ? hintInfo["area"].get<std::string>() : "";
|
||||
AddHint(static_cast<RandomizerHintKey>(gossipStoneLoc - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), hintedLocation, hintType, hintedArea);
|
||||
RandomizerArea hintedArea = hintInfo.contains("area") ? mSpoilerfileAreaNameToEnum[hintInfo["area"].get<std::string>()] : RA_NONE;
|
||||
std::string distribution = hintInfo["distribution"].get<std::string>();
|
||||
AddHint(static_cast<RandomizerHintKey>(gossipStoneLoc - RC_COLOSSUS_GOSSIP_STONE + 1), Text(hintText), hintedLocation, hintType, distribution, hintedArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue