Rando: Shuffle consumable bags (#3959)

* Main implementation

* Fix sticks & nuts from shops & checks

* Change the models to normal stick & nut

Worth noting that before you have the bags, the refills are blue rupees so there will not be model collision

* Update hook_handlers.cpp
This commit is contained in:
Pepe20129 2024-07-17 18:42:56 +02:00 committed by GitHub
parent f2958aea1c
commit a5c0cede12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 127 additions and 17 deletions

View File

@ -977,6 +977,13 @@ void GenerateItemPool() {
AddItemToMainPool(RG_PROGRESSIVE_WALLET);
}
if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) {
AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE);
}
if (ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG)) {
AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE);
}
if (ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)) {
AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS, 5);

View File

@ -1443,6 +1443,25 @@ void RandomizerOnActorInitHandler(void* actorRef) {
Actor_Kill(actor);
}
}
//consumable bags
if (
actor->id = ACTOR_EN_ITEM00 &&
(
(
RAND_GET_OPTION(RSK_SHUFFLE_DEKU_STICK_BAG) &&
CUR_UPG_VALUE(UPG_STICKS) == 0 &&
actor->params == ITEM00_STICK
) ||
(
RAND_GET_OPTION(RSK_SHUFFLE_DEKU_NUT_BAG) &&
CUR_UPG_VALUE(UPG_NUTS) == 0 &&
actor->params == ITEM00_NUTS
)
)
) {
Actor_Kill(actor);
}
}
void RandomizerRegisterHooks() {

View File

@ -123,6 +123,10 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
case RG_PROGRESSIVE_STICK_UPGRADE:
switch (CUR_UPG_VALUE(UPG_STICKS)) {
case 0:
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) {
actual = RG_DEKU_STICK_BAG;
break;
}
case 1:
actual = RG_DEKU_STICK_CAPACITY_20;
break;
@ -137,6 +141,10 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
case RG_PROGRESSIVE_NUT_UPGRADE:
switch (CUR_UPG_VALUE(UPG_NUTS)) {
case 0:
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) {
actual = RG_DEKU_NUT_BAG;
break;
}
case 1:
actual = RG_DEKU_NUT_CAPACITY_30;
break;

View File

@ -64,8 +64,8 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, &logic->ProgressiveBulletBag,RHT_PROGRESSIVE_SLINGSHOT, true);
itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Brieftasche" }, ITEMTYPE_ITEM, 0x85, true, &logic->ProgressiveWallet, RHT_PROGRESSIVE_WALLET, true);
itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Skala" }, ITEMTYPE_ITEM, 0x86, true, &logic->ProgressiveScale, RHT_PROGRESSIVE_SCALE, true);
itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nusskapazität" }, ITEMTYPE_ITEM, 0x87, false, &logic->noVariable, RHT_PROGRESSIVE_NUT_UPGRADE, true);
itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stick-Kapazität" }, ITEMTYPE_ITEM, 0x88, false, &logic->noVariable, RHT_PROGRESSIVE_STICK_UPGRADE, true);
itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nusskapazität" }, ITEMTYPE_ITEM, 0x87, true, &logic->ProgressiveNutBag, RHT_PROGRESSIVE_NUT_UPGRADE, true);
itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stick-Kapazität" }, ITEMTYPE_ITEM, 0x88, true, &logic->ProgressiveStickBag, RHT_PROGRESSIVE_STICK_UPGRADE, true);
itemTable[RG_PROGRESSIVE_BOMBCHUS] = Item(RG_PROGRESSIVE_BOMBCHUS, Text{ "Progressive Bombchu", "Missiles (prog.)", "Progressive Kriechgrube" }, ITEMTYPE_ITEM, 0x89, true, &logic->Bombchus, RHT_PROGRESSIVE_BOMBCHUS, RG_PROGRESSIVE_BOMBCHUS, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, true);
itemTable[RG_PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives magisches Messgerät" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_PROGRESSIVE_MAGIC_METER, true);
itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, &logic->ProgressiveOcarina, RHT_PROGRESSIVE_OCARINA, true);
@ -289,6 +289,10 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, &logic->ProgressiveWallet, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale);
itemTable[RG_DEKU_STICK_BAG] = Item(RG_DEKU_STICK_BAG, Text{ "Deku Stick Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, &logic->ProgressiveStickBag, RHT_NONE, RG_DEKU_STICK_BAG, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, &logic->ProgressiveNutBag, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, &logic->noVariable, RHT_NONE);
itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, &logic->noVariable, RHT_NONE);
// Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen)
@ -314,10 +318,10 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesige Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, &logic->ProgressiveWallet, RHT_GIANT_WALLET, ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Reiche Geldbörse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, &logic->ProgressiveWallet, RHT_TYCOON_WALLET, RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_CHILD_WALLET] = Item(RG_CHILD_WALLET, Text{ "Child Wallet", "Bourse de Magnat", "Reiche Geldbörse" },/*FIXME: still says tycoon in french & german*/ ITEMTYPE_ITEM, RG_CHILD_WALLET, true, &logic->ProgressiveWallet, RHT_CHILD_WALLET, RG_CHILD_WALLET, OBJECT_GI_PURSE, GID_WALLET_ADULT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{ "Deku Nut Capacity (30)", "Capacité de noix Mojo (30)", "Deku Nuss Kapazität (30)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, false, &logic->noVariable, RHT_DEKU_NUT_CAPACITY_30, ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{ "Deku Nut Capacity (40)", "Capacité de noix Mojo (40)", "Deku Nuss Kapazität (40)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_40, false, &logic->noVariable, RHT_DEKU_NUT_CAPACITY_40, ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_STICK_CAPACITY_20] = Item(RG_DEKU_STICK_CAPACITY_20, Text{ "Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Deku Stick Kapazität (20)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_20,false, &logic->noVariable, RHT_DEKU_STICK_CAPACITY_20, ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_STICK_CAPACITY_30] = Item(RG_DEKU_STICK_CAPACITY_30, Text{ "Deku Stick Capacity (30)", "Capacité de Bâtons Mojo (30)", "Deku Stick Kapazität (30)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30,false, &logic->noVariable, RHT_DEKU_STICK_CAPACITY_30, ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{ "Deku Nut Capacity (30)", "Capacité de noix Mojo (30)", "Deku Nuss Kapazität (30)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, &logic->ProgressiveNutBag, RHT_DEKU_NUT_CAPACITY_30, ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{ "Deku Nut Capacity (40)", "Capacité de noix Mojo (40)", "Deku Nuss Kapazität (40)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_40, true, &logic->ProgressiveNutBag, RHT_DEKU_NUT_CAPACITY_40, ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_STICK_CAPACITY_20] = Item(RG_DEKU_STICK_CAPACITY_20, Text{ "Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Deku Stick Kapazität (20)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_20,true, &logic->ProgressiveStickBag, RHT_DEKU_STICK_CAPACITY_20, ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_STICK_CAPACITY_30] = Item(RG_DEKU_STICK_CAPACITY_30, Text{ "Deku Stick Capacity (30)", "Capacité de Bâtons Mojo (30)", "Deku Stick Kapazität (30)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30,true, &logic->ProgressiveStickBag, RHT_DEKU_STICK_CAPACITY_30, ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_MAGIC_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magisches Messgerät" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_MAGIC_SINGLE, RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbesserte Magieanzeige" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce Piece" }, ITEMTYPE_ITEM, 0xDF, true, &logic->TriforcePieces, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);

View File

@ -297,8 +297,8 @@ namespace Rando {
//refills
Bombs = BombBag;
Nuts = DekuNutDrop || Nuts;
Sticks = DekuStickDrop || Sticks;
Nuts = (ProgressiveNutBag != 0 && DekuNutDrop) || Nuts;
Sticks = (ProgressiveStickBag != 0 && DekuStickDrop) || Sticks;
Bugs = HasBottle && BugsAccess;
BlueFire = (HasBottle && BlueFireAccess) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS));
Fish = HasBottle && FishAccess;
@ -626,6 +626,8 @@ namespace Rando {
OcarinaCDownButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1;
//Progressive Items
ProgressiveStickBag = ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1;
ProgressiveNutBag = ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1;
ProgressiveBulletBag = 0;
ProgressiveBombBag = 0;
ProgressiveMagic = 0;

View File

@ -140,6 +140,8 @@ class Logic {
bool GregInLacsLogic = false;
// Progressive Items
uint8_t ProgressiveStickBag = 0;
uint8_t ProgressiveNutBag = 0;
uint8_t ProgressiveBulletBag = 0;
uint8_t ProgressiveBombBag = 0;
uint8_t ProgressiveMagic = 0;

View File

@ -249,6 +249,12 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n"
"\n"
"The fishing pole is required to play the fishing pond minigame.";
mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG] = "Shuffles the deku stick bag into the item pool.\n"
"\n"
"The deku stick bag is required to hold deku sticks.";
mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG] = "Shuffles the deku nut bag into the item pool.\n"
"\n"
"The deku nut bag is required to hold deku nuts.";
mOptionDescriptions[RSK_SHOPSANITY] = "Off - All shop items will be the same as vanilla.\n"
"\n"
"0 Items - Vanilla shop items will be shuffled among different shops.\n"

View File

@ -397,8 +397,16 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
// Inventory Items
case RG_PROGRESSIVE_STICK_UPGRADE:
return CUR_UPG_VALUE(UPG_STICKS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE;
case RG_DEKU_STICK_1:
case RG_BUY_DEKU_STICK_1:
return CUR_UPG_VALUE(UPG_STICKS) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE;
case RG_PROGRESSIVE_NUT_UPGRADE:
return CUR_UPG_VALUE(UPG_NUTS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE;
case RG_DEKU_NUTS_5:
case RG_DEKU_NUTS_10:
case RG_BUY_DEKU_NUTS_5:
case RG_BUY_DEKU_NUTS_10:
return CUR_UPG_VALUE(UPG_NUTS) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE;
case RG_PROGRESSIVE_BOMB_BAG:
return CUR_UPG_VALUE(UPG_BOMB_BAG) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE;
case RG_BOMBS_5:
@ -694,14 +702,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
case RG_PIECE_OF_HEART:
case RG_HEART_CONTAINER:
case RG_ICE_TRAP:
case RG_DEKU_NUTS_5:
case RG_DEKU_NUTS_10:
case RG_DEKU_STICK_1:
case RG_TREASURE_GAME_HEART:
case RG_TREASURE_GAME_GREEN_RUPEE:
case RG_BUY_DEKU_NUTS_5:
case RG_BUY_DEKU_NUTS_10:
case RG_BUY_DEKU_STICK_1:
case RG_BUY_HEART:
case RG_TRIFORCE_PIECE:
default:
@ -2952,7 +2954,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) {
void Randomizer::CreateCustomMessages() {
// RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED
// with GIMESSAGE(getItemID, itemID, english, german, french).
const std::array<GetItemMessage, 74> getItemMessages = {{
const std::array<GetItemMessage, 76> getItemMessages = {{
GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON,
"You found %gGreg%w!",
"%gGreg%w! Du hast ihn wirklich gefunden!",
@ -3224,6 +3226,8 @@ void Randomizer::CreateCustomMessages() {
"Vous trouvez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
GIMESSAGE_UNTRANSLATED(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!"),
GIMESSAGE_UNTRANSLATED(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!"),
GIMESSAGE_UNTRANSLATED(RG_DEKU_STICK_BAG, ITEM_STICK, "You found the %rDeku Stick Bag%w!&You can now hold deku sticks!"),
GIMESSAGE_UNTRANSLATED(RG_DEKU_NUT_BAG, ITEM_NUT, "You found the %rDeku Nut Bag%w!&You can now hold deku nuts!"),
}};
CreateGetItemMessages(&getItemMessages);
CreateRupeeMessages();

View File

@ -1980,6 +1980,8 @@ typedef enum {
RG_OCARINA_C_LEFT_BUTTON,
RG_OCARINA_C_RIGHT_BUTTON,
RG_FISHING_POLE,
RG_DEKU_STICK_BAG,
RG_DEKU_NUT_BAG,
RG_HINT,
RG_TYCOON_WALLET,
RG_BRONZE_SCALE,
@ -3711,6 +3713,8 @@ typedef enum {
RSK_FISHSANITY_POND_COUNT,
RSK_FISHSANITY_AGE_SPLIT,
RSK_SHUFFLE_FISHING_POLE,
RSK_SHUFFLE_DEKU_STICK_BAG,
RSK_SHUFFLE_DEKU_NUT_BAG,
RSK_MAX
} RandomizerSettingKey;

View File

@ -150,8 +150,12 @@ void SetStartingItems() {
}
if (Randomizer_GetSettingValue(RSK_STARTING_CONSUMABLES)) {
GiveLinkDekuSticks(10);
GiveLinkDekuNuts(20);
if (!Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) {
GiveLinkDekuSticks(10);
}
if (!Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) {
GiveLinkDekuNuts(20);
}
}
if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {

View File

@ -120,6 +120,8 @@ void Settings::CreateOptions() {
mOptions[RSK_SHUFFLE_CHEST_MINIGAME] = Option::U8("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"});
mOptions[RSK_SHUFFLE_100_GS_REWARD] = Option::Bool("Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
mOptions[RSK_SHUFFLE_BOSS_SOULS] = Option::U8("Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox);
mOptions[RSK_SHUFFLE_DEKU_STICK_BAG] = Option::Bool("Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
mOptions[RSK_SHUFFLE_DEKU_NUT_BAG] = Option::Bool("Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF);
mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF);
mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE);
mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]);
@ -662,6 +664,8 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
&mOptions[RSK_SHUFFLE_FISHING_POLE],
&mOptions[RSK_SHUFFLE_DEKU_STICK_BAG],
&mOptions[RSK_SHUFFLE_DEKU_NUT_BAG],
}, false, WidgetContainerType::COLUMN);
mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", {
&mOptions[RSK_SHOPSANITY],
@ -889,6 +893,8 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_BOSS_SOULS],
&mOptions[RSK_SHUFFLE_DEKU_STICK_BAG],
&mOptions[RSK_SHUFFLE_DEKU_NUT_BAG],
});
mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", {
&mOptions[RSK_SHUFFLE_MAPANDCOMPASS],
@ -1117,6 +1123,8 @@ void Settings::CreateOptions() {
{ "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS },
{ "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD },
{ "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS },
{ "Shuffle Settings:Shuffle Deku Stick Bag", RSK_SHUFFLE_DEKU_STICK_BAG },
{ "Shuffle Settings:Shuffle Deku Nut Bag", RSK_SHUFFLE_DEKU_NUT_BAG },
{ "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD },
{ "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD },
{ "Start with Fairy Ocarina", RSK_STARTING_OCARINA },

View File

@ -1926,6 +1926,26 @@ u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) {
* @return u8
*/
u8 Item_Give(PlayState* play, u8 item) {
//prevents getting sticks without the bag in case something got missed
if (
IS_RANDO &&
(item == ITEM_STICK || item == ITEM_STICKS_5 || item == ITEM_STICKS_10) &&
Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG) &&
CUR_UPG_VALUE(UPG_STICKS) == 0
) {
return;
}
//prevents getting nuts without the bag in case something got missed
if (
IS_RANDO &&
(item == ITEM_NUT || item == ITEM_NUTS_5 || item == ITEM_NUTS_10) &&
Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG) &&
CUR_UPG_VALUE(UPG_NUTS) == 0
) {
return;
}
lusprintf(__FILE__, __LINE__, 2, "Item Give - item: %#x", item);
static s16 sAmmoRefillCounts[] = { 5, 10, 20, 30, 5, 10, 30, 0, 5, 20, 1, 5, 20, 50, 200, 10 };
s16 i;
@ -2776,6 +2796,20 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
return Return_Item_Entry(giEntry, RG_NONE);
}
if (item == RG_DEKU_STICK_BAG) {
Inventory_ChangeUpgrade(UPG_STICKS, 1);
INV_CONTENT(ITEM_STICK) = ITEM_STICK;
AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS);
return Return_Item_Entry(giEntry, RG_NONE);
}
if (item == RG_DEKU_NUT_BAG) {
Inventory_ChangeUpgrade(UPG_NUTS, 1);
INV_CONTENT(ITEM_NUT) = ITEM_NUT;
AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS);
return Return_Item_Entry(giEntry, RG_NONE);
}
temp = gSaveContext.inventory.items[slot];
osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp);
INV_CONTENT(item) = item;

View File

@ -487,6 +487,10 @@ s32 EnGirlA_CanBuy_Bombs(PlayState* play, EnGirlA* this) {
}
s32 EnGirlA_CanBuy_DekuNuts(PlayState* play, EnGirlA* this) {
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG) && CUR_CAPACITY(UPG_NUTS) == 0) {
return CANBUY_RESULT_CANT_GET_NOW;
}
if ((CUR_CAPACITY(UPG_NUTS) != 0) && (AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS))) {
return CANBUY_RESULT_CANT_GET_NOW;
}
@ -500,6 +504,10 @@ s32 EnGirlA_CanBuy_DekuNuts(PlayState* play, EnGirlA* this) {
}
s32 EnGirlA_CanBuy_DekuSticks(PlayState* play, EnGirlA* this) {
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG) && CUR_CAPACITY(UPG_STICKS) == 0) {
return CANBUY_RESULT_CANT_GET_NOW;
}
if ((CUR_CAPACITY(UPG_STICKS) != 0) && (AMMO(ITEM_STICK) >= CUR_CAPACITY(UPG_STICKS))) {
return CANBUY_RESULT_CANT_GET_NOW;
}