mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-10-13 15:33:53 -04:00
Remove FQwc preset. Skip learning song
Also render exempt settings on preset selection, with values they'll have in-game
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
"Autosave": 0,
|
||||
"BetterAmmoRendering": 0,
|
||||
"BetterFarore": 0,
|
||||
"BetterOwl": 1,
|
||||
"BombchuBowlingFirstPrize": 4,
|
||||
"BombchusOOB": 1,
|
||||
"BowArrowCycle": 1,
|
||||
@@ -42,7 +43,9 @@
|
||||
"EquipmentCanBeRemoved": 0,
|
||||
"FastBoomerang": 0,
|
||||
"FastChests": 1,
|
||||
"FasterHeavyBlockLift": 1,
|
||||
"FasterPauseMenu": 0,
|
||||
"FasterShadowShip": 1,
|
||||
"FileSelectMoreInfo": 1,
|
||||
"FirstPersonGauntlets": 0,
|
||||
"FishNeverEscape": 1,
|
||||
@@ -88,18 +91,19 @@
|
||||
"ShowDoorLocksOnBothSides": 0,
|
||||
"SkipArrowAnimation": 1,
|
||||
"SkipText": 1,
|
||||
"SkulltulaFreeze": 1,
|
||||
"SlowTextSpeed": 5,
|
||||
"StaticExplosionRadius": 0,
|
||||
"StrengthDisabled": 0,
|
||||
"SwordToggle": 0,
|
||||
"TextSpeed": 5,
|
||||
"TextSpeed": 6,
|
||||
"TimeFlowFileSelect": 0,
|
||||
"TimeSavers": {
|
||||
"SkipCutscene": {
|
||||
"BossIntro": 1,
|
||||
"Entrances": 1,
|
||||
"Intro": 1,
|
||||
"LearnSong": 0,
|
||||
"LearnSong": 1,
|
||||
"OnePoint": 0,
|
||||
"QuickBossDeaths": 1,
|
||||
"Story": 1
|
||||
@@ -118,6 +122,8 @@
|
||||
"exempt": [
|
||||
"/gDeveloperTools/LogLevel",
|
||||
"/gDeveloperTools/ResourceLogging",
|
||||
"/gEnhancements/AskToEquip",
|
||||
"/gEnhancements/BetterSaveMenu",
|
||||
"/gEnhancements/DrawLineupTick",
|
||||
"/gEnhancements/GraveHoles",
|
||||
"/gEnhancements/IncludeHeldInputsBufferWindow",
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
{
|
||||
"blocks": {
|
||||
"enhancements": {
|
||||
"gCheats": {
|
||||
"EasyFrameAdvance": 0,
|
||||
"HookshotReachMultiplier": 1.0,
|
||||
"MoonJumpOnL": 0,
|
||||
"SpeedModifier": {
|
||||
"Value": 1.0
|
||||
}
|
||||
},
|
||||
"gDeveloperTools": null,
|
||||
"gEnhancements": {
|
||||
"3DSceneRender": 0,
|
||||
"AlwaysShowDungeonMinimapIcon": 0,
|
||||
"AskToEquip": 0,
|
||||
"AssignableTunicsAndBoots": 0,
|
||||
"Autosave": 0,
|
||||
"BetterAmmoRendering": 0,
|
||||
"BetterFarore": 0,
|
||||
"BombchuBowlingFirstPrize": 4,
|
||||
"BombchusOOB": 1,
|
||||
"BowArrowCycle": 1,
|
||||
"ChildHookshotSoftlock": 1,
|
||||
"CustomizeBombchuBowling": 1,
|
||||
"CustomizeFishing": 1,
|
||||
"CustomizeOcarinaGame": 0,
|
||||
"DampeWin": 1,
|
||||
"DisableBlackBars": 0,
|
||||
"DisableBombBillboarding": 0,
|
||||
"DisableCritWiggle": 1,
|
||||
"DisableFixedCamera": 0,
|
||||
"DisableGrottoRotation": 0,
|
||||
"DisableLOD": 1,
|
||||
"DisableLinkSwordTrail": 0,
|
||||
"DpadEquips": 1,
|
||||
"DpadNoDropOcarinaInput": 1,
|
||||
"DrawLineupTick": 0,
|
||||
"DynamicWalletIcon": 1,
|
||||
"EarlyEyeballFrog": 1,
|
||||
"EquipmentAlwaysVisible": 0,
|
||||
"EquipmentCanBeRemoved": 0,
|
||||
"FastBoomerang": 0,
|
||||
"FastChests": 1,
|
||||
"FasterPauseMenu": 0,
|
||||
"FileSelectMoreInfo": 1,
|
||||
"FirstPersonGauntlets": 0,
|
||||
"FishNeverEscape": 1,
|
||||
"FixDampeGoingBackwards": 0,
|
||||
"FixDaruniaDanceSpeed": 1,
|
||||
"FixDungeonMinimapIcon": 1,
|
||||
"FixSawSoftlock": 1,
|
||||
"FixVineFall": 1,
|
||||
"ForgeTime": 1,
|
||||
"GravediggingTourFix": 1,
|
||||
"HoverFishing": 1,
|
||||
"HyperBosses": 0,
|
||||
"HyperEnemies": 0,
|
||||
"IncludeHeldInputsBufferWindow": 0,
|
||||
"InjectItemCounts": {
|
||||
"GoldSkulltula": 1,
|
||||
"HeartContainer": 1,
|
||||
"HeartPiece": 1
|
||||
},
|
||||
"ItemUnequip": 0,
|
||||
"MinimalUI": 0,
|
||||
"MweepSpeed": 5.0,
|
||||
"N64WeirdFrames": 1,
|
||||
"NewDrops": 0,
|
||||
"NoHUDHeartAnimation": 0,
|
||||
"NoInputForCredits": 1,
|
||||
"OcarinaGame": {
|
||||
"StartingNotes": 8
|
||||
},
|
||||
"PauseAnyCursor": 2,
|
||||
"PauseBufferWindow": 5,
|
||||
"PauseMenuAnimatedLink": 0,
|
||||
"QuickBongoKill": 1,
|
||||
"QuickPutaway": 1,
|
||||
"QuitFishingAtDoor": 1,
|
||||
"RedGanonBlood": 1,
|
||||
"RememberMapToggleState": 0,
|
||||
"ReworkedTargeting": {
|
||||
"Enabled": 0
|
||||
},
|
||||
"ScaleAdultEquipmentAsChild": 1,
|
||||
"SceneSpecificDirtPathFix": 1,
|
||||
"ShowDoorLocksOnBothSides": 0,
|
||||
"SkipArrowAnimation": 1,
|
||||
"SkipText": 1,
|
||||
"SlowTextSpeed": 5,
|
||||
"StaticExplosionRadius": 0,
|
||||
"StrengthDisabled": 0,
|
||||
"SwordToggle": 0,
|
||||
"TextSpeed": 5,
|
||||
"TimeFlowFileSelect": 0,
|
||||
"TimeSavers": {
|
||||
"SkipCutscene": {
|
||||
"Intro": 1,
|
||||
"QuickBossDeaths": 1
|
||||
}
|
||||
},
|
||||
"ToTMedallionsColors": 0,
|
||||
"ToggleStrength": 0,
|
||||
"VisualAgony": 0,
|
||||
"WideShutterDoorRange": 1
|
||||
},
|
||||
"gRandoEnhancements": null
|
||||
}
|
||||
},
|
||||
"exempt": [
|
||||
"/gDeveloperTools/LogLevel",
|
||||
"/gDeveloperTools/ResourceLogging",
|
||||
"/gEnhancements/DrawLineupTick",
|
||||
"/gEnhancements/GraveHoles",
|
||||
"/gEnhancements/IncludeHeldInputsBufferWindow",
|
||||
"/gEnhancements/PauseBufferWindow"
|
||||
],
|
||||
"fileType": 2,
|
||||
"presetName": "Speedrun - 3 Faster Quest with Cutscenes",
|
||||
"isBuiltIn": true,
|
||||
"ConfigVersion": 7
|
||||
}
|
||||
@@ -47,7 +47,8 @@ static const std::array<const char*, 4> sOwnedBlocks = {
|
||||
};
|
||||
|
||||
#define SPEEDRUN_PRESET_NONE "None"
|
||||
#define SPEEDRUN_MAX_OPTIONS_ON_SCREEN 6
|
||||
#define SPEEDRUN_MAX_OPTIONS_ON_SCREEN 4
|
||||
#define SPEEDRUN_EXEMPT_ROWS 4
|
||||
|
||||
// {display name, preset name}, ending with "None" which has no preset.
|
||||
static std::vector<std::pair<std::string, std::string>> sPresetChoices;
|
||||
@@ -59,6 +60,9 @@ static nlohmann::json sExempt = nlohmann::json::array();
|
||||
static std::string sPresetName = SPEEDRUN_PRESET_NONE;
|
||||
static uint32_t sSettingsHash = 0;
|
||||
static bool sMenuLocked = false;
|
||||
// "Name: value" of each exempt setting for the preset picked in the menu, and which preset they were made for.
|
||||
static std::vector<std::string> sExemptLines;
|
||||
static int sExemptLinesIndex = -1;
|
||||
|
||||
// Everything else, menu included, is hidden so settings can't be changed mid-run.
|
||||
static const std::vector<std::string> sAllowedWindows = {
|
||||
@@ -104,10 +108,10 @@ static void SetOwnedBlocks(const nlohmann::json& blocks) {
|
||||
ShipInit::InitAll();
|
||||
}
|
||||
|
||||
static std::vector<nlohmann::json::json_pointer> GetExemptPaths() {
|
||||
static std::vector<nlohmann::json::json_pointer> GetExemptPaths(const nlohmann::json& exempt) {
|
||||
std::vector<nlohmann::json::json_pointer> paths;
|
||||
|
||||
for (const auto& path : sExempt) {
|
||||
for (const auto& path : exempt) {
|
||||
try {
|
||||
paths.emplace_back(path.get<std::string>());
|
||||
} catch (const std::exception& e) { SPDLOG_ERROR("Speedrun: bad exempt path {}: {}", path.dump(), e.what()); }
|
||||
@@ -117,8 +121,8 @@ static std::vector<nlohmann::json::json_pointer> GetExemptPaths() {
|
||||
}
|
||||
|
||||
// Copies the player's exempt settings onto blocks. Ones the player never set keep the preset's value.
|
||||
static void OverlayExemptSettings(nlohmann::json& blocks, const nlohmann::json& custom) {
|
||||
for (const auto& path : GetExemptPaths()) {
|
||||
static void OverlayExemptSettings(nlohmann::json& blocks, const nlohmann::json& custom, const nlohmann::json& exempt) {
|
||||
for (const auto& path : GetExemptPaths(exempt)) {
|
||||
if (custom.contains(path)) {
|
||||
blocks[path] = custom[path];
|
||||
}
|
||||
@@ -253,7 +257,7 @@ extern "C" bool Ship_QuestDebugEnabled(u8 questId) {
|
||||
// same build and settings. nlohmann sorts object keys, so the dump is stable.
|
||||
static uint32_t HashSettings() {
|
||||
nlohmann::json stripped = sSettings;
|
||||
for (const auto& path : GetExemptPaths()) {
|
||||
for (const auto& path : GetExemptPaths(sExempt)) {
|
||||
if (stripped.contains(path)) {
|
||||
stripped[path.parent_pointer()].erase(path.back());
|
||||
}
|
||||
@@ -279,6 +283,41 @@ static void EmitHashNotification() {
|
||||
});
|
||||
}
|
||||
|
||||
// The settings a new file gets with this preset: the player's settings, then the preset, then the exempt ones put back.
|
||||
static nlohmann::json BuildFileSettings(const std::string& presetKey, const nlohmann::json& custom,
|
||||
const nlohmann::json& exempt) {
|
||||
nlohmann::json settings = custom;
|
||||
|
||||
if (!presetKey.empty()) {
|
||||
// Applied to the file's copy only, never the player's config.
|
||||
settings = applyPresetToBlocks(presetKey, settings, { PRESET_SECTION_ENHANCEMENTS });
|
||||
}
|
||||
|
||||
OverlayExemptSettings(settings, custom, exempt);
|
||||
return settings;
|
||||
}
|
||||
|
||||
static void UpdateExemptLines(uint8_t presetIndex) {
|
||||
if (sExemptLinesIndex == presetIndex) {
|
||||
return;
|
||||
}
|
||||
sExemptLinesIndex = presetIndex;
|
||||
sExemptLines.clear();
|
||||
|
||||
const std::string& presetKey = sPresetChoices[presetIndex].second;
|
||||
nlohmann::json exempt = GetPresetExempt(presetKey);
|
||||
nlohmann::json settings = BuildFileSettings(presetKey, GetOwnedBlocks(), exempt);
|
||||
|
||||
for (const auto& path : GetExemptPaths(exempt)) {
|
||||
std::string value = "default";
|
||||
if (settings.contains(path)) {
|
||||
const auto& entry = settings[path];
|
||||
value = entry.is_string() ? entry.get<std::string>() : entry.dump();
|
||||
}
|
||||
sExemptLines.push_back(spdlog::fmt_lib::format("{}: {}", path.back(), value));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void Speedrun_LoadPresetChoices(FileChooseContext* fileChooseContext) {
|
||||
// "None" keeps the player's current settings.
|
||||
sPresetChoices = GetSpeedrunPresets();
|
||||
@@ -287,6 +326,8 @@ extern "C" void Speedrun_LoadPresetChoices(FileChooseContext* fileChooseContext)
|
||||
fileChooseContext->speedrunIndex = 0;
|
||||
fileChooseContext->speedrunOffset = 0;
|
||||
}
|
||||
// Player may have changed settings since the menu was last open.
|
||||
sExemptLinesIndex = -1;
|
||||
}
|
||||
|
||||
extern "C" void FileChoose_UpdateSpeedrunMenu(GameState* gameState) {
|
||||
@@ -335,6 +376,15 @@ extern "C" void FileChoose_DrawSpeedrunMenuWindowContents(FileChooseContext* fil
|
||||
static_cast<f32>(92 + textYOffset), false);
|
||||
}
|
||||
}
|
||||
|
||||
// Exempt settings of the selected preset, with the values the new file will get, in columns under the list.
|
||||
UpdateExemptLines(fileChooseContext->speedrunIndex);
|
||||
for (size_t i = 0; i < sExemptLines.size(); i++) {
|
||||
int16_t x = 65 + (int16_t)(i / SPEEDRUN_EXEMPT_ROWS) * 100;
|
||||
int16_t y = 87 + SPEEDRUN_MAX_OPTIONS_ON_SCREEN * 16 + (int16_t)(i % SPEEDRUN_EXEMPT_ROWS) * 7;
|
||||
Interface_DrawTextLine(fileChooseContext->state.gfxCtx, (char*)sExemptLines[i].c_str(), x, y, 180, 180, 180,
|
||||
textAlpha, 0.5f, false);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void Speedrun_InitSaveFile(u8 presetIndex) {
|
||||
@@ -342,16 +392,9 @@ extern "C" void Speedrun_InitSaveFile(u8 presetIndex) {
|
||||
sPresetName = sPresetChoices[presetIndex].first;
|
||||
|
||||
nlohmann::json custom = GetOwnedBlocks();
|
||||
sSettings = custom;
|
||||
sConfigVersion = SOH::GetLatestConfigVersion();
|
||||
sExempt = GetPresetExempt(presetKey);
|
||||
|
||||
if (!presetKey.empty()) {
|
||||
// Applied to the file's copy only, never the player's config.
|
||||
sSettings = applyPresetToBlocks(presetKey, sSettings, { PRESET_SECTION_ENHANCEMENTS });
|
||||
}
|
||||
|
||||
OverlayExemptSettings(sSettings, custom);
|
||||
sSettings = BuildFileSettings(presetKey, custom, sExempt);
|
||||
|
||||
// Runs are always timed in real time, whatever the "RTA Timing on new files" option says.
|
||||
gSaveContext.ship.stats.rtaTiming = 1;
|
||||
@@ -416,7 +459,7 @@ static void LoadSaveSection() {
|
||||
blocks = GetOwnedBlocks();
|
||||
}
|
||||
|
||||
OverlayExemptSettings(blocks, custom);
|
||||
OverlayExemptSettings(blocks, custom, sExempt);
|
||||
|
||||
// No cosmetics during a run. Some scale Link or his sword, which changes his hitbox and reach.
|
||||
blocks[CVAR_PREFIX_COSMETIC] = nlohmann::json::object();
|
||||
|
||||
Reference in New Issue
Block a user