Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mm/2s2h/BenGui/BenGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void SetupGuiElements() {
mNotificationWindow->Show();

mRandoCheckTrackerWindow = std::make_shared<Rando::CheckTracker::CheckTrackerWindow>(
"gWindows.CheckTracker", "Check Tracker", ImVec2(375, 460));
"gCheckTracker.Enable", "Check Tracker", ImVec2(375, 460));
gui->AddGuiWindow(mRandoCheckTrackerWindow);

mRandoCheckTrackerSettingsWindow = std::make_shared<Rando::CheckTracker::SettingsWindow>(
Expand Down
3 changes: 3 additions & 0 deletions mm/2s2h/BenGui/BenMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,9 @@ void BenMenu::AddEnhancements() {
.Min(1)
.Max(20)
.DefaultValue(20));
AddWidget(path, "Skip Little Beaver Brother Races", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Minigames.SkipLittleBeaver")
.Options(CheckboxOptions().Tooltip("Only Race the Older Beaver."));
AddWidget(path, "Mark Shooting Gallery Octoroks", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Minigames.MarkShootingGalleryOctoroks")
.Options(CheckboxOptions().Tooltip("Places markers on the Town Shooting Gallery Octoroks, indicating whether "
Expand Down
44 changes: 38 additions & 6 deletions mm/2s2h/Enhancements/Minigames/BeaverRace.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <libultraship/bridge/consolevariablebridge.h>
#include "2s2h/GameInteractor/GameInteractor.h"
#include "2s2h/ShipInit.hpp"
#include "CustomMessage/CustomMessage.h"

extern "C" {
#include "overlays/actors/ovl_En_Az/z_en_az.h"
Expand All @@ -9,18 +10,21 @@ void func_80A979DC(EnAz* thisx, PlayState* play);
void func_80A97F9C(EnAz* thisx, PlayState* play);
}

#define CVAR_NAME "gEnhancements.Minigames.BeaverRaceRingsCollected"
#define CVAR CVarGetInteger(CVAR_NAME, 20)
#define CVAR_RINGS_NAME "gEnhancements.Minigames.BeaverRaceRingsCollected"
#define CVAR_RINGS CVarGetInteger(CVAR_RINGS_NAME, 20)

#define CVAR_SPEEDUP_NAME "gEnhancements.Minigames.SkipLittleBeaver"
#define CVAR_SPEEDUP CVarGetInteger(CVAR_SPEEDUP_NAME, 0)

static bool minigameScoreSet = false; // Flag to track if the score has been set

void RegisterBeaverRace() {
COND_ID_HOOK(ShouldActorUpdate, ACTOR_EN_AZ, CVAR < 20, [](Actor* actor, bool* should) {
void RegisterBeaverRaceRings() {
COND_ID_HOOK(ShouldActorUpdate, ACTOR_EN_AZ, CVAR_RINGS < 20, [](Actor* actor, bool* should) {
EnAz* enAz = (EnAz*)actor;
Player* player = GET_PLAYER(gPlayState);

if (!minigameScoreSet) {
gSaveContext.minigameScore = CVAR;
gSaveContext.minigameScore = CVAR_RINGS;
minigameScoreSet = true; // Set the flag after assignment
}

Expand Down Expand Up @@ -60,4 +64,32 @@ void RegisterBeaverRace() {
});
}

static RegisterShipInitFunc initFunc(RegisterBeaverRace, { CVAR_NAME });
void RegisterBeaverRaceSpeedup() {
COND_ID_HOOK(ShouldActorUpdate, ACTOR_EN_AZ, CVAR_SPEEDUP, [](Actor* actor, bool* should) {
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_24_04)) {
SET_WEEKEVENTREG(WEEKEVENTREG_24_04);
}
});

COND_ID_HOOK(OnOpenText, 0x10D6, CVAR_SPEEDUP, [](u16* textId, bool* loadFromMessageTable) {
std::string replaceMsg = "My older brother will show you\x11the way, so follow him and\x11"
"don't get separated!";
auto entry = CustomMessage::LoadVanillaMessageTableEntry(*textId);
entry.msg.replace(entry.msg.begin(), entry.msg.end(), replaceMsg);

CustomMessage::LoadCustomMessageIntoFont(entry);
*loadFromMessageTable = false;
});

COND_ID_HOOK(OnOpenText, 0x10FA, CVAR_SPEEDUP, [](u16* textId, bool* loadFromMessageTable) {
std::string replaceMsg = "The time limit is %r1:50%w, let's race.";
auto entry = CustomMessage::LoadVanillaMessageTableEntry(*textId);
entry.msg.replace(entry.msg.begin(), entry.msg.end(), replaceMsg);

CustomMessage::LoadCustomMessageIntoFont(entry);
*loadFromMessageTable = false;
});
}

static RegisterShipInitFunc initRingsFunc(RegisterBeaverRaceRings, { CVAR_RINGS_NAME });
static RegisterShipInitFunc initSpeedupFunc(RegisterBeaverRaceSpeedup, { CVAR_SPEEDUP_NAME });
81 changes: 81 additions & 0 deletions mm/2s2h/PresetManager/PresetDescriptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#pragma once
#include "2s2h/BenGui/UIWidgets.hpp"
#include <string>

#define COLOR_ORANGE UIWidgets::Colors::Orange
#define COLOR_GREEN UIWidgets::Colors::Green
#define TEXT_COLOR(color) UIWidgets::ColorValues.at(COLOR_##color)

std::vector<std::pair<std::string, std::string>> deckScrubberReqs = {
{ "Dungeon Access:", "Requires Transformation & Song" },
{ "Moon Access Remains:", "4 Boss Remains & Oath to Order" },
{ "Stray Fairies Required:", "5" },
};

std::vector<std::string> deckScrubberShuffles = {
"Shuffle Boss Remains", "Shuffle Owl Statues", "Shuffle Shops", "Shuffle Songs", "Shuffle Stray Fairies",
};

std::vector<std::string> deckScrubberStarting = {
"Bunny Hood", "Full Wallets", "Hero's Shield", "Maps and Compasses",
"Kokiri Sword", "Random Boss Remain", "Ocarina of Time", "",
"Song of Time",
};

std::vector<std::pair<std::string, std::string>> deckScrubberHints = {
{ "General Hints", "The Bomb shop 4th Item, Lottery, Great Fairy Fountains, and Mountain Smithy rewards can be "
"hinted by speaking to their respective NPCs." },
{ "Spider House Rewards", "Swamp is hinted within the Spider House.\n"
"Ocean is hinted in South Clock Town day 1 on top of the scaffolding." },
{ "Gossip Stone Static", "Similar to Ship of Harkinian, Gossip Stones will provide hints." },
{ "Boss Remains", "In South Clock Town there is a big poster on the side of the Chest Building, this will tell you "
"where each Boss Remain is located." },
{ "Oath to Order",
"Once you have all 4 Remains, talking to Skull Kid on the Clock Tower Rooftop will hint at the songs location." },
{ "Hookshot", "The Zora near Pirates Fortress will hint the items location." },
{ "Transformation Masks", "In South Clock Town, the sign leaning up against the stall near the Business Scrub will "
"tell you where one of each mask is located." },
};

void DrawDeckScrubberDescription() {
ImGui::SeparatorText("Deckscrubber Settings");
ImGui::TextColored(TEXT_COLOR(ORANGE), "Requirements");
if (ImGui::BeginTable("DesckscrubberReq", 2)) {
for (auto& [key, value] : deckScrubberReqs) {
ImGui::TableNextColumn();
ImGui::TextColored(TEXT_COLOR(GREEN), key.c_str());
ImGui::TableNextColumn();
ImGui::Text(value.c_str());
}
ImGui::EndTable();
}
ImGui::Separator();
if (ImGui::BeginTable("DeckscrubberSeedSettings", 2)) {
ImGui::TableNextColumn();
ImGui::TextColored(TEXT_COLOR(ORANGE), "Included Shuffles");
if (ImGui::BeginTable("DesckscrubberShuffles", 2)) {
for (auto& shuffle : deckScrubberShuffles) {
ImGui::TableNextColumn();
ImGui::Text(shuffle.c_str());
}
ImGui::EndTable();
}
ImGui::TableNextColumn();
ImGui::TextColored(TEXT_COLOR(ORANGE), "Starting Items");
if (ImGui::BeginTable("DesckscrubberStarting", 2)) {
for (auto& item : deckScrubberStarting) {
ImGui::TableNextColumn();
ImGui::Text(item.c_str());
}
ImGui::EndTable();
}
ImGui::EndTable();
}
ImGui::Separator();
ImGui::TextColored(TEXT_COLOR(ORANGE), "Hints");
for (auto& [key, value] : deckScrubberHints) {
ImGui::TextColored(TEXT_COLOR(GREEN), key.c_str());
ImGui::TextWrapped(value.c_str());
ImGui::Separator();
}
}
146 changes: 146 additions & 0 deletions mm/2s2h/PresetManager/PresetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,151 @@ nlohmann::json curatedPresetJ = R"(
}
)"_json;

nlohmann::json deckScrubberJ = R"(
{
"ClearCVars": [
"gCheats",
"gCollisionViewer",
"gDeveloperTools",
"gEnhancements",
"gEventLog",
"gFixes",
"gModes",
"gNetwork",
"gNotifications",
"gRando"
],
"CVars": {
"gCheats": {
"EasyFrameAdvance": 1
},
"gEnhancements": {
"Cutscenes": {
"SkipEnemyCutscenes": 1,
"SkipEntranceCutscenes": 1,
"SkipFirstCycle": 1,
"SkipGetItemCutscenes": 1,
"SkipIntroSequence": 1,
"SkipMiscInteractions": 1,
"SkipOnePointCutscenes": 1,
"SkipStoryCutscenes": 1,
"SkipToFileSelect": 1
},
"Dialogue": {
"AutoBombersCode": 1,
"FastBankSelection": 1,
"FastText": 1
},
"DifficultyOptions": {
"DekuGuardSearchBalls": 1,
"LowerBankRewardThresholds": 1
},
"Dpad": {
"DpadEquips": 1
},
"Equipment": {
"BetterPictoMessage": 1,
"ChuDrops": 1,
"MagicArrowEquipSpeed": 1,
"TwoHandedSwordSpinAttack": 1
},
"Fixes": {
"CompletedHeartContainerAudio": 1,
"ControlCharacters": 1,
"FierceDeityZTargetMovement": 1
},
"Masks": {
"FastTransformation": 1,
"FierceDeitysAnywhere": 1,
"NoBlastMaskCooldown": 1,
"PersistentBunnyHood": {
"Enabled": 1
}
},
"Minigames": {
"AlwaysWinDoggyRace": 1,
"CuccoShackCuccoCount": 1,
"SwampArcheryScore": 2179,
"SkipLittleBeaver": 1
},
"Playback": {
"DpadOcarina": 1,
"NoDropOcarinaInput": 1,
"SkipScarecrowSong": 1
},
"Player": {
"ClimbSpeed": 2,
"FasterPushAndPull": 1,
"FierceDeityPutaway": 1,
"InstantPutaway": 1
},
"PlayerActions": {
"ArrowCycle": 1,
"InstantRecall": 1
},
"Restorations": {
"PowerCrouchStab": 2,
"WoodfallMountainAppearance": 1
},
"Saving": {
"PauseSave": 1
},
"Songs": {
"BetterSongOfDoubleTime": 1,
"FasterSongPlayback": 1,
"ZoraEggCount": 1
},
"Timesavers": {
"DampeDiggingSkip": 1,
"FastChests": 1,
"FasterSceneTransitions": 1,
"GalleryTwofer": 1,
"MarineLabHP": 1,
"SkipBalladOfWindfish": 1,
"SwampBoatSpeed": 1
}
},
"gFixes": {
"FixAmmoCountEnvColor": 1,
"FixEponaStealingSword": 1,
"FixIkanaGreatFairyFountainColor": 1
},
"gRando": {
"Enabled": 1,
"InputSeed": "",
"Options": {
"RO_LOGIC": 4,
"RO_HINTS_BOSS_REMAINS": 1,
"RO_HINTS_GOSSIP_STONES": 1,
"RO_HINTS_HOOKSHOT": 1,
"RO_HINTS_OATH_TO_ORDER": 1,
"RO_HINTS_SPIDER_HOUSES": 1,
"RO_HINTS_TRANSFORMATIONS": 1,
"RO_MINIMUM_STRAY_FAIRIES": 5,
"RO_PLENTIFUL_ITEMS": 1,
"RO_SHUFFLE_BOSS_REMAINS": 1,
"RO_SHUFFLE_GOLD_SKULLTULAS": 0,
"RO_SHUFFLE_OWL_STATUES": 1,
"RO_SHUFFLE_SHOPS": 1,
"RO_SHUFFLE_TRAPS": 1,
"RO_STARTING_MAPS_AND_COMPASSES": 1,
"RO_STARTING_RUPEES": 1,
"RO_TRAP_AMOUNT": 6
},
"SpoilerFile": "",
"SpoilerFileIndex": 0,
"StartingItems": "109,126,91,146,66",
"Traps": {
"Freeze": 1,
"Shock": 1
}
}
},
"type": "2S2H_PRESET",
"version": 1
}
)"_json;

std::unordered_map<std::string, std::pair<nlohmann::json, std::set<std::string>>> presets = {};
const std::filesystem::path presetsFolderPath(Ship::Context::GetPathRelativeToAppDirectory("presets", appShortName));

Expand All @@ -264,6 +409,7 @@ void PresetManager_RefreshPresets() {
presets.insert(
{ "Defaults (Everything Off)", { defaultsPresetJ, { "Developer Tools", "Enhancements", "HUD", "Rando" } } });
presets.insert({ "Curated", { curatedPresetJ, { "Developer Tools", "Enhancements", "HUD" } } });
presets.insert({ "Deckscrubber v3", { deckScrubberJ, { "Developer Tools", "Enhancements", "HUD", "Rando" } } });

// ensure the presets folder exists
if (!std::filesystem::exists(presetsFolderPath)) {
Expand Down
2 changes: 2 additions & 0 deletions mm/2s2h/PresetManager/PresetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
#define PRESET_MANAGER_H

#include <string>
extern nlohmann::json deckScrubberJ;

bool PresetManager_HandleFileDropped(const std::string& filePath);
void PresetManager_ApplyPreset(nlohmann::json j);
void PresetManager_Draw();

#endif // PRESET_MANAGER_H
Loading
Loading