Merge branch 'HarbourMasters:develop' into accessible-checks

This commit is contained in:
Anthony Stewart 2025-03-06 22:21:38 -06:00
commit 5b10a70735
70 changed files with 489 additions and 852 deletions

View file

@ -160,7 +160,6 @@ typedef struct {
#pragma region SoH #pragma region SoH
typedef struct ShipRandomizerSaveContextData { typedef struct ShipRandomizerSaveContextData {
u16 adultTradeItems;
u8 triforcePiecesCollected; u8 triforcePiecesCollected;
} ShipRandomizerSaveContextData; } ShipRandomizerSaveContextData;

View file

@ -24,11 +24,11 @@ typedef enum {
bool Autosave_CanSave() { bool Autosave_CanSave() {
// Don't save when in title screen // Don't save when in title screen or debug file
// Don't save the first 60 frames to not save the magic meter when it's still in the animation of filling it. // Don't save the first 60 frames to not save the magic meter when it's still in the animation of filling it.
// Don't save in Ganon's fight and chamber of sages because of master sword and remember save location issues. // Don't save in Chamber of Sages and the Cutscene map because of remember save location and cutscene item gives.
if (!GameInteractor::IsSaveLoaded(true) || gPlayState->gameplayFrames < 60 || if (!GameInteractor::IsSaveLoaded(false) || gPlayState->gameplayFrames < 60 ||
gPlayState->sceneNum == SCENE_GANON_BOSS || gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES || gPlayState->sceneNum == SCENE_CUTSCENE_MAP) {
return false; return false;
} }

View file

@ -0,0 +1,46 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "functions.h"
#include "macros.h"
#include "variables.h"
#include "z64save.h"
extern "C" PlayState* gPlayState;
static constexpr int32_t CVAR_BGS_FIX_DEFAULT = 0;
#define CVAR_BGS_FIX_NAME CVAR_ENHANCEMENT("FixBrokenGiantsKnife")
#define CVAR_BGS_FIX_VALUE CVarGetInteger(CVAR_BGS_FIX_NAME, CVAR_BGS_FIX_DEFAULT)
void OnReceiveBrokenGiantsKnife(GetItemEntry itemEntry) {
if (itemEntry.itemId != ITEM_SWORD_BGS) {
return;
}
// Flag wasn't reset because Kokiri or Master Sword was missing, so we need to bypass those checks
int32_t bypassEquipmentChecks = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER);
int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD);
int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) |
(1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE);
if (allSwordsInEquipment != allSwordFlags) {
return;
}
gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE);
if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
if (gPlayState != NULL) {
Interface_LoadItemIcon1(gPlayState, 0);
}
}
}
void RegisterBrokenGiantsKnifeFix() {
// If enhancement is off, flag should be handled exclusively by vanilla behaviour
COND_HOOK(OnItemReceive, CVAR_BGS_FIX_VALUE || IS_RANDO, OnReceiveBrokenGiantsKnife);
}
static RegisterShipInitFunc initFunc(RegisterBrokenGiantsKnifeFix, { CVAR_BGS_FIX_NAME, "IS_RANDO" });

View file

@ -205,7 +205,7 @@ void OnZTitleUpdateSkipToFileSelect(void* gameState) {
gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = 0xFF; gSaveContext.natureAmbienceId = 0xFF;
gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; gSaveContext.gameMode = GAMEMODE_FILE_SELECT;
titleContext->state.running = false; titleContext->state.running = false;
SET_NEXT_GAMESTATE(&titleContext->state, FileChoose_Init, FileChooseContext); SET_NEXT_GAMESTATE(&titleContext->state, FileChoose_Init, FileChooseContext);

View file

@ -146,7 +146,7 @@ static bool SetPlayerHealthHandler(std::shared_ptr<Ship::Console> Console, const
static bool LoadSceneHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&, std::string* output) { static bool LoadSceneHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&, std::string* output) {
gSaveContext.respawnFlag = 0; gSaveContext.respawnFlag = 0;
gSaveContext.seqId = 0xFF; gSaveContext.seqId = 0xFF;
gSaveContext.gameMode = 0; gSaveContext.gameMode = GAMEMODE_NORMAL;
return 0; return 0;
} }
@ -489,13 +489,14 @@ static bool FWHandler(std::shared_ptr<Ship::Console> Console, const std::vector<
} }
static bool FileSelectHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) { static bool FileSelectHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (gPlayState != nullptr) { if (gGameState == nullptr) {
SET_NEXT_GAMESTATE(&gPlayState->state, FileChoose_Init, FileChooseContext); ERROR_MESSAGE("gGameState == nullptr");
gPlayState->state.running = 0;
} else {
ERROR_MESSAGE("gPlayState == nullptr");
return 1; return 1;
} }
gSaveContext.gameMode = GAMEMODE_FILE_SELECT;
SET_NEXT_GAMESTATE(gGameState, FileChoose_Init, FileChooseContext);
gGameState->running = false;
return 0; return 0;
} }

View file

@ -19,7 +19,6 @@ extern "C" {
#include "functions.h" #include "functions.h"
#include "macros.h" #include "macros.h"
#include "soh/cvar_prefixes.h" #include "soh/cvar_prefixes.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
extern PlayState* gPlayState; extern PlayState* gPlayState;
#include "textures/icon_item_static/icon_item_static.h" #include "textures/icon_item_static/icon_item_static.h"
@ -414,22 +413,6 @@ void DrawInfoTab() {
void DrawBGSItemFlag(uint8_t itemID) { void DrawBGSItemFlag(uint8_t itemID) {
const ItemMapEntry& slotEntry = itemMapping[itemID]; const ItemMapEntry& slotEntry = itemMapping[itemID];
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1)); ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
ImGui::SameLine();
int tradeIndex = itemID - ITEM_POCKET_EGG;
bool hasItem = (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) != 0;
bool shouldHaveItem = hasItem;
ImGui::Checkbox(("##adultTradeFlag" + std::to_string(itemID)).c_str(), &shouldHaveItem);
if (hasItem != shouldHaveItem) {
if (shouldHaveItem) {
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= (1 << tradeIndex);
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_NONE) {
INV_CONTENT(ITEM_TRADE_ADULT) = ITEM_POCKET_EGG + tradeIndex;
}
} else {
gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~(1 << tradeIndex);
Inventory_ReplaceItem(gPlayState, itemID, Randomizer_GetNextAdultTradeItem());
}
}
} }
void DrawInventoryTab() { void DrawInventoryTab() {
@ -476,9 +459,6 @@ void DrawInventoryTab() {
if (ImGui::BeginPopup(itemPopupPicker)) { if (ImGui::BeginPopup(itemPopupPicker)) {
if (ImGui::Button("##itemNonePicker", ImVec2(32.0f, 32.0f))) { if (ImGui::Button("##itemNonePicker", ImVec2(32.0f, 32.0f))) {
gSaveContext.inventory.items[selectedIndex] = ITEM_NONE; gSaveContext.inventory.items[selectedIndex] = ITEM_NONE;
if (selectedIndex == SLOT_TRADE_ADULT) {
gSaveContext.ship.quest.data.randomizer.adultTradeItems = 0;
}
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
UIWidgets::SetLastItemHoverText("None"); UIWidgets::SetLastItemHoverText("None");
@ -512,13 +492,6 @@ void DrawInventoryTab() {
ImGui::PopStyleVar(); ImGui::PopStyleVar();
if (ret) { if (ret) {
gSaveContext.inventory.items[selectedIndex] = slotEntry.id; gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
// Set adult trade item flag if you're playing adult trade shuffle in rando
if (IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) &&
selectedIndex == SLOT_TRADE_ADULT &&
slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) {
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(slotEntry.id);
}
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id)); UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id));

View file

@ -1600,6 +1600,30 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" }, { RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" },
{ RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" }, { RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" },
{ RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" }, { RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" },
{ RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG, "RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG" },
{ RAND_INF_CHILD_TRADES_HAS_CHICKEN, "RAND_INF_CHILD_TRADES_HAS_CHICKEN" },
{ RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA, "RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_KEATON, "RAND_INF_CHILD_TRADES_HAS_MASK_KEATON" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_SKULL, "RAND_INF_CHILD_TRADES_HAS_MASK_SKULL" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY, "RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY, "RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_GORON, "RAND_INF_CHILD_TRADES_HAS_MASK_GORON" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_ZORA, "RAND_INF_CHILD_TRADES_HAS_MASK_ZORA" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO, "RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO" },
{ RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH, "RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH" },
{ RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, "RAND_INF_ADULT_TRADES_HAS_POCKET_EGG" },
{ RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO, "RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO" },
{ RAND_INF_ADULT_TRADES_HAS_COJIRO, "RAND_INF_ADULT_TRADES_HAS_COJIRO" },
{ RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM, "RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM" },
{ RAND_INF_ADULT_TRADES_HAS_ODD_POTION, "RAND_INF_ADULT_TRADES_HAS_ODD_POTION" },
{ RAND_INF_ADULT_TRADES_HAS_SAW, "RAND_INF_ADULT_TRADES_HAS_SAW" },
{ RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN, "RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN" },
{ RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION, "RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION" },
{ RAND_INF_ADULT_TRADES_HAS_FROG, "RAND_INF_ADULT_TRADES_HAS_FROG" },
{ RAND_INF_ADULT_TRADES_HAS_EYEDROPS, "RAND_INF_ADULT_TRADES_HAS_EYEDROPS" },
{ RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK, "RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK" },
} }, } },
}; };

View file

@ -22,6 +22,7 @@ DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneSpawnActors, ()); DEFINE_HOOK(OnSceneSpawnActors, ());
DEFINE_HOOK(OnPlayerUpdate, ()); DEFINE_HOOK(OnPlayerUpdate, ());
DEFINE_HOOK(OnOcarinaSongAction, ()); DEFINE_HOOK(OnOcarinaSongAction, ());
DEFINE_HOOK(OnCuccoOrChickenHatch, ());
DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price)); DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price));
DEFINE_HOOK(OnActorInit, (void* actor)); DEFINE_HOOK(OnActorInit, (void* actor));
DEFINE_HOOK(OnActorUpdate, (void* actor)); DEFINE_HOOK(OnActorUpdate, (void* actor));

View file

@ -80,6 +80,10 @@ void GameInteractor_ExecuteOnOcarinaSongAction() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnOcarinaSongAction>(); GameInteractor::Instance->ExecuteHooks<GameInteractor::OnOcarinaSongAction>();
} }
void GameInteractor_ExecuteOnCuccoOrChickenHatch() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnCuccoOrChickenHatch>();
}
void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) { void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnShopSlotChange>(cursorIndex, price); GameInteractor::Instance->ExecuteHooks<GameInteractor::OnShopSlotChange>(cursorIndex, price);
} }

View file

@ -24,6 +24,7 @@ void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag);
void GameInteractor_ExecuteOnSceneSpawnActors(); void GameInteractor_ExecuteOnSceneSpawnActors();
void GameInteractor_ExecuteOnPlayerUpdate(); void GameInteractor_ExecuteOnPlayerUpdate();
void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnOcarinaSongAction();
void GameInteractor_ExecuteOnCuccoOrChickenHatch();
void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorInit(void* actor);
void GameInteractor_ExecuteOnActorUpdate(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor);
void GameInteractor_ExecuteOnActorKill(void* actor); void GameInteractor_ExecuteOnActorKill(void* actor);
@ -33,7 +34,6 @@ void GameInteractor_ExecuteOnTimestamp (u8 item);
void GameInteractor_ExecuteOnPlayerBonk(); void GameInteractor_ExecuteOnPlayerBonk();
void GameInteractor_ExecuteOnPlayerHealthChange(int16_t amount); void GameInteractor_ExecuteOnPlayerHealthChange(int16_t amount);
void GameInteractor_ExecuteOnPlayerBottleUpdate(int16_t contents); void GameInteractor_ExecuteOnPlayerBottleUpdate(int16_t contents);
void GameInteractor_ExecuteOnOcarinaSongAction();
void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price);
void GameInteractor_ExecuteOnPlayDestroy(); void GameInteractor_ExecuteOnPlayDestroy();
void GameInteractor_ExecuteOnPlayDrawEnd(); void GameInteractor_ExecuteOnPlayDrawEnd();

View file

@ -371,6 +371,11 @@ typedef enum {
// #### `args` // #### `args`
// - `*Actor` // - `*Actor`
VB_DOOR_PLAY_SCENE_TRANSITION, VB_DOOR_PLAY_SCENE_TRANSITION,
// Vanilla condition: true
VB_HATCH_CUCCO_OR_CHICKEN,
// Vanilla condition: exchangeItemId == EXCH_ITEM_LETTER_ZELDA
// Opt: s32
VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER,
// #### `result` // #### `result`
// In `Interface_DrawAmmoCount`: // In `Interface_DrawAmmoCount`:

View file

@ -35,7 +35,6 @@
#include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" #include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h"
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" #include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_boy/object_link_boy.h"
#include "objects/object_link_child/object_link_child.h" #include "objects/object_link_child/object_link_child.h"
@ -47,7 +46,6 @@ extern "C" {
#include "align_asset_macro.h" #include "align_asset_macro.h"
#include "macros.h" #include "macros.h"
#include "soh/cvar_prefixes.h" #include "soh/cvar_prefixes.h"
#include "functions.h"
#include "variables.h" #include "variables.h"
#include "functions.h" #include "functions.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h"
@ -552,42 +550,6 @@ void RegisterResetNaviTimer() {
}); });
} }
void RegisterBrokenGiantsKnifeFix() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry itemEntry) {
if (itemEntry.itemId != ITEM_SWORD_BGS) {
return;
}
int32_t bypassEquipmentChecks = 0;
if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 0)) {
// Flag wasn't reset because Kokiri or Master Sword was missing, so we need to
// bypass those checks
bypassEquipmentChecks |= (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER);
} else {
// If enhancement is off, flag should be handled exclusively by vanilla behaviour
return;
}
int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD);
int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) |
(1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE);
if (allSwordsInEquipment != allSwordFlags) {
return;
}
gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE);
if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
if (gPlayState != NULL) {
Interface_LoadItemIcon1(gPlayState, 0);
}
}
});
}
//this map is used for enemies that can be uniquely identified by their id //this map is used for enemies that can be uniquely identified by their id
//and that are always counted //and that are always counted
//enemies that can't be uniquely identified by their id //enemies that can't be uniquely identified by their id
@ -1098,7 +1060,6 @@ void InitMods() {
RegisterMenuPathFix(); RegisterMenuPathFix();
RegisterMirrorModeHandler(); RegisterMirrorModeHandler();
RegisterResetNaviTimer(); RegisterResetNaviTimer();
RegisterBrokenGiantsKnifeFix();
RegisterEnemyDefeatCounts(); RegisterEnemyDefeatCounts();
RegisterBossDefeatTimestamps(); RegisterBossDefeatTimestamps();
RegisterRandomizedEnemySizes(); RegisterRandomizedEnemySizes();

View file

@ -6,12 +6,6 @@
#include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/UIWidgets.hpp"
#include <libultraship/libultraship.h> #include <libultraship/libultraship.h>
void clearCvars(std::vector<const char*> cvarsToClear) {
for(const char* cvar : cvarsToClear) {
CVarClear(cvar);
}
}
std::string FormatLocations(std::vector<RandomizerCheck> locs) { std::string FormatLocations(std::vector<RandomizerCheck> locs) {
std::string locString = ""; std::string locString = "";
for (auto loc: locs) { for (auto loc: locs) {
@ -69,10 +63,13 @@ void DrawPresetSelector(PresetType presetTypeId) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f));
if (ImGui::Button(("Apply Preset##" + presetTypeCvar).c_str())) { if (ImGui::Button(("Apply Preset##" + presetTypeCvar).c_str())) {
clearCvars(presetTypeDef.cvarsToClear); for(const char* block : presetTypeDef.blocksToClear) {
CVarClearBlock(block);
}
if (selectedPresetId != 0) { if (selectedPresetId != 0) {
applyPreset(selectedPresetDef.entries); applyPreset(selectedPresetDef.entries);
} }
CVarSetInteger(presetTypeCvar.c_str(), selectedPresetId);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
if (presetTypeId == PRESET_TYPE_RANDOMIZER){ if (presetTypeId == PRESET_TYPE_RANDOMIZER){
Rando::Settings::GetInstance()->ReloadOptions(); Rando::Settings::GetInstance()->ReloadOptions();

View file

@ -61,499 +61,6 @@ void applyPreset(std::vector<PresetEntry> entries);
// TODO: Ideally everything below this point will come from one/many JSON files // TODO: Ideally everything below this point will come from one/many JSON files
const std::vector<const char*> enhancementsCvars = {
CVAR_SETTING("DPadOnPause"),
CVAR_SETTING("DpadInText"),
CVAR_SETTING("OcarinaControl.Dpad"),
CVAR_SETTING("OcarinaControl.RStick"),
CVAR_ENHANCEMENT("DpadEquips"),
CVAR_ENHANCEMENT("PauseAnyCursor"),
CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"),
CVAR_ENHANCEMENT("NaviOnL"),
CVAR_SETTING("FreeLook.InvertXAxis"),
CVAR_SETTING("FreeLook.InvertYAxis"),
CVAR_SETTING("Controls.RightStickAim"),
CVAR_SETTING("DisableFirstPersonAutoCenterView"),
CVAR_ENHANCEMENT("TextSpeed"),
CVAR_ENHANCEMENT("MweepSpeed"),
CVAR_ENHANCEMENT("ForgeTime"),
CVAR_ENHANCEMENT("ClimbSpeed"),
CVAR_ENHANCEMENT("FasterBlockPush"),
CVAR_ENHANCEMENT("CrawlSpeed"),
CVAR_ENHANCEMENT("FasterHeavyBlockLift"),
CVAR_ENHANCEMENT("NoForcedNavi"),
CVAR_ENHANCEMENT("SkulltulaFreeze"),
CVAR_ENHANCEMENT("MMBunnyHood"),
CVAR_ENHANCEMENT("AdultMasks"),
CVAR_ENHANCEMENT("FastChests"),
CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"),
CVAR_ENHANCEMENT("FastDrops"),
CVAR_ENHANCEMENT("BetterOwl"),
CVAR_ENHANCEMENT("FastOcarinaPlayback"),
CVAR_ENHANCEMENT("InstantPutaway"),
CVAR_ENHANCEMENT("FastBoomerang"),
CVAR_ENHANCEMENT("AskToEquip"),
CVAR_ENHANCEMENT("MaskSelect"),
CVAR_ENHANCEMENT("RememberSaveLocation"),
CVAR_ENHANCEMENT("DamageMult"),
CVAR_ENHANCEMENT("FallDamageMult"),
CVAR_ENHANCEMENT("VoidDamageMult"),
CVAR_ENHANCEMENT("BonkDamageMult"),
CVAR_ENHANCEMENT("NoRandomDrops"),
CVAR_ENHANCEMENT("NoHeartDrops"),
CVAR_ENHANCEMENT("EnableBombchuDrops"),
CVAR_ENHANCEMENT("GoronPot"),
CVAR_ENHANCEMENT("FullHealthSpawn"),
CVAR_ENHANCEMENT("DampeWin"),
CVAR_ENHANCEMENT("CustomizeFishing"),
CVAR_ENHANCEMENT("InstantFishing"),
CVAR_ENHANCEMENT("GuaranteeFishingBite"),
CVAR_ENHANCEMENT("FishNeverEscape"),
CVAR_ENHANCEMENT("MinimumFishWeightChild"),
CVAR_ENHANCEMENT("MinimumFishWeightAdult"),
CVAR_ENHANCEMENT("LowHpAlarm"),
CVAR_ENHANCEMENT("MinimalUI"),
CVAR_ENHANCEMENT("DisableNaviCallAudio"),
CVAR_ENHANCEMENT("VisualAgony"),
CVAR_ENHANCEMENT("AssignableTunicsAndBoots"),
CVAR_ENHANCEMENT("EquipmentCanBeRemoved"),
CVAR_ENHANCEMENT("CowOfTime"),
CVAR_ENHANCEMENT("GuardVision"),
CVAR_ENHANCEMENT("TimeFlowFileSelect"),
CVAR_ENHANCEMENT("InjectItemCounts.GoldSkulltula"),
CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"),
CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"),
CVAR_ENHANCEMENT("DayGravePull"),
CVAR_ENHANCEMENT("DampeAllNight"),
CVAR_ENHANCEMENT("QuitFishingAtDoor"),
CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"),
CVAR_ENHANCEMENT("InstantScarecrow"),
CVAR_ENHANCEMENT("BlueFireArrows"),
CVAR_ENHANCEMENT("SunlightArrows"),
CVAR_ENHANCEMENT("MinFrameCount"),
CVAR_ENHANCEMENT("NewDrops"),
CVAR_ENHANCEMENT("DisableBlackBars"),
CVAR_ENHANCEMENT("DynamicWalletIcon"),
CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"),
CVAR_ENHANCEMENT("FixMenuLR"),
CVAR_ENHANCEMENT("NGCKaleidoSwitcher"),
CVAR_ENHANCEMENT("FixDungeonMinimapIcon"),
CVAR_ENHANCEMENT("TwoHandedIdle"),
CVAR_ENHANCEMENT("GravediggingTourFix"),
CVAR_ENHANCEMENT("DekuNutUpgradeFix"),
CVAR_ENHANCEMENT("NaviTextFix"),
CVAR_ENHANCEMENT("AnubisFix"),
CVAR_ENHANCEMENT("CrouchStabHammerFix"),
CVAR_ENHANCEMENT("CrouchStabFix"),
CVAR_ENHANCEMENT("GerudoWarriorClothingFix"),
CVAR_ENHANCEMENT("FixCameraDrift"),
CVAR_ENHANCEMENT("FixCameraSwing"),
CVAR_ENHANCEMENT("FixHangingLedgeSwingRate"),
CVAR_ENHANCEMENT("RedGanonBlood"),
CVAR_ENHANCEMENT("HoverFishing"),
CVAR_ENHANCEMENT("N64WeirdFrames"),
CVAR_ENHANCEMENT("BombchusOOB"),
CVAR_ENHANCEMENT("QuickPutaway"),
CVAR_ENHANCEMENT("GSCutscene"),
CVAR_ENHANCEMENT("RestoreRBAValues"),
CVAR_ENHANCEMENT("SkipSaveConfirmation"),
CVAR_ENHANCEMENT("DisableCritWiggle"),
CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"),
CVAR_ENHANCEMENT("SkipArrowAnimation"),
CVAR_ENHANCEMENT("SeparateArrows"),
CVAR_ENHANCEMENT("CustomizeShootingGallery"),
CVAR_ENHANCEMENT("InstantShootingGalleryWin"),
CVAR_ENHANCEMENT("ConstantAdultGallery"),
CVAR_ENHANCEMENT("ShootingGalleryAmmoChild"),
CVAR_ENHANCEMENT("ShootingGalleryAmmoAdult"),
CVAR_ENHANCEMENT("CustomizeBombchuBowling"),
CVAR_ENHANCEMENT("BombchuBowlingNoSmallCucco"),
CVAR_ENHANCEMENT("BombchuBowlingNoBigCucco"),
CVAR_ENHANCEMENT("BombchuBowlingAmmo"),
CVAR_ENHANCEMENT("CustomizeOcarinaGame"),
CVAR_ENHANCEMENT("InstantOcarinaGameWin"),
CVAR_ENHANCEMENT("OcarinaGame.NoteSpeed"),
CVAR_ENHANCEMENT("OcarinaUnlimitedFailTime"),
CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"),
CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes"),
CVAR_ENHANCEMENT("OcarinaGame.RoundTwoNotes"),
CVAR_ENHANCEMENT("OcarinaGame.RoundThreeNotes"),
CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"),
CVAR_ENHANCEMENT("InstantFrogsGameWin"),
CVAR_ENHANCEMENT("FrogsUnlimitedFailTime"),
CVAR_ENHANCEMENT("FrogsModifyFailTime"),
CVAR_ENHANCEMENT("CreditsFix"),
CVAR_ENHANCEMENT("SilverRupeeJingleExtend"),
CVAR_ENHANCEMENT("StaticExplosionRadius"),
CVAR_ENHANCEMENT("NoInputForCredits"),
CVAR_ENHANCEMENT("FastFarores"),
CVAR_ENHANCEMENT("NightGSAlwaysSpawn"),
CVAR_ENHANCEMENT("SkipText"),
CVAR_ENHANCEMENT("LinkDefaultName"),
CVAR_ENHANCEMENT("MarketSneak"),
CVAR_ENHANCEMENT("TimeTravel"),
CVAR_ENHANCEMENT("NutsExplodeBombs"),
CVAR_ENHANCEMENT("BowSlingshotAmmoFix"),
CVAR_ENHANCEMENT("BetterFarore"),
CVAR_ENHANCEMENT("DisableFirstPersonChus"),
CVAR_ENHANCEMENT("BetterBombchuShopping"),
CVAR_ENHANCEMENT("HyperBosses"),
CVAR_ENHANCEMENT("RupeeDash"),
CVAR_ENHANCEMENT("RupeeDashInterval"),
CVAR_ENHANCEMENT("DogFollowsEverywhere"),
CVAR_ENHANCEMENT("DisableTunicWarningText"),
CVAR_ENHANCEMENT("DisableLOD"),
CVAR_ENHANCEMENT("DisableDrawDistance"),
CVAR_ENHANCEMENT("DisableKokiriDrawDistance"),
CVAR_ENHANCEMENT("WidescreenActorCulling"),
CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"),
CVAR_LOW_RES_MODE,
CVAR_ENHANCEMENT("DrawLineupTick"),
CVAR_ENHANCEMENT("QuickBongoKill"),
CVAR_ENHANCEMENT("FirstPersonGauntlets"),
CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"),
CVAR_Z_FIGHTING_MODE,
CVAR_ENHANCEMENT("AuthenticLogo"),
CVAR_ENHANCEMENT("BowReticle"),
CVAR_ENHANCEMENT("BoomerangFirstPerson"),
CVAR_ENHANCEMENT("BoomerangReticle"),
CVAR_ENHANCEMENT("FixTexturesOOB"),
CVAR_ENHANCEMENT("IvanCoopModeEnabled"),
CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"),
CVAR_ENHANCEMENT("TreesDropSticks"),
CVAR_ENHANCEMENT("ShadowTag"),
CVAR_ENHANCEMENT("RandomizedEnemySizes"),
CVAR_ENHANCEMENT("RandomizedEnemies"),
CVAR_ENHANCEMENT("MirroredWorldMode"),
CVAR_ENHANCEMENT("MirroredWorld"),
CVAR_ENHANCEMENT("HyperEnemies"),
CVAR_ENHANCEMENT("HookshotableReticle"),
CVAR_ENHANCEMENT("HideBunnyHood"),
CVAR_ENHANCEMENT("FixVineFall"),
CVAR_ENHANCEMENT("FileSelectMoreInfo"),
CVAR_ENHANCEMENT("EnemyHealthBar"),
CVAR_ENHANCEMENT("BushDropFix"),
CVAR_ENHANCEMENT("AllDogsRichard"),
CVAR_ENHANCEMENT("ExtraTraps.Enabled"),
CVAR_ENHANCEMENT("ExtraTraps.Ammo"),
CVAR_ENHANCEMENT("ExtraTraps.Bomb"),
CVAR_ENHANCEMENT("ExtraTraps.Burn"),
CVAR_ENHANCEMENT("ExtraTraps.Ice"),
CVAR_ENHANCEMENT("ExtraTraps.Kill"),
CVAR_ENHANCEMENT("ExtraTraps.Knockback"),
CVAR_ENHANCEMENT("ExtraTraps.Shock"),
CVAR_ENHANCEMENT("ExtraTraps.Speed"),
CVAR_ENHANCEMENT("ExtraTraps.Teleport"),
CVAR_ENHANCEMENT("ExtraTraps.Void"),
CVAR_ENHANCEMENT("ToTMedallionsColors"),
CVAR_ENHANCEMENT("CuccoStayDurationMult"),
CVAR_ENHANCEMENT("DeleteFileOnDeath"),
CVAR_ENHANCEMENT("EnemySizeScalesHealth"),
CVAR_ENHANCEMENT("BetterAmmoRendering"),
CVAR_ENHANCEMENT("EquipmentAlwaysVisible"),
CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"),
CVAR_ENHANCEMENT("OpenAllHours"),
CVAR_ENHANCEMENT("ResetNaviTimer"),
CVAR_ENHANCEMENT("ScaleAdultEquipmentAsChild"),
CVAR_ENHANCEMENT("LeeverSpawnRate"),
CVAR_ENHANCEMENT("SwordToggle"),
CVAR_ENHANCEMENT("FixFloorSwitches"),
CVAR_ENHANCEMENT("FixZoraHintDialogue"),
CVAR_ENHANCEMENT("HurtContainer"),
CVAR_ENHANCEMENT("PauseWarp"),
CVAR_ENHANCEMENT("PermanentHeartLoss"),
CVAR_ENHANCEMENT("RemoveExplosiveLimit"),
CVAR_ENHANCEMENT("ToggleStrength"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"),
CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"),
CVAR_ENHANCEMENT("TimeSavers.NoForcedDialog"),
CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"),
CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"),
CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"),
CVAR_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"),
CVAR_ENHANCEMENT("TimeSavers.SkipChildStealth"),
CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"),
CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog"),
CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"),
CVAR_ENHANCEMENT("SlowTextSpeed"),
};
const std::vector<const char*> cheatCvars = {
CVAR_CONSOLE_WINDOW_OPEN,
CVAR_WINDOW("ActorViewer"),
CVAR_WINDOW("CollisionViewer"),
CVAR_WINDOW("DLViewer"),
CVAR_WINDOW("SaveEditor"),
CVAR_SETTING("WalkModifier.Enabled"),
CVAR_SETTING("WalkModifier.SpeedToggle"),
CVAR_SETTING("WalkModifier.Mapping1"),
CVAR_SETTING("WalkModifier.Mapping2"),
CVAR_SETTING("WalkModifier.SwimMapping1"),
CVAR_SETTING("WalkModifier.SwimMapping2"),
CVAR_ENHANCEMENT("GoronPot"),
CVAR_ENHANCEMENT("DampeWin"),
CVAR_ENHANCEMENT("CustomizeShootingGallery"),
CVAR_ENHANCEMENT("CustomizeBombchuBowling"),
CVAR_ENHANCEMENT("CustomizeFishing"),
CVAR_CHEAT("InfiniteAmmo"),
CVAR_CHEAT("InfiniteEponaBoost"),
CVAR_CHEAT("InfiniteHealth"),
CVAR_CHEAT("InfiniteMagic"),
CVAR_CHEAT("InfiniteMoney"),
CVAR_CHEAT("InfiniteNayru"),
CVAR_CHEAT("NoClip"),
CVAR_CHEAT("ClimbEverything"),
CVAR_CHEAT("HookshotEverything"),
CVAR_CHEAT("HookshotReachMultiplier"),
CVAR_CHEAT("MoonJumpOnL"),
CVAR_CHEAT("SuperTunic"),
CVAR_CHEAT("EasyISG"),
CVAR_CHEAT("EasyQPA"),
CVAR_CHEAT("TimelessEquipment"),
CVAR_CHEAT("NoRestrictItems"),
CVAR_CHEAT("FreezeTime"),
CVAR_GENERAL("PrevTime"),
CVAR_CHEAT("DropsDontDie"),
CVAR_CHEAT("FireproofDekuShield"),
CVAR_CHEAT("ShieldTwoHanded"),
CVAR_CHEAT("TimeSync"),
CVAR_DEVELOPER_TOOLS("DebugEnabled"),
CVAR_DEVELOPER_TOOLS("SkulltulaDebugEnabled"),
CVAR_DEVELOPER_TOOLS("SkipLogoTitle"),
CVAR_DEVELOPER_TOOLS("SaveFileID"),
CVAR_CHEAT("EnableBetaQuest"),
CVAR_DEVELOPER_TOOLS("BetterDebugWarpScreen"),
CVAR_CHEAT("NoRedeadFreeze"),
CVAR_CHEAT("NoKeeseGuayTarget"),
CVAR_CHEAT("BombTimerMultiplier"),
CVAR_CHEAT("NoFishDespawn"),
CVAR_CHEAT("NoBugsDespawn"),
CVAR_SETTING("WalkModifier.DoesntChangeJump"),
CVAR_STATS_WINDOW_OPEN,
CVAR_CHEAT("SaveStatesEnabled"),
CVAR_CHEAT("SaveStatePromise"),
CVAR_DEVELOPER_TOOLS("RegEditEnabled"),
CVAR_CHEAT("DekuStick"),
CVAR_DEVELOPER_TOOLS("DebugWarpScreenTranslation"),
CVAR_DEVELOPER_TOOLS("DebugSaveFileMode"),
CVAR_COSMETIC("Link.BodyScale.Changed"),
CVAR_COSMETIC("Link.BodyScale.Value"),
CVAR_COSMETIC("Link.HeadScale.Changed"),
CVAR_COSMETIC("Link.HeadScale.Value"),
CVAR_COSMETIC("Link.SwordScale.Changed"),
CVAR_COSMETIC("Link.SwordScale.Value"),
CVAR_ENHANCEMENT("RememberMapToggleState"),
};
const std::vector<const char*> randomizerCvars = {
CVAR_RANDOMIZER_ENHANCEMENT("MatchKeyColors"),
CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"),
CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"),
CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"),
CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"),
CVAR_RANDOMIZER_SETTING("100GSHint"),
CVAR_RANDOMIZER_SETTING("10GSHint"),
CVAR_RANDOMIZER_SETTING("20GSHint"),
CVAR_RANDOMIZER_SETTING("30GSHint"),
CVAR_RANDOMIZER_SETTING("40GSHint"),
CVAR_RANDOMIZER_SETTING("50GSHint"),
CVAR_RANDOMIZER_SETTING("AllLocationsReachable"),
CVAR_RANDOMIZER_SETTING("AltarHint"),
CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"),
CVAR_RANDOMIZER_SETTING("BigPoesHint"),
CVAR_RANDOMIZER_SETTING("BiggoronHint"),
CVAR_RANDOMIZER_SETTING("BlueFireArrows"),
CVAR_RANDOMIZER_SETTING("BombchuBag"),
CVAR_RANDOMIZER_SETTING("BossKeysanity"),
CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"),
CVAR_RANDOMIZER_SETTING("ChickensHint"),
CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"),
CVAR_RANDOMIZER_SETTING("CuccosToReturn"),
CVAR_RANDOMIZER_SETTING("DampeHint"),
CVAR_RANDOMIZER_SETTING("DecoupleEntrances"),
CVAR_RANDOMIZER_SETTING("DoorOfTime"),
CVAR_RANDOMIZER_SETTING("DungeonCount"),
CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"),
CVAR_RANDOMIZER_SETTING("FishingPoleHint"),
CVAR_RANDOMIZER_SETTING("Fishsanity"),
CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"),
CVAR_RANDOMIZER_SETTING("FishsanityPondCount"),
CVAR_RANDOMIZER_SETTING("ClosedForest"),
CVAR_RANDOMIZER_SETTING("FrogsHint"),
CVAR_RANDOMIZER_SETTING("FullWallets"),
CVAR_RANDOMIZER_SETTING("GanonTrial"),
CVAR_RANDOMIZER_SETTING("GanonTrialCount"),
CVAR_RANDOMIZER_SETTING("GanondorfHint"),
CVAR_RANDOMIZER_SETTING("FortressCarpenters"),
CVAR_RANDOMIZER_SETTING("GerudoKeys"),
CVAR_RANDOMIZER_SETTING("GossipStoneHints"),
CVAR_RANDOMIZER_SETTING("GregHint"),
CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"),
CVAR_RANDOMIZER_SETTING("HBAHint"),
CVAR_RANDOMIZER_SETTING("HintClarity"),
CVAR_RANDOMIZER_SETTING("HintDistribution"),
CVAR_RANDOMIZER_SETTING("IceTraps"),
CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"),
CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"),
CVAR_RANDOMIZER_SETTING("ItemPool"),
CVAR_RANDOMIZER_SETTING("KakarikoGate"),
CVAR_RANDOMIZER_SETTING("Keysanity"),
CVAR_RANDOMIZER_SETTING("LacsDungeonCount"),
CVAR_RANDOMIZER_SETTING("LacsMedallionCount"),
CVAR_RANDOMIZER_SETTING("LacsRewardCount"),
CVAR_RANDOMIZER_SETTING("LacsRewardOptions"),
CVAR_RANDOMIZER_SETTING("LacsStoneCount"),
CVAR_RANDOMIZER_SETTING("LacsTokenCount"),
CVAR_RANDOMIZER_SETTING("LinksPocket"),
CVAR_RANDOMIZER_SETTING("LoachHint"),
CVAR_RANDOMIZER_SETTING("LogicRules"),
CVAR_RANDOMIZER_SETTING("MQDungeonCount"),
CVAR_RANDOMIZER_SETTING("MQDungeons"),
CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"),
CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"),
CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"),
CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"),
CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"),
CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"),
CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"),
CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"),
CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"),
CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"),
CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"),
CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"),
CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"),
CVAR_RANDOMIZER_SETTING("MalonHint"),
CVAR_RANDOMIZER_SETTING("MaskShopHint"),
CVAR_RANDOMIZER_SETTING("MedallionCount"),
CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"),
CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"),
CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"),
CVAR_RANDOMIZER_SETTING("MerchantPrices"),
CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"),
CVAR_RANDOMIZER_SETTING("MerchantText"),
CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"),
CVAR_RANDOMIZER_SETTING("MixBosses"),
CVAR_RANDOMIZER_SETTING("MixDungeons"),
CVAR_RANDOMIZER_SETTING("MixGrottos"),
CVAR_RANDOMIZER_SETTING("MixInteriors"),
CVAR_RANDOMIZER_SETTING("MixOverworld"),
CVAR_RANDOMIZER_SETTING("MixedEntrances"),
CVAR_RANDOMIZER_SETTING("OoTHint"),
CVAR_RANDOMIZER_SETTING("RainbowBridge"),
CVAR_RANDOMIZER_SETTING("RewardCount"),
CVAR_RANDOMIZER_SETTING("SariaHint"),
CVAR_RANDOMIZER_SETTING("ScrubText"),
CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"),
CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"),
CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"),
CVAR_RANDOMIZER_SETTING("ScrubsPrices"),
CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"),
CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"),
CVAR_RANDOMIZER_SETTING("SheikLAHint"),
CVAR_RANDOMIZER_SETTING("Shopsanity"),
CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityCount"),
CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"),
CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"),
CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"),
CVAR_RANDOMIZER_SETTING("ShopsanityPrices"),
CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"),
CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"),
CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"),
CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"),
CVAR_RANDOMIZER_SETTING("ShuffleBeehives"),
CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"),
CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"),
CVAR_RANDOMIZER_SETTING("ShuffleCows"),
CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"),
CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"),
CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"),
CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"),
CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"),
CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"),
CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"),
CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"),
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"),
CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"),
CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"),
CVAR_RANDOMIZER_SETTING("ShuffleMerchants"),
CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"),
CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"),
CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"),
CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"),
CVAR_RANDOMIZER_SETTING("ShuffleScrubs"),
CVAR_RANDOMIZER_SETTING("ShuffleSongs"),
CVAR_RANDOMIZER_SETTING("ShuffleSwim"),
CVAR_RANDOMIZER_SETTING("ShuffleTokens"),
CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"),
CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"),
CVAR_RANDOMIZER_SETTING("SkeletonKey"),
CVAR_RANDOMIZER_SETTING("SkipChildStealth"),
CVAR_RANDOMIZER_SETTING("SkipChildZelda"),
CVAR_RANDOMIZER_SETTING("SkipEponaRace"),
CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"),
CVAR_RANDOMIZER_SETTING("SleepingWaterfall"),
CVAR_RANDOMIZER_SETTING("StartingAge"),
CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"),
CVAR_RANDOMIZER_SETTING("StartingConsumables"),
CVAR_RANDOMIZER_SETTING("StartingDekuShield"),
CVAR_RANDOMIZER_SETTING("StartingEponasSong"),
CVAR_RANDOMIZER_SETTING("StartingHearts"),
CVAR_RANDOMIZER_SETTING("StartingKokiriSword"),
CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"),
CVAR_RANDOMIZER_SETTING("StartingMasterSword"),
CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"),
CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"),
CVAR_RANDOMIZER_SETTING("StartingOcarina"),
CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"),
CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"),
CVAR_RANDOMIZER_SETTING("StartingSariasSong"),
CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"),
CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"),
CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"),
CVAR_RANDOMIZER_SETTING("StartingSongOfTime"),
CVAR_RANDOMIZER_SETTING("StartingSunsSong"),
CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"),
CVAR_RANDOMIZER_SETTING("StoneCount"),
CVAR_RANDOMIZER_SETTING("SunlightArrows"),
CVAR_RANDOMIZER_SETTING("TokenCount"),
CVAR_RANDOMIZER_SETTING("TriforceHunt"),
CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"),
CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"),
CVAR_RANDOMIZER_SETTING("WarpSongText"),
CVAR_RANDOMIZER_SETTING("ZorasFountain"),
};
const std::vector<PresetEntry> vanillaPlusPresetEntries = { const std::vector<PresetEntry> vanillaPlusPresetEntries = {
// D-pad Support in text and file select // D-pad Support in text and file select
PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1), PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1),
@ -1325,12 +832,12 @@ typedef struct PresetDefinition {
} PresetDefinition; } PresetDefinition;
typedef struct PresetTypeDefinition { typedef struct PresetTypeDefinition {
std::vector<const char*> cvarsToClear; std::vector<const char*> blocksToClear;
std::map<uint16_t, PresetDefinition> presets; std::map<uint16_t, PresetDefinition> presets;
} PresetTypeDefinition; } PresetTypeDefinition;
const std::map<PresetType, PresetTypeDefinition> presetTypes = { const std::map<PresetType, PresetTypeDefinition> presetTypes = {
{ PRESET_TYPE_ENHANCEMENTS, { enhancementsCvars, { { PRESET_TYPE_ENHANCEMENTS, { { CVAR_PREFIX_ENHANCEMENT, CVAR_PREFIX_CHEAT }, {
{ ENHANCEMENT_PRESET_DEFAULT, { { ENHANCEMENT_PRESET_DEFAULT, {
"Default", "Default",
"Reset all options to their default values.", "Reset all options to their default values.",
@ -1352,7 +859,7 @@ const std::map<PresetType, PresetTypeDefinition> presetTypes = {
randomizerPresetEntries randomizerPresetEntries
} }, } },
} } }, } } },
{ PRESET_TYPE_RANDOMIZER, { randomizerCvars, { { PRESET_TYPE_RANDOMIZER, { { CVAR_PREFIX_RANDOMIZER_SETTING, CVAR_PREFIX_RANDOMIZER_ENHANCEMENT }, {
{ RANDOMIZER_PRESET_DEFAULT, { { RANDOMIZER_PRESET_DEFAULT, {
"Default", "Default",
"Reset all options to their default values.", "Reset all options to their default values.",

View file

@ -65,10 +65,6 @@ void GenerateStartingInventory() {
AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD); AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD);
} }
if (ctx->GetOption(RSK_SKIP_CHILD_ZELDA)) {
AddItemToInventory(RG_ZELDAS_LETTER);
}
//Starting Inventory Menu //Starting Inventory Menu
//Values are associated so that the count of items matches the index of //Values are associated so that the count of items matches the index of
//the option selected. If None is selected, the value will be zero and //the option selected. If None is selected, the value will be zero and

View file

@ -0,0 +1,74 @@
#include <soh/OTRGlobals.h>
#include "static_data.h"
extern "C" {
#include "src/overlays/actors/ovl_En_Cow/z_en_cow.h"
extern PlayState* gPlayState;
}
void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) {
bool moved = false;
// Don't reposition the tail
if (enCow->actor.params != 0) {
return;
}
if (play->sceneNum == SCENE_LON_LON_BUILDINGS && enCow->actor.world.pos.x == -108 &&
enCow->actor.world.pos.z == -65) {
// Move left cow in lon lon tower
enCow->actor.world.pos.x = -229.0f;
enCow->actor.world.pos.z = 157.0f;
enCow->actor.shape.rot.y = 15783.0f;
moved = true;
} else if (play->sceneNum == SCENE_STABLE && enCow->actor.world.pos.x == -3 && enCow->actor.world.pos.z == -254) {
// Move right cow in lon lon stable
enCow->actor.world.pos.x += 119.0f;
moved = true;
}
if (moved) {
// Reposition collider
func_809DEE9C(enCow);
}
}
void RegisterShuffleCows() {
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_COWS).Get();
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, {
EnCow* enCow = va_arg(args, EnCow*);
CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z);
// Has this cow already rewarded an item?
if (!Flags_GetRandomizerInf(cowIdentity.randomizerInf)) {
Flags_SetRandomizerInf(cowIdentity.randomizerInf);
// setting the ocarina mode here prevents intermittent issues
// with the item get not triggering until walking away
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_00;
*should = false;
}
});
COND_VB_SHOULD(VB_DESPAWN_HORSE_RACE_COW, shouldRegister, {
EnCow* enCow = va_arg(args, EnCow*);
// If this is a cow we have to move, then move it now.
EnCow_MoveForRandomizer(enCow, gPlayState);
});
}
static RegisterShipInitFunc initFunc(RegisterShuffleCows, { "IS_RANDO" });
void Rando::StaticData::RegisterCowLocations() {
locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW));
locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW));
locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW));
locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW));
locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW));
locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW));
locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW));
locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW));
locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW));
locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW));
}
static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterCowLocations);

View file

@ -0,0 +1,51 @@
#include "functions.h"
#include "variables.h"
#include "macros.h"
u8 Randomizer_GetNextChildTradeItem() {
const u8 numTradeItems = ITEM_MASK_TRUTH - ITEM_WEIRD_EGG + 1;
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_CHILD) - ITEM_WEIRD_EGG;
for (int i = 0; i < numTradeItems; i++) {
u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems;
if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG)) {
return ITEM_WEIRD_EGG + tradeIndex;
}
}
return ITEM_NONE;
}
u8 Randomizer_GetPrevChildTradeItem() {
const u8 numTradeItems = ITEM_MASK_TRUTH - ITEM_WEIRD_EGG + 1;
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_CHILD) - ITEM_WEIRD_EGG;
for (int i = 0; i < numTradeItems; i++) {
u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems;
if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG)) {
return ITEM_WEIRD_EGG + tradeIndex;
}
}
return ITEM_NONE;
}
u8 Randomizer_GetNextAdultTradeItem() {
const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1;
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
for (int i = 0; i < numTradeItems; i++) {
u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems;
if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) {
return ITEM_POCKET_EGG + tradeIndex;
}
}
return ITEM_NONE;
}
u8 Randomizer_GetPrevAdultTradeItem() {
const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1;
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
for (int i = 0; i < numTradeItems; i++) {
u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems;
if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) {
return ITEM_POCKET_EGG + tradeIndex;
}
}
return ITEM_NONE;
}

View file

@ -0,0 +1,11 @@
#ifndef Z_ADULT_TRADE_SHUFFLE_H
#define Z_ADULT_TRADE_SHUFFLE_H
#include <libultraship/libultra/types.h>
u8 Randomizer_GetNextChildTradeItem();
u8 Randomizer_GetPrevChildTradeItem();
u8 Randomizer_GetNextAdultTradeItem();
u8 Randomizer_GetPrevAdultTradeItem();
#endif

View file

@ -1,33 +0,0 @@
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "functions.h"
#include "variables.h"
#include "macros.h"
void Randomizer_ConsumeAdultTradeItem(PlayState* play, u8 itemId) {
gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~ADULT_TRADE_FLAG(itemId);
Inventory_ReplaceItem(play, itemId, Randomizer_GetNextAdultTradeItem());
}
u8 Randomizer_GetNextAdultTradeItem() {
const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1;
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
for (int i = 0; i < numTradeItems; i++) {
u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems;
if (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) {
return ITEM_POCKET_EGG + tradeIndex;
}
}
return ITEM_NONE;
}
u8 Randomizer_GetPrevAdultTradeItem() {
const u8 numTradeItems = ITEM_CLAIM_CHECK - ITEM_POCKET_EGG + 1;
u8 currentTradeItemIndex = INV_CONTENT(ITEM_TRADE_ADULT) - ITEM_POCKET_EGG;
for (int i = 0; i < numTradeItems; i++) {
u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems;
if (gSaveContext.ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex)) {
return ITEM_POCKET_EGG + tradeIndex;
}
}
return ITEM_NONE;
}

View file

@ -1,13 +0,0 @@
#ifndef Z_ADULT_TRADE_SHUFFLE_H
#define Z_ADULT_TRADE_SHUFFLE_H
#include <z64.h>
#define ADULT_TRADE_FLAG(itemId) (1 << (itemId - ITEM_POCKET_EGG))
#define PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(itemID) (IS_RANDO && gSaveContext.ship.quest.data.randomizer.adultTradeItems & ADULT_TRADE_FLAG(itemID))
void Randomizer_ConsumeAdultTradeItem(PlayState* play, u8 itemId);
u8 Randomizer_GetNextAdultTradeItem();
u8 Randomizer_GetPrevAdultTradeItem();
#endif

View file

@ -21,12 +21,11 @@ extern "C" {
#include "macros.h" #include "macros.h"
#include "functions.h" #include "functions.h"
#include "variables.h" #include "variables.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/Enhancements/randomizer/ShuffleTradeItems.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h"
#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_Si/z_en_si.h" #include "src/overlays/actors/ovl_En_Si/z_en_si.h"
#include "src/overlays/actors/ovl_En_Cow/z_en_cow.h"
#include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h" #include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h"
#include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" #include "src/overlays/actors/ovl_En_Dns/z_en_dns.h"
#include "src/overlays/actors/ovl_En_Gb/z_en_gb.h" #include "src/overlays/actors/ovl_En_Gb/z_en_gb.h"
@ -56,7 +55,6 @@ extern "C" {
#include "src/overlays/actors/ovl_En_Xc/z_en_xc.h" #include "src/overlays/actors/ovl_En_Xc/z_en_xc.h"
#include "src/overlays/actors/ovl_Fishing/z_fishing.h" #include "src/overlays/actors/ovl_Fishing/z_fishing.h"
#include "src/overlays/actors/ovl_En_Mk/z_en_mk.h" #include "src/overlays/actors/ovl_En_Mk/z_en_mk.h"
#include "adult_trade_shuffle.h"
#include "draw.h" #include "draw.h"
extern SaveContext gSaveContext; extern SaveContext gSaveContext;
@ -220,14 +218,21 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) {
if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && flagType == FLAG_RANDOMIZER_INF) { if (RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && flagType == FLAG_RANDOMIZER_INF) {
switch (flag) { switch (flag) {
case RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD: case RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD:
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SWORD_BROKEN); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN);
Inventory_ReplaceItem(gPlayState, ITEM_SWORD_BROKEN, Randomizer_GetNextAdultTradeItem());
break; break;
case RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS: case RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS:
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_EYEDROPS); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_EYEDROPS);
Inventory_ReplaceItem(gPlayState, ITEM_EYEDROPS, Randomizer_GetNextAdultTradeItem());
break; break;
} }
} }
if (flagType == FLAG_EVENT_CHECK_INF && flag == EVENTCHKINF_TALON_WOKEN_IN_CASTLE) {
//remove chicken as this is the only use for it
Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_CHICKEN);
}
RandomizerCheck rc = GetRandomizerCheckFromFlag(flagType, flag); RandomizerCheck rc = GetRandomizerCheckFromFlag(flagType, flag);
if (rc == RC_UNKNOWN_CHECK) return; if (rc == RC_UNKNOWN_CHECK) return;
@ -513,33 +518,6 @@ void ItemEtcetera_UpdateRandomizedFireArrow(ItemEtcetera* itemEtcetera, PlayStat
} }
} }
void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) {
bool moved = false;
// Don't reposition the tail
if (enCow->actor.params != 0) {
return;
}
// Move left cow in lon lon tower
if (play->sceneNum == SCENE_LON_LON_BUILDINGS && enCow->actor.world.pos.x == -108 &&
enCow->actor.world.pos.z == -65) {
enCow->actor.world.pos.x = -229.0f;
enCow->actor.world.pos.z = 157.0f;
enCow->actor.shape.rot.y = 15783.0f;
moved = true;
// Move right cow in lon lon stable
} else if (play->sceneNum == SCENE_STABLE && enCow->actor.world.pos.x == -3 && enCow->actor.world.pos.z == -254) {
enCow->actor.world.pos.x += 119.0f;
moved = true;
}
if (moved) {
// Reposition collider
func_809DEE9C(enCow);
}
}
u8 EnDs_RandoCanGetGrannyItem() { u8 EnDs_RandoCanGetGrannyItem() {
return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS || return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS ||
RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) && RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) &&
@ -1061,23 +1039,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
*should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SARIAS_SONG); *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SARIAS_SONG);
break; break;
} }
case VB_GIVE_ITEM_FROM_COW: {
if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) {
break;
}
EnCow* enCow = va_arg(args, EnCow*);
CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z);
// Has this cow already rewarded an item?
if (Flags_GetRandomizerInf(cowIdentity.randomizerInf)) {
break;
}
Flags_SetRandomizerInf(cowIdentity.randomizerInf);
// setting the ocarina mode here prevents intermittent issues
// with the item get not triggering until walking away
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_00;
*should = false;
break;
}
case VB_GIVE_ITEM_FROM_GRANNYS_SHOP: { case VB_GIVE_ITEM_FROM_GRANNYS_SHOP: {
if (!EnDs_RandoCanGetGrannyItem()) { if (!EnDs_RandoCanGetGrannyItem()) {
break; break;
@ -1188,7 +1149,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
} }
case VB_TRADE_POCKET_CUCCO: { case VB_TRADE_POCKET_CUCCO: {
EnNiwLady* enNiwLady = va_arg(args, EnNiwLady*); EnNiwLady* enNiwLady = va_arg(args, EnNiwLady*);
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_POCKET_CUCCO); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO);
Inventory_ReplaceItem(gPlayState, ITEM_POCKET_CUCCO, Randomizer_GetNextAdultTradeItem());
// Trigger the reward now // Trigger the reward now
Flags_SetItemGetInf(ITEMGETINF_2E); Flags_SetItemGetInf(ITEMGETINF_2E);
enNiwLady->actionFunc = func_80ABA778; enNiwLady->actionFunc = func_80ABA778;
@ -1197,13 +1159,15 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break; break;
} }
case VB_TRADE_COJIRO: { case VB_TRADE_COJIRO: {
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_COJIRO); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO);
Inventory_ReplaceItem(gPlayState, ITEM_COJIRO, Randomizer_GetNextAdultTradeItem());
*should = false; *should = false;
break; break;
} }
case VB_TRADE_ODD_MUSHROOM: { case VB_TRADE_ODD_MUSHROOM: {
EnDs* granny = va_arg(args, EnDs*); EnDs* granny = va_arg(args, EnDs*);
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_MUSHROOM); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM);
Inventory_ReplaceItem(gPlayState, ITEM_ODD_MUSHROOM, Randomizer_GetNextAdultTradeItem());
// Trigger the reward now // Trigger the reward now
Flags_SetItemGetInf(ITEMGETINF_30); Flags_SetItemGetInf(ITEMGETINF_30);
granny->actor.textId = 0x504F; granny->actor.textId = 0x504F;
@ -1214,14 +1178,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
} }
case VB_TRADE_ODD_POTION: { case VB_TRADE_ODD_POTION: {
EnKo* enKo = va_arg(args, EnKo*); EnKo* enKo = va_arg(args, EnKo*);
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_POTION); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_POTION);
Inventory_ReplaceItem(gPlayState, ITEM_ODD_POTION, Randomizer_GetNextAdultTradeItem());
// Trigger the reward now // Trigger the reward now
Flags_SetItemGetInf(ITEMGETINF_31); Flags_SetItemGetInf(ITEMGETINF_31);
*should = false; *should = false;
break; break;
} }
case VB_TRADE_SAW: { case VB_TRADE_SAW: {
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_SAW); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_SAW);
Inventory_ReplaceItem(gPlayState, ITEM_SAW, Randomizer_GetNextAdultTradeItem());
*should = false; *should = false;
break; break;
} }
@ -1238,14 +1204,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
if (func_8002F368(gPlayState) == EXCH_ITEM_PRESCRIPTION || if (func_8002F368(gPlayState) == EXCH_ITEM_PRESCRIPTION ||
(hasShieldHoldingR && INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_FROG)) { (hasShieldHoldingR && INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_FROG)) {
Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION);
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION);
Inventory_ReplaceItem(gPlayState, ITEM_PRESCRIPTION, Randomizer_GetNextAdultTradeItem());
} else { } else {
Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED);
} }
} else { } else {
if (enKz->isTrading){ if (enKz->isTrading) {
Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION);
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION);
Inventory_ReplaceItem(gPlayState, ITEM_PRESCRIPTION, Randomizer_GetNextAdultTradeItem());
} else { } else {
Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED);
} }
@ -1254,19 +1222,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break; break;
} }
case VB_TRADE_FROG: { case VB_TRADE_FROG: {
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_FROG); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_FROG);
Inventory_ReplaceItem(gPlayState, ITEM_FROG, Randomizer_GetNextAdultTradeItem());
*should = false; *should = false;
break; break;
} }
case VB_DESPAWN_HORSE_RACE_COW: {
if (!RAND_GET_OPTION(RSK_SHUFFLE_COWS)) {
break;
}
EnCow* enCow = va_arg(args, EnCow*);
// If this is a cow we have to move, then move it now.
EnCow_MoveForRandomizer(enCow, gPlayState);
break;
}
case VB_BUSINESS_SCRUB_DESPAWN: { case VB_BUSINESS_SCRUB_DESPAWN: {
EnShopnuts* enShopnuts = va_arg(args, EnShopnuts*); EnShopnuts* enShopnuts = va_arg(args, EnShopnuts*);
s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1);
@ -1291,9 +1251,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
if (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE)) { if (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE)) {
break; break;
} }
if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { if (Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO)) {
*should = false; *should = false;
} else if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION)) { } else if (Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_POTION)) {
*should = true; *should = true;
} else { } else {
*should = Flags_GetItemGetInf(ITEMGETINF_30); // Traded odd mushroom *should = Flags_GetItemGetInf(ITEMGETINF_30); // Traded odd mushroom
@ -1305,10 +1265,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break; break;
} }
if (PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO)) { if (Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO)) {
*should = false; *should = false;
} else { } else {
*should = PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_ODD_POTION); *should = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_ODD_POTION);
} }
break; break;
@ -1650,9 +1610,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
} }
break; break;
} }
case VB_GIVE_ITEM_ZELDAS_LETTER: { case VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER: {
Flags_SetRandomizerInf(RAND_INF_ZELDAS_LETTER); if (*should) {
*should = false; //remove zelda's letter as this is the only use for it
Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA);
}
break; break;
} }
case VB_FREEZE_ON_SKULL_TOKEN: case VB_FREEZE_ON_SKULL_TOKEN:
@ -1671,6 +1633,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
case VB_GIVE_ITEM_WEIRD_EGG: case VB_GIVE_ITEM_WEIRD_EGG:
case VB_GIVE_ITEM_LIGHT_ARROW: case VB_GIVE_ITEM_LIGHT_ARROW:
case VB_GIVE_ITEM_STRENGTH_1: case VB_GIVE_ITEM_STRENGTH_1:
case VB_GIVE_ITEM_ZELDAS_LETTER:
case VB_GIVE_ITEM_OCARINA_OF_TIME: case VB_GIVE_ITEM_OCARINA_OF_TIME:
case VB_GIVE_ITEM_LIGHT_MEDALLION: case VB_GIVE_ITEM_LIGHT_MEDALLION:
case VB_GIVE_ITEM_FOREST_MEDALLION: case VB_GIVE_ITEM_FOREST_MEDALLION:
@ -2352,6 +2315,13 @@ void RandomizerOnKaleidoscopeUpdateHandler(int16_t inDungeonScene) {
prevKaleidoState = gPlayState->pauseCtx.state; prevKaleidoState = gPlayState->pauseCtx.state;
} }
void RandomizerOnCuccoOrChickenHatch() {
if (LINK_IS_CHILD) {
Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_CHICKEN);
}
}
void RandomizerRegisterHooks() { void RandomizerRegisterHooks() {
static uint32_t onFlagSetHook = 0; static uint32_t onFlagSetHook = 0;
static uint32_t onSceneFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0;
@ -2369,6 +2339,7 @@ void RandomizerRegisterHooks() {
static uint32_t onPlayDestroyHook = 0; static uint32_t onPlayDestroyHook = 0;
static uint32_t onExitGameHook = 0; static uint32_t onExitGameHook = 0;
static uint32_t onKaleidoUpdateHook = 0; static uint32_t onKaleidoUpdateHook = 0;
static uint32_t onCuccoOrChickenHatchHook = 0;
static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorInitHook = 0;
static uint32_t fishsanityOnActorUpdateHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0;
@ -2404,6 +2375,7 @@ void RandomizerRegisterHooks() {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnPlayDestroy>(onPlayDestroyHook); GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnPlayDestroy>(onPlayDestroyHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnExitGame>(onExitGameHook); GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnExitGame>(onExitGameHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnKaleidoscopeUpdate>(onKaleidoUpdateHook); GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnKaleidoscopeUpdate>(onKaleidoUpdateHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnCuccoOrChickenHatch>(onCuccoOrChickenHatchHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(fishsanityOnActorInitHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(fishsanityOnActorUpdateHook); GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(fishsanityOnActorUpdateHook);
@ -2432,6 +2404,7 @@ void RandomizerRegisterHooks() {
onPlayDestroyHook = 0; onPlayDestroyHook = 0;
onExitGameHook = 0; onExitGameHook = 0;
onKaleidoUpdateHook = 0; onKaleidoUpdateHook = 0;
onCuccoOrChickenHatchHook = 0;
fishsanityOnActorInitHook = 0; fishsanityOnActorInitHook = 0;
fishsanityOnActorUpdateHook = 0; fishsanityOnActorUpdateHook = 0;
@ -2473,6 +2446,7 @@ void RandomizerRegisterHooks() {
onPlayDestroyHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDestroy>(RandomizerOnPlayDestroyHandler); onPlayDestroyHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDestroy>(RandomizerOnPlayDestroyHandler);
onExitGameHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnExitGame>(RandomizerOnExitGameHandler); onExitGameHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnExitGame>(RandomizerOnExitGameHandler);
onKaleidoUpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnKaleidoscopeUpdate>(RandomizerOnKaleidoscopeUpdateHandler); onKaleidoUpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnKaleidoscopeUpdate>(RandomizerOnKaleidoscopeUpdateHandler);
onCuccoOrChickenHatchHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnCuccoOrChickenHatch>(RandomizerOnCuccoOrChickenHatch);
if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) {
OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave();

View file

@ -350,7 +350,7 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->DekuTreeClear, []{return logic->DekuTreeClear || (logic->HasBossSoul(RG_GOHMA_SOUL) && (logic->CanJumpslashExceptHammer() && (logic->CanUse(RG_NUTS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HookshotOrBoomerang())));}), EventAccess(&logic->DekuTreeClear, []{return logic->DekuTreeClear || logic->CanKillEnemy(RE_GOHMA);}),
}, { }, {
// Locations // Locations
LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear), LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear),

View file

@ -528,7 +528,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernClear || (logic->HasBossSoul(RG_KING_DODONGO_SOUL) && (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanJumpslashExceptHammer())); /*todo add chu kill to tricks*/}), EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernClear || (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && logic->CanKillEnemy(RE_KING_DODONGO)); /*todo add chu kill to tricks*/}),
}, { }, {
// Locations // Locations
LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true),

View file

@ -705,7 +705,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->FireTempleClear, []{return logic->FireTempleClear || (logic->HasBossSoul(RG_VOLVAGIA_SOUL) && (logic->FireTimer() >= 64 && logic->CanUse(RG_MEGATON_HAMMER)));}), EventAccess(&logic->FireTempleClear, []{return logic->FireTempleClear || (logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA));}),
}, { }, {
// Locations // Locations
LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear), LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear),

View file

@ -600,7 +600,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleClear || (logic->HasBossSoul(RG_PHANTOM_GANON_SOUL) && ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))));}), EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleClear || logic->CanKillEnemy(RE_PHANTOM_GANON);}),
}, { }, {
// Locations // Locations
LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear), LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear),

View file

@ -341,7 +341,7 @@ void RegionTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, {
// Events //todo: add pot kill trick // Events //todo: add pot kill trick
EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyClear || (logic->HasBossSoul(RG_BARINADE_SOUL) && (logic->CanUse(RG_BOOMERANG) && logic->CanJumpslashExceptHammer()));}), EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyClear || logic->CanKillEnemy(RE_BARINADE);}),
}, { }, {
// Locations // Locations
LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()),

View file

@ -399,11 +399,7 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->ShadowTempleClear, []{ EventAccess(&logic->ShadowTempleClear, []{return logic->ShadowTempleClear || logic->CanKillEnemy(RE_BONGO_BONGO);}),
return logic->ShadowTempleClear || (logic->HasBossSoul(RG_BONGO_BONGO_SOUL) && ((logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) &&
(logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) &&
(logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO))));
}),
}, { }, {
// Locations // Locations
LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear), LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear),

View file

@ -544,7 +544,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleClear || (logic->HasBossSoul(RG_TWINROVA_SOUL) && (logic->CanUse(RG_MIRROR_SHIELD) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))));}), EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleClear || logic->CanKillEnemy(RE_TWINROVA);}),
}, { }, {
// Locations // Locations
LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear), LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear),

View file

@ -725,7 +725,7 @@ void RegionTable_Init_WaterTemple() {
areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, {
// Events // Events
EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleClear || (logic->HasBossSoul(RG_MORPHA_SOUL) && (logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))));}), EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleClear || logic->CanKillEnemy(RE_MORPHA);}),
}, { }, {
// Locations // Locations
LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear), LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear),

View file

@ -13,10 +13,11 @@ void RegionTable_Init_GerudoValley() {
}, { }, {
//Exits //Exits
Entrance(RR_HYRULE_FIELD, []{return true;}), Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_GV_UPPER_STREAM, []{return true;}), Entrance(RR_GV_UPPER_STREAM, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}),
Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_GV_GROTTO_LEDGE, []{return true;}), Entrance(RR_GV_GROTTO_LEDGE, []{return true;}),
Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_LAKE_HYLIA, []{return logic->IsChild;}), //can use cucco as child
}); });
areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, { areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {
@ -41,11 +42,12 @@ void RegionTable_Init_GerudoValley() {
areaTable[RR_GV_LOWER_STREAM] = Region("GV Lower Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_GV_LOWER_STREAM] = Region("GV Lower Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_LAKE_HYLIA, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE);}),//can use cucco as child Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
}); });
areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}),
Entrance(RR_GV_LOWER_STREAM, []{return true;}), Entrance(RR_GV_LOWER_STREAM, []{return true;}),
Entrance(RR_GV_OCTOROK_GROTTO, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}), Entrance(RR_GV_OCTOROK_GROTTO, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}),
Entrance(RR_GV_CRATE_LEDGE, []{return logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->CanUse(RG_LONGSHOT);}),

View file

@ -39,7 +39,7 @@ void RegionTable_Init_Market() {
EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}), EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}),
}, { }, {
//Locations //Locations
LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->BigPoeKill), LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes > ctx->GetOption(RSK_BIG_POE_COUNT).Get())),
LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild),
LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()),

View file

@ -874,18 +874,6 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO)); locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO));
locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO)); locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO));
// Cows
locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW));
locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW));
locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW));
locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW));
locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW));
locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW));
locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW));
locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW));
locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW));
locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW));
/*------------------------------- /*-------------------------------
--- SHOPS --- --- SHOPS ---
8 6 2 4 8 6 2 4

View file

@ -231,7 +231,7 @@ namespace Rando {
case RG_EYEBALL_FROG: case RG_EYEBALL_FROG:
case RG_EYEDROPS: case RG_EYEDROPS:
case RG_CLAIM_CHECK: case RG_CLAIM_CHECK:
return HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId); return CheckRandoInf(itemName - RG_POCKET_EGG + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG);
case RG_BOTTLE_WITH_BIG_POE: case RG_BOTTLE_WITH_BIG_POE:
case RG_BOTTLE_WITH_BLUE_FIRE: case RG_BOTTLE_WITH_BLUE_FIRE:
case RG_BOTTLE_WITH_BLUE_POTION: case RG_BOTTLE_WITH_BLUE_POTION:
@ -678,6 +678,31 @@ namespace Rando {
case RE_BIG_OCTO: case RE_BIG_OCTO:
//If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigains anyway. Bunny makes it free //If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigains anyway. Bunny makes it free
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD);
case RE_GOHMA:
return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() &&
(CanUse(RG_NUTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HookshotOrBoomerang());
case RE_KING_DODONGO:
return HasBossSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() &&
(CanUse(RG_BOMB_BAG) || HasItem(RG_GORONS_BRACELET));
case RE_BARINADE:
return HasBossSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer();
case RE_PHANTOM_GANON:
return HasBossSoul(RG_PHANTOM_GANON_SOUL) &&
(CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) &&
(CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT));
case RE_VOLVAGIA:
return HasBossSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER);
case RE_MORPHA:
return HasBossSoul(RG_MORPHA_SOUL) && CanUse(RG_HOOKSHOT) &&
(CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER));
case RE_BONGO_BONGO:
return HasBossSoul(RG_BONGO_BONGO_SOUL) &&
(CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) &&
(CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) &&
(CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO));
case RE_TWINROVA:
return HasBossSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) &&
(CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER));
case RE_GANONDORF: case RE_GANONDORF:
// RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the energy ball // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the energy ball
// and either of them regardless of jumpslashing to damage and kill ganondorf // and either of them regardless of jumpslashing to damage and kill ganondorf
@ -1489,7 +1514,7 @@ namespace Rando {
case RG_EYEBALL_FROG: case RG_EYEBALL_FROG:
case RG_EYEDROPS: case RG_EYEDROPS:
case RG_CLAIM_CHECK: case RG_CLAIM_CHECK:
SetAdultTrade(item.GetGIEntry()->itemId, state); SetRandoInf(randoGet - RG_POCKET_EGG + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, state);
break; break;
case RG_PROGRESSIVE_HOOKSHOT: case RG_PROGRESSIVE_HOOKSHOT:
{ {
@ -1699,6 +1724,9 @@ namespace Rando {
if (BottleRandomizerGetToItemID.contains(randoGet)) { if (BottleRandomizerGetToItemID.contains(randoGet)) {
itemId = BottleRandomizerGetToItemID[randoGet]; itemId = BottleRandomizerGetToItemID[randoGet];
} }
if (randoGet == RG_BOTTLE_WITH_BIG_POE) {
BigPoes++;
}
mSaveContext->inventory.items[slot] = itemId; mSaveContext->inventory.items[slot] = itemId;
} break; } break;
case RG_RUTOS_LETTER: case RG_RUTOS_LETTER:
@ -2056,26 +2084,10 @@ namespace Rando {
return ((1 << item) & mSaveContext->inventory.questItems); return ((1 << item) & mSaveContext->inventory.questItems);
} }
bool Logic::HasAdultTrade(uint32_t itemID) {
int tradeIndex = itemID - ITEM_POCKET_EGG;
return mSaveContext->ship.quest.data.randomizer.adultTradeItems & (1 << tradeIndex);
}
void Logic::SetAdultTrade(uint32_t itemID, bool state) {
int tradeIndex = itemID - ITEM_POCKET_EGG;
if (!state) {
mSaveContext->ship.quest.data.randomizer.adultTradeItems &= ~(1 << tradeIndex);
}
else {
mSaveContext->ship.quest.data.randomizer.adultTradeItems |= (1 << tradeIndex);
}
}
void Logic::SetQuestItem(uint32_t item, bool state) { void Logic::SetQuestItem(uint32_t item, bool state) {
if (!state) { if (!state) {
mSaveContext->inventory.questItems &= ~(1 << item); mSaveContext->inventory.questItems &= ~(1 << item);
} } else {
else {
mSaveContext->inventory.questItems |= (1 << item); mSaveContext->inventory.questItems |= (1 << item);
} }
} }
@ -2191,8 +2203,7 @@ namespace Rando {
void Logic::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) { void Logic::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) {
if (!state) { if (!state) {
mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item]; mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item];
} } else {
else {
mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item]; mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item];
} }
} }
@ -2204,8 +2215,7 @@ namespace Rando {
void Logic::SetRandoInf(uint32_t flag, bool state) { void Logic::SetRandoInf(uint32_t flag, bool state) {
if (!state) { if (!state) {
mSaveContext->ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); mSaveContext->ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
} } else {
else {
mSaveContext->ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); mSaveContext->ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
} }
} }
@ -2217,8 +2227,7 @@ namespace Rando {
void Logic::SetEventChkInf(int32_t flag, bool state) { void Logic::SetEventChkInf(int32_t flag, bool state) {
if (!state) { if (!state) {
mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF));
} } else {
else {
mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF));
} }
} }
@ -2357,6 +2366,7 @@ namespace Rando {
IsAdult = false; IsAdult = false;
//CanPlantBean = false; //CanPlantBean = false;
BigPoeKill = false; BigPoeKill = false;
BigPoes = 0;
BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1; BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1;

View file

@ -36,7 +36,6 @@ class Logic {
// Adult logic // Adult logic
bool FreedEpona = false; bool FreedEpona = false;
//bool BigPoe = false; //unused
// Trade Quest Events // Trade Quest Events
bool WakeUpAdultTalon = false; bool WakeUpAdultTalon = false;
@ -101,6 +100,7 @@ class Logic {
bool IsChild = false; bool IsChild = false;
bool IsAdult = false; bool IsAdult = false;
bool BigPoeKill = false; bool BigPoeKill = false;
uint8_t BigPoes = 0;
uint8_t BaseHearts = 0; uint8_t BaseHearts = 0;
// Bridge and LACS Requirements // Bridge and LACS Requirements
@ -261,8 +261,6 @@ class Logic {
bool CheckEquipment(uint32_t item); bool CheckEquipment(uint32_t item);
bool CheckQuestItem(uint32_t item); bool CheckQuestItem(uint32_t item);
void SetQuestItem(uint32_t item, bool state); void SetQuestItem(uint32_t item, bool state);
bool HasAdultTrade(uint32_t item);
void SetAdultTrade(uint32_t item, bool state);
uint8_t GetSmallKeyCount(uint32_t dungeonIndex); uint8_t GetSmallKeyCount(uint32_t dungeonIndex);
void SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count); void SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count);
bool CheckDungeonItem(uint32_t item, uint32_t dungeonIndex); bool CheckDungeonItem(uint32_t item, uint32_t dungeonIndex);

View file

@ -5732,6 +5732,14 @@ typedef enum {
RE_BIG_OCTO, RE_BIG_OCTO,
RE_GERUDO_WARRIOR, RE_GERUDO_WARRIOR,
RE_GIBDO, RE_GIBDO,
RE_GOHMA,
RE_KING_DODONGO,
RE_BARINADE,
RE_PHANTOM_GANON,
RE_VOLVAGIA,
RE_MORPHA,
RE_BONGO_BONGO,
RE_TWINROVA,
RE_GANONDORF, RE_GANONDORF,
RE_GANON, RE_GANON,
RE_DARK_LINK, RE_DARK_LINK,

View file

@ -440,7 +440,7 @@ void Entrance_SetWarpSongEntrance(void) {
// have to force the grotto return afterwards // have to force the grotto return afterwards
Grotto_ForceGrottoReturnOnSpecialEntrance(); Grotto_ForceGrottoReturnOnSpecialEntrance();
if (gSaveContext.gameMode != 0) { if (gSaveContext.gameMode != GAMEMODE_NORMAL) {
// During DHWW the cutscene must play at the destination // During DHWW the cutscene must play at the destination
gSaveContext.respawnFlag = -3; gSaveContext.respawnFlag = -3;
} else if (gSaveContext.respawnFlag == -3) { } else if (gSaveContext.respawnFlag == -3) {

View file

@ -1325,6 +1325,30 @@ typedef enum {
RAND_INF_FISHING_HOLE_UNLOCKED, RAND_INF_FISHING_HOLE_UNLOCKED,
RAND_INF_FISHING_HOLE_KEY_OBTAINED, RAND_INF_FISHING_HOLE_KEY_OBTAINED,
RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG,
RAND_INF_CHILD_TRADES_HAS_CHICKEN,
RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA,
RAND_INF_CHILD_TRADES_HAS_MASK_KEATON,
RAND_INF_CHILD_TRADES_HAS_MASK_SKULL,
RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY,
RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY,
RAND_INF_CHILD_TRADES_HAS_MASK_GORON,
RAND_INF_CHILD_TRADES_HAS_MASK_ZORA,
RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO,
RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH,
RAND_INF_ADULT_TRADES_HAS_POCKET_EGG,
RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO,
RAND_INF_ADULT_TRADES_HAS_COJIRO,
RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM,
RAND_INF_ADULT_TRADES_HAS_ODD_POTION,
RAND_INF_ADULT_TRADES_HAS_SAW,
RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN,
RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION,
RAND_INF_ADULT_TRADES_HAS_FROG,
RAND_INF_ADULT_TRADES_HAS_EYEDROPS,
RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK,
// If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16)
RAND_INF_MAX, RAND_INF_MAX,

View file

@ -260,11 +260,6 @@ extern "C" void Randomizer_InitSaveFile() {
// Give Link's pocket item // Give Link's pocket item
GiveLinksPocketItem(); GiveLinksPocketItem();
// shuffle adult trade quest
if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
gSaveContext.ship.quest.data.randomizer.adultTradeItems = 0;
}
// remove One Time scrubs with scrubsanity off // remove One Time scrubs with scrubsanity off
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) {
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE); Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE);
@ -316,6 +311,7 @@ extern "C" void Randomizer_InitSaveFile() {
// Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM. // Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM.
Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA);
// Got item from impa // Got item from impa
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY);
@ -325,7 +321,6 @@ extern "C" void Randomizer_InitSaveFile() {
// set this at the end to ensure we always start with the letter // set this at the end to ensure we always start with the letter
// this is for the off chance we got the weird egg from impa (which should never happen) // this is for the off chance we got the weird egg from impa (which should never happen)
INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA;
Flags_SetRandomizerInf(RAND_INF_ZELDAS_LETTER);
} }
if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) {
@ -376,6 +371,7 @@ extern "C" void Randomizer_InitSaveFile() {
if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) { if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) {
Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD);
Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA);
} }
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST ||
@ -413,6 +409,16 @@ extern "C" void Randomizer_InitSaveFile() {
if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) { if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) {
Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK);
Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO);
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH);
gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask
gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask
gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask

View file

@ -46,6 +46,7 @@ class StaticData {
static std::vector<RandomizerCheck> GetPondFishLocations(); static std::vector<RandomizerCheck> GetPondFishLocations();
static std::vector<RandomizerCheck> GetOverworldFishLocations(); static std::vector<RandomizerCheck> GetOverworldFishLocations();
static std::vector<RandomizerCheck> GetOverworldFairyLocations(); static std::vector<RandomizerCheck> GetOverworldFairyLocations();
static void RegisterCowLocations();
static void RegisterFishLocations(); static void RegisterFishLocations();
static void RegisterFairyLocations(); static void RegisterFairyLocations();
static void RegisterPotLocations(); static void RegisterPotLocations();

View file

@ -2254,7 +2254,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
messageEntry = OTRGlobals::Instance->gRandomizer->GetGoronMessage(choice); messageEntry = OTRGlobals::Instance->gRandomizer->GetGoronMessage(choice);
} }
else if (textId == TEXT_FROGS_UNDERWATER && ctx->GetOption(RSK_FROGS_HINT)) { else if (textId == TEXT_FROGS_UNDERWATER && ctx->GetOption(RSK_FROGS_HINT)) {
messageEntry = ctx->GetHint(RH_FROGS_HINT)->GetHintMessage(MF_AUTO_FORMAT), TEXTBOX_TYPE_BLUE; messageEntry = ctx->GetHint(RH_FROGS_HINT)->GetHintMessage(MF_AUTO_FORMAT);
} }
else if ( else if (
Randomizer_GetSettingValue(RSK_LOACH_HINT) && Randomizer_GetSettingValue(RSK_LOACH_HINT) &&
@ -2437,9 +2437,11 @@ void SoH_ProcessDroppedFiles(std::string filePath) {
return; return;
} }
clearCvars(enhancementsCvars); CVarClearBlock(CVAR_PREFIX_ENHANCEMENT);
clearCvars(cheatCvars); CVarClearBlock(CVAR_PREFIX_CHEAT);
clearCvars(randomizerCvars); CVarClearBlock(CVAR_PREFIX_RANDOMIZER_SETTING);
CVarClearBlock(CVAR_PREFIX_RANDOMIZER_ENHANCEMENT);
CVarClearBlock(CVAR_PREFIX_DEVELOPER_TOOLS);
// Flatten everything under CVars into a single array // Flatten everything under CVars into a single array
auto cvars = configJson["CVars"].flatten(); auto cvars = configJson["CVars"].flatten();

View file

@ -218,8 +218,6 @@ void SaveManager::LoadRandomizerVersion1() {
} }
randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, {CustomMessage(ganonText)})); randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, {CustomMessage(ganonText)}));
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
@ -348,8 +346,6 @@ void SaveManager::LoadRandomizerVersion2() {
SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText); SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText);
randoContext->AddHint(RH_PRELUDE_WARP_LOC, Rando::Hint(RH_PRELUDE_WARP_LOC, {CustomMessage(warpPreludeText)})); randoContext->AddHint(RH_PRELUDE_WARP_LOC, Rando::Hint(RH_PRELUDE_WARP_LOC, {CustomMessage(warpPreludeText)}));
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
@ -445,8 +441,6 @@ void SaveManager::LoadRandomizerVersion3() {
randoContext->AddHint(hint, Rando::Hint(hint, json)); randoContext->AddHint(hint, Rando::Hint(hint, json));
}); });
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.ship.quest.data.randomizer.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
@ -588,8 +582,6 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
}); });
}); });
SaveManager::Instance->SaveData("adultTradeItems", saveContext->ship.quest.data.randomizer.adultTradeItems);
SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext->ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext->ship.quest.data.randomizer.triforcePiecesCollected);
SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->ship.pendingIceTrapCount); SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->ship.pendingIceTrapCount);

View file

@ -24,9 +24,18 @@
#include "soh/resource/type/scenecommand/SetTransitionActorList.h" #include "soh/resource/type/scenecommand/SetTransitionActorList.h"
#include "soh/resource/type/scenecommand/SetWindSettings.h" #include "soh/resource/type/scenecommand/SetWindSettings.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include <string.h>
namespace SOH { namespace SOH {
const char* TrimOTRSignature(const char* fileName) {
static const char* sOTRSignature = "__OTR__";
if (strncmp(fileName, sOTRSignature, strlen(sOTRSignature)) == 0) {
return fileName + 7;
}
return fileName;
}
void LogEndMarkerAsXML(std::shared_ptr<Ship::IResource> resource) { void LogEndMarkerAsXML(std::shared_ptr<Ship::IResource> resource) {
std::shared_ptr<EndMarker> endMarker = std::static_pointer_cast<EndMarker>(resource); std::shared_ptr<EndMarker> endMarker = std::static_pointer_cast<EndMarker>(resource);
@ -292,12 +301,12 @@ void LogMeshAsXML(std::shared_ptr<Ship::IResource> resource) {
for (int i = 0; i < setMesh->meshHeader.polygon0.num; i += 1) { for (int i = 0; i < setMesh->meshHeader.polygon0.num; i += 1) {
tinyxml2::XMLElement* polygon = doc.NewElement("Polygon"); tinyxml2::XMLElement* polygon = doc.NewElement("Polygon");
polygon->SetAttribute("PolyType", "0"); polygon->SetAttribute("PolyType", "0");
polygon->SetAttribute("MeshOpa", setMesh->opaPaths[i].c_str()); polygon->SetAttribute("MeshOpa", TrimOTRSignature(dlist->opa ? (char*)dlist->opa : ""));
polygon->SetAttribute("MeshXlu", setMesh->xluPaths[i].c_str()); polygon->SetAttribute("MeshXlu", TrimOTRSignature(dlist->xlu ? (char*)dlist->xlu : ""));
root->InsertEndChild(polygon); root->InsertEndChild(polygon);
}
dlist += 1; dlist += 1;
}
} else if (setMesh->meshHeader.base.type == 1) { } else if (setMesh->meshHeader.base.type == 1) {
root->SetAttribute("PolyNum", "1"); root->SetAttribute("PolyNum", "1");
tinyxml2::XMLElement* polygon = doc.NewElement("Polygon"); tinyxml2::XMLElement* polygon = doc.NewElement("Polygon");
@ -313,8 +322,10 @@ void LogMeshAsXML(std::shared_ptr<Ship::IResource> resource) {
polygon->SetAttribute("PolyType", "0"); polygon->SetAttribute("PolyType", "0");
polygon->SetAttribute("MeshOpa", setMesh->opaPaths[0].c_str()); PolygonDlist* dlist = (PolygonDlist*)setMesh->meshHeader.polygon1.dlist;
polygon->SetAttribute("MeshXlu", setMesh->xluPaths[0].c_str());
polygon->SetAttribute("MeshOpa", TrimOTRSignature(dlist->opa ? (char*)dlist->opa : ""));
polygon->SetAttribute("MeshXlu", TrimOTRSignature(dlist->xlu ? (char*)dlist->xlu : ""));
root->InsertEndChild(polygon); root->InsertEndChild(polygon);
@ -325,7 +336,7 @@ void LogMeshAsXML(std::shared_ptr<Ship::IResource> resource) {
if (setMesh->meshHeader.polygon1.format == 1) { if (setMesh->meshHeader.polygon1.format == 1) {
bgImage->SetAttribute("Unknown_00", image->unk_00); bgImage->SetAttribute("Unknown_00", image->unk_00);
bgImage->SetAttribute("Id", image->id); bgImage->SetAttribute("Id", image->id);
bgImage->SetAttribute("ImagePath", setMesh->imagePaths[i].c_str()); bgImage->SetAttribute("ImagePath", TrimOTRSignature((char*)setMesh->meshHeader.polygon1.single.source));
bgImage->SetAttribute("Unknown_0C", setMesh->meshHeader.polygon1.single.unk_0C); bgImage->SetAttribute("Unknown_0C", setMesh->meshHeader.polygon1.single.unk_0C);
bgImage->SetAttribute("TLUT", setMesh->meshHeader.polygon1.single.tlut); bgImage->SetAttribute("TLUT", setMesh->meshHeader.polygon1.single.tlut);
bgImage->SetAttribute("Width", setMesh->meshHeader.polygon1.single.width); bgImage->SetAttribute("Width", setMesh->meshHeader.polygon1.single.width);
@ -337,7 +348,7 @@ void LogMeshAsXML(std::shared_ptr<Ship::IResource> resource) {
} else { } else {
bgImage->SetAttribute("Unknown_00", image->unk_00); bgImage->SetAttribute("Unknown_00", image->unk_00);
bgImage->SetAttribute("Id", image->id); bgImage->SetAttribute("Id", image->id);
bgImage->SetAttribute("ImagePath", setMesh->imagePaths[i].c_str()); bgImage->SetAttribute("ImagePath", TrimOTRSignature((char*)image->source));
bgImage->SetAttribute("Unknown_0C", image->unk_0C); bgImage->SetAttribute("Unknown_0C", image->unk_0C);
bgImage->SetAttribute("TLUT", image->tlut); bgImage->SetAttribute("TLUT", image->tlut);
bgImage->SetAttribute("Width", image->width); bgImage->SetAttribute("Width", image->width);
@ -363,8 +374,8 @@ void LogMeshAsXML(std::shared_ptr<Ship::IResource> resource) {
polygon->SetAttribute("PosZ", dlist->pos.z); polygon->SetAttribute("PosZ", dlist->pos.z);
polygon->SetAttribute("Unknown", dlist->unk_06); polygon->SetAttribute("Unknown", dlist->unk_06);
polygon->SetAttribute("MeshOpa", setMesh->opaPaths[i].c_str()); polygon->SetAttribute("MeshOpa", TrimOTRSignature(dlist->opa ? (char*)dlist->opa : ""));
polygon->SetAttribute("MeshXlu", setMesh->xluPaths[i].c_str()); polygon->SetAttribute("MeshXlu", TrimOTRSignature(dlist->xlu ? (char*)dlist->xlu : ""));
root->InsertEndChild(polygon); root->InsertEndChild(polygon);
dlist += 1; dlist += 1;

View file

@ -412,7 +412,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
{ {
if (CHECK_BTN_ALL(gameState->input[0].press.button, BTN_Z) && if (CHECK_BTN_ALL(gameState->input[0].press.button, BTN_Z) &&
CHECK_BTN_ALL(gameState->input[0].cur.button, BTN_L | BTN_R)) { CHECK_BTN_ALL(gameState->input[0].cur.button, BTN_L | BTN_R)) {
gSaveContext.gameMode = 0; gSaveContext.gameMode = GAMEMODE_NORMAL;
SET_NEXT_GAMESTATE(gameState, Select_Init, SelectContext); SET_NEXT_GAMESTATE(gameState, Select_Init, SelectContext);
gameState->running = false; gameState->running = false;
} }

View file

@ -7589,7 +7589,7 @@ Vec3s Camera_Update(Camera* camera) {
} }
if (camera->status == CAM_STAT_ACTIVE) { if (camera->status == CAM_STAT_ACTIVE) {
if ((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 3)) { if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS)) {
sCameraInterfaceFlags = 0; sCameraInterfaceFlags = 0;
Camera_UpdateInterface(sCameraInterfaceFlags); Camera_UpdateInterface(sCameraInterfaceFlags);
} else if ((D_8011D3F0 != 0) && (camera->thisIdx == MAIN_CAM)) { } else if ((D_8011D3F0 != 0) && (camera->thisIdx == MAIN_CAM)) {

View file

@ -479,7 +479,7 @@ void Regs_InitDataImpl(void) {
WREG(94) = 3; WREG(94) = 3;
WREG(95) = 6; WREG(95) = 6;
if (gSaveContext.gameMode == 0) { if (gSaveContext.gameMode == GAMEMODE_NORMAL) {
R_TEXTBOX_X = 52; R_TEXTBOX_X = 52;
R_TEXTBOX_Y = 36; R_TEXTBOX_Y = 36;
VREG(2) = 214; VREG(2) = 214;

View file

@ -510,8 +510,8 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC) && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)); (gSaveContext.fileNum != 0xFEDC) && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0));
if ((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 3) && (play->sceneNum != SCENE_HYRULE_FIELD) && if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS) &&
(csCtx->frames > 20) && (play->sceneNum != SCENE_HYRULE_FIELD) && (csCtx->frames > 20) &&
(CHECK_BTN_ALL(play->state.input[0].press.button, BTN_A) || (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_A) ||
CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B) || CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B) ||
CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START)) && CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START)) &&
@ -575,7 +575,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
osSyncPrintf("\n分岐先指定!!=[%d]番", cmd->base); // "Future fork designation=No. [%d]" osSyncPrintf("\n分岐先指定!!=[%d]番", cmd->base); // "Future fork designation=No. [%d]"
if ((gSaveContext.gameMode != 0) && (csCtx->frames != cmd->startFrame)) { if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (csCtx->frames != cmd->startFrame)) {
gSaveContext.unk_13E7 = 1; gSaveContext.unk_13E7 = 1;
} }
@ -908,7 +908,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
play->transitionType = TRANS_TYPE_FADE_WHITE; play->transitionType = TRANS_TYPE_FADE_WHITE;
break; break;
case 54: case 54:
gSaveContext.gameMode = 3; gSaveContext.gameMode = GAMEMODE_END_CREDITS;
Audio_SetSoundBanksMute(0x6F); Audio_SetSoundBanksMute(0x6F);
play->linkAgeOnLoad = 1; play->linkAgeOnLoad = 1;
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT; play->nextEntranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT;
@ -1288,7 +1288,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE;
break; break;
case 117: case 117:
gSaveContext.gameMode = 3; gSaveContext.gameMode = GAMEMODE_END_CREDITS;
Audio_SetSoundBanksMute(0x6F); Audio_SetSoundBanksMute(0x6F);
play->linkAgeOnLoad = 0; play->linkAgeOnLoad = 0;
play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN;
@ -2080,7 +2080,7 @@ void func_80068DC0(PlayState* play, CutsceneContext* csCtx) {
osSyncPrintf("\n\n\n\n\nやっぱりここかいな"); // "Right here, huh" osSyncPrintf("\n\n\n\n\nやっぱりここかいな"); // "Right here, huh"
gSaveContext.cutsceneIndex = 0; gSaveContext.cutsceneIndex = 0;
gSaveContext.gameMode = 0; gSaveContext.gameMode = GAMEMODE_NORMAL;
if (D_8015FCC8 != 0) { if (D_8015FCC8 != 0) {
switch (gSaveContext.entranceIndex) { switch (gSaveContext.entranceIndex) {
@ -2203,7 +2203,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
return; return;
} }
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { if ((gSaveContext.gameMode == GAMEMODE_NORMAL) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) {
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT);
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT;

View file

@ -6,6 +6,8 @@
#include "soh/frame_interpolation.h" #include "soh/frame_interpolation.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
typedef enum { typedef enum {
/* 0 */ LENS_FLARE_CIRCLE0, /* 0 */ LENS_FLARE_CIRCLE0,
@ -895,7 +897,7 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex
EnvLightSettings* lightSettingsList = play->envCtx.lightSettingsList; EnvLightSettings* lightSettingsList = play->envCtx.lightSettingsList;
s32 adjustment; s32 adjustment;
if ((((void)0, gSaveContext.gameMode) != 0) && (((void)0, gSaveContext.gameMode) != 3)) { if ((((void)0, gSaveContext.gameMode) != GAMEMODE_NORMAL) && (((void)0, gSaveContext.gameMode) != GAMEMODE_END_CREDITS)) {
func_800AA16C(play); func_800AA16C(play);
} }
@ -925,9 +927,9 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex
} }
if ((pauseCtx->state == 0) && (gameOverCtx->state == GAMEOVER_INACTIVE)) { if ((pauseCtx->state == 0) && (gameOverCtx->state == GAMEOVER_INACTIVE)) {
if (((msgCtx->msgLength == 0) && (msgCtx->msgMode == 0)) || (((void)0, gSaveContext.gameMode) == 3)) { if (((msgCtx->msgLength == 0) && (msgCtx->msgMode == 0)) || (((void)0, gSaveContext.gameMode) == GAMEMODE_END_CREDITS)) {
if ((envCtx->unk_1A == 0) && !FrameAdvance_IsEnabled(play) && if ((envCtx->unk_1A == 0) && !FrameAdvance_IsEnabled(play) &&
(play->transitionMode == TRANS_MODE_OFF || ((void)0, gSaveContext.gameMode) != 0)) { (play->transitionMode == TRANS_MODE_OFF || ((void)0, gSaveContext.gameMode) != GAMEMODE_NORMAL)) {
if (IS_DAY || gTimeIncrement >= 0x190) { if (IS_DAY || gTimeIncrement >= 0x190) {
gSaveContext.dayTime += gTimeIncrement; gSaveContext.dayTime += gTimeIncrement;
@ -2111,6 +2113,7 @@ void func_80075B44(PlayState* play) {
if ((Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) || if ((Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) ||
Inventory_HatchPocketCucco(play)) && Inventory_HatchPocketCucco(play)) &&
play->csCtx.state == 0 && !Player_InCsMode(play)) { play->csCtx.state == 0 && !Player_InCsMode(play)) {
GameInteractor_ExecuteOnCuccoOrChickenHatch();
Message_StartTextbox(play, 0x3066, NULL); Message_StartTextbox(play, 0x3066, NULL);
} }
play->envCtx.unk_E0++; play->envCtx.unk_E0++;

View file

@ -4,7 +4,6 @@
#include "textures/do_action_static/do_action_static.h" #include "textures/do_action_static/do_action_static.h"
#include "textures/icon_item_static/icon_item_static.h" #include "textures/icon_item_static/icon_item_static.h"
#include "soh_assets.h" #include "soh_assets.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "libultraship/bridge.h" #include "libultraship/bridge.h"
@ -2446,8 +2445,17 @@ u8 Item_Give(PlayState* play, u8 item) {
Flags_SetItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE); Flags_SetItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE);
} }
if (IS_RANDO) {
if (item >= ITEM_POCKET_EGG) { if (item >= ITEM_POCKET_EGG) {
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(item); Flags_SetRandomizerInf(item - ITEM_POCKET_EGG + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG);
} else if (item == ITEM_LETTER_ZELDA) {
//don't care about zelda's letter if it's already been shown to the guard
if (!Flags_GetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD)) {
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA);
}
} else {
Flags_SetRandomizerInf(item - ITEM_WEIRD_EGG + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG);
}
} }
temp = INV_CONTENT(item); temp = INV_CONTENT(item);
@ -2759,12 +2767,12 @@ bool Inventory_HatchPocketCucco(PlayState* play) {
return Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO); return Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO);
} }
if (!PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_POCKET_EGG)) { if (!Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) {
return 0; return 0;
} }
gSaveContext.ship.quest.data.randomizer.adultTradeItems &= ~ADULT_TRADE_FLAG(ITEM_POCKET_EGG); Flags_UnsetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG);
gSaveContext.ship.quest.data.randomizer.adultTradeItems |= ADULT_TRADE_FLAG(ITEM_POCKET_CUCCO); Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO);
Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO); Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO);
return 1; return 1;
} }
@ -3215,7 +3223,7 @@ void Interface_UpdateMagicBar(PlayState* play) {
case MAGIC_STATE_FILL: case MAGIC_STATE_FILL:
gSaveContext.magic += 4; gSaveContext.magic += 4;
if (gSaveContext.gameMode == 0 && gSaveContext.sceneSetupIndex < 4) { if (gSaveContext.gameMode == GAMEMODE_NORMAL && gSaveContext.sceneSetupIndex < 4) {
Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb); &gSfxDefaultReverb);
} }

View file

@ -521,6 +521,7 @@ void Play_Init(GameState* thisx) {
if (Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) || if (Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) ||
Inventory_HatchPocketCucco(play)) { Inventory_HatchPocketCucco(play)) {
GameInteractor_ExecuteOnCuccoOrChickenHatch();
Message_StartTextbox(play, 0x3066, NULL); Message_StartTextbox(play, 0x3066, NULL);
} }

View file

@ -1131,7 +1131,7 @@ void Player_DrawImpl(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dL
if (((CVarGetInteger(CVAR_ENHANCEMENT("FirstPersonGauntlets"), 0) && LINK_IS_ADULT) || (overrideLimbDraw != Player_OverrideLimbDrawGameplayFirstPerson)) && if (((CVarGetInteger(CVAR_ENHANCEMENT("FirstPersonGauntlets"), 0) && LINK_IS_ADULT) || (overrideLimbDraw != Player_OverrideLimbDrawGameplayFirstPerson)) &&
(overrideLimbDraw != Player_OverrideLimbDrawGameplayCrawling) && (overrideLimbDraw != Player_OverrideLimbDrawGameplayCrawling) &&
(gSaveContext.gameMode != 3)) { (gSaveContext.gameMode != GAMEMODE_END_CREDITS)) {
if (LINK_IS_ADULT) { if (LINK_IS_ADULT) {
s32 strengthUpgrade = CUR_UPG_VALUE(UPG_STRENGTH); s32 strengthUpgrade = CUR_UPG_VALUE(UPG_STRENGTH);

View file

@ -24,7 +24,6 @@
#include "overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h" #include "overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h"
#include "soh/mq_asset_hacks.h" #include "soh/mq_asset_hacks.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
@ -1300,7 +1299,7 @@ void func_8009EE44(PlayState* play) {
bool playerHasCojiro = INV_CONTENT(ITEM_COJIRO) == ITEM_COJIRO; bool playerHasCojiro = INV_CONTENT(ITEM_COJIRO) == ITEM_COJIRO;
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) { if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
playerHasCojiro = PLAYER_HAS_SHUFFLED_ADULT_TRADE_ITEM(ITEM_COJIRO); playerHasCojiro = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_HAS_COJIRO);
} }
if ((play->roomCtx.unk_74[0] == 0) && playerHasCojiro) { if ((play->roomCtx.unk_74[0] == 0) && playerHasCojiro) {
if (play->roomCtx.unk_74[1] == 50) { if (play->roomCtx.unk_74[1] == 50) {

View file

@ -6,7 +6,6 @@
#include "z_en_ds.h" #include "z_en_ds.h"
#include "objects/object_ds/object_ds.h" #include "objects/object_ds/object_ds.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -3,7 +3,6 @@
#include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_oF1d_map/object_oF1d_map.h" #include "objects/object_oF1d_map/object_oF1d_map.h"
#include "soh/frame_interpolation.h" #include "soh/frame_interpolation.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED) #define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)

View file

@ -3,7 +3,6 @@
#include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_oF1d_map/object_oF1d_map.h" #include "objects/object_oF1d_map/object_oF1d_map.h"
#include "soh/frame_interpolation.h" #include "soh/frame_interpolation.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -12,6 +12,8 @@
#include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h" #include "overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY) #define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
@ -407,7 +409,7 @@ void func_80A53AD4(EnHeishi2* this, PlayState* play) {
this->unk_300 = TEXT_STATE_DONE; this->unk_300 = TEXT_STATE_DONE;
if (Actor_ProcessTalkRequest(&this->actor, play)) { if (Actor_ProcessTalkRequest(&this->actor, play)) {
exchangeItemId = func_8002F368(play); exchangeItemId = func_8002F368(play);
if (exchangeItemId == EXCH_ITEM_LETTER_ZELDA) { if (GameInteractor_Should(VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER, exchangeItemId == EXCH_ITEM_LETTER_ZELDA, exchangeItemId)) {
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
player->actor.textId = 0x2010; player->actor.textId = 0x2010;
this->unk_300 = TEXT_STATE_EVENT; this->unk_300 = TEXT_STATE_EVENT;

View file

@ -7,7 +7,6 @@
#include "z_en_hs.h" #include "z_en_hs.h"
#include "vt.h" #include "vt.h"
#include "objects/object_hs/object_hs.h" #include "objects/object_hs/object_hs.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -10,7 +10,6 @@
#include "objects/object_km1/object_km1.h" #include "objects/object_km1/object_km1.h"
#include "objects/object_kw1/object_kw1.h" #include "objects/object_kw1/object_kw1.h"
#include "vt.h" #include "vt.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -6,7 +6,6 @@
#include "z_en_kz.h" #include "z_en_kz.h"
#include "objects/object_kz/object_kz.h" #include "objects/object_kz/object_kz.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -50,7 +50,7 @@ void EnLight_Init(Actor* thisx, PlayState* play) {
EnLight* this = (EnLight*)thisx; EnLight* this = (EnLight*)thisx;
s16 yOffset; s16 yOffset;
if (gSaveContext.gameMode == 3) { if (gSaveContext.gameMode == GAMEMODE_END_CREDITS) {
// special case for the credits // special case for the credits
yOffset = (this->actor.params < 0) ? 1 : 40; yOffset = (this->actor.params < 0) ? 1 : 40;
Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, yOffset + (s16)this->actor.world.pos.y, Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, yOffset + (s16)this->actor.world.pos.y,

View file

@ -251,7 +251,7 @@ void EnMag_UpdateMq(Actor* thisx, PlayState* play) {
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb); &gSfxDefaultReverb);
gSaveContext.gameMode = 2; gSaveContext.gameMode = GAMEMODE_FILE_SELECT;
play->transitionTrigger = TRANS_TRIGGER_START; play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK; play->transitionType = TRANS_TYPE_FADE_BLACK;
} }
@ -411,7 +411,7 @@ void EnMag_UpdateVanilla(Actor* thisx, PlayState* play) {
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb); &gSfxDefaultReverb);
gSaveContext.gameMode = 2; gSaveContext.gameMode = GAMEMODE_FILE_SELECT;
play->transitionTrigger = TRANS_TRIGGER_START; play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK; play->transitionType = TRANS_TYPE_FADE_BLACK;
} }

View file

@ -6,7 +6,6 @@
#include "z_en_mk.h" #include "z_en_mk.h"
#include "objects/object_mk/object_mk.h" #include "objects/object_mk/object_mk.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -463,7 +463,7 @@ void func_80AAE294(EnMm* this, PlayState* play) {
dustPos.y = this->actor.world.pos.y; dustPos.y = this->actor.world.pos.y;
dustPos.z = this->actor.world.pos.z; dustPos.z = this->actor.world.pos.z;
if (gSaveContext.gameMode != 3) { if (gSaveContext.gameMode != GAMEMODE_END_CREDITS) {
func_80033480(play, &dustPos, 50.0f, 2, 350, 20, 0); func_80033480(play, &dustPos, 50.0f, 2, 350, 20, 0);
} }

View file

@ -3,7 +3,6 @@
#include "objects/object_os_anime/object_os_anime.h" #include "objects/object_os_anime/object_os_anime.h"
#include "overlays/actors/ovl_En_Niw/z_en_niw.h" #include "overlays/actors/ovl_En_Niw/z_en_niw.h"
#include "vt.h" #include "vt.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -73,7 +73,7 @@ void EnOkarinaEffect_ManageStorm(EnOkarinaEffect* this, PlayState* play) {
Flags_UnsetEnv(play, 5); // clear storms env flag Flags_UnsetEnv(play, 5); // clear storms env flag
if (((play->pauseCtx.state == 0) && (play->gameOverCtx.state == GAMEOVER_INACTIVE) && if (((play->pauseCtx.state == 0) && (play->gameOverCtx.state == GAMEOVER_INACTIVE) &&
(play->msgCtx.msgLength == 0) && (!FrameAdvance_IsEnabled(play)) && (play->msgCtx.msgLength == 0) && (!FrameAdvance_IsEnabled(play)) &&
((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != 0))) || ((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != GAMEMODE_NORMAL))) ||
(this->timer >= 250)) { (this->timer >= 250)) {
if (play->envCtx.indoors || play->envCtx.unk_1F != 1) { if (play->envCtx.indoors || play->envCtx.unk_1F != 1) {
this->timer--; this->timer--;

View file

@ -6,7 +6,6 @@
#include "z_en_toryo.h" #include "z_en_toryo.h"
#include "objects/object_toryo/object_toryo.h" #include "objects/object_toryo/object_toryo.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h" #include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"

View file

@ -10859,7 +10859,7 @@ void Player_Init(Actor* thisx, PlayState* play2) {
} }
if (startMode != PLAYER_START_MODE_NOTHING) { if (startMode != PLAYER_START_MODE_NOTHING) {
if ((gSaveContext.gameMode == 0) || (gSaveContext.gameMode == 3)) { if ((gSaveContext.gameMode == GAMEMODE_NORMAL) || (gSaveContext.gameMode == GAMEMODE_END_CREDITS)) {
this->naviActor = Player_SpawnFairy(play, this, &thisx->world.pos, &D_80854778, FAIRY_NAVI); this->naviActor = Player_SpawnFairy(play, this, &thisx->world.pos, &D_80854778, FAIRY_NAVI);
if (gSaveContext.dogParams != 0) { if (gSaveContext.dogParams != 0) {
gSaveContext.dogParams |= 0x8000; gSaveContext.dogParams |= 0x8000;

View file

@ -3112,7 +3112,7 @@ void FileChoose_LoadGame(GameState* thisx) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
gSaveContext.fileNum = this->buttonIndex; gSaveContext.fileNum = this->buttonIndex;
gSaveContext.gameMode = 0; gSaveContext.gameMode = GAMEMODE_NORMAL;
if ((this->buttonIndex == FS_BTN_SELECT_FILE_1 && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)) || this->buttonIndex == 0xFF) { if ((this->buttonIndex == FS_BTN_SELECT_FILE_1 && CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)) || this->buttonIndex == 0xFF) {
if (this->buttonIndex == 0xFF) { if (this->buttonIndex == 0xFF) {
@ -3737,7 +3737,4 @@ void FileChoose_Init(GameState* thisx) {
Font_LoadOrderedFont(&this->font); Font_LoadOrderedFont(&this->font);
Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA); Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA);
func_800F5E18(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1); func_800F5E18(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1);
// Originally this was only set when transitioning from the title screen, but gSkipLogoTitle skips that process so we're ensuring it's set here
gSaveContext.gameMode = GAMEMODE_FILE_SELECT;
} }

View file

@ -9,7 +9,7 @@
void Sram_InitDebugSave(void); void Sram_InitDebugSave(void);
void Opening_SetupTitleScreen(OpeningContext* this) { void Opening_SetupTitleScreen(OpeningContext* this) {
gSaveContext.gameMode = 1; gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN;
this->state.running = false; this->state.running = false;
gSaveContext.linkAge = 0; gSaveContext.linkAge = 0;
gSaveContext.fileNum = 0xFF; gSaveContext.fileNum = 0xFF;

View file

@ -137,7 +137,7 @@ void Title_Main(GameState* thisx) {
if (this->exit) { if (this->exit) {
gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = 0xFF; gSaveContext.natureAmbienceId = 0xFF;
gSaveContext.gameMode = 1; gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN;
this->state.running = false; this->state.running = false;
SET_NEXT_GAMESTATE(&this->state, Opening_Init, OpeningContext); SET_NEXT_GAMESTATE(&this->state, Opening_Init, OpeningContext);
} }

View file

@ -1,7 +1,7 @@
#include "z_kaleido_scope.h" #include "z_kaleido_scope.h"
#include "textures/parameter_static/parameter_static.h" #include "textures/parameter_static/parameter_static.h"
#include "textures/icon_item_static/icon_item_static.h" #include "textures/icon_item_static/icon_item_static.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" #include "soh/Enhancements/randomizer/ShuffleTradeItems.h"
#include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/randomizer/randomizerTypes.h"
#include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
@ -316,6 +316,10 @@ void KaleidoScope_HandleItemCycleExtras(PlayState* play, u8 slot, bool canCycle,
} }
bool CanMaskSelect() { bool CanMaskSelect() {
if (IS_RANDO) {
return CVarGetInteger(CVAR_ENHANCEMENT("MaskSelect"), 0) /* || Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_TRADE) */;
}
// only allow mask select when: // only allow mask select when:
// the shop is open: // the shop is open:
// * zelda's letter check: Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER) // * zelda's letter check: Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER)
@ -333,12 +337,20 @@ void KaleidoScope_HandleItemCycles(PlayState* play) {
play, play,
SLOT_TRADE_CHILD, SLOT_TRADE_CHILD,
CanMaskSelect(), CanMaskSelect(),
IS_RANDO ?
Randomizer_GetPrevChildTradeItem() :
(
INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ? INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ?
ITEM_MASK_TRUTH : ITEM_MASK_TRUTH :
INV_CONTENT(ITEM_TRADE_CHILD) - 1, INV_CONTENT(ITEM_TRADE_CHILD) - 1
),
IS_RANDO ?
Randomizer_GetNextChildTradeItem() :
(
INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ? INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ?
ITEM_MASK_KEATON : ITEM_MASK_KEATON :
INV_CONTENT(ITEM_TRADE_CHILD) + 1, INV_CONTENT(ITEM_TRADE_CHILD) + 1
),
true true
); );
@ -379,12 +391,20 @@ void KaleidoScope_DrawItemCycles(PlayState* play) {
play, play,
SLOT_TRADE_CHILD, SLOT_TRADE_CHILD,
CanMaskSelect(), CanMaskSelect(),
IS_RANDO ?
Randomizer_GetPrevChildTradeItem() :
(
INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ? INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH ?
ITEM_MASK_TRUTH : ITEM_MASK_TRUTH :
INV_CONTENT(ITEM_TRADE_CHILD) - 1, INV_CONTENT(ITEM_TRADE_CHILD) - 1
),
IS_RANDO ?
Randomizer_GetNextChildTradeItem() :
(
INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ? INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_TRUTH || INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON ?
ITEM_MASK_KEATON : ITEM_MASK_KEATON :
INV_CONTENT(ITEM_TRADE_CHILD) + 1 INV_CONTENT(ITEM_TRADE_CHILD) + 1
)
); );
//draw the adult trade select //draw the adult trade select