Merge pull request #5497 from HarbourMasters/develop-blair

blair -> dev
This commit is contained in:
Malkierian 2025-05-16 21:46:00 -07:00 committed by GitHub
commit 23a5198986
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 203 additions and 89 deletions

View file

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE) set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")

View file

@ -4,6 +4,7 @@ set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
project(soh LANGUAGES C CXX) project(soh LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use")
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
enable_language(OBJCXX) enable_language(OBJCXX)

View file

@ -544,7 +544,7 @@ typedef enum {
LANGUAGE_MAX LANGUAGE_MAX
} Language; } Language;
#define TODO_TRANSLATE "__Translate_This__" #define TODO_TRANSLATE "TranslateThis"
// TODO get these properties from the textures themselves // TODO get these properties from the textures themselves
#define FONT_CHAR_TEX_WIDTH 16 #define FONT_CHAR_TEX_WIDTH 16

View file

@ -265,6 +265,9 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
} }
} }
auto playingFromMenu = CVarGetInteger(CVAR_AUDIO("Playing"), 0);
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
// Longest text in Audio Editor // Longest text in Audio Editor
ImVec2 columnSize = ImGui::CalcTextSize("Navi - Look/Hey/Watchout (Target Enemy)"); ImVec2 columnSize = ImGui::CalcTextSize("Navi - Look/Hey/Watchout (Target Enemy)");
ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit); ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit);
@ -291,10 +294,13 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
const std::string lockedButton = ICON_FA_LOCK + hiddenKey; const std::string lockedButton = ICON_FA_LOCK + hiddenKey;
const std::string unlockedButton = ICON_FA_UNLOCK + hiddenKey; const std::string unlockedButton = ICON_FA_UNLOCK + hiddenKey;
const int currentValue = CVarGetInteger(cvarKey.c_str(), defaultValue); const int currentValue = CVarGetInteger(cvarKey.c_str(), defaultValue);
const bool isCurrentlyPlaying = currentValue == playingFromMenu || seqData.sequenceId == currentBGM;
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s", seqData.label.c_str()); ImGui::TextColored(
UIWidgets::ColorValues.at(isCurrentlyPlaying ? UIWidgets::Colors::Yellow : UIWidgets::Colors::White), "%s",
seqData.label.c_str());
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::PushItemWidth(-FLT_MIN); ImGui::PushItemWidth(-FLT_MIN);
const int initialValue = map.contains(currentValue) ? currentValue : defaultValue; const int initialValue = map.contains(currentValue) ? currentValue : defaultValue;

View file

@ -642,10 +642,14 @@ void SohInputEditorWindow::DrawStickSection(uint8_t port, uint8_t stick, int32_t
ImGui::SameLine(); ImGui::SameLine();
ImGui::BeginGroup(); ImGui::BeginGroup();
DrawStickDirectionLine(ICON_FA_ARROW_UP, port, stick, Ship::UP, color); DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_UP, stick).c_str(), port, stick, Ship::UP,
DrawStickDirectionLine(ICON_FA_ARROW_DOWN, port, stick, Ship::DOWN, color); color);
DrawStickDirectionLine(ICON_FA_ARROW_LEFT, port, stick, Ship::LEFT, color); DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_DOWN, stick).c_str(), port, stick, Ship::DOWN,
DrawStickDirectionLine(ICON_FA_ARROW_RIGHT, port, stick, Ship::RIGHT, color); color);
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_LEFT, stick).c_str(), port, stick, Ship::LEFT,
color);
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_RIGHT, stick).c_str(), port, stick,
Ship::RIGHT, color);
ImGui::EndGroup(); ImGui::EndGroup();
ImGui::SetNextItemOpen(true, ImGuiCond_Once); ImGui::SetNextItemOpen(true, ImGuiCond_Once);
if (ImGui::TreeNode(StringHelper::Sprintf("Analog Stick Options##%d", id).c_str())) { if (ImGui::TreeNode(StringHelper::Sprintf("Analog Stick Options##%d", id).c_str())) {
@ -1335,12 +1339,12 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() {
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
ImGui::BulletText("Disable song detection"); ImGui::BulletText("Disable song detection");
DrawButtonLine(ICON_FA_BAN, 0, BTN_CUSTOM_OCARINA_DISABLE_SONGS); DrawButtonLine(ICON_FA_BAN "##DisableSongDetection", 0, BTN_CUSTOM_OCARINA_DISABLE_SONGS);
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
ImGui::BulletText("Pitch"); ImGui::BulletText("Pitch");
DrawButtonLine(ICON_FA_ARROW_UP, 0, BTN_CUSTOM_OCARINA_PITCH_UP); DrawButtonLine(ICON_FA_ARROW_UP "##Pitch", 0, BTN_CUSTOM_OCARINA_PITCH_UP);
DrawButtonLine(ICON_FA_ARROW_DOWN, 0, BTN_CUSTOM_OCARINA_PITCH_DOWN); DrawButtonLine(ICON_FA_ARROW_DOWN "##Pitch", 0, BTN_CUSTOM_OCARINA_PITCH_DOWN);
if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) { if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) {
ImGui::EndDisabled(); ImGui::EndDisabled();

View file

@ -155,12 +155,12 @@ const std::string CustomMessage::GetFrench(MessageFormat format) const {
} }
const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const { const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const {
return GetForLanguage(((Language)gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language, return GetForLanguage(
format); ((Language)gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : (Language)gSaveContext.language, format);
} }
const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const { const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const {
std::string output = messages[language] != TODO_TRANSLATE ? messages[language] : messages[LANGUAGE_ENG]; std::string output = !messages[language].starts_with(TODO_TRANSLATE) ? messages[language] : messages[LANGUAGE_ENG];
ProcessMessageFormat(output, format); ProcessMessageFormat(output, format);
return output; return output;
} }

View file

@ -1403,6 +1403,14 @@ typedef enum {
// - `*BgTreemouth` // - `*BgTreemouth`
VB_PLAY_DEKU_TREE_INTRO_CS, VB_PLAY_DEKU_TREE_INTRO_CS,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*DemoKekkai`
VB_PLAY_DISPEL_BARRIER_CS,
// #### `result` // #### `result`
// ```c // ```c
// true // true
@ -1467,6 +1475,15 @@ typedef enum {
// - None // - None
VB_PLAY_FIRE_ARROW_CS, VB_PLAY_FIRE_ARROW_CS,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*EnHeishi2`
// - `bool` (clearCamera - true if the code clears a sub-camera, false otherwise)
VB_PLAY_GATE_OPENING_OR_CLOSING_CS,
// #### `result` // #### `result`
// ```c // ```c
// true // true

View file

@ -625,6 +625,8 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce
if (ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF)) { if (ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF)) {
Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect();
} }
RegionTable(RR_ROOT)->adultNight = true;
RegionTable(RR_ROOT)->adultDay = true;
} else { } else {
ApplyAllAdvancmentItems(); ApplyAllAdvancmentItems();
} }

View file

@ -2467,13 +2467,13 @@ void StaticData::HintTable_Init() {
/*german*/ "ein abgelegener Ort", /*german*/ "ein abgelegener Ort",
/*french*/ "un lieu isolé")); /*french*/ "un lieu isolé"));
hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage(" It's ordinary.", hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage("&It's %gordinary%w.",
/*german*/ "&Sieht aus wie immer.", /*german*/ "&Sieht aus %gwie immer%w.",
/*french*/ "&Elle vous semble %rordinaire%w.")); /*french*/ "&Elle vous semble %gordinaire%w."));
hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage(" It's masterful!", hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage("&It's %rmasterful%w!",
/*german*/ "&Man kann darauf die Worte&%r\"Master Quest\"%w entziffern...", /*german*/ "&Man kann darauf die Worte %r\"Master_Quest\"%w entziffern...",
/*french*/ "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus.")); /*french*/ "&Étrange... les mots %r\"Master_Quest\"%w sont gravés dessus."));
// clang-format on // clang-format on
} }

View file

@ -658,7 +658,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
EventAccess(&logic->MQWaterDragonTorches, []{return true;}), EventAccess(&logic->MQWaterDragonTorches, []{return logic->HasFireSource();}),
}, },
{ {
//Locations //Locations

View file

@ -2496,6 +2496,7 @@ void Logic::Reset() {
ForestOpenBossCorridor = false; ForestOpenBossCorridor = false;
ShadowTrialFirstChest = false; ShadowTrialFirstChest = false;
MQGTGMazeSwitch = false; MQGTGMazeSwitch = false;
MQGTGRightSideSwitch = false;
GTGPlatformSilverRupees = false; GTGPlatformSilverRupees = false;
MQJabuHolesRoomDoor = false; MQJabuHolesRoomDoor = false;
JabuWestTentacle = false; JabuWestTentacle = false;

View file

@ -65,7 +65,7 @@ const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap"; const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints"; const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints";
static const char* englishRupeeNames[190] = { static const char* englishRupeeNames[188] = {
"[P]", "[P]",
"Bad RNG Rolls", "Bad RNG Rolls",
"Baht", "Baht",
@ -111,8 +111,6 @@ static const char* englishRupeeNames[190] = {
"Dimes", "Dimes",
"Dinars", "Dinars",
"DNA", "DNA",
"Doge",
"Dogecoin",
"Doll Hairs", "Doll Hairs",
"Dollars", "Dollars",
"Dollarydoos", "Dollarydoos",
@ -258,25 +256,25 @@ static const char* englishRupeeNames[190] = {
"Zorkmids", "Zorkmids",
}; };
static const char* germanRupeeNames[80] = { static const char* germanRupeeNames[79] = {
"Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent", "Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent",
"Diamanten", "Dinar", "Diridari", "Dogecoin", "Dollar", "Draken", "ECU", "Elexit", "Diamanten", "Dinar", "Diridari", "Dollar", "Draken", "ECU", "Elexit", "Erz",
"Erz", "Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil", "Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil", "Gold",
"Gold", "Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln", "Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln", "Kies",
"Kies", "Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken", "Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken", "Kröten",
"Kröten", "Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen", "Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen", "Naira",
"Naira", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", "Pokédollar",
"Pokédollar", "Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine", "Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine", "Rupien",
"Rupien", "Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne", "Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne", "Sternis",
"Sternis", "Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny", "Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny",
}; };
static const char* frenchRupeeNames[40] = { static const char* frenchRupeeNames[39] = {
"Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules", "Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules",
"Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", "Dollars", "Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dollars", "Émeraudes",
"Émeraudes", "Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils", "Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils", "Grouses",
"Grouses", "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens", "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens", "Pépètes",
"Pépètes", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies",
}; };
Randomizer::Randomizer() { Randomizer::Randomizer() {
@ -4523,6 +4521,9 @@ CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) {
messageEntry.Replace("[[typeHint]]", Rando::StaticData::hintTextTable[RHT_DUNGEON_ORDINARY].GetHintMessage()); messageEntry.Replace("[[typeHint]]", Rando::StaticData::hintTextTable[RHT_DUNGEON_ORDINARY].GetHintMessage());
} }
// BUG: the icon is not in the message yet so are not accounted for, so overflows are possible
messageEntry.AutoFormat();
return messageEntry; return messageEntry;
} }

View file

@ -1532,8 +1532,9 @@ void ItemTrackerWindow::DrawElement() {
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_MAIN_WINDOW && SECTION_DISPLAY_MAIN_WINDOW &&
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING &&
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) ==
TRACKER_DISPLAY_ALWAYS) { TRACKER_DISPLAY_ALWAYS)) {
DrawNotes(); DrawNotes();
} }
EndFloatingWindows(); EndFloatingWindows();
@ -1642,7 +1643,10 @@ void ItemTrackerWindow::DrawElement() {
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_SEPARATE && SECTION_DISPLAY_SEPARATE &&
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW ||
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING &&
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) !=
TRACKER_DISPLAY_COMBO_BUTTON))) {
ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver);
BeginFloatingWindows("Personal Notes", ImGuiWindowFlags_NoFocusOnAppearing); BeginFloatingWindows("Personal Notes", ImGuiWindowFlags_NoFocusOnAppearing);
DrawNotes(true); DrawNotes(true);
@ -1943,7 +1947,10 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true; shouldUpdateVectors = true;
} }
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW ||
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING &&
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) !=
TRACKER_DISPLAY_COMBO_BUTTON)) {
if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes,
ComboboxOptions() ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN) .DefaultIndex(SECTION_DISPLAY_HIDDEN)

View file

@ -250,7 +250,7 @@ void Settings::CreateOptions() {
OPT_U8(RSK_LACS_REWARD_COUNT, "GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true); OPT_U8(RSK_LACS_REWARD_COUNT, "GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true);
OPT_U8(RSK_LACS_DUNGEON_COUNT, "GCBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true); OPT_U8(RSK_LACS_DUNGEON_COUNT, "GCBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true);
OPT_U8(RSK_LACS_TOKEN_COUNT, "GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true); OPT_U8(RSK_LACS_TOKEN_COUNT, "GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true);
OPT_U8(RSK_LACS_OPTIONS, "GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD); OPT_U8(RSK_LACS_OPTIONS, "GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), mOptionDescriptions[RSK_LACS_OPTIONS], WidgetType::Combobox, RO_LACS_STANDARD_REWARD);
OPT_U8(RSK_KEYRINGS, "Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF); OPT_U8(RSK_KEYRINGS, "Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF);
OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, "Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8); OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, "Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8);
OPT_U8(RSK_KEYRINGS_GERUDO_FORTRESS, "Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WidgetType::Combobox, 0); OPT_U8(RSK_KEYRINGS_GERUDO_FORTRESS, "Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WidgetType::Combobox, 0);

View file

@ -13,12 +13,14 @@ extern "C" {
#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h"
#include "src/overlays/actors/ovl_En_Owl/z_en_owl.h" #include "src/overlays/actors/ovl_En_Owl/z_en_owl.h"
#include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" #include "src/overlays/actors/ovl_En_Go2/z_en_go2.h"
#include "src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h"
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" #include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
#include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h" #include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h"
#include "src/overlays/actors/ovl_En_Ru2/z_en_ru2.h" #include "src/overlays/actors/ovl_En_Ru2/z_en_ru2.h"
#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" #include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h"
#include "src/overlays/actors/ovl_En_Box/z_en_box.h" #include "src/overlays/actors/ovl_En_Box/z_en_box.h"
#include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h" #include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h"
#include "src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.h"
#include "src/overlays/actors/ovl_En_Sa/z_en_sa.h" #include "src/overlays/actors/ovl_En_Sa/z_en_sa.h"
#include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h" #include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h"
#include "src/overlays/actors/ovl_En_Tk/z_en_tk.h" #include "src/overlays/actors/ovl_En_Tk/z_en_tk.h"
@ -217,6 +219,25 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), IS_RANDO) && if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), IS_RANDO) &&
(entranceFlag != EVENTCHKINF_EPONA_OBTAINED) && entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE) { (entranceFlag != EVENTCHKINF_EPONA_OBTAINED) && entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE) {
*should = false; *should = false;
// Check for dispulsion of Ganon's Tower barrier
switch (entranceIndex) {
case ENTR_INSIDE_GANONS_CASTLE_2:
case ENTR_INSIDE_GANONS_CASTLE_3:
case ENTR_INSIDE_GANONS_CASTLE_4:
case ENTR_INSIDE_GANONS_CASTLE_5:
case ENTR_INSIDE_GANONS_CASTLE_6:
case ENTR_INSIDE_GANONS_CASTLE_7:
if (Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_WATER_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SHADOW_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FIRE_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_LIGHT_TRIAL) &&
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SPIRIT_TRIAL)) {
Flags_SetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER);
}
break;
}
} }
break; break;
} }
@ -275,6 +296,11 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
} }
switch (actor->id) { switch (actor->id) {
case ACTOR_OBJ_SWITCH: { case ACTOR_OBJ_SWITCH: {
if ((actor->params == 8224 && gPlayState->sceneNum == SCENE_DODONGOS_CAVERN) ||
(actor->params == 6979 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) &&
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) {
break;
}
ObjSwitch* switchActor = (ObjSwitch*)actor; ObjSwitch* switchActor = (ObjSwitch*)actor;
switchActor->cooldownTimer = 0; switchActor->cooldownTimer = 0;
*should = false; *should = false;
@ -441,6 +467,26 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
*should = false; *should = false;
} }
break; break;
case VB_PLAY_DISPEL_BARRIER_CS: {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
static s16 trialEntrances[] = {
0,
ENTR_INSIDE_GANONS_CASTLE_3,
ENTR_INSIDE_GANONS_CASTLE_6,
ENTR_INSIDE_GANONS_CASTLE_5,
ENTR_INSIDE_GANONS_CASTLE_4,
ENTR_INSIDE_GANONS_CASTLE_7,
ENTR_INSIDE_GANONS_CASTLE_2,
};
RateLimitedSuccessChime();
DemoKekkai* kekkai = va_arg(args, DemoKekkai*);
gPlayState->nextEntranceIndex = trialEntrances[kekkai->actor.params];
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
gPlayState->transitionType = TRANS_TYPE_FADE_BLACK;
*should = false;
}
break;
}
case VB_OWL_INTERACTION: { case VB_OWL_INTERACTION: {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), IS_RANDO) && *should) { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), IS_RANDO) && *should) {
EnOwl* enOwl = va_arg(args, EnOwl*); EnOwl* enOwl = va_arg(args, EnOwl*);
@ -720,6 +766,18 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
break; break;
} }
case VB_PLAY_GATE_OPENING_OR_CLOSING_CS: {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
EnHeishi2* enHeishi2 = va_arg(args, EnHeishi2*);
enHeishi2->unk_2F2[0] = 0;
// The second argument determines whether the vanilla code should be run anyway. It
// should be set to `true` ONLY IF said code calls `Play_ClearCamera`, false otherwise.
bool clearCamera = (bool)va_arg(args, int);
*should = clearCamera && enHeishi2->cameraId != MAIN_CAM;
}
break;
}
case VB_PLAY_RAINBOW_BRIDGE_CS: { case VB_PLAY_RAINBOW_BRIDGE_CS: {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
*should = false; *should = false;

View file

@ -336,8 +336,8 @@ void SohMenu::AddMenuEnhancements() {
.CVar(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding")) .CVar(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"))
.Options(CheckboxOptions().Tooltip( .Options(CheckboxOptions().Tooltip(
"Don't skip cutscenes that are associated with useful glitches. Currently, it is " "Don't skip cutscenes that are associated with useful glitches. Currently, it is "
"only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS, and the Box Skip One " "only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS, Dodongo Boss "
"Point in Jabu.")); "Door Switch CS, Water Temple Dragon Switch CS, and the Box Skip One Point in Jabu."));
AddWidget(path, "Text", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Text", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Skip Pickup Messages", WIDGET_CVAR_CHECKBOX) AddWidget(path, "Skip Pickup Messages", WIDGET_CVAR_CHECKBOX)

View file

@ -4113,7 +4113,8 @@ void Interface_DrawItemButtons(PlayState* play) {
if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.UseMargins"), 0) != 0) { if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.UseMargins"), 0) != 0) {
X_Margins_CD = Left_HUD_Margin; X_Margins_CD = Left_HUD_Margin;
}; };
C_Down_BTN_Pos[0] = (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosX"), 0) + X_Margins_CD); C_Down_BTN_Pos[0] =
OTRGetDimensionFromLeftEdge(CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosX"), 0) + X_Margins_CD);
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosType"), 0) == ANCHOR_RIGHT) { } else if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosType"), 0) == ANCHOR_RIGHT) {
if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.UseMargins"), 0) != 0) { if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.UseMargins"), 0) != 0) {
X_Margins_CD = Right_HUD_Margin; X_Margins_CD = Right_HUD_Margin;

View file

@ -7,6 +7,7 @@
#include "z_demo_kekkai.h" #include "z_demo_kekkai.h"
#include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "objects/object_demo_kekkai/object_demo_kekkai.h"
#include "scenes/dungeons/ganontika/ganontika_scene.h" #include "scenes/dungeons/ganontika/ganontika_scene.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) #define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
@ -257,6 +258,7 @@ void DemoKekkai_TrialBarrierIdle(Actor* thisx, PlayState* play) {
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base);
if (this->collider2.base.acFlags & AC_HIT) { if (this->collider2.base.acFlags & AC_HIT) {
if (GameInteractor_Should(VB_PLAY_DISPEL_BARRIER_CS, true, this)) {
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
// "I got it" // "I got it"
LOG_STRING("当ったよ"); LOG_STRING("当ったよ");
@ -265,6 +267,7 @@ void DemoKekkai_TrialBarrierIdle(Actor* thisx, PlayState* play) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(sSageCutscenes[this->actor.params]); play->csCtx.segment = SEGMENTED_TO_VIRTUAL(sSageCutscenes[this->actor.params]);
gSaveContext.cutsceneTrigger = 1; gSaveContext.cutsceneTrigger = 1;
} }
}
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base); CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base);
func_8002F974(&this->actor, NA_SE_EV_TOWER_ENERGY - SFX_FLAG); func_8002F974(&this->actor, NA_SE_EV_TOWER_ENERGY - SFX_FLAG);
} }

View file

@ -6,7 +6,7 @@
struct DemoKekkai; struct DemoKekkai;
typedef void (*DemoKekkaiUpdateFunc)(struct DemoKekkai* this, PlayState* play); typedef void (*DemoKekkaiUpdateFunc)(struct DemoKekkai* thisx, PlayState* play);
typedef struct DemoKekkai { typedef struct DemoKekkai {
/* 0x0000 */ Actor actor; /* 0x0000 */ Actor actor;

View file

@ -314,6 +314,7 @@ void func_80A5372C(EnHeishi2* this, PlayState* play) {
f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim); f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim);
Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f); Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f);
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
this->unk_2F2[0] = 200; this->unk_2F2[0] = 200;
this->cameraId = Play_CreateSubCamera(play); this->cameraId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
@ -327,6 +328,7 @@ void func_80A5372C(EnHeishi2* this, PlayState* play) {
this->unk_28C.z = 3014.0f; this->unk_28C.z = 3014.0f;
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
}
this->actionFunc = func_80A53850; this->actionFunc = func_80A53850;
} }
@ -334,11 +336,15 @@ void func_80A53850(EnHeishi2* this, PlayState* play) {
BgSpot15Saku* gate; BgSpot15Saku* gate;
SkelAnime_Update(&this->skelAnime); SkelAnime_Update(&this->skelAnime);
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
}
gate = (BgSpot15Saku*)this->gate; gate = (BgSpot15Saku*)this->gate;
if ((this->unk_2F2[0] == 0) || (gate->unk_168 == 0)) { if ((this->unk_2F2[0] == 0) || (gate->unk_168 == 0)) {
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, true)) {
Play_ClearCamera(play, this->cameraId); Play_ClearCamera(play, this->cameraId);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
}
Message_CloseTextbox(play); Message_CloseTextbox(play);
this->unk_30C = 1; this->unk_30C = 1;
Player_SetCsActionWithHaltedActors(play, NULL, 7); Player_SetCsActionWithHaltedActors(play, NULL, 7);
@ -479,6 +485,7 @@ void func_80A53DF8(EnHeishi2* this, PlayState* play) {
f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim); f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim);
Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f); Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f);
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
this->unk_2F2[0] = 200; this->unk_2F2[0] = 200;
this->cameraId = Play_CreateSubCamera(play); this->cameraId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
@ -496,6 +503,7 @@ void func_80A53DF8(EnHeishi2* this, PlayState* play) {
this->unk_298.z = -1079.0f; this->unk_298.z = -1079.0f;
this->unk_28C.z = -1079.0f; this->unk_28C.z = -1079.0f;
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
}
this->actionFunc = func_80A53F30; this->actionFunc = func_80A53F30;
} }
@ -503,11 +511,15 @@ void func_80A53F30(EnHeishi2* this, PlayState* play) {
BgGateShutter* gate; BgGateShutter* gate;
SkelAnime_Update(&this->skelAnime); SkelAnime_Update(&this->skelAnime);
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C); Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
}
gate = (BgGateShutter*)this->gate; gate = (BgGateShutter*)this->gate;
if ((this->unk_2F2[0] == 0) || (gate->openingState == 0)) { if ((this->unk_2F2[0] == 0) || (gate->openingState == 0)) {
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, true)) {
Play_ClearCamera(play, this->cameraId); Play_ClearCamera(play, this->cameraId);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
}
if ((this->unk_30A != 2)) { if ((this->unk_30A != 2)) {
if (this->unk_30A == 0) { if (this->unk_30A == 0) {
this->actor.textId = 0x2015; this->actor.textId = 0x2015;