Shipwright/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp

775 lines
29 KiB
C++
Raw Normal View History

testing out item replacement (#416) * skip learning song of storms * don't set flag when getting goron tunic as child * Initiates prelude check when master sword unloads. Not quite how N64 rando does it but so far it's the only way I've found to make it trigger without also triggering the time travel again. * Stops Shadow Temple lore prompts from appearing in rando. * Skips cutscene of royal tomb explosion in rando. Explosion sound doesn't play correctly and I think the debris appears in the wrong place, but the functionality is here. * Improves visual of exploding gravestone. * Adds some comments explaining the rando differences * Skip ruto text box in jabu blue warp For rando * skip intro cutscene in dodongo's cavern * load spoiler files on boot, fix spoilerfile existing check when making new saves * name entry dropped spoiler logic * make sure to actually init the cvar * no chime on load * uncomment * Skip ganondrof cutscene Skip to scream part of the death animation, skipping the text boxes etc. For rando * Update z_boss_ganondrof.c * skip owl flight cutscenes in rando * Fixes skipped text so it only applies to shadow temple. Earlier fix inadvertently applied to some other text as well, changed logic so that only specified sceneNums and textIds can have this enabled, and text skipped by sceneNum can have the skip overriden by textId if needed. Currently there are no overrides so the textId section of the logic is commented out to avoid compilation errors. * Adds a default to the switch case statements that leaves the randoSkipText variable unchanged, just in case. * TEST: Text for item * Adding ganon flavor text * ADD: AMMO Count * format ganon text/hint text * Autoskip the tower cutscene if settings call for tower collapse. * ganon hint text logic * Improved prelude after time travel fix * swapped the sizes between ganon hint text and ganon text, as they were set to the wrong things. * this is all i did * not the cleanest code ever but it's working * ADD: GS Count * ADD: Wallter (crash for now) * TWEAK: Wallet check * FIX: Use DrawItem instread of DrawUpgrade... b-baka! * Fixes some vanilla bugs introduced by rando code. * Added cutscene skip for zelda escaping Using the debug cutscene skipping function. Also added a conditional so the bridge doesn't spawn closed when cutscene is ready to trigger * ADD: X Spacing + Placeholders for song * ADD: default case for items * TWEAK: Spacing * FIX: Light Arrow * ADD: Ammo Option * use groups instead * ADD: More spacing logic * songs and names * TWEAK: Color on wallet * colors * Added flags cutscene before nabooru fight * ADD: ChromaKey text * First attempt skip cs after nabooru defeat * Better implementation for specific rando cutscene skips * use pulseaudio defaults * spaces/tabs * move color push/pop to stop crash * make the colors work again * the real bottle fix * pulseaudio values tuned for n64 audio at 44.1khz * update tlength * remove one hardcoded samplerate * Cleaned up and fixed zelda escape skip The if statement is a freaking monster, but unless we want to skip more cutscenes in the same way later, this is the most compact way of doing it that I know of. * Revert one line to match original nothing functional * another hint line that breaks autonewline logic * don't autospawn epona if we don't have the song/ocarina * Trying to use iron knuckle death effects not working yet * Streamlined OoT cutscene skip for future additions Also cleaned up if statement in general * Made if statement more readable Also added clarity for what cutscene was skipped * Fixed typo in comment * Janky nabooru defeat cs skip * altar text formatting (gonna need help shortening some of the french ones) * more altar text formatting * english altar text formatting complete * make gtg blocking guard check for card not bridge * FIX: Typo! * FIX: Uppercases * FIX: Typo * TWEAK: Alter + some names * TWEAK: More caps! * ADD: Missing string TWEAK more uppercases and namefixe s * Hide nabooru death by covering her in flames * bandaid fix for death crash issue * Twinrova defeat cs skip Skips the animation and manually calls the function to show the "beam" around the sisters * fix crash * fix caps to match * fix great fairy reward mashing/shielding issue * TWEAK : Typo clé to Clé * TWEAK: Some Altar hints TWEAK: Some capitals * TWEAK: Unmatching text + some cap again * TWEAK: More tweaks * fix build * remove extra json.hpp, add hint * Update randomizer_item_tracker.cpp * TWEAK: Double Defense with RedParticles instead of white * make sure we don't optimize out the check to ensure a spoilerfile exists * vanilla ganon boss key hint formatting * TWEAK: FR- better way of the hero text * fix * and again * Initializes dungeonsDone items in gSaveContext to 0. * Replaces sizeof calculation with a NUM_DUNGEONS constant. * Fixes Saria's Gift on the LW Bridge from getting killed when holding shield. * More airtight fix for Saria's Gift on the Bridge. * Lifts one of the conditions in the if statement a little higher to prevent unnecessary lookups of getItemId. * Invalidate text box icon before drawing * Fixes the case where Saria's gift is an Ice Trap. We still get the Ice Trap once, but never again. This does mean you can now hold R while walking in to avoid the ice trap, but everything else seems to work fine. * Initial commit Might need changing when we change the settings in the future * Fixes Door of Time opening cutscene after warping with prelude. * Initial waterfall skip Very rudimentary way of doing things but it seems to work so :shrug: * inital rework * fixed default rotation for 2D sprites * fix tab/space issues * 3d drops rando merge fix again * Allows Impa to appear in the Lullaby check post drawbridge escape. * Changes Ganon's Trials Count setting to a checkbox The checkbox is whether or not to skip all of them. Leaving the box unchecked will mean doing all of them. Eventually this will be switched back to a slider once we implement the logic for which trials start out completed. * Sets all Ganon's Trials to incomplete in new saves. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131 * fix castle guards when oot throw cutscene has already played in rando * Properly removes the beams when trials are cleared. * Removes Question Mark from Skip Ganon's Trials UI. * Adds a todo comment about when to change back to slider. * make deku seeds check for bullet bag * Various tweaks TWEAK: Altar Text TWEAK: Hint names TWEAK: Replace more problematic œ to oe * upgrade ocarina on both child and adult equips * FIX: Jabu Item * update equipped hookshot/longshot when obtained as other age * add hint * don't give the bgs check without the claim check * Skips Darunia Cutscene in Fire Temple * Added a TODO note about not skipping the cutscene. There is a setting we will want to have eventually that will require this cutscene to not be skipped since it is used during a glitch. * remove todo * restore fast ocarina option in imgui that was lost in merge * Fixes grey screen issue + tooltip for 2 handed shield * update to use dg instead of g for textures in item tracker * TWEAK: Default color for cosmetic RAND button was not the corect one * fix texture crash, remove unused item tracker code * don't open mask shop until we get zelda's letter * Update README.md * Prevents "correct" chime under incorrect conditions. * Fixes typo in conditional and adds "bonk" sound effect. "Bonk" sound is NA_SE_SY_OCARINA_ERROR and it plays when conditions for the Door of Time have not been met after playing Song of Time. This is only possible in rando's "Intended" Door of Time option, in which the Ocarina of Time and all 3 spritual stones are required to open the door, instead of the vanilla requirements of just having the song of time. * remove modify dpad equips toggle, replace with checks for dpad menu * remove extra check * add ability to hold c-up to assign to dpad when dpad menuing is enabled * disable d-pad navigation on item menu when holding c-up to equip * dpad+c-up stuff for equipment menu * ADD: Checbox for songs colors * TWEAK: RandoColors for normal songs * kind of quick and dirty but it works * TWEAK: Clarity of the tooltip Co-authored-by: briaguya <briaguya@alice> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: aMannus <mannusmenting@gmail.com> Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com> Co-authored-by: Dog <5172592+Dog@users.noreply.github.com> Co-authored-by: Vague Rant <vaguerant@users.noreply.github.com> Co-authored-by: Baoulettes <perlouzerie@hotmail.fr> Co-authored-by: Ada <60364512+GreatArgorath@users.noreply.github.com>
2022-07-11 20:11:07 -04:00
#include "spoiler_log.hpp"
#include "dungeon.hpp"
#include "item_list.hpp"
#include "item_location.hpp"
#include "entrance.hpp"
#include "random.hpp"
#include "settings.hpp"
#include "trial.hpp"
#include "tinyxml2.h"
#include "utils.hpp"
#include "shops.hpp"
#include "hints.hpp"
#include "Lib/nlohmann/json.hpp"
testing out item replacement (#416) * skip learning song of storms * don't set flag when getting goron tunic as child * Initiates prelude check when master sword unloads. Not quite how N64 rando does it but so far it's the only way I've found to make it trigger without also triggering the time travel again. * Stops Shadow Temple lore prompts from appearing in rando. * Skips cutscene of royal tomb explosion in rando. Explosion sound doesn't play correctly and I think the debris appears in the wrong place, but the functionality is here. * Improves visual of exploding gravestone. * Adds some comments explaining the rando differences * Skip ruto text box in jabu blue warp For rando * skip intro cutscene in dodongo's cavern * load spoiler files on boot, fix spoilerfile existing check when making new saves * name entry dropped spoiler logic * make sure to actually init the cvar * no chime on load * uncomment * Skip ganondrof cutscene Skip to scream part of the death animation, skipping the text boxes etc. For rando * Update z_boss_ganondrof.c * skip owl flight cutscenes in rando * Fixes skipped text so it only applies to shadow temple. Earlier fix inadvertently applied to some other text as well, changed logic so that only specified sceneNums and textIds can have this enabled, and text skipped by sceneNum can have the skip overriden by textId if needed. Currently there are no overrides so the textId section of the logic is commented out to avoid compilation errors. * Adds a default to the switch case statements that leaves the randoSkipText variable unchanged, just in case. * TEST: Text for item * Adding ganon flavor text * ADD: AMMO Count * format ganon text/hint text * Autoskip the tower cutscene if settings call for tower collapse. * ganon hint text logic * Improved prelude after time travel fix * swapped the sizes between ganon hint text and ganon text, as they were set to the wrong things. * this is all i did * not the cleanest code ever but it's working * ADD: GS Count * ADD: Wallter (crash for now) * TWEAK: Wallet check * FIX: Use DrawItem instread of DrawUpgrade... b-baka! * Fixes some vanilla bugs introduced by rando code. * Added cutscene skip for zelda escaping Using the debug cutscene skipping function. Also added a conditional so the bridge doesn't spawn closed when cutscene is ready to trigger * ADD: X Spacing + Placeholders for song * ADD: default case for items * TWEAK: Spacing * FIX: Light Arrow * ADD: Ammo Option * use groups instead * ADD: More spacing logic * songs and names * TWEAK: Color on wallet * colors * Added flags cutscene before nabooru fight * ADD: ChromaKey text * First attempt skip cs after nabooru defeat * Better implementation for specific rando cutscene skips * use pulseaudio defaults * spaces/tabs * move color push/pop to stop crash * make the colors work again * the real bottle fix * pulseaudio values tuned for n64 audio at 44.1khz * update tlength * remove one hardcoded samplerate * Cleaned up and fixed zelda escape skip The if statement is a freaking monster, but unless we want to skip more cutscenes in the same way later, this is the most compact way of doing it that I know of. * Revert one line to match original nothing functional * another hint line that breaks autonewline logic * don't autospawn epona if we don't have the song/ocarina * Trying to use iron knuckle death effects not working yet * Streamlined OoT cutscene skip for future additions Also cleaned up if statement in general * Made if statement more readable Also added clarity for what cutscene was skipped * Fixed typo in comment * Janky nabooru defeat cs skip * altar text formatting (gonna need help shortening some of the french ones) * more altar text formatting * english altar text formatting complete * make gtg blocking guard check for card not bridge * FIX: Typo! * FIX: Uppercases * FIX: Typo * TWEAK: Alter + some names * TWEAK: More caps! * ADD: Missing string TWEAK more uppercases and namefixe s * Hide nabooru death by covering her in flames * bandaid fix for death crash issue * Twinrova defeat cs skip Skips the animation and manually calls the function to show the "beam" around the sisters * fix crash * fix caps to match * fix great fairy reward mashing/shielding issue * TWEAK : Typo clé to Clé * TWEAK: Some Altar hints TWEAK: Some capitals * TWEAK: Unmatching text + some cap again * TWEAK: More tweaks * fix build * remove extra json.hpp, add hint * Update randomizer_item_tracker.cpp * TWEAK: Double Defense with RedParticles instead of white * make sure we don't optimize out the check to ensure a spoilerfile exists * vanilla ganon boss key hint formatting * TWEAK: FR- better way of the hero text * fix * and again * Initializes dungeonsDone items in gSaveContext to 0. * Replaces sizeof calculation with a NUM_DUNGEONS constant. * Fixes Saria's Gift on the LW Bridge from getting killed when holding shield. * More airtight fix for Saria's Gift on the Bridge. * Lifts one of the conditions in the if statement a little higher to prevent unnecessary lookups of getItemId. * Invalidate text box icon before drawing * Fixes the case where Saria's gift is an Ice Trap. We still get the Ice Trap once, but never again. This does mean you can now hold R while walking in to avoid the ice trap, but everything else seems to work fine. * Initial commit Might need changing when we change the settings in the future * Fixes Door of Time opening cutscene after warping with prelude. * Initial waterfall skip Very rudimentary way of doing things but it seems to work so :shrug: * inital rework * fixed default rotation for 2D sprites * fix tab/space issues * 3d drops rando merge fix again * Allows Impa to appear in the Lullaby check post drawbridge escape. * Changes Ganon's Trials Count setting to a checkbox The checkbox is whether or not to skip all of them. Leaving the box unchecked will mean doing all of them. Eventually this will be switched back to a slider once we implement the logic for which trials start out completed. * Sets all Ganon's Trials to incomplete in new saves. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131 * fix castle guards when oot throw cutscene has already played in rando * Properly removes the beams when trials are cleared. * Removes Question Mark from Skip Ganon's Trials UI. * Adds a todo comment about when to change back to slider. * make deku seeds check for bullet bag * Various tweaks TWEAK: Altar Text TWEAK: Hint names TWEAK: Replace more problematic œ to oe * upgrade ocarina on both child and adult equips * FIX: Jabu Item * update equipped hookshot/longshot when obtained as other age * add hint * don't give the bgs check without the claim check * Skips Darunia Cutscene in Fire Temple * Added a TODO note about not skipping the cutscene. There is a setting we will want to have eventually that will require this cutscene to not be skipped since it is used during a glitch. * remove todo * restore fast ocarina option in imgui that was lost in merge * Fixes grey screen issue + tooltip for 2 handed shield * update to use dg instead of g for textures in item tracker * TWEAK: Default color for cosmetic RAND button was not the corect one * fix texture crash, remove unused item tracker code * don't open mask shop until we get zelda's letter * Update README.md * Prevents "correct" chime under incorrect conditions. * Fixes typo in conditional and adds "bonk" sound effect. "Bonk" sound is NA_SE_SY_OCARINA_ERROR and it plays when conditions for the Door of Time have not been met after playing Song of Time. This is only possible in rando's "Intended" Door of Time option, in which the Ocarina of Time and all 3 spritual stones are required to open the door, instead of the vanilla requirements of just having the song of time. * remove modify dpad equips toggle, replace with checks for dpad menu * remove extra check * add ability to hold c-up to assign to dpad when dpad menuing is enabled * disable d-pad navigation on item menu when holding c-up to equip * dpad+c-up stuff for equipment menu * ADD: Checbox for songs colors * TWEAK: RandoColors for normal songs * kind of quick and dirty but it works * TWEAK: Clarity of the tooltip Co-authored-by: briaguya <briaguya@alice> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: aMannus <mannusmenting@gmail.com> Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com> Co-authored-by: Dog <5172592+Dog@users.noreply.github.com> Co-authored-by: Vague Rant <vaguerant@users.noreply.github.com> Co-authored-by: Baoulettes <perlouzerie@hotmail.fr> Co-authored-by: Ada <60364512+GreatArgorath@users.noreply.github.com>
2022-07-11 20:11:07 -04:00
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <variables.h>
#define NOGDI
#define WIN32_LEAN_AND_MEAN
#include "GlobalCtx2.h"
testing out item replacement (#416) * skip learning song of storms * don't set flag when getting goron tunic as child * Initiates prelude check when master sword unloads. Not quite how N64 rando does it but so far it's the only way I've found to make it trigger without also triggering the time travel again. * Stops Shadow Temple lore prompts from appearing in rando. * Skips cutscene of royal tomb explosion in rando. Explosion sound doesn't play correctly and I think the debris appears in the wrong place, but the functionality is here. * Improves visual of exploding gravestone. * Adds some comments explaining the rando differences * Skip ruto text box in jabu blue warp For rando * skip intro cutscene in dodongo's cavern * load spoiler files on boot, fix spoilerfile existing check when making new saves * name entry dropped spoiler logic * make sure to actually init the cvar * no chime on load * uncomment * Skip ganondrof cutscene Skip to scream part of the death animation, skipping the text boxes etc. For rando * Update z_boss_ganondrof.c * skip owl flight cutscenes in rando * Fixes skipped text so it only applies to shadow temple. Earlier fix inadvertently applied to some other text as well, changed logic so that only specified sceneNums and textIds can have this enabled, and text skipped by sceneNum can have the skip overriden by textId if needed. Currently there are no overrides so the textId section of the logic is commented out to avoid compilation errors. * Adds a default to the switch case statements that leaves the randoSkipText variable unchanged, just in case. * TEST: Text for item * Adding ganon flavor text * ADD: AMMO Count * format ganon text/hint text * Autoskip the tower cutscene if settings call for tower collapse. * ganon hint text logic * Improved prelude after time travel fix * swapped the sizes between ganon hint text and ganon text, as they were set to the wrong things. * this is all i did * not the cleanest code ever but it's working * ADD: GS Count * ADD: Wallter (crash for now) * TWEAK: Wallet check * FIX: Use DrawItem instread of DrawUpgrade... b-baka! * Fixes some vanilla bugs introduced by rando code. * Added cutscene skip for zelda escaping Using the debug cutscene skipping function. Also added a conditional so the bridge doesn't spawn closed when cutscene is ready to trigger * ADD: X Spacing + Placeholders for song * ADD: default case for items * TWEAK: Spacing * FIX: Light Arrow * ADD: Ammo Option * use groups instead * ADD: More spacing logic * songs and names * TWEAK: Color on wallet * colors * Added flags cutscene before nabooru fight * ADD: ChromaKey text * First attempt skip cs after nabooru defeat * Better implementation for specific rando cutscene skips * use pulseaudio defaults * spaces/tabs * move color push/pop to stop crash * make the colors work again * the real bottle fix * pulseaudio values tuned for n64 audio at 44.1khz * update tlength * remove one hardcoded samplerate * Cleaned up and fixed zelda escape skip The if statement is a freaking monster, but unless we want to skip more cutscenes in the same way later, this is the most compact way of doing it that I know of. * Revert one line to match original nothing functional * another hint line that breaks autonewline logic * don't autospawn epona if we don't have the song/ocarina * Trying to use iron knuckle death effects not working yet * Streamlined OoT cutscene skip for future additions Also cleaned up if statement in general * Made if statement more readable Also added clarity for what cutscene was skipped * Fixed typo in comment * Janky nabooru defeat cs skip * altar text formatting (gonna need help shortening some of the french ones) * more altar text formatting * english altar text formatting complete * make gtg blocking guard check for card not bridge * FIX: Typo! * FIX: Uppercases * FIX: Typo * TWEAK: Alter + some names * TWEAK: More caps! * ADD: Missing string TWEAK more uppercases and namefixe s * Hide nabooru death by covering her in flames * bandaid fix for death crash issue * Twinrova defeat cs skip Skips the animation and manually calls the function to show the "beam" around the sisters * fix crash * fix caps to match * fix great fairy reward mashing/shielding issue * TWEAK : Typo clé to Clé * TWEAK: Some Altar hints TWEAK: Some capitals * TWEAK: Unmatching text + some cap again * TWEAK: More tweaks * fix build * remove extra json.hpp, add hint * Update randomizer_item_tracker.cpp * TWEAK: Double Defense with RedParticles instead of white * make sure we don't optimize out the check to ensure a spoilerfile exists * vanilla ganon boss key hint formatting * TWEAK: FR- better way of the hero text * fix * and again * Initializes dungeonsDone items in gSaveContext to 0. * Replaces sizeof calculation with a NUM_DUNGEONS constant. * Fixes Saria's Gift on the LW Bridge from getting killed when holding shield. * More airtight fix for Saria's Gift on the Bridge. * Lifts one of the conditions in the if statement a little higher to prevent unnecessary lookups of getItemId. * Invalidate text box icon before drawing * Fixes the case where Saria's gift is an Ice Trap. We still get the Ice Trap once, but never again. This does mean you can now hold R while walking in to avoid the ice trap, but everything else seems to work fine. * Initial commit Might need changing when we change the settings in the future * Fixes Door of Time opening cutscene after warping with prelude. * Initial waterfall skip Very rudimentary way of doing things but it seems to work so :shrug: * inital rework * fixed default rotation for 2D sprites * fix tab/space issues * 3d drops rando merge fix again * Allows Impa to appear in the Lullaby check post drawbridge escape. * Changes Ganon's Trials Count setting to a checkbox The checkbox is whether or not to skip all of them. Leaving the box unchecked will mean doing all of them. Eventually this will be switched back to a slider once we implement the logic for which trials start out completed. * Sets all Ganon's Trials to incomplete in new saves. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131 * fix castle guards when oot throw cutscene has already played in rando * Properly removes the beams when trials are cleared. * Removes Question Mark from Skip Ganon's Trials UI. * Adds a todo comment about when to change back to slider. * make deku seeds check for bullet bag * Various tweaks TWEAK: Altar Text TWEAK: Hint names TWEAK: Replace more problematic œ to oe * upgrade ocarina on both child and adult equips * FIX: Jabu Item * update equipped hookshot/longshot when obtained as other age * add hint * don't give the bgs check without the claim check * Skips Darunia Cutscene in Fire Temple * Added a TODO note about not skipping the cutscene. There is a setting we will want to have eventually that will require this cutscene to not be skipped since it is used during a glitch. * remove todo * restore fast ocarina option in imgui that was lost in merge * Fixes grey screen issue + tooltip for 2 handed shield * update to use dg instead of g for textures in item tracker * TWEAK: Default color for cosmetic RAND button was not the corect one * fix texture crash, remove unused item tracker code * don't open mask shop until we get zelda's letter * Update README.md * Prevents "correct" chime under incorrect conditions. * Fixes typo in conditional and adds "bonk" sound effect. "Bonk" sound is NA_SE_SY_OCARINA_ERROR and it plays when conditions for the Door of Time have not been met after playing Song of Time. This is only possible in rando's "Intended" Door of Time option, in which the Ocarina of Time and all 3 spritual stones are required to open the door, instead of the vanilla requirements of just having the song of time. * remove modify dpad equips toggle, replace with checks for dpad menu * remove extra check * add ability to hold c-up to assign to dpad when dpad menuing is enabled * disable d-pad navigation on item menu when holding c-up to equip * dpad+c-up stuff for equipment menu * ADD: Checbox for songs colors * TWEAK: RandoColors for normal songs * kind of quick and dirty but it works * TWEAK: Clarity of the tooltip Co-authored-by: briaguya <briaguya@alice> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: aMannus <mannusmenting@gmail.com> Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com> Co-authored-by: Dog <5172592+Dog@users.noreply.github.com> Co-authored-by: Vague Rant <vaguerant@users.noreply.github.com> Co-authored-by: Baoulettes <perlouzerie@hotmail.fr> Co-authored-by: Ada <60364512+GreatArgorath@users.noreply.github.com>
2022-07-11 20:11:07 -04:00
using json = nlohmann::json;
json jsonData;
namespace {
std::string placementtxt;
} // namespace
static RandomizerHash randomizerHash;
static SpoilerData spoilerData;
void GenerateHash() {
for (size_t i = 0; i < Settings::seed.size(); i++) {
int number = Settings::seed[i] - '0';
Settings::hashIconIndexes[i] = number;
}
// Clear out spoiler log data here, in case we aren't going to re-generate it
// spoilerData = { 0 };
}
const RandomizerHash& GetRandomizerHash() {
return randomizerHash;
}
// Returns the randomizer hash as concatenated string, separated by comma.
const std::string GetRandomizerHashAsString() {
std::string hash = "";
for (const std::string& str : randomizerHash) {
hash += str + ", ";
}
hash.erase(hash.length() - 2); // Erase last comma
return hash;
}
const SpoilerData& GetSpoilerData() {
return spoilerData;
}
static auto GetGeneralPath() {
return "./randomizer/haha.xml";
}
static auto GetSpoilerLogPath() {
return GetGeneralPath();
}
static auto GetPlacementLogPath() {
return GetGeneralPath();
}
void WriteIngameSpoilerLog() {
uint16_t spoilerItemIndex = 0;
uint32_t spoilerStringOffset = 0;
uint16_t spoilerSphereItemoffset = 0;
uint16_t spoilerGroupOffset = 0;
// Intentionally junk value so we trigger the 'new group, record some stuff' code
uint8_t currentGroup = SpoilerCollectionCheckGroup::SPOILER_COLLECTION_GROUP_COUNT;
bool spoilerOutOfSpace = false;
// Create map of string data offsets for all _unique_ item locations and names in the playthrough
// Some item names, like gold skulltula tokens, can appear many times in a playthrough
std::unordered_map<uint32_t, uint16_t>
itemLocationsMap; // Map of LocationKey to an index into spoiler data item locations
itemLocationsMap.reserve(allLocations.size());
std::unordered_map<std::string, uint16_t>
stringOffsetMap; // Map of strings to their offset into spoiler string data array
stringOffsetMap.reserve(allLocations.size() * 2);
// Sort all locations by their group, so the in-game log can show a group of items by simply starting/ending at
// certain indices
std::stable_sort(allLocations.begin(), allLocations.end(), [](const uint32_t& a, const uint32_t& b) {
auto groupA = Location(a)->GetCollectionCheckGroup();
auto groupB = Location(b)->GetCollectionCheckGroup();
return groupA < groupB;
});
for (const uint32_t key : allLocations) {
auto loc = Location(key);
// Hide excluded locations from ingame tracker
if (loc->IsExcluded()) {
continue;
}
// Cows
else if (!Settings::ShuffleCows && loc->IsCategory(Category::cCow)) {
continue;
}
// Merchants
else if (Settings::ShuffleMerchants.Is(SHUFFLEMERCHANTS_OFF) && loc->IsCategory(Category::cMerchant)) {
continue;
}
// Adult Trade
else if (!Settings::ShuffleAdultTradeQuest && loc->IsCategory(Category::cAdultTrade)) {
continue;
}
// Chest Minigame
else if (Settings::ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_OFF) &&
loc->IsCategory(Category::cChestMinigame)) {
continue;
}
// Gerudo Fortress
else if ((Settings::GerudoFortress.Is(GERUDOFORTRESS_OPEN) &&
(loc->IsCategory(Category::cVanillaGFSmallKey) || loc->GetHintKey() == GF_GERUDO_MEMBERSHIP_CARD)) ||
(Settings::GerudoFortress.Is(GERUDOFORTRESS_FAST) && loc->IsCategory(Category::cVanillaGFSmallKey) &&
loc->GetHintKey() != GF_NORTH_F1_CARPENTER)) {
continue;
}
// Copy at most 51 chars from the name and location name to avoid issues with names that don't fit on screen
const char* nameFormatStr = "%.51s";
auto locName = loc->GetName();
if (stringOffsetMap.find(locName) == stringOffsetMap.end()) {
if (spoilerStringOffset + locName.size() + 1 >= SPOILER_STRING_DATA_SIZE) {
spoilerOutOfSpace = true;
break;
} else {
stringOffsetMap[locName] = spoilerStringOffset;
spoilerStringOffset +=
sprintf(&spoilerData.StringData[spoilerStringOffset], nameFormatStr, locName.c_str()) + 1;
}
}
// PURPLE TODO: LOCALIZATION
auto locItem = loc->GetPlacedItemName().GetEnglish();
if (loc->GetPlacedItemKey() == ICE_TRAP && loc->IsCategory(Category::cShop)) {
locItem = NonShopItems[TransformShopIndex(GetShopIndex(key))].Name.GetEnglish();
}
if (stringOffsetMap.find(locItem) == stringOffsetMap.end()) {
if (spoilerStringOffset + locItem.size() + 1 >= SPOILER_STRING_DATA_SIZE) {
spoilerOutOfSpace = true;
break;
} else {
stringOffsetMap[locItem] = spoilerStringOffset;
spoilerStringOffset +=
sprintf(&spoilerData.StringData[spoilerStringOffset], nameFormatStr, locItem.c_str()) + 1;
}
}
spoilerData.ItemLocations[spoilerItemIndex].LocationStrOffset = stringOffsetMap[locName];
spoilerData.ItemLocations[spoilerItemIndex].ItemStrOffset = stringOffsetMap[locItem];
spoilerData.ItemLocations[spoilerItemIndex].LocationStr = locName;
spoilerData.ItemLocations[spoilerItemIndex].ItemStr = locItem;
spoilerData.ItemLocations[spoilerItemIndex].CollectionCheckType = loc->GetCollectionCheck().type;
spoilerData.ItemLocations[spoilerItemIndex].LocationScene = loc->GetCollectionCheck().scene;
spoilerData.ItemLocations[spoilerItemIndex].LocationFlag = loc->GetCollectionCheck().flag;
// Collect Type and Reveal Type
if (key == GANON) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_NEVER;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
} else if (key == MARKET_BOMBCHU_BOWLING_BOMBCHUS) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
// Shops
else if (loc->IsShop()) {
if (Settings::Shopsanity.Is(SHOPSANITY_OFF)) {
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
} else {
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_SCENE;
}
if (loc->GetPlacedItem().GetItemType() == ITEMTYPE_REFILL ||
loc->GetPlacedItem().GetItemType() == ITEMTYPE_SHOP ||
loc->GetPlacedItem().GetHintKey() == PROGRESSIVE_BOMBCHUS) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE;
}
}
// Gold Skulltulas
else if (loc->IsCategory(Category::cSkulltula) &&
((Settings::Tokensanity.Is(TOKENSANITY_OFF)) ||
(Settings::Tokensanity.Is(TOKENSANITY_DUNGEONS) && !loc->IsDungeon()) ||
(Settings::Tokensanity.Is(TOKENSANITY_OVERWORLD) && loc->IsDungeon()))) {
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
// Deku Scrubs
else if (loc->IsCategory(Category::cDekuScrub) && !loc->IsCategory(Category::cDekuScrubUpgrades) &&
Settings::Scrubsanity.Is(SCRUBSANITY_OFF)) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
auto checkGroup = loc->GetCollectionCheckGroup();
spoilerData.ItemLocations[spoilerItemIndex].Group = checkGroup;
// Group setup
if (checkGroup != currentGroup) {
currentGroup = checkGroup;
spoilerData.GroupOffsets[currentGroup] = spoilerGroupOffset;
}
++spoilerData.GroupItemCounts[currentGroup];
++spoilerGroupOffset;
itemLocationsMap[key] = spoilerItemIndex++;
}
spoilerData.ItemLocationsCount = spoilerItemIndex;
if (Settings::IngameSpoilers) {
bool playthroughItemNotFound = false;
// Write playthrough data to in-game spoiler log
if (!spoilerOutOfSpace) {
for (uint32_t i = 0; i < playthroughLocations.size(); i++) {
if (i >= SPOILER_SPHERES_MAX) {
spoilerOutOfSpace = true;
break;
}
spoilerData.Spheres[i].ItemLocationsOffset = spoilerSphereItemoffset;
for (uint32_t loc = 0; loc < playthroughLocations[i].size(); ++loc) {
if (spoilerSphereItemoffset >= SPOILER_ITEMS_MAX) {
spoilerOutOfSpace = true;
break;
}
const auto foundItemLoc = itemLocationsMap.find(playthroughLocations[i][loc]);
if (foundItemLoc != itemLocationsMap.end()) {
spoilerData.SphereItemLocations[spoilerSphereItemoffset++] = foundItemLoc->second;
} else {
playthroughItemNotFound = true;
}
++spoilerData.Spheres[i].ItemCount;
}
++spoilerData.SphereCount;
}
}
if (spoilerOutOfSpace || playthroughItemNotFound) {
printf("%sError!%s ", YELLOW, WHITE);
}
}
}
// Writes the location to the specified node.
static void WriteLocation(
std::string sphere, const uint32_t locationKey, const bool withPadding = false) {
ItemLocation* location = Location(locationKey);
// auto node = parentNode->InsertNewChildElement("location");
switch (gSaveContext.language) {
case LANGUAGE_ENG:
default:
jsonData["playthrough"][sphere][location->GetName()] = location->GetPlacedItemName().GetEnglish();
break;
case LANGUAGE_FRA:
jsonData["playthrough"][sphere][location->GetName()] = location->GetPlacedItemName().GetFrench();
break;
}
// node->SetAttribute("name", location->GetName().c_str());
// node->SetText(location->GetPlacedItemName().GetEnglish().c_str());
// if (withPadding) {
// constexpr int16_t LONGEST_NAME = 56; // The longest name of a location.
// constexpr int16_t PRICE_ATTRIBUTE = 12; // Length of a 3-digit price attribute.
// // Insert a padding so we get a kind of table in the XML document.
// int16_t requiredPadding = LONGEST_NAME - location->GetName().length();
// if (location->IsCategory(Category::cShop)) {
// // Shop items have short location names, but come with an additional price attribute.
// requiredPadding -= PRICE_ATTRIBUTE;
// }
// if (requiredPadding >= 0) {
// std::string padding(requiredPadding, ' ');
// node->SetAttribute("_", padding.c_str());
// }
// }
// if (location->IsCategory(Category::cShop)) {
// char price[6];
// sprintf(price, "%03d", location->GetPrice());
// node->SetAttribute("price", price);
// }
// if (!location->IsAddedToPool()) {
// #ifdef ENABLE_DEBUG
// node->SetAttribute("not-added", true);
// #endif
// }
}
//Writes a shuffled entrance to the specified node
static void WriteShuffledEntrance(
tinyxml2::XMLElement* parentNode,
Entrance* entrance,
const bool withPadding = false
) {
auto node = parentNode->InsertNewChildElement("entrance");
node->SetAttribute("name", entrance->GetName().c_str());
auto text = entrance->GetConnectedRegion()->regionName + " from " + entrance->GetReplacement()->GetParentRegion()->regionName;
node->SetText(text.c_str());
if (withPadding) {
constexpr int16_t LONGEST_NAME = 56; //The longest name of a vanilla entrance
//Insert padding so we get a kind of table in the XML document
int16_t requiredPadding = LONGEST_NAME - entrance->GetName().length();
if (requiredPadding > 0) {
std::string padding(requiredPadding, ' ');
node->SetAttribute("_", padding.c_str());
}
}
}
// Writes the settings (without excluded locations, starting inventory and tricks) to the spoilerLog document.
static void WriteSettings(const bool printAll = false) {
// auto parentNode = spoilerLog.NewElement("settings");
std::vector<Menu*> allMenus = Settings::GetAllOptionMenus();
for (const Menu* menu : allMenus) {
if (menu->name == "Cosmetic Settings" ||
menu->name == "Ingame Defaults" ||
menu->name == "Item Usability Settings" ||
menu->name == "Multiplayer Settings") continue;
if (menu->name == "Timesaver Settings") {
for (const Option* setting : *menu->settingsList) {
if (setting->GetName() == "Big Poe Target Count" ||
setting->GetName() == "Cuccos to return" ||
setting->GetName() == "Skip Epona Race" ||
setting->GetName() == "Skip Tower Escape" ||
setting->GetName() == "Skip Child Stealth") {
std::string settingName = menu->name + ":" + setting->GetName();
jsonData["settings"][settingName] = setting->GetSelectedOptionText();
}
}
continue;
}
//This is a menu of settings, write them
if (menu->mode == OPTION_SUB_MENU && menu->printInSpoiler) {
for (const Option* setting : *menu->settingsList) {
std::string settingName = menu->name + ":" + setting->GetName();
jsonData["settings"][settingName] = setting->GetSelectedOptionText();
}
// for (const Option* setting : *menu->settingsList) {
// if (printAll || (!setting->IsHidden() && setting->IsCategory(OptionCategory::Setting))) {
// auto node = parentNode->InsertNewChildElement("setting");
// node->SetAttribute("name", RemoveLineBreaks(setting->GetName()).c_str());
// node->SetText(setting->GetSelectedOptionText().c_str());
// }
// }
}
// 3drando doesn't have a "skip child zelda" setting, manually add it to the spoilerfile
jsonData["settings"]["Skip Child Zelda"] = Settings::skipChildZelda ? "On" : "Off";
testing out item replacement (#416) * skip learning song of storms * don't set flag when getting goron tunic as child * Initiates prelude check when master sword unloads. Not quite how N64 rando does it but so far it's the only way I've found to make it trigger without also triggering the time travel again. * Stops Shadow Temple lore prompts from appearing in rando. * Skips cutscene of royal tomb explosion in rando. Explosion sound doesn't play correctly and I think the debris appears in the wrong place, but the functionality is here. * Improves visual of exploding gravestone. * Adds some comments explaining the rando differences * Skip ruto text box in jabu blue warp For rando * skip intro cutscene in dodongo's cavern * load spoiler files on boot, fix spoilerfile existing check when making new saves * name entry dropped spoiler logic * make sure to actually init the cvar * no chime on load * uncomment * Skip ganondrof cutscene Skip to scream part of the death animation, skipping the text boxes etc. For rando * Update z_boss_ganondrof.c * skip owl flight cutscenes in rando * Fixes skipped text so it only applies to shadow temple. Earlier fix inadvertently applied to some other text as well, changed logic so that only specified sceneNums and textIds can have this enabled, and text skipped by sceneNum can have the skip overriden by textId if needed. Currently there are no overrides so the textId section of the logic is commented out to avoid compilation errors. * Adds a default to the switch case statements that leaves the randoSkipText variable unchanged, just in case. * TEST: Text for item * Adding ganon flavor text * ADD: AMMO Count * format ganon text/hint text * Autoskip the tower cutscene if settings call for tower collapse. * ganon hint text logic * Improved prelude after time travel fix * swapped the sizes between ganon hint text and ganon text, as they were set to the wrong things. * this is all i did * not the cleanest code ever but it's working * ADD: GS Count * ADD: Wallter (crash for now) * TWEAK: Wallet check * FIX: Use DrawItem instread of DrawUpgrade... b-baka! * Fixes some vanilla bugs introduced by rando code. * Added cutscene skip for zelda escaping Using the debug cutscene skipping function. Also added a conditional so the bridge doesn't spawn closed when cutscene is ready to trigger * ADD: X Spacing + Placeholders for song * ADD: default case for items * TWEAK: Spacing * FIX: Light Arrow * ADD: Ammo Option * use groups instead * ADD: More spacing logic * songs and names * TWEAK: Color on wallet * colors * Added flags cutscene before nabooru fight * ADD: ChromaKey text * First attempt skip cs after nabooru defeat * Better implementation for specific rando cutscene skips * use pulseaudio defaults * spaces/tabs * move color push/pop to stop crash * make the colors work again * the real bottle fix * pulseaudio values tuned for n64 audio at 44.1khz * update tlength * remove one hardcoded samplerate * Cleaned up and fixed zelda escape skip The if statement is a freaking monster, but unless we want to skip more cutscenes in the same way later, this is the most compact way of doing it that I know of. * Revert one line to match original nothing functional * another hint line that breaks autonewline logic * don't autospawn epona if we don't have the song/ocarina * Trying to use iron knuckle death effects not working yet * Streamlined OoT cutscene skip for future additions Also cleaned up if statement in general * Made if statement more readable Also added clarity for what cutscene was skipped * Fixed typo in comment * Janky nabooru defeat cs skip * altar text formatting (gonna need help shortening some of the french ones) * more altar text formatting * english altar text formatting complete * make gtg blocking guard check for card not bridge * FIX: Typo! * FIX: Uppercases * FIX: Typo * TWEAK: Alter + some names * TWEAK: More caps! * ADD: Missing string TWEAK more uppercases and namefixe s * Hide nabooru death by covering her in flames * bandaid fix for death crash issue * Twinrova defeat cs skip Skips the animation and manually calls the function to show the "beam" around the sisters * fix crash * fix caps to match * fix great fairy reward mashing/shielding issue * TWEAK : Typo clé to Clé * TWEAK: Some Altar hints TWEAK: Some capitals * TWEAK: Unmatching text + some cap again * TWEAK: More tweaks * fix build * remove extra json.hpp, add hint * Update randomizer_item_tracker.cpp * TWEAK: Double Defense with RedParticles instead of white * make sure we don't optimize out the check to ensure a spoilerfile exists * vanilla ganon boss key hint formatting * TWEAK: FR- better way of the hero text * fix * and again * Initializes dungeonsDone items in gSaveContext to 0. * Replaces sizeof calculation with a NUM_DUNGEONS constant. * Fixes Saria's Gift on the LW Bridge from getting killed when holding shield. * More airtight fix for Saria's Gift on the Bridge. * Lifts one of the conditions in the if statement a little higher to prevent unnecessary lookups of getItemId. * Invalidate text box icon before drawing * Fixes the case where Saria's gift is an Ice Trap. We still get the Ice Trap once, but never again. This does mean you can now hold R while walking in to avoid the ice trap, but everything else seems to work fine. * Initial commit Might need changing when we change the settings in the future * Fixes Door of Time opening cutscene after warping with prelude. * Initial waterfall skip Very rudimentary way of doing things but it seems to work so :shrug: * inital rework * fixed default rotation for 2D sprites * fix tab/space issues * 3d drops rando merge fix again * Allows Impa to appear in the Lullaby check post drawbridge escape. * Changes Ganon's Trials Count setting to a checkbox The checkbox is whether or not to skip all of them. Leaving the box unchecked will mean doing all of them. Eventually this will be switched back to a slider once we implement the logic for which trials start out completed. * Sets all Ganon's Trials to incomplete in new saves. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131 * fix castle guards when oot throw cutscene has already played in rando * Properly removes the beams when trials are cleared. * Removes Question Mark from Skip Ganon's Trials UI. * Adds a todo comment about when to change back to slider. * make deku seeds check for bullet bag * Various tweaks TWEAK: Altar Text TWEAK: Hint names TWEAK: Replace more problematic œ to oe * upgrade ocarina on both child and adult equips * FIX: Jabu Item * update equipped hookshot/longshot when obtained as other age * add hint * don't give the bgs check without the claim check * Skips Darunia Cutscene in Fire Temple * Added a TODO note about not skipping the cutscene. There is a setting we will want to have eventually that will require this cutscene to not be skipped since it is used during a glitch. * remove todo * restore fast ocarina option in imgui that was lost in merge * Fixes grey screen issue + tooltip for 2 handed shield * update to use dg instead of g for textures in item tracker * TWEAK: Default color for cosmetic RAND button was not the corect one * fix texture crash, remove unused item tracker code * don't open mask shop until we get zelda's letter * Update README.md * Prevents "correct" chime under incorrect conditions. * Fixes typo in conditional and adds "bonk" sound effect. "Bonk" sound is NA_SE_SY_OCARINA_ERROR and it plays when conditions for the Door of Time have not been met after playing Song of Time. This is only possible in rando's "Intended" Door of Time option, in which the Ocarina of Time and all 3 spritual stones are required to open the door, instead of the vanilla requirements of just having the song of time. * remove modify dpad equips toggle, replace with checks for dpad menu * remove extra check * add ability to hold c-up to assign to dpad when dpad menuing is enabled * disable d-pad navigation on item menu when holding c-up to equip * dpad+c-up stuff for equipment menu * ADD: Checbox for songs colors * TWEAK: RandoColors for normal songs * kind of quick and dirty but it works * TWEAK: Clarity of the tooltip Co-authored-by: briaguya <briaguya@alice> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: aMannus <mannusmenting@gmail.com> Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com> Co-authored-by: Dog <5172592+Dog@users.noreply.github.com> Co-authored-by: Vague Rant <vaguerant@users.noreply.github.com> Co-authored-by: Baoulettes <perlouzerie@hotmail.fr> Co-authored-by: Ada <60364512+GreatArgorath@users.noreply.github.com>
2022-07-11 20:11:07 -04:00
}
// spoilerLog.RootElement()->InsertEndChild(parentNode);
// for (const uint32_t key : allLocations) {
// ItemLocation* location = Location(key);
// settingsJsonData["locations"][location->GetName()] = location->GetPlacedItemName().english;
// }
}
// Writes the excluded locations to the spoiler log, if there are any.
static void WriteExcludedLocations() {
// auto parentNode = spoilerLog.NewElement("excluded-locations");
for (size_t i = 1; i < Settings::excludeLocationsOptionsVector.size(); i++) {
for (const auto& location : Settings::excludeLocationsOptionsVector[i]) {
if (location->GetSelectedOptionIndex() == INCLUDE) {
continue;
}
jsonData["excludedLocations"].push_back(RemoveLineBreaks(location->GetName()));
// tinyxml2::XMLElement* node = spoilerLog.NewElement("location");
// node->SetAttribute("name", RemoveLineBreaks(location->GetName()).c_str());
// parentNode->InsertEndChild(node);
}
}
// if (!parentNode->NoChildren()) {
// spoilerLog.RootElement()->InsertEndChild(parentNode);
// }
}
// Writes the starting inventory to the spoiler log, if there is any.
static void WriteStartingInventory() {
std::vector<std::vector<Option *>*> startingInventoryOptions = {
&Settings::startingItemsOptions,
&Settings::startingSongsOptions,
&Settings::startingEquipmentOptions,
&Settings::startingStonesMedallionsOptions,
&Settings::startingOthersOptions
};
for (std::vector<Option *>* menu : startingInventoryOptions) {
for (size_t i = 0; i < menu->size(); ++i) {
const auto setting = menu->at(i);
// we need to write these every time because we're not clearing jsondata, so
// the default logic of only writing it when we aren't using the default value
// doesn't work, and because it'd be bad to set every single possible starting
// inventory item as "false" in the json, we're just going to check
// to see if the name is one of the 3 we're using rn
if(setting->GetName() == "Deku Shield" || setting->GetName() == "Kokiri Sword" || setting->GetName() == "Ocarina") {
jsonData["settings"]["Start With " + setting->GetName()] = setting->GetSelectedOptionText();
}
if (setting->GetName() == "Start with Consumables" || setting->GetName() == "Start with Max Rupees") {
jsonData["settings"][setting->GetName()] = setting->GetSelectedOptionText();
}
}
}
}
// Writes the enabled tricks to the spoiler log, if there are any.
static void WriteEnabledTricks(tinyxml2::XMLDocument& spoilerLog) {
auto parentNode = spoilerLog.NewElement("enabled-tricks");
for (const auto& setting : Settings::trickOptions) {
if (setting->GetSelectedOptionIndex() != TRICK_ENABLED || !setting->IsCategory(OptionCategory::Setting)) {
continue;
}
auto node = parentNode->InsertNewChildElement("trick");
node->SetAttribute("name", RemoveLineBreaks(setting->GetName()).c_str());
}
if (!parentNode->NoChildren()) {
spoilerLog.RootElement()->InsertEndChild(parentNode);
}
}
// Writes the enabled glitches to the spoiler log, if there are any.
static void WriteEnabledGlitches(tinyxml2::XMLDocument& spoilerLog) {
auto parentNode = spoilerLog.NewElement("enabled-glitches");
for (const auto& setting : Settings::glitchCategories) {
if (setting->Value<uint8_t>() == 0) {
continue;
}
auto node = parentNode->InsertNewChildElement("glitch-category");
node->SetAttribute("name", setting->GetName().c_str());
node->SetText(setting->GetSelectedOptionText().c_str());
}
for (const auto& setting : Settings::miscGlitches) {
if (!setting->Value<bool>()) {
continue;
}
auto node = parentNode->InsertNewChildElement("misc-glitch");
node->SetAttribute("name", RemoveLineBreaks(setting->GetName()).c_str());
}
if (!parentNode->NoChildren()) {
spoilerLog.RootElement()->InsertEndChild(parentNode);
}
}
// Writes the Master Quest dungeons to the spoiler log, if there are any.
static void WriteMasterQuestDungeons(tinyxml2::XMLDocument& spoilerLog) {
auto parentNode = spoilerLog.NewElement("master-quest-dungeons");
for (const auto* dungeon : Dungeon::dungeonList) {
if (dungeon->IsVanilla()) {
continue;
}
auto node = parentNode->InsertNewChildElement("dungeon");
node->SetAttribute("name", dungeon->GetName().c_str());
}
if (!parentNode->NoChildren()) {
spoilerLog.RootElement()->InsertEndChild(parentNode);
}
}
// Writes the required trails to the spoiler log, if there are any.
static void WriteRequiredTrials(tinyxml2::XMLDocument& spoilerLog) {
auto parentNode = spoilerLog.NewElement("required-trials");
for (const auto* trial : Trial::trialList) {
if (trial->IsSkipped()) {
continue;
}
auto node = parentNode->InsertNewChildElement("trial");
// PURPLE TODO: LOCALIZATION
std::string name = trial->GetName().GetEnglish();
name[0] = toupper(name[0]); // Capitalize T in "The"
node->SetAttribute("name", name.c_str());
}
if (!parentNode->NoChildren()) {
spoilerLog.RootElement()->InsertEndChild(parentNode);
}
}
// Writes the intended playthrough to the spoiler log, separated into spheres.
static void WritePlaythrough() {
// auto playthroughNode = spoilerLog.NewElement("playthrough");
for (uint32_t i = 0; i < playthroughLocations.size(); ++i) {
auto sphereNum = std::to_string(i);
std::string sphereString = "sphere ";
if (sphereNum.length() == 1) sphereString += "0";
sphereString += sphereNum;
for (const uint32_t key : playthroughLocations[i]) {
WriteLocation(sphereString, key, true);
}
}
// spoilerLog.RootElement()->InsertEndChild(playthroughNode);
}
//Write the randomized entrance playthrough to the spoiler log, if applicable
static void WriteShuffledEntrances(tinyxml2::XMLDocument& spoilerLog) {
if (!Settings::ShuffleEntrances || noRandomEntrances) {
return;
}
auto playthroughNode = spoilerLog.NewElement("entrance-playthrough");
for (uint32_t i = 0; i < playthroughEntrances.size(); ++i) {
auto sphereNode = playthroughNode->InsertNewChildElement("sphere");
sphereNode->SetAttribute("level", i + 1);
for (Entrance* entrance : playthroughEntrances[i]) {
WriteShuffledEntrance(sphereNode, entrance, true);
}
}
spoilerLog.RootElement()->InsertEndChild(playthroughNode);
}
// Writes the WOTH locations to the spoiler log, if there are any.
static void WriteWayOfTheHeroLocation(tinyxml2::XMLDocument& spoilerLog) {
auto parentNode = spoilerLog.NewElement("way-of-the-hero-locations");
for (const uint32_t key : wothLocations) {
// WriteLocation(parentNode, key, true);
}
if (!parentNode->NoChildren()) {
spoilerLog.RootElement()->InsertEndChild(parentNode);
}
}
std::string AutoFormatHintTextString(std::string unformattedHintTextString) {
std::string textStr = unformattedHintTextString;
// RANDOTODO: don't just make manual exceptions
bool needsAutomaicNewlines = true;
if (textStr == "Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!" ||
textStr == "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda" ||
textStr == "What about Zelda makes you think she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the hungry,&and my castle floats." ||
textStr == "Many tricks are up my sleeve,&to save yourself&you'd better leave!" ||
textStr == "I've learned this spell,&it's really neat,&I'll keep it later&for your treat!" ||
textStr == "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!" ||
textStr == "Gamin, ton destin achève,&sous mon sort tu périras!&Cette partie ne fut pas brève,&et cette mort, tu subiras!" ||
textStr == "Oh! It's @.&I was expecting someone called Sheik.&Do you know what happened to them?" ||
textStr == "Ah, c'est @.&J'attendais un certain Sheik.&Tu sais ce qui lui est arrivé?") {
needsAutomaicNewlines = false;
}
if (needsAutomaicNewlines) {
//insert newlines either manually or when encountering a '&'
constexpr size_t lineLength = 34;
size_t lastNewline = 0;
while (lastNewline + lineLength < textStr.length()) {
size_t carrot = textStr.find('^', lastNewline);
size_t ampersand = textStr.find('&', lastNewline);
size_t lastSpace = textStr.rfind(' ', lastNewline + lineLength);
size_t lastPeriod = textStr.rfind('.', lastNewline + lineLength);
//replace '&' first if it's within the newline range
if (ampersand < lastNewline + lineLength) {
lastNewline = ampersand;
//or move the lastNewline cursor to the next line if a '^' is encountered
} else if (carrot < lastNewline + lineLength) {
lastNewline = carrot + 1;
//some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
textStr.replace(lastPeriod, 1, ".&");
lastNewline = lastPeriod + 2;
} else {
textStr.replace(lastSpace, 1, "&");
lastNewline = lastSpace + 1;
}
}
}
// todo add colors (see `AddColorsAndFormat` in `custom_messages.cpp`)
textStr.erase(std::remove(textStr.begin(), textStr.end(), '#'), textStr.end());
return textStr;
}
// Writes the hints to the spoiler log, if they are enabled.
static void WriteHints(int language) {
std::string unformattedGanonText;
std::string unformattedGanonHintText;
switch (language) {
case 0:
default:
unformattedGanonText = GetGanonText().GetEnglish();
unformattedGanonHintText = GetGanonHintText().GetEnglish();
jsonData["childAltarText"] = GetChildAltarText().GetEnglish();
jsonData["adultAltarText"] = GetAdultAltarText().GetEnglish();
break;
case 2:
unformattedGanonText = GetGanonText().GetFrench();
unformattedGanonHintText = GetGanonHintText().GetFrench();
jsonData["childAltarText"] = GetChildAltarText().GetFrench();
jsonData["adultAltarText"] = GetAdultAltarText().GetFrench();
break;
}
std::string ganonText = AutoFormatHintTextString(unformattedGanonText);
std::string ganonHintText = AutoFormatHintTextString(unformattedGanonHintText);
jsonData["ganonText"] = ganonText;
jsonData["ganonHintText"] = ganonHintText;
if (Settings::GossipStoneHints.Is(HINTS_NO_HINTS)) {
return;
}
for (const uint32_t key : gossipStoneLocations) {
ItemLocation* location = Location(key);
std::string unformattedHintTextString;
switch (language) {
case 0:
default:
unformattedHintTextString = location->GetPlacedItemName().GetEnglish();
break;
case 2:
unformattedHintTextString = location->GetPlacedItemName().GetFrench();
break;
}
std::string textStr = AutoFormatHintTextString(unformattedHintTextString);
jsonData["hints"][location->GetName()] = textStr;
}
}
static void WriteAllLocations(int language) {
for (const uint32_t key : allLocations) {
ItemLocation* location = Location(key);
switch (language) {
case 0:
default:
jsonData["locations"][location->GetName()] = location->GetPlacedItemName().english;
break;
case 2:
jsonData["locations"][location->GetName()] = location->GetPlacedItemName().french;
break;
}
}
}
const char* SpoilerLog_Write(int language) {
auto spoilerLog = tinyxml2::XMLDocument(false);
spoilerLog.InsertEndChild(spoilerLog.NewDeclaration());
auto rootNode = spoilerLog.NewElement("spoiler-log");
spoilerLog.InsertEndChild(rootNode);
rootNode->SetAttribute("version", Settings::version.c_str());
rootNode->SetAttribute("seed", Settings::seed.c_str());
rootNode->SetAttribute("hash", GetRandomizerHashAsString().c_str());
jsonData.clear();
// Write Hash
int index = 0;
for (uint8_t seed_value : Settings::hashIconIndexes) {
jsonData["file_hash"][index] = seed_value;
index++;
}
WriteSettings();
WriteExcludedLocations();
WriteStartingInventory();
//WriteEnabledTricks(spoilerLog);
//if (Settings::Logic.Is(LOGIC_GLITCHED)) {
// WriteEnabledGlitches(spoilerLog);
//}
//WriteMasterQuestDungeons(spoilerLog);
//WriteRequiredTrials(spoilerLog);
WritePlaythrough();
//WriteWayOfTheHeroLocation(spoilerLog);
playthroughLocations.clear();
playthroughBeatable = false;
wothLocations.clear();
WriteHints(language);
//WriteShuffledEntrances(spoilerLog);
WriteAllLocations(language);
if (!std::filesystem::exists(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Randomizer"))) {
std::filesystem::create_directory(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Randomizer"));
testing out item replacement (#416) * skip learning song of storms * don't set flag when getting goron tunic as child * Initiates prelude check when master sword unloads. Not quite how N64 rando does it but so far it's the only way I've found to make it trigger without also triggering the time travel again. * Stops Shadow Temple lore prompts from appearing in rando. * Skips cutscene of royal tomb explosion in rando. Explosion sound doesn't play correctly and I think the debris appears in the wrong place, but the functionality is here. * Improves visual of exploding gravestone. * Adds some comments explaining the rando differences * Skip ruto text box in jabu blue warp For rando * skip intro cutscene in dodongo's cavern * load spoiler files on boot, fix spoilerfile existing check when making new saves * name entry dropped spoiler logic * make sure to actually init the cvar * no chime on load * uncomment * Skip ganondrof cutscene Skip to scream part of the death animation, skipping the text boxes etc. For rando * Update z_boss_ganondrof.c * skip owl flight cutscenes in rando * Fixes skipped text so it only applies to shadow temple. Earlier fix inadvertently applied to some other text as well, changed logic so that only specified sceneNums and textIds can have this enabled, and text skipped by sceneNum can have the skip overriden by textId if needed. Currently there are no overrides so the textId section of the logic is commented out to avoid compilation errors. * Adds a default to the switch case statements that leaves the randoSkipText variable unchanged, just in case. * TEST: Text for item * Adding ganon flavor text * ADD: AMMO Count * format ganon text/hint text * Autoskip the tower cutscene if settings call for tower collapse. * ganon hint text logic * Improved prelude after time travel fix * swapped the sizes between ganon hint text and ganon text, as they were set to the wrong things. * this is all i did * not the cleanest code ever but it's working * ADD: GS Count * ADD: Wallter (crash for now) * TWEAK: Wallet check * FIX: Use DrawItem instread of DrawUpgrade... b-baka! * Fixes some vanilla bugs introduced by rando code. * Added cutscene skip for zelda escaping Using the debug cutscene skipping function. Also added a conditional so the bridge doesn't spawn closed when cutscene is ready to trigger * ADD: X Spacing + Placeholders for song * ADD: default case for items * TWEAK: Spacing * FIX: Light Arrow * ADD: Ammo Option * use groups instead * ADD: More spacing logic * songs and names * TWEAK: Color on wallet * colors * Added flags cutscene before nabooru fight * ADD: ChromaKey text * First attempt skip cs after nabooru defeat * Better implementation for specific rando cutscene skips * use pulseaudio defaults * spaces/tabs * move color push/pop to stop crash * make the colors work again * the real bottle fix * pulseaudio values tuned for n64 audio at 44.1khz * update tlength * remove one hardcoded samplerate * Cleaned up and fixed zelda escape skip The if statement is a freaking monster, but unless we want to skip more cutscenes in the same way later, this is the most compact way of doing it that I know of. * Revert one line to match original nothing functional * another hint line that breaks autonewline logic * don't autospawn epona if we don't have the song/ocarina * Trying to use iron knuckle death effects not working yet * Streamlined OoT cutscene skip for future additions Also cleaned up if statement in general * Made if statement more readable Also added clarity for what cutscene was skipped * Fixed typo in comment * Janky nabooru defeat cs skip * altar text formatting (gonna need help shortening some of the french ones) * more altar text formatting * english altar text formatting complete * make gtg blocking guard check for card not bridge * FIX: Typo! * FIX: Uppercases * FIX: Typo * TWEAK: Alter + some names * TWEAK: More caps! * ADD: Missing string TWEAK more uppercases and namefixe s * Hide nabooru death by covering her in flames * bandaid fix for death crash issue * Twinrova defeat cs skip Skips the animation and manually calls the function to show the "beam" around the sisters * fix crash * fix caps to match * fix great fairy reward mashing/shielding issue * TWEAK : Typo clé to Clé * TWEAK: Some Altar hints TWEAK: Some capitals * TWEAK: Unmatching text + some cap again * TWEAK: More tweaks * fix build * remove extra json.hpp, add hint * Update randomizer_item_tracker.cpp * TWEAK: Double Defense with RedParticles instead of white * make sure we don't optimize out the check to ensure a spoilerfile exists * vanilla ganon boss key hint formatting * TWEAK: FR- better way of the hero text * fix * and again * Initializes dungeonsDone items in gSaveContext to 0. * Replaces sizeof calculation with a NUM_DUNGEONS constant. * Fixes Saria's Gift on the LW Bridge from getting killed when holding shield. * More airtight fix for Saria's Gift on the Bridge. * Lifts one of the conditions in the if statement a little higher to prevent unnecessary lookups of getItemId. * Invalidate text box icon before drawing * Fixes the case where Saria's gift is an Ice Trap. We still get the Ice Trap once, but never again. This does mean you can now hold R while walking in to avoid the ice trap, but everything else seems to work fine. * Initial commit Might need changing when we change the settings in the future * Fixes Door of Time opening cutscene after warping with prelude. * Initial waterfall skip Very rudimentary way of doing things but it seems to work so :shrug: * inital rework * fixed default rotation for 2D sprites * fix tab/space issues * 3d drops rando merge fix again * Allows Impa to appear in the Lullaby check post drawbridge escape. * Changes Ganon's Trials Count setting to a checkbox The checkbox is whether or not to skip all of them. Leaving the box unchecked will mean doing all of them. Eventually this will be switched back to a slider once we implement the logic for which trials start out completed. * Sets all Ganon's Trials to incomplete in new saves. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131 * fix castle guards when oot throw cutscene has already played in rando * Properly removes the beams when trials are cleared. * Removes Question Mark from Skip Ganon's Trials UI. * Adds a todo comment about when to change back to slider. * make deku seeds check for bullet bag * Various tweaks TWEAK: Altar Text TWEAK: Hint names TWEAK: Replace more problematic œ to oe * upgrade ocarina on both child and adult equips * FIX: Jabu Item * update equipped hookshot/longshot when obtained as other age * add hint * don't give the bgs check without the claim check * Skips Darunia Cutscene in Fire Temple * Added a TODO note about not skipping the cutscene. There is a setting we will want to have eventually that will require this cutscene to not be skipped since it is used during a glitch. * remove todo * restore fast ocarina option in imgui that was lost in merge * Fixes grey screen issue + tooltip for 2 handed shield * update to use dg instead of g for textures in item tracker * TWEAK: Default color for cosmetic RAND button was not the corect one * fix texture crash, remove unused item tracker code * don't open mask shop until we get zelda's letter * Update README.md * Prevents "correct" chime under incorrect conditions. * Fixes typo in conditional and adds "bonk" sound effect. "Bonk" sound is NA_SE_SY_OCARINA_ERROR and it plays when conditions for the Door of Time have not been met after playing Song of Time. This is only possible in rando's "Intended" Door of Time option, in which the Ocarina of Time and all 3 spritual stones are required to open the door, instead of the vanilla requirements of just having the song of time. * remove modify dpad equips toggle, replace with checks for dpad menu * remove extra check * add ability to hold c-up to assign to dpad when dpad menuing is enabled * disable d-pad navigation on item menu when holding c-up to equip * dpad+c-up stuff for equipment menu * ADD: Checbox for songs colors * TWEAK: RandoColors for normal songs * kind of quick and dirty but it works * TWEAK: Clarity of the tooltip Co-authored-by: briaguya <briaguya@alice> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: aMannus <mannusmenting@gmail.com> Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com> Co-authored-by: Dog <5172592+Dog@users.noreply.github.com> Co-authored-by: Vague Rant <vaguerant@users.noreply.github.com> Co-authored-by: Baoulettes <perlouzerie@hotmail.fr> Co-authored-by: Ada <60364512+GreatArgorath@users.noreply.github.com>
2022-07-11 20:11:07 -04:00
}
std::string jsonString = jsonData.dump(4);
std::ofstream jsonFile(Ship::GlobalCtx2::GetPathRelativeToAppDirectory(
(std::string("Randomizer/") + std::string(Settings::seed) + std::string(".json")).c_str()));
testing out item replacement (#416) * skip learning song of storms * don't set flag when getting goron tunic as child * Initiates prelude check when master sword unloads. Not quite how N64 rando does it but so far it's the only way I've found to make it trigger without also triggering the time travel again. * Stops Shadow Temple lore prompts from appearing in rando. * Skips cutscene of royal tomb explosion in rando. Explosion sound doesn't play correctly and I think the debris appears in the wrong place, but the functionality is here. * Improves visual of exploding gravestone. * Adds some comments explaining the rando differences * Skip ruto text box in jabu blue warp For rando * skip intro cutscene in dodongo's cavern * load spoiler files on boot, fix spoilerfile existing check when making new saves * name entry dropped spoiler logic * make sure to actually init the cvar * no chime on load * uncomment * Skip ganondrof cutscene Skip to scream part of the death animation, skipping the text boxes etc. For rando * Update z_boss_ganondrof.c * skip owl flight cutscenes in rando * Fixes skipped text so it only applies to shadow temple. Earlier fix inadvertently applied to some other text as well, changed logic so that only specified sceneNums and textIds can have this enabled, and text skipped by sceneNum can have the skip overriden by textId if needed. Currently there are no overrides so the textId section of the logic is commented out to avoid compilation errors. * Adds a default to the switch case statements that leaves the randoSkipText variable unchanged, just in case. * TEST: Text for item * Adding ganon flavor text * ADD: AMMO Count * format ganon text/hint text * Autoskip the tower cutscene if settings call for tower collapse. * ganon hint text logic * Improved prelude after time travel fix * swapped the sizes between ganon hint text and ganon text, as they were set to the wrong things. * this is all i did * not the cleanest code ever but it's working * ADD: GS Count * ADD: Wallter (crash for now) * TWEAK: Wallet check * FIX: Use DrawItem instread of DrawUpgrade... b-baka! * Fixes some vanilla bugs introduced by rando code. * Added cutscene skip for zelda escaping Using the debug cutscene skipping function. Also added a conditional so the bridge doesn't spawn closed when cutscene is ready to trigger * ADD: X Spacing + Placeholders for song * ADD: default case for items * TWEAK: Spacing * FIX: Light Arrow * ADD: Ammo Option * use groups instead * ADD: More spacing logic * songs and names * TWEAK: Color on wallet * colors * Added flags cutscene before nabooru fight * ADD: ChromaKey text * First attempt skip cs after nabooru defeat * Better implementation for specific rando cutscene skips * use pulseaudio defaults * spaces/tabs * move color push/pop to stop crash * make the colors work again * the real bottle fix * pulseaudio values tuned for n64 audio at 44.1khz * update tlength * remove one hardcoded samplerate * Cleaned up and fixed zelda escape skip The if statement is a freaking monster, but unless we want to skip more cutscenes in the same way later, this is the most compact way of doing it that I know of. * Revert one line to match original nothing functional * another hint line that breaks autonewline logic * don't autospawn epona if we don't have the song/ocarina * Trying to use iron knuckle death effects not working yet * Streamlined OoT cutscene skip for future additions Also cleaned up if statement in general * Made if statement more readable Also added clarity for what cutscene was skipped * Fixed typo in comment * Janky nabooru defeat cs skip * altar text formatting (gonna need help shortening some of the french ones) * more altar text formatting * english altar text formatting complete * make gtg blocking guard check for card not bridge * FIX: Typo! * FIX: Uppercases * FIX: Typo * TWEAK: Alter + some names * TWEAK: More caps! * ADD: Missing string TWEAK more uppercases and namefixe s * Hide nabooru death by covering her in flames * bandaid fix for death crash issue * Twinrova defeat cs skip Skips the animation and manually calls the function to show the "beam" around the sisters * fix crash * fix caps to match * fix great fairy reward mashing/shielding issue * TWEAK : Typo clé to Clé * TWEAK: Some Altar hints TWEAK: Some capitals * TWEAK: Unmatching text + some cap again * TWEAK: More tweaks * fix build * remove extra json.hpp, add hint * Update randomizer_item_tracker.cpp * TWEAK: Double Defense with RedParticles instead of white * make sure we don't optimize out the check to ensure a spoilerfile exists * vanilla ganon boss key hint formatting * TWEAK: FR- better way of the hero text * fix * and again * Initializes dungeonsDone items in gSaveContext to 0. * Replaces sizeof calculation with a NUM_DUNGEONS constant. * Fixes Saria's Gift on the LW Bridge from getting killed when holding shield. * More airtight fix for Saria's Gift on the Bridge. * Lifts one of the conditions in the if statement a little higher to prevent unnecessary lookups of getItemId. * Invalidate text box icon before drawing * Fixes the case where Saria's gift is an Ice Trap. We still get the Ice Trap once, but never again. This does mean you can now hold R while walking in to avoid the ice trap, but everything else seems to work fine. * Initial commit Might need changing when we change the settings in the future * Fixes Door of Time opening cutscene after warping with prelude. * Initial waterfall skip Very rudimentary way of doing things but it seems to work so :shrug: * inital rework * fixed default rotation for 2D sprites * fix tab/space issues * 3d drops rando merge fix again * Allows Impa to appear in the Lullaby check post drawbridge escape. * Changes Ganon's Trials Count setting to a checkbox The checkbox is whether or not to skip all of them. Leaving the box unchecked will mean doing all of them. Eventually this will be switched back to a slider once we implement the logic for which trials start out completed. * Sets all Ganon's Trials to incomplete in new saves. Fixes https://github.com/briaguya-ai/rando-issue-tracker/issues/131 * fix castle guards when oot throw cutscene has already played in rando * Properly removes the beams when trials are cleared. * Removes Question Mark from Skip Ganon's Trials UI. * Adds a todo comment about when to change back to slider. * make deku seeds check for bullet bag * Various tweaks TWEAK: Altar Text TWEAK: Hint names TWEAK: Replace more problematic œ to oe * upgrade ocarina on both child and adult equips * FIX: Jabu Item * update equipped hookshot/longshot when obtained as other age * add hint * don't give the bgs check without the claim check * Skips Darunia Cutscene in Fire Temple * Added a TODO note about not skipping the cutscene. There is a setting we will want to have eventually that will require this cutscene to not be skipped since it is used during a glitch. * remove todo * restore fast ocarina option in imgui that was lost in merge * Fixes grey screen issue + tooltip for 2 handed shield * update to use dg instead of g for textures in item tracker * TWEAK: Default color for cosmetic RAND button was not the corect one * fix texture crash, remove unused item tracker code * don't open mask shop until we get zelda's letter * Update README.md * Prevents "correct" chime under incorrect conditions. * Fixes typo in conditional and adds "bonk" sound effect. "Bonk" sound is NA_SE_SY_OCARINA_ERROR and it plays when conditions for the Door of Time have not been met after playing Song of Time. This is only possible in rando's "Intended" Door of Time option, in which the Ocarina of Time and all 3 spritual stones are required to open the door, instead of the vanilla requirements of just having the song of time. * remove modify dpad equips toggle, replace with checks for dpad menu * remove extra check * add ability to hold c-up to assign to dpad when dpad menuing is enabled * disable d-pad navigation on item menu when holding c-up to equip * dpad+c-up stuff for equipment menu * ADD: Checbox for songs colors * TWEAK: RandoColors for normal songs * kind of quick and dirty but it works * TWEAK: Clarity of the tooltip Co-authored-by: briaguya <briaguya@alice> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: aMannus <mannusmenting@gmail.com> Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com> Co-authored-by: Dog <5172592+Dog@users.noreply.github.com> Co-authored-by: Vague Rant <vaguerant@users.noreply.github.com> Co-authored-by: Baoulettes <perlouzerie@hotmail.fr> Co-authored-by: Ada <60364512+GreatArgorath@users.noreply.github.com>
2022-07-11 20:11:07 -04:00
jsonFile << std::setw(4) << jsonString << std::endl;
jsonFile.close();
return Settings::seed.c_str();
}
void PlacementLog_Msg(std::string_view msg) {
placementtxt += msg;
}
void PlacementLog_Clear() {
placementtxt = "";
}
bool PlacementLog_Write() {
auto placementLog = tinyxml2::XMLDocument(false);
placementLog.InsertEndChild(placementLog.NewDeclaration());
auto rootNode = placementLog.NewElement("placement-log");
placementLog.InsertEndChild(rootNode);
rootNode->SetAttribute("version", Settings::version.c_str());
rootNode->SetAttribute("seed", Settings::seed.c_str());
rootNode->SetAttribute("hash", GetRandomizerHashAsString().c_str());
// WriteSettings(placementLog, true); // Include hidden settings.
// WriteExcludedLocations(placementLog);
// WriteStartingInventory(placementLog);
WriteEnabledTricks(placementLog);
WriteEnabledGlitches(placementLog);
WriteMasterQuestDungeons(placementLog);
WriteRequiredTrials(placementLog);
placementtxt = "\n" + placementtxt;
auto node = rootNode->InsertNewChildElement("log");
auto contentNode = node->InsertNewText(placementtxt.c_str());
contentNode->SetCData(true);
return true;
}