diff --git a/soh/assets/custom/lang/en_US.json b/soh/assets/custom/lang/en_US.json index a9eb2b5cb2..a5667e882c 100644 --- a/soh/assets/custom/lang/en_US.json +++ b/soh/assets/custom/lang/en_US.json @@ -1495,6 +1495,13 @@ "The jump can also be used when already in mid-air. Roc's Feather is not considered by logic." ] }, + "nayrus_love_uses": { + "name": "Nayru's Love Uses", + "description": [ + "Limits Nayru's Love to a set number of casts. Each Nayru's Love you find adds one use, and this sets ", + "how many are placed in the item pool. Starting with Nayru's Love counts as one. 0 keeps it unlimited." + ] + }, "slingbow_break_beehives": { "name": "Slingshot/Bow Can Break Beehives", "description": "Allows Slingshot and Bow to break beehives when Beehive Shuffle is turned on." diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 511dc8955a..6624151c06 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -227,6 +227,7 @@ typedef struct { typedef struct ShipRandomizerSaveContextData { u8 triforcePiecesCollected; u8 bombchuUpgradeLevel; + u8 nayrusLoveUses; s8 silverShadowBlades; s8 silverShadowPit; s8 silverShadowSpikes; diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 1cbb0b7e5b..850a7c36aa 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -702,6 +702,11 @@ typedef enum { // ```c // true // ``` + // In `ItemInSlotUsesAmmo` (pause menu, with Better Ammo Rendering): + // ```c + // item == ITEM_STICK || item == ITEM_NUT || item == ITEM_BOMB || item == ITEM_BOW || + // item == ITEM_SLINGSHOT || item == ITEM_BOMBCHU || item == ITEM_BEAN + // ``` // #### `args` // - `*int16_t` (item id) VB_DRAW_AMMO_COUNT, @@ -2025,6 +2030,16 @@ typedef enum { // - `*EnKo` VB_OPEN_KOKIRI_FOREST, + // #### `result` + // In `Interface_DrawAmmoCount` and `KaleidoScope_DrawAmmoCount`: + // ```c + // true + // ``` + // #### `args` + // - `*int16_t` (item id) + // - `*int16_t` (ammo count) + VB_OVERRIDE_AMMO_COUNT, + // #### `result` // ```c // false diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 53059dd80d..5e8764ce68 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -175,7 +175,12 @@ void GenerateItemPool() { if (!ctx->GetOption(RSK_STARTING_LIGHT_ARROWS)) AddItemToPool(RG_LIGHT_ARROWS, 2, 1, 1, 1); if (!ctx->GetOption(RSK_STARTING_DINS_FIRE)) AddItemToPool(RG_DINS_FIRE, 2, 1, 1, 1); if (!ctx->GetOption(RSK_STARTING_FARORES_WIND)) AddItemToPool(RG_FARORES_WIND, 2, 1, 1, 0); - if (!ctx->GetOption(RSK_STARTING_NAYRUS_LOVE)) AddItemToPool(RG_NAYRUS_LOVE, 2, 1, 1, 0); + if (ctx->GetOption(RSK_NAYRUS_LOVE_USES).Get() > 0) { + AddFixedItemToPool(RG_NAYRUS_LOVE, ctx->GetOption(RSK_NAYRUS_LOVE_USES).Get() - + (ctx->GetOption(RSK_STARTING_NAYRUS_LOVE) ? 1 : 0)); + } else if (!ctx->GetOption(RSK_STARTING_NAYRUS_LOVE)) { + AddItemToPool(RG_NAYRUS_LOVE, 2, 1, 1, 0); + } AddItemToPool(RG_GREG_RUPEE, 1, 1, 1, 1); AddFixedItemToPool(RG_PROGRESSIVE_HOOKSHOT, 2 - ctx->GetOption(RSK_STARTING_HOOKSHOT).Get()); if (!ctx->GetOption(RSK_STARTING_HYLIAN_SHIELD)) AddItemToPool(RG_HYLIAN_SHIELD, 1, 1, 1, 1); diff --git a/soh/soh/Enhancements/randomizer/ConsumableNayrusLove.cpp b/soh/soh/Enhancements/randomizer/ConsumableNayrusLove.cpp new file mode 100644 index 0000000000..ef6855db26 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ConsumableNayrusLove.cpp @@ -0,0 +1,82 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/custom-message/CustomMessageManager.h" +#include "soh/Enhancements/randomizer/SeedContext.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include +#include "functions.h" +#include "macros.h" +#include "variables.h" +} + +#define NAYRUS_LOVE_USES_MAX 99 + +#define TEXT_GET_NAYRUS_LOVE 0xAF + +static u8& NayrusLoveUses() { + return gSaveContext.ship.quest.data.randomizer.nayrusLoveUses; +} + +// The text opens before Item_Give runs, so the stored count doesn't include this item yet +static void BuildNayrusLoveMessage(uint16_t* textId, bool* loadFromMessageTable) { + CustomMessage msg = CustomMessage("You got %bNayru's Love%w!&You now have %b[[d]]%w |use|uses| of it!", + "Du erhältst %bNayrus Umarmung%w!&Du kannst sie nun %b[[d]]%w-mal einsetzen!", + "Vous obtenez l'%bAmour de Nayru%w!&Vous pouvez l'utiliser %b[[d]]%w fois!"); + uint8_t uses = NayrusLoveUses() < NAYRUS_LOVE_USES_MAX ? NayrusLoveUses() + 1 : NAYRUS_LOVE_USES_MAX; + msg.InsertNumber(uses); + msg.AutoFormat(ITEM_NAYRUS_LOVE); + msg.LoadIntoFont(); + *loadFromMessageTable = false; +} + +void RegisterConsumableNayrusLove() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_NAYRUS_LOVE_USES).Get() > 0; + + COND_HOOK(OnItemReceive, shouldRegister, [](GetItemEntry itemEntry) { + if (itemEntry.modIndex != MOD_NONE || itemEntry.itemId != ITEM_NAYRUS_LOVE) { + return; + } + if (NayrusLoveUses() < NAYRUS_LOVE_USES_MAX) { + NayrusLoveUses()++; + } + }); + + COND_VB_SHOULD(VB_CHANGE_HELD_ITEM_AND_USE_ITEM, shouldRegister, { + int32_t usedItem = va_arg(args, int32_t); + if (usedItem == ITEM_NAYRUS_LOVE && NayrusLoveUses() == 0) { + *should = false; + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); + } + }); + + COND_ID_HOOK(OnActorInit, ACTOR_MAGIC_DARK, shouldRegister, [](void*) { + // Don't consume a usage if the timer is still active + if (gSaveContext.nayrusLoveTimer != 0) { + return; + } + if (NayrusLoveUses() > 0) { + NayrusLoveUses()--; + } + }); + + COND_VB_SHOULD(VB_OVERRIDE_AMMO_COUNT, shouldRegister, { + int16_t item = *va_arg(args, int16_t*); + int16_t* ammo = va_arg(args, int16_t*); + if (item == ITEM_NAYRUS_LOVE) { + *ammo = NayrusLoveUses(); + *should = false; + } + }); + + COND_VB_SHOULD(VB_COLOR_AMMO_GREEN, shouldRegister, { + int16_t item = va_arg(args, int); + if (item == ITEM_NAYRUS_LOVE && NayrusLoveUses() >= RAND_GET_OPTION(RSK_NAYRUS_LOVE_USES).Get()) { + *should = true; + } + }); + + COND_ID_HOOK(OnOpenText, TEXT_GET_NAYRUS_LOVE, shouldRegister, BuildNayrusLoveMessage); +} + +static RegisterShipInitFunc initFunc(RegisterConsumableNayrusLove, { "IS_RANDO" }); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index c9fd6f7089..a1f60e2058 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1890,6 +1890,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l gPlayState->bombchuBowlingStatus < 1)) { *should = false; } + if (item == ITEM_NAYRUS_LOVE) { + return RAND_GET_OPTION(RSK_NAYRUS_LOVE_USES).Get() > 0; + } break; } case VB_HAVE_OCARINA_NOTE_A4: { diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 97278b6680..a6998f2a41 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -552,9 +552,13 @@ bool Logic::CanUse(RandomizerGet itemName) { return true; // AmmoCanDrop || (HasBottle() && Get(LOGIC_BUY_MAGIC_POTION)) case RG_DINS_FIRE: case RG_FARORES_WIND: - case RG_NAYRUS_LOVE: case RG_LENS_OF_TRUTH: return CanUse(RG_MAGIC_SINGLE); + case RG_NAYRUS_LOVE: + if (ctx->GetOption(RSK_NAYRUS_LOVE_USES).Get() > 0) { + return false; + } + return CanUse(RG_MAGIC_SINGLE); case RG_FIRE_ARROWS: case RG_ICE_ARROWS: case RG_LIGHT_ARROWS: diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 94388ffc31..dee09dd55e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -437,6 +437,9 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_FARORES_WIND: return INV_CONTENT(ITEM_FARORES_WIND) == ITEM_NONE ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_NAYRUS_LOVE: + if (GetRandoSettingValue(RSK_NAYRUS_LOVE_USES) > 0) { + return CAN_OBTAIN; + } if (!GetRandoSettingValue(RSK_ROCS_FEATHER)) { return INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NONE ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; } else { diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h index 0b2ca16784..1328ffb9d1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerSettingKey.h @@ -321,6 +321,7 @@ RANDO_ENUM_ITEM(RSK_STARTING_ZORA_MASK) RANDO_ENUM_ITEM(RSK_STARTING_GERUDO_MASK) RANDO_ENUM_ITEM(RSK_STARTING_MASK_OF_TRUTH) RANDO_ENUM_ITEM(RSK_PROGRESSIVE_GORON_SWORD) +RANDO_ENUM_ITEM(RSK_NAYRUS_LOVE_USES) RANDO_ENUM_ITEM(RSK_MAX) RANDO_ENUM_END(RandomizerSettingKey) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 436318c6b9..f463483ef3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -533,6 +533,13 @@ void ItemTracker_LoadFromPreset(const nlohmann::json& trackerInfo) { } } +// Roc's Feather shares Nayru's Love's slot, so the slot being filled isn't enough +static bool HasNayrusLove() { + return IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ROCS_FEATHER) + ? Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE) + : INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NAYRUS_LOVE; +} + ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { ItemTrackerNumbers result; result.currentCapacity = 0; @@ -599,6 +606,15 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { result.maxCapacity = 10; result.currentAmmo = AMMO(ITEM_BEAN); break; + case ITEM_NAYRUS_LOVE: + if (IS_RANDO) { + const uint8_t nlUses = RAND_GET_OPTION(RSK_NAYRUS_LOVE_USES).Get(); + if (nlUses > 0 && HasNayrusLove()) { + result.currentCapacity = result.maxCapacity = nlUses; + result.currentAmmo = gSaveContext.ship.quest.data.randomizer.nayrusLoveUses; + } + } + break; case ITEM_HEART_CONTAINER: result.maxCapacity = result.currentCapacity = 8; result.currentAmmo = gSaveContext.ship.stats.heartContainers; @@ -770,8 +786,8 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY || // These items have a static capacity, so display ammo instead (item.kind == ITEM_KIND_QUEST && item.id == QUEST_SKULL_TOKEN) || - (item.kind == ITEM_KIND_ITEM && - (item.id == ITEM_BEAN || item.id == ITEM_HEART_CONTAINER || item.id == ITEM_HEART_PIECE)); + (item.kind == ITEM_KIND_ITEM && (item.id == ITEM_BEAN || item.id == ITEM_NAYRUS_LOVE || + item.id == ITEM_HEART_CONTAINER || item.id == ITEM_HEART_PIECE)); bool shouldDisplayMax = !(trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 4817dcae99..b687f7521a 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -50,6 +50,8 @@ static uint16_t rupeeCounts[] = { 200, // ITEM_RUPEE_GOLD }; +static uint8_t sStartingNayrusLoveGives = 0; + void StartingItemGive(GetItemEntry getItemEntry, RandomizerCheck randomizerCheck) { if (randomizerCheck != RC_MAX) { OTRGlobals::Instance->gRandoContext->GetItemLocation(randomizerCheck)->SetCheckStatus(RCSHOW_SAVED); @@ -61,6 +63,9 @@ void StartingItemGive(GetItemEntry getItemEntry, RandomizerCheck randomizerCheck if (getItemEntry.getItemId == GI_SWORD_BGS) { gSaveContext.bgsFlag = true; } + if (getItemEntry.itemId == ITEM_NAYRUS_LOVE) { + sStartingNayrusLoveGives++; + } Item_Give(NULL, static_cast(getItemEntry.itemId)); } } else if (getItemEntry.modIndex == MOD_RANDOMIZER) { @@ -451,6 +456,9 @@ extern "C" void Randomizer_InitSaveFile() { // Reset Bombchu Bag Upgrade gSaveContext.ship.quest.data.randomizer.bombchuUpgradeLevel = 0; + gSaveContext.ship.quest.data.randomizer.nayrusLoveUses = 0; + sStartingNayrusLoveGives = 0; + SetStartingItems(); // Debug saves start with bombchus but no bag level, which would cap them at 0 @@ -679,4 +687,12 @@ extern "C" void Randomizer_InitSaveFile() { Item_Give(NULL, ITEM_GERUDO_CARD); } } + + // The item hooks aren't registered yet, so count the starting gives here + if (Randomizer_GetSettingValue(RSK_NAYRUS_LOVE_USES) > 0) { + uint8_t uses = (Randomizer_GetSettingValue(RSK_STARTING_NAYRUS_LOVE) ? 1 : 0) + sStartingNayrusLoveGives; + gSaveContext.ship.quest.data.randomizer.nayrusLoveUses = uses < 99 ? uses : 99; + } else { + gSaveContext.ship.quest.data.randomizer.nayrusLoveUses = 0; + } } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 69c7053596..860c1abc21 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1400,6 +1400,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_BUNNY_HOOD, CVAR_RANDOMIZER_SETTING("BunnyHood")); OPT_BOOL(RSK_MASKS_AS_ADULT, CVAR_RANDOMIZER_SETTING("MasksAsAdult")); OPT_BOOL(RSK_ROCS_FEATHER, CVAR_RANDOMIZER_SETTING("RocsFeather")); + OPT_U8(RSK_NAYRUS_LOVE_USES, {NumOpts(0, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("NayrusLoveUses"), WIDGET_CVAR_SLIDER_INT, 0); OPT_U8(RSK_INFINITE_UPGRADES, {"Off", "Progressive", "Condensed Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("InfiniteUpgrades")); OPT_BOOL(RSK_SKELETON_KEY, CVAR_RANDOMIZER_SETTING("SkeletonKey")); OPT_BOOL(RSK_SLINGBOW_BREAK_BEEHIVES, CVAR_RANDOMIZER_SETTING("SlingBowBeehives")); @@ -2109,29 +2110,21 @@ void Settings::CreateOptions() { WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_SHOP_SHUFFLES] = OptionGroup::SubGroup("", { &mOptionGroups[RSG_MENU_SECTION_SHOP_SHUFFLES] }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_MENU_SECTION_ADDITIONAL_ITEMS] = OptionGroup::SubGroup("Additional Items", - { - &mOptions[RSK_SHUFFLE_CHILD_WALLET], - &mOptions[RSK_INCLUDE_TYCOON_WALLET], - &mOptions[RSK_SHUFFLE_FISHING_POLE], - &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], - &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], - &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], - &mOptions[RSK_SHUFFLE_SWIM], - &mOptions[RSK_SHUFFLE_GRAB], - &mOptions[RSK_SHUFFLE_CLIMB], - &mOptions[RSK_SHUFFLE_CRAWL], - &mOptions[RSK_SHUFFLE_SPEAK], - &mOptions[RSK_SHUFFLE_OPEN_CHEST], - &mOptions[RSK_SHUFFLE_BEAN_SOULS], - &mOptions[RSK_ROCS_FEATHER], - &mOptions[RSK_BOMBCHU_BAG], - &mOptions[RSK_ENABLE_BOMBCHU_DROPS], - &mOptions[RSK_PROGRESSIVE_GORON_SWORD], - &mOptions[RSK_INFINITE_UPGRADES], - &mOptions[RSK_SKELETON_KEY], - }, - WidgetContainerType::SECTION); + mOptionGroups[RSG_MENU_SECTION_ADDITIONAL_ITEMS] = + OptionGroup::SubGroup("Additional Items", + { + &mOptions[RSK_SHUFFLE_CHILD_WALLET], &mOptions[RSK_INCLUDE_TYCOON_WALLET], + &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], + &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], + &mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_GRAB], + &mOptions[RSK_SHUFFLE_CLIMB], &mOptions[RSK_SHUFFLE_CRAWL], + &mOptions[RSK_SHUFFLE_SPEAK], &mOptions[RSK_SHUFFLE_OPEN_CHEST], + &mOptions[RSK_SHUFFLE_BEAN_SOULS], &mOptions[RSK_ROCS_FEATHER], + &mOptions[RSK_NAYRUS_LOVE_USES], &mOptions[RSK_BOMBCHU_BAG], + &mOptions[RSK_ENABLE_BOMBCHU_DROPS], &mOptions[RSK_PROGRESSIVE_GORON_SWORD], + &mOptions[RSK_INFINITE_UPGRADES], &mOptions[RSK_SKELETON_KEY], + }, + WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_ADDITIONAL_ITEMS] = OptionGroup::SubGroup("", { &mOptionGroups[RSG_MENU_SECTION_ADDITIONAL_ITEMS] }, WidgetContainerType::COLUMN); mOptionGroups[RSG_MENU_SIDEBAR_SHUFFLES] = @@ -2321,6 +2314,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BEAN_SOULS], &mOptions[RSK_ROCS_FEATHER], + &mOptions[RSK_NAYRUS_LOVE_USES], &mOptions[RSK_PROGRESSIVE_GORON_SWORD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 5b55b033b1..26b395d4aa 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -303,6 +303,7 @@ void SaveManager::LoadRandomizer() { SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->LoadData("bombchuUpgradeLevel", gSaveContext.ship.quest.data.randomizer.bombchuUpgradeLevel); + SaveManager::Instance->LoadData("nayrusLoveUses", gSaveContext.ship.quest.data.randomizer.nayrusLoveUses); SaveManager::Instance->LoadData("silverShadowBlades", gSaveContext.ship.quest.data.randomizer.silverShadowBlades); SaveManager::Instance->LoadData("silverShadowPit", gSaveContext.ship.quest.data.randomizer.silverShadowPit); SaveManager::Instance->LoadData("silverShadowSpikes", gSaveContext.ship.quest.data.randomizer.silverShadowSpikes); @@ -493,6 +494,7 @@ void SaveManager::SaveRandomizer(const SaveContext& saveContext, int sectionID, SaveManager::Instance->SaveData("triforcePiecesCollected", saveContext.ship.quest.data.randomizer.triforcePiecesCollected); SaveManager::Instance->SaveData("bombchuUpgradeLevel", saveContext.ship.quest.data.randomizer.bombchuUpgradeLevel); + SaveManager::Instance->SaveData("nayrusLoveUses", saveContext.ship.quest.data.randomizer.nayrusLoveUses); SaveManager::Instance->SaveData("silverShadowBlades", gSaveContext.ship.quest.data.randomizer.silverShadowBlades); SaveManager::Instance->SaveData("silverShadowPit", gSaveContext.ship.quest.data.randomizer.silverShadowPit); SaveManager::Instance->SaveData("silverShadowSpikes", gSaveContext.ship.quest.data.randomizer.silverShadowSpikes); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 524ecd89f0..d630dbebdd 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -4918,7 +4918,9 @@ void Interface_DrawAmmoCount(PlayState* play, s16 button, s16 alpha) { i = ITEM_BOW; } - ammo = AMMO(i); + if (GameInteractor_Should(VB_OVERRIDE_AMMO_COUNT, true, &i, &ammo)) { + ammo = AMMO(i); + } gDPPipeSync(OVERLAY_DISP++); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index 4a5a79b830..aa59fd939f 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -31,8 +31,10 @@ extern const char* _gAmmoDigit0Tex[]; s8 ItemInSlotUsesAmmo(s16 slot) { s16 item = gSaveContext.inventory.items[slot]; - return item == ITEM_STICK || item == ITEM_NUT || item == ITEM_BOMB || item == ITEM_BOW || item == ITEM_SLINGSHOT || - item == ITEM_BOMBCHU || item == ITEM_BEAN; + return GameInteractor_Should(VB_DRAW_AMMO_COUNT, + item == ITEM_STICK || item == ITEM_NUT || item == ITEM_BOMB || item == ITEM_BOW || + item == ITEM_SLINGSHOT || item == ITEM_BOMBCHU || item == ITEM_BEAN, + &item); } void KaleidoScope_DrawAmmoCount(PauseContext* pauseCtx, GraphicsContext* gfxCtx, s16 item, int slot) { @@ -45,7 +47,9 @@ void KaleidoScope_DrawAmmoCount(PauseContext* pauseCtx, GraphicsContext* gfxCtx, OPEN_DISPS(gfxCtx); - ammo = AMMO(item); + if (GameInteractor_Should(VB_OVERRIDE_AMMO_COUNT, true, &item, &ammo)) { + ammo = AMMO(item); + } gDPPipeSync(POLY_OPA_DISP++);