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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion soh/soh/Enhancements/Cheats/Infinite/Money.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "soh/Enhancements/randomizer/BankCards.h"
#include "z64save.h"
#include "variables.h"

Expand All @@ -19,7 +20,7 @@ void OnGameFrameUpdateInfiniteMoney() {
return;
}

gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
gSaveContext.rupees = Randomizer_BankCards_GetMaxRupees();
}

void RegisterInfiniteMoney() {
Expand Down
6 changes: 4 additions & 2 deletions soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ShipInit.hpp"
#include "soh/Enhancements/randomizer/BankCards.h"

extern "C" {
#include "z64save.h"
Expand All @@ -18,12 +19,13 @@ void RegisterFasterRupeeAccumulator() {

// Gaining rupees
if (gSaveContext.rupeeAccumulator > 0) {
s16 maxRupees = Randomizer_BankCards_GetMaxRupees();
// Wallet is full
if (gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET)) {
if (gSaveContext.rupees >= maxRupees) {
return;
}

if (gSaveContext.rupeeAccumulator >= 10 && gSaveContext.rupees + 10 < CUR_CAPACITY(UPG_WALLET)) {
if (gSaveContext.rupeeAccumulator >= 10 && gSaveContext.rupees + 10 < maxRupees) {
gSaveContext.rupeeAccumulator -= 10;
gSaveContext.rupees += 10;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ have functions to both enable and disable said effect.
#include "GameInteractor.h"
#include <libultraship/bridge.h>
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
#include "soh/Enhancements/randomizer/BankCards.h"

extern "C" {
#include <z64.h>
Expand Down Expand Up @@ -148,7 +149,7 @@ GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if ((parameters[0] < 0 && gSaveContext.rupees <= 0) ||
(parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))) {
(parameters[0] > 0 && gSaveContext.rupees >= Randomizer_BankCards_GetMaxRupees())) {
return GameInteractionEffectQueryResult::NotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
Expand Down
122 changes: 122 additions & 0 deletions soh/soh/Enhancements/randomizer/BankCards.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include "BankCards.h"
#include "soh/OTRGlobals.h"
#include "randomizerTypes.h"

extern "C" {
#include "macros.h"
#include "z64save.h"
#include "functions.h"
#include "variables.h"
extern s32 Flags_GetRandomizerInf(RandomizerInf flag);
}

namespace Rando::BankCards {

static constexpr s16 BANK_CARD_MAX_RUPEES = 9999;

static bool HasRandomizerContext() {
return OTRGlobals::Instance != nullptr && OTRGlobals::Instance->gRandomizer != nullptr;
}

bool IsEnabled() {
return IS_RANDO && HasRandomizerContext() &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BANK_CARDS) != 0;
}

s16 GetMaxRupees() {
// When the setting is off we behave exactly like the vanilla wallet cap.
if (!IsEnabled()) {
return CUR_CAPACITY(UPG_WALLET);
}

return BANK_CARD_MAX_RUPEES;
}

s16 GetTransactionLimit() {
if (IsEnabled() && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) {
return 0;
}

return CUR_CAPACITY(UPG_WALLET);
}

bool CanSpend(s32 price) {
if (price < 0) {
return false;
}

// Bank Cards restrict a single purchase to the current wallet size; otherwise only check the total rupees.
if (IsEnabled() && price > GetTransactionLimit()) {
return false;
}

return gSaveContext.rupees >= price;
}

bool ShouldApplyFullWallets() {
if (!HasRandomizerContext() || IsEnabled()) {
return false;
}

return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS) != 0;
}

bool FormatRupeeDigits(s16 rupees, s16* counterDigits, s16* firstDigitIndex, s16* digitCount) {
if (!IsEnabled() || counterDigits == nullptr || firstDigitIndex == nullptr || digitCount == nullptr) {
return false;
}

s16 cappedRupees = rupees;
if (cappedRupees < 0) {
cappedRupees = 0;
}
s16 maxRupees = GetMaxRupees();
if (cappedRupees > maxRupees) {
cappedRupees = maxRupees;
}

counterDigits[0] = cappedRupees / 1000;
counterDigits[1] = (cappedRupees / 100) % 10;
counterDigits[2] = (cappedRupees / 10) % 10;
counterDigits[3] = cappedRupees % 10;

if (cappedRupees >= 1000) {
*firstDigitIndex = 0;
*digitCount = 4;
} else if (cappedRupees >= 100) {
*firstDigitIndex = 0;
*digitCount = 3;
} else {
*firstDigitIndex = 1;
*digitCount = 2;
}

return true;
}

} // namespace Rando::BankCards

extern "C" bool Randomizer_BankCardsEnabled() {
return Rando::BankCards::IsEnabled();
}

extern "C" s16 Randomizer_BankCards_GetMaxRupees() {
return Rando::BankCards::GetMaxRupees();
}

extern "C" s16 Randomizer_BankCards_GetTransactionLimit() {
return Rando::BankCards::GetTransactionLimit();
}

extern "C" bool Randomizer_BankCards_CanSpend(s32 price) {
return Rando::BankCards::CanSpend(price);
}

extern "C" bool Randomizer_BankCards_ShouldApplyFullWallets() {
return Rando::BankCards::ShouldApplyFullWallets();
}

extern "C" bool Randomizer_BankCards_FormatRupeeDigits(s16 rupees, s16* counterDigits, s16* firstDigitIndex,
s16* digitCount) {
return Rando::BankCards::FormatRupeeDigits(rupees, counterDigits, firstDigitIndex, digitCount);
}
21 changes: 21 additions & 0 deletions soh/soh/Enhancements/randomizer/BankCards.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <stdbool.h>
#include <libultraship/libultra.h>

#ifdef __cplusplus
extern "C" {
#endif

bool Randomizer_BankCardsEnabled();
s16 Randomizer_BankCards_GetMaxRupees();
s16 Randomizer_BankCards_GetTransactionLimit();
bool Randomizer_BankCards_CanSpend(s32 price);
bool Randomizer_BankCards_ShouldApplyFullWallets();
bool Randomizer_BankCards_FormatRupeeDigits(s16 rupees, s16* counterDigits, s16* firstDigitIndex,
s16* digitCount);

#ifdef __cplusplus
}
#endif

22 changes: 12 additions & 10 deletions soh/soh/Enhancements/randomizer/hook_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "soh/Enhancements/randomizer/randomizerTypes.h"
#include "soh/Enhancements/randomizer/dungeon.h"
#include "soh/Enhancements/randomizer/static_data.h"
#include "soh/Enhancements/randomizer/BankCards.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/SohGui/ImGuiUtils.h"
Expand Down Expand Up @@ -1160,9 +1161,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
}
case VB_CHECK_RANDO_PRICE_OF_CARPET_SALESMAN: {
if (EnJs_RandoCanGetCarpetMerchantItem()) {
*should =
gSaveContext.rupees <
const s32 price =
OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice();
*should = !Randomizer_BankCards_CanSpend(price);
}
break;
}
Expand All @@ -1188,8 +1189,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
}
case VB_CHECK_RANDO_PRICE_OF_MEDIGORON: {
if (EnGm_RandoCanGetMedigoronItem()) {
*should = gSaveContext.rupees <
OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice();
const s32 price = OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice();
*should = !Randomizer_BankCards_CanSpend(price);
}
break;
}
Expand Down Expand Up @@ -1401,8 +1402,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
}
case VB_GRANNY_SAY_INSUFFICIENT_RUPEES: {
if (EnDs_RandoCanGetGrannyItem()) {
*should = gSaveContext.rupees <
OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice();
const s32 price = OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice();
*should = !Randomizer_BankCards_CanSpend(price);
}
break;
}
Expand Down Expand Up @@ -1617,7 +1618,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break;
}
case VB_RENDER_RUPEE_COUNTER: {
if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) || Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) {
if ((!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) && !Randomizer_BankCardsEnabled()) ||
Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) {
*should = false;
}
break;
Expand Down Expand Up @@ -1916,7 +1918,7 @@ u32 EnDns_RandomizerPurchaseableCheck(EnDns* enDns) {
if (Flags_GetRandomizerInf(enDns->sohScrubIdentity.randomizerInf)) {
return 3; // Can't get this now
}
if (gSaveContext.rupees < enDns->dnsItemEntry->itemPrice) {
if (!Randomizer_BankCards_CanSpend(enDns->dnsItemEntry->itemPrice)) {
return 0; // Not enough rupees
}
return 4;
Expand Down Expand Up @@ -2226,10 +2228,10 @@ void RandomizerOnGameFrameUpdateHandler() {
}

if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) {
gSaveContext.rupees = static_cast<s16>(CUR_CAPACITY(UPG_WALLET));
gSaveContext.rupees = Randomizer_BankCards_GetMaxRupees();
}

if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) {
if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) && !Randomizer_BankCardsEnabled()) {
gSaveContext.rupees = 0;
}
}
Expand Down
3 changes: 3 additions & 0 deletions soh/soh/Enhancements/randomizer/option_descriptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,9 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_MASK_SHOP_HINT] =
"Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre.";
mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees.";
mOptionDescriptions[RSK_BANK_CARDS] =
"Raises the rupee balance cap to 9999 while wallet upgrades set the maximum you can spend per purchase. "
"Full Wallets is ignored when this is on.";
mOptionDescriptions[RSK_BOMBCHU_BAG] =
"None - Bombchus have vanilla behavior, any Bombchu requirement is filled by Bomb Bag + a renewable source of "
"Bombchus.\n\n"
Expand Down
5 changes: 3 additions & 2 deletions soh/soh/Enhancements/randomizer/randomizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <stdexcept>
#include "randomizer_check_objects.h"
#include "randomizer_check_tracker.h"
#include "BankCards.h"
#include <sstream>
#include <tuple>
#include <functional>
Expand Down Expand Up @@ -6266,13 +6267,13 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
break;
case RG_TYCOON_WALLET:
Inventory_ChangeUpgrade(UPG_WALLET, 3);
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS)) {
if (Randomizer_BankCards_ShouldApplyFullWallets()) {
Rupees_ChangeBy(999);
}
break;
case RG_CHILD_WALLET:
Flags_SetRandomizerInf(RAND_INF_HAS_WALLET);
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS)) {
if (Randomizer_BankCards_ShouldApplyFullWallets()) {
Rupees_ChangeBy(99);
}
break;
Expand Down
1 change: 1 addition & 0 deletions soh/soh/Enhancements/randomizer/randomizerTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -6183,6 +6183,7 @@ typedef enum {
RSK_STARTING_STICKS,
RSK_STARTING_NUTS,
RSK_FULL_WALLETS,
RSK_BANK_CARDS,
RSK_SHUFFLE_CHEST_MINIGAME,
RSK_BIG_POE_COUNT,
RSK_SKIP_EPONA_RACE,
Expand Down
14 changes: 10 additions & 4 deletions soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "randomizer_check_tracker.h"
#include "randomizer_item_tracker.h"
#include "randomizerTypes.h"
#include "BankCards.h"
#include "soh/cvar_prefixes.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/OTRGlobals.h"
Expand Down Expand Up @@ -471,10 +472,15 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
case ITEM_WALLET_ADULT:
case ITEM_WALLET_GIANT:
result.currentCapacity =
IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET);
result.maxCapacity =
IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999
: 500;
(IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) && !Randomizer_BankCardsEnabled())
? 0
: Randomizer_BankCards_GetMaxRupees();
result.maxCapacity = IS_RANDO && Randomizer_BankCardsEnabled()
? Randomizer_BankCards_GetMaxRupees()
: (IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET)
? 999
: 500);
result.currentAmmo = gSaveContext.rupees;
break;
case ITEM_BOMBCHU:
Expand Down
12 changes: 3 additions & 9 deletions soh/soh/Enhancements/randomizer/savefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/randomizer/logic.h"
#include "soh/Enhancements/randomizer/BankCards.h"

extern "C" {
#include <z64.h>
Expand All @@ -18,14 +19,7 @@ GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, G
// Item_Give in z_parameter, we'll need to update Item_Give to ensure
// nothing breaks when calling it without a valid play first.
void GiveLinkRupees(int numOfRupees) {
int maxRupeeCount = 0;
if (CUR_UPG_VALUE(UPG_WALLET) == 0) {
maxRupeeCount = 99;
} else if (CUR_UPG_VALUE(UPG_WALLET) == 1) {
maxRupeeCount = 200;
} else if (CUR_UPG_VALUE(UPG_WALLET) == 2) {
maxRupeeCount = 500;
}
int maxRupeeCount = Randomizer_BankCards_GetMaxRupees();

int newRupeeCount = gSaveContext.rupees;
newRupeeCount += numOfRupees;
Expand Down Expand Up @@ -179,7 +173,7 @@ void SetStartingItems() {
}
}

if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {
if (Randomizer_BankCards_ShouldApplyFullWallets()) {
GiveLinkRupees(9001);
}

Expand Down
2 changes: 2 additions & 0 deletions soh/soh/Enhancements/randomizer/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ void Settings::CreateOptions() {
OPT_BOOL(RSK_STARTING_STICKS, "Start with Stick Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSticks"), "", WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_STARTING_NUTS, "Start with Nut Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingNuts"), "", WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_FULL_WALLETS, "Full Wallets", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), mOptionDescriptions[RSK_FULL_WALLETS], WidgetType::Checkbox, RO_GENERIC_OFF);
OPT_BOOL(RSK_BANK_CARDS, "Bank Cards", CVAR_RANDOMIZER_SETTING("BankCards"), mOptionDescriptions[RSK_BANK_CARDS]);
OPT_BOOL(RSK_STARTING_ZELDAS_LULLABY, "Start with Zelda's Lullaby", CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_EPONAS_SONG, "Start with Epona's Song", CVAR_RANDOMIZER_SETTING("StartingEponasSong"), "", IMFLAG_NONE);
OPT_BOOL(RSK_STARTING_SARIAS_SONG, "Start with Saria's Song", CVAR_RANDOMIZER_SETTING("StartingSariasSong"), "", IMFLAG_NONE);
Expand Down Expand Up @@ -1430,6 +1431,7 @@ void Settings::CreateOptions() {
mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] = OptionGroup::SubGroup("Additional Features",
{
&mOptions[RSK_FULL_WALLETS],
&mOptions[RSK_BANK_CARDS],
&mOptions[RSK_BOMBCHU_BAG],
&mOptions[RSK_ENABLE_BOMBCHU_DROPS],
&mOptions[RSK_BLUE_FIRE_ARROWS],
Expand Down
Loading
Loading