diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e4f5e6798..b758d4075 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1184,7 +1184,7 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_ALL; if (location->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) { - scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF;; + scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF; } scrubIdentity.itemPrice = OTRGlobals::Instance->gRandoContext->GetItemLocation(scrubIdentity.randomizerCheck)->GetPrice(); @@ -3026,3 +3026,348 @@ void RandomizerSettingsWindow::InitElement() { seedString = (char*)calloc(MAX_SEED_STRING_SIZE, sizeof(char)); Rando::Context::GetInstance()->GetSettings()->UpdateOptionProperties(); } + +// Gameplay stat tracking: Update time the item was acquired +// (special cases for rando items) +void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { + + u32 time = GAMEPLAYSTAT_TOTAL_TIME; + + // Have items in Link's pocket shown as being obtained at 0.1 seconds + if (time == 0) { + time = 1; + } + + // Use ITEM_KEY_BOSS to timestamp Ganon's boss key + if (item == RG_GANONS_CASTLE_BOSS_KEY) { + gSaveContext.sohStats.itemTimestamp[ITEM_KEY_BOSS] = time; + } + + // Count any bottled item as a bottle + if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) { + if (gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] == 0) { + gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] = time; + } + return; + } + // Count any bombchu pack as bombchus + if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) { + if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) { + gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time; + } + return; + } + if (item == RG_MAGIC_SINGLE) { + gSaveContext.sohStats.itemTimestamp[ITEM_SINGLE_MAGIC] = time; + } + if (item == RG_DOUBLE_DEFENSE) { + gSaveContext.sohStats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time; + } +} + +extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); + +// used for items that only set a rand inf when obtained +std::map randomizerGetToRandInf = { + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, + { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, + { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, + { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, + { RG_STICK_UPGRADE_INF, RAND_INF_HAS_INFINITE_STICK_UPGRADE }, + { RG_NUT_UPGRADE_INF, RAND_INF_HAS_INFINITE_NUT_UPGRADE }, + { RG_MAGIC_INF, RAND_INF_HAS_INFINITE_MAGIC_METER }, + { RG_BOMBCHU_INF, RAND_INF_HAS_INFINITE_BOMBCHUS }, + { RG_WALLET_INF, RAND_INF_HAS_INFINITE_MONEY }, + { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, + { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, + { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, + { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, + { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, + { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, + { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, +}; + +extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { + if (giEntry.modIndex != MOD_RANDOMIZER) { + LUSLOG_WARN("Randomizer_Item_Give was called with a GetItemEntry with a mod index different from MOD_RANDOMIZER (%d)", giEntry.modIndex); + assert(false); + return -1; + } + + RandomizerGet item = (RandomizerGet)giEntry.getItemId; + + // Gameplay stats: Update the time the item was obtained + Randomizer_GameplayStats_SetTimestamp(item); + + //if it's an item that just sets a randomizerInf, set it + if (randomizerGetToRandInf.find(item) != randomizerGetToRandInf.end()) { + Flags_SetRandomizerInf(randomizerGetToRandInf.find(item)->second); + return Return_Item_Entry(giEntry, RG_NONE); + } + + //bottle items + if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) { + for (u16 i = 0; i < 4; i++) { + if (gSaveContext.inventory.items[SLOT_BOTTLE_1 + i] == ITEM_NONE) { + ItemID bottleItem = ITEM_NONE; + switch (item) { + case RG_BOTTLE_WITH_RED_POTION: + bottleItem = ITEM_POTION_RED; + break; + case RG_BOTTLE_WITH_GREEN_POTION: + bottleItem = ITEM_POTION_GREEN; + break; + case RG_BOTTLE_WITH_BLUE_POTION: + bottleItem = ITEM_POTION_BLUE; + break; + case RG_BOTTLE_WITH_FAIRY: + bottleItem = ITEM_FAIRY; + break; + case RG_BOTTLE_WITH_FISH: + bottleItem = ITEM_FISH; + break; + case RG_BOTTLE_WITH_BLUE_FIRE: + bottleItem = ITEM_BLUE_FIRE; + break; + case RG_BOTTLE_WITH_BUGS: + bottleItem = ITEM_BUG; + break; + case RG_BOTTLE_WITH_POE: + bottleItem = ITEM_POE; + break; + case RG_BOTTLE_WITH_BIG_POE: + bottleItem = ITEM_BIG_POE; + break; + } + + gSaveContext.inventory.items[SLOT_BOTTLE_1 + i] = bottleItem; + return Return_Item_Entry(giEntry, RG_NONE); + } + } + } + + //dungeon items + if ( + (item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || + (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_GANONS_CASTLE_KEY_RING) || + (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || + (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || + (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS) + ) { + u16 mapIndex = gSaveContext.mapIndex; + u8 numOfKeysOnKeyring = 0; + switch (item) { + case RG_DEKU_TREE_MAP: + case RG_DEKU_TREE_COMPASS: + mapIndex = SCENE_DEKU_TREE; + break; + case RG_DODONGOS_CAVERN_MAP: + case RG_DODONGOS_CAVERN_COMPASS: + mapIndex = SCENE_DODONGOS_CAVERN; + break; + case RG_JABU_JABUS_BELLY_MAP: + case RG_JABU_JABUS_BELLY_COMPASS: + mapIndex = SCENE_JABU_JABU; + break; + case RG_FOREST_TEMPLE_MAP: + case RG_FOREST_TEMPLE_COMPASS: + case RG_FOREST_TEMPLE_SMALL_KEY: + case RG_FOREST_TEMPLE_KEY_RING: + case RG_FOREST_TEMPLE_BOSS_KEY: + mapIndex = SCENE_FOREST_TEMPLE; + numOfKeysOnKeyring = FOREST_TEMPLE_SMALL_KEY_MAX; + break; + case RG_FIRE_TEMPLE_MAP: + case RG_FIRE_TEMPLE_COMPASS: + case RG_FIRE_TEMPLE_SMALL_KEY: + case RG_FIRE_TEMPLE_KEY_RING: + case RG_FIRE_TEMPLE_BOSS_KEY: + mapIndex = SCENE_FIRE_TEMPLE; + numOfKeysOnKeyring = FIRE_TEMPLE_SMALL_KEY_MAX; + break; + case RG_WATER_TEMPLE_MAP: + case RG_WATER_TEMPLE_COMPASS: + case RG_WATER_TEMPLE_SMALL_KEY: + case RG_WATER_TEMPLE_KEY_RING: + case RG_WATER_TEMPLE_BOSS_KEY: + mapIndex = SCENE_WATER_TEMPLE; + numOfKeysOnKeyring = WATER_TEMPLE_SMALL_KEY_MAX; + break; + case RG_SPIRIT_TEMPLE_MAP: + case RG_SPIRIT_TEMPLE_COMPASS: + case RG_SPIRIT_TEMPLE_SMALL_KEY: + case RG_SPIRIT_TEMPLE_KEY_RING: + case RG_SPIRIT_TEMPLE_BOSS_KEY: + mapIndex = SCENE_SPIRIT_TEMPLE; + numOfKeysOnKeyring = SPIRIT_TEMPLE_SMALL_KEY_MAX; + break; + case RG_SHADOW_TEMPLE_MAP: + case RG_SHADOW_TEMPLE_COMPASS: + case RG_SHADOW_TEMPLE_SMALL_KEY: + case RG_SHADOW_TEMPLE_KEY_RING: + case RG_SHADOW_TEMPLE_BOSS_KEY: + mapIndex = SCENE_SHADOW_TEMPLE; + numOfKeysOnKeyring = SHADOW_TEMPLE_SMALL_KEY_MAX; + break; + case RG_BOTTOM_OF_THE_WELL_MAP: + case RG_BOTTOM_OF_THE_WELL_COMPASS: + case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: + case RG_BOTTOM_OF_THE_WELL_KEY_RING: + mapIndex = SCENE_BOTTOM_OF_THE_WELL; + numOfKeysOnKeyring = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; + break; + case RG_ICE_CAVERN_MAP: + case RG_ICE_CAVERN_COMPASS: + mapIndex = SCENE_ICE_CAVERN; + break; + case RG_GANONS_CASTLE_BOSS_KEY: + mapIndex = SCENE_GANONS_TOWER; + break; + case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + case RG_GERUDO_TRAINING_GROUNDS_KEY_RING: + mapIndex = SCENE_GERUDO_TRAINING_GROUND; + numOfKeysOnKeyring = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; + break; + case RG_GERUDO_FORTRESS_SMALL_KEY: + case RG_GERUDO_FORTRESS_KEY_RING: + mapIndex = SCENE_THIEVES_HIDEOUT; + numOfKeysOnKeyring = GERUDO_FORTRESS_SMALL_KEY_MAX; + break; + case RG_GANONS_CASTLE_SMALL_KEY: + case RG_GANONS_CASTLE_KEY_RING: + mapIndex = SCENE_INSIDE_GANONS_CASTLE; + numOfKeysOnKeyring = GANONS_CASTLE_SMALL_KEY_MAX; + break; + } + + if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) { + gSaveContext.sohStats.dungeonKeys[mapIndex]++; + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + } + return Return_Item_Entry(giEntry, RG_NONE); + } + + if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_GANONS_CASTLE_KEY_RING)) { + gSaveContext.sohStats.dungeonKeys[mapIndex] = numOfKeysOnKeyring; + gSaveContext.inventory.dungeonKeys[mapIndex] = numOfKeysOnKeyring; + return Return_Item_Entry(giEntry, RG_NONE); + } + + u32 bitmask; + if ((item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP)) { + bitmask = gBitFlags[2]; + } else if ((item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) { + bitmask = gBitFlags[1]; + } else { + bitmask = gBitFlags[0]; + } + + gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; + return Return_Item_Entry(giEntry, RG_NONE); + } + + switch (item) { + case RG_MAGIC_SINGLE: + gSaveContext.isMagicAcquired = true; + gSaveContext.magicFillTarget = MAGIC_NORMAL_METER; + Magic_Fill(play); + break; + case RG_MAGIC_DOUBLE: + if (!gSaveContext.isMagicAcquired) { + gSaveContext.isMagicAcquired = true; + } + gSaveContext.isDoubleMagicAcquired = true; + gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER; + gSaveContext.magicLevel = 0; + Magic_Fill(play); + break; + case RG_MAGIC_BEAN_PACK: + if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) { + INV_CONTENT(ITEM_BEAN) = ITEM_BEAN; + AMMO(ITEM_BEAN) = 10; + } + break; + case RG_DOUBLE_DEFENSE: + gSaveContext.isDoubleDefenseAcquired = true; + gSaveContext.inventory.defenseHearts = 20; + gSaveContext.healthAccumulator = 0x140; + break; + case RG_TYCOON_WALLET: + Inventory_ChangeUpgrade(UPG_WALLET, 3); + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS)) { + Rupees_ChangeBy(999); + } + break; + case RG_CHILD_WALLET: + Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS)) { + Rupees_ChangeBy(99); + } + break; + case RG_GREG_RUPEE: + Rupees_ChangeBy(1); + Flags_SetRandomizerInf(RAND_INF_GREG_FOUND); + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_FOUND_GREG] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case RG_TRIFORCE_PIECE: + gSaveContext.triforcePiecesCollected++; + GameInteractor_SetTriforceHuntPieceGiven(true); + + // Teleport to credits when goal is reached. + if (gSaveContext.triforcePiecesCollected == (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = 1; + Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); + Play_PerformSave(play); + GameInteractor_SetTriforceHuntCreditsWarpActive(true); + } + + break; + case RG_PROGRESSIVE_BOMBCHUS: + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { + INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; + AMMO(ITEM_BOMBCHU) = 20; + } else if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INFINITE_UPGRADES)) { + Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS); + } else { + AMMO(ITEM_BOMBCHU) += AMMO(ITEM_BOMBCHU) < 5 ? 10 : 5; + if (AMMO(ITEM_BOMBCHU) > 50) { + AMMO(ITEM_BOMBCHU) = 50; + } + } + break; + case RG_MASTER_SWORD: + if (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { + gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_TYPE_SWORD]; + } + break; + case RG_DEKU_STICK_BAG: + Inventory_ChangeUpgrade(UPG_STICKS, 1); + INV_CONTENT(ITEM_STICK) = ITEM_STICK; + AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); + break; + case RG_DEKU_NUT_BAG: + Inventory_ChangeUpgrade(UPG_NUTS, 1); + INV_CONTENT(ITEM_NUT) = ITEM_NUT; + AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); + break; + default: + LUSLOG_WARN("Randomizer_Item_Give didn't have behaviour specified for getItemId=%d", item); + assert(false); + return -1; + } + + return Return_Item_Entry(giEntry, RG_NONE); +} \ No newline at end of file diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 3135eb210..b519c84a3 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1847,45 +1847,7 @@ void GameplayStats_SetTimestamp(PlayState* play, u8 item) { GameInteractor_ExecuteOnTimestamp(item); } -// Gameplay stat tracking: Update time the item was acquired -// (special cases for rando items) -void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { - - u32 time = GAMEPLAYSTAT_TOTAL_TIME; - - // Have items in Link's pocket shown as being obtained at 0.1 seconds - if (time == 0) { - time = 1; - } - - // Use ITEM_KEY_BOSS to timestamp Ganon's boss key - if (item == RG_GANONS_CASTLE_BOSS_KEY) { - gSaveContext.sohStats.itemTimestamp[ITEM_KEY_BOSS] = time; - } - - // Count any bottled item as a bottle - if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) { - if (gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] == 0) { - gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] = time; - } - return; - } - // Count any bombchu pack as bombchus - if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) { - if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) { - gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time; - } - return; - } - if (item == RG_MAGIC_SINGLE) { - gSaveContext.sohStats.itemTimestamp[ITEM_SINGLE_MAGIC] = time; - } - if (item == RG_DOUBLE_DEFENSE) { - gSaveContext.sohStats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time; - } -} - -u8 Return_Item_Entry(GetItemEntry itemEntry, ItemID returnItem ) { +u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem) { GameInteractor_ExecuteOnItemReceiveHooks(itemEntry); return returnItem; } @@ -1912,6 +1874,7 @@ u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) { // All randomizer items should go through Randomizer_Item_Give, so this should never be reached // but leaving this here just in case, as it was in the original behavior + assert(false); return Return_Item_Entry(ItemTable_RetrieveEntry(MOD_RANDOMIZER, itemID), returnItem); } @@ -2517,354 +2480,6 @@ u8 Item_Give(PlayState* play, u8 item) { return Return_Item(item, MOD_NONE, returnItem); } -u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { - uint16_t item = giEntry.getItemId; - uint16_t temp; - uint16_t i; - uint16_t slot; - - // Gameplay stats: Update the time the item was obtained - Randomizer_GameplayStats_SetTimestamp(item); - - slot = SLOT(item); - if (item == RG_MAGIC_SINGLE) { - gSaveContext.isMagicAcquired = true; - gSaveContext.magicFillTarget = MAGIC_NORMAL_METER; - Magic_Fill(play); - return Return_Item_Entry(giEntry, RG_NONE); - } else if (item == RG_MAGIC_DOUBLE) { - if (!gSaveContext.isMagicAcquired) { - gSaveContext.isMagicAcquired = true; - } - gSaveContext.isDoubleMagicAcquired = true; - gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER; - gSaveContext.magicLevel = 0; - Magic_Fill(play); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_MAGIC_BEAN_PACK) { - if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) { - INV_CONTENT(ITEM_BEAN) = ITEM_BEAN; - AMMO(ITEM_BEAN) = 10; - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_DOUBLE_DEFENSE) { - gSaveContext.isDoubleDefenseAcquired = true; - gSaveContext.inventory.defenseHearts = 20; - gSaveContext.healthAccumulator = 0x140; - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) { - temp = SLOT(ITEM_BOTTLE); - for (i = 0; i < 4; i++) { - if (gSaveContext.inventory.items[temp + i] == ITEM_NONE) { - switch (item) { - case RG_BOTTLE_WITH_RED_POTION: - item = ITEM_POTION_RED; - break; - case RG_BOTTLE_WITH_GREEN_POTION: - item = ITEM_POTION_GREEN; - break; - case RG_BOTTLE_WITH_BLUE_POTION: - item = ITEM_POTION_BLUE; - break; - case RG_BOTTLE_WITH_FAIRY: - item = ITEM_FAIRY; - break; - case RG_BOTTLE_WITH_FISH: - item = ITEM_FISH; - break; - case RG_BOTTLE_WITH_BLUE_FIRE: - item = ITEM_BLUE_FIRE; - break; - case RG_BOTTLE_WITH_BUGS: - item = ITEM_BUG; - break; - case RG_BOTTLE_WITH_POE: - item = ITEM_POE; - break; - case RG_BOTTLE_WITH_BIG_POE: - item = ITEM_BIG_POE; - break; - } - - gSaveContext.inventory.items[temp + i] = item; - return Return_Item_Entry(giEntry, RG_NONE); - } - } - } else if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || - (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_GANONS_CASTLE_KEY_RING) || - (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || - (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || - (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) { - int mapIndex = gSaveContext.mapIndex; - int numOfKeysOnKeyring = 0; - switch (item) { - case RG_DEKU_TREE_MAP: - case RG_DEKU_TREE_COMPASS: - mapIndex = SCENE_DEKU_TREE; - break; - case RG_DODONGOS_CAVERN_MAP: - case RG_DODONGOS_CAVERN_COMPASS: - mapIndex = SCENE_DODONGOS_CAVERN; - break; - case RG_JABU_JABUS_BELLY_MAP: - case RG_JABU_JABUS_BELLY_COMPASS: - mapIndex = SCENE_JABU_JABU; - break; - case RG_FOREST_TEMPLE_MAP: - case RG_FOREST_TEMPLE_COMPASS: - case RG_FOREST_TEMPLE_SMALL_KEY: - case RG_FOREST_TEMPLE_KEY_RING: - case RG_FOREST_TEMPLE_BOSS_KEY: - mapIndex = SCENE_FOREST_TEMPLE; - numOfKeysOnKeyring = FOREST_TEMPLE_SMALL_KEY_MAX; - break; - case RG_FIRE_TEMPLE_MAP: - case RG_FIRE_TEMPLE_COMPASS: - case RG_FIRE_TEMPLE_SMALL_KEY: - case RG_FIRE_TEMPLE_KEY_RING: - case RG_FIRE_TEMPLE_BOSS_KEY: - mapIndex = SCENE_FIRE_TEMPLE; - numOfKeysOnKeyring = FIRE_TEMPLE_SMALL_KEY_MAX; - break; - case RG_WATER_TEMPLE_MAP: - case RG_WATER_TEMPLE_COMPASS: - case RG_WATER_TEMPLE_SMALL_KEY: - case RG_WATER_TEMPLE_KEY_RING: - case RG_WATER_TEMPLE_BOSS_KEY: - mapIndex = SCENE_WATER_TEMPLE; - numOfKeysOnKeyring = WATER_TEMPLE_SMALL_KEY_MAX; - break; - case RG_SPIRIT_TEMPLE_MAP: - case RG_SPIRIT_TEMPLE_COMPASS: - case RG_SPIRIT_TEMPLE_SMALL_KEY: - case RG_SPIRIT_TEMPLE_KEY_RING: - case RG_SPIRIT_TEMPLE_BOSS_KEY: - mapIndex = SCENE_SPIRIT_TEMPLE; - numOfKeysOnKeyring = SPIRIT_TEMPLE_SMALL_KEY_MAX; - break; - case RG_SHADOW_TEMPLE_MAP: - case RG_SHADOW_TEMPLE_COMPASS: - case RG_SHADOW_TEMPLE_SMALL_KEY: - case RG_SHADOW_TEMPLE_KEY_RING: - case RG_SHADOW_TEMPLE_BOSS_KEY: - mapIndex = SCENE_SHADOW_TEMPLE; - numOfKeysOnKeyring = SHADOW_TEMPLE_SMALL_KEY_MAX; - break; - case RG_BOTTOM_OF_THE_WELL_MAP: - case RG_BOTTOM_OF_THE_WELL_COMPASS: - case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: - case RG_BOTTOM_OF_THE_WELL_KEY_RING: - mapIndex = SCENE_BOTTOM_OF_THE_WELL; - numOfKeysOnKeyring = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; - break; - case RG_ICE_CAVERN_MAP: - case RG_ICE_CAVERN_COMPASS: - mapIndex = SCENE_ICE_CAVERN; - break; - case RG_GANONS_CASTLE_BOSS_KEY: - mapIndex = SCENE_GANONS_TOWER; - break; - case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - case RG_GERUDO_TRAINING_GROUNDS_KEY_RING: - mapIndex = SCENE_GERUDO_TRAINING_GROUND; - numOfKeysOnKeyring = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; - break; - case RG_GERUDO_FORTRESS_SMALL_KEY: - case RG_GERUDO_FORTRESS_KEY_RING: - mapIndex = SCENE_THIEVES_HIDEOUT; - numOfKeysOnKeyring = GERUDO_FORTRESS_SMALL_KEY_MAX; - break; - case RG_GANONS_CASTLE_SMALL_KEY: - case RG_GANONS_CASTLE_KEY_RING: - mapIndex = SCENE_INSIDE_GANONS_CASTLE; - numOfKeysOnKeyring = GANONS_CASTLE_SMALL_KEY_MAX; - break; - } - - if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) { - gSaveContext.sohStats.dungeonKeys[mapIndex]++; - if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[mapIndex] = 1; - } else { - gSaveContext.inventory.dungeonKeys[mapIndex]++; - } - return Return_Item_Entry(giEntry, RG_NONE); - } else if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_GANONS_CASTLE_KEY_RING)) { - gSaveContext.sohStats.dungeonKeys[mapIndex] = numOfKeysOnKeyring; - gSaveContext.inventory.dungeonKeys[mapIndex] = numOfKeysOnKeyring; - return Return_Item_Entry(giEntry, RG_NONE); - } else { - int bitmask; - if ((item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP)) { - bitmask = gBitFlags[2]; - } else if ((item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) { - bitmask = gBitFlags[1]; - } else { - bitmask = gBitFlags[0]; - } - - gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; - return Return_Item_Entry(giEntry, RG_NONE); - } - } - - if (item == RG_TYCOON_WALLET) { - Inventory_ChangeUpgrade(UPG_WALLET, 3); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { - Rupees_ChangeBy(999); - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_CHILD_WALLET) { - Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { - Rupees_ChangeBy(99); - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_GREG_RUPEE) { - Rupees_ChangeBy(1); - Flags_SetRandomizerInf(RAND_INF_GREG_FOUND); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_FOUND_GREG] = GAMEPLAYSTAT_TOTAL_TIME; - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_TRIFORCE_PIECE) { - gSaveContext.triforcePiecesCollected++; - GameInteractor_SetTriforceHuntPieceGiven(true); - - // Teleport to credits when goal is reached. - if (gSaveContext.triforcePiecesCollected == (Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME; - gSaveContext.sohStats.gameComplete = 1; - Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); - Play_PerformSave(play); - GameInteractor_SetTriforceHuntCreditsWarpActive(true); - } - - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item >= RG_GOHMA_SOUL && item <= RG_GANON_SOUL) { - u8 index = item - RG_GOHMA_SOUL; - Flags_SetRandomizerInf(RAND_INF_GOHMA_SOUL + index); - - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_FISHING_POLE) { - Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_PROGRESSIVE_BOMBCHUS) { - if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { - INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; - AMMO(ITEM_BOMBCHU) = 20; - } else if (Randomizer_GetSettingValue(RSK_INFINITE_UPGRADES)) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS); - } else { - AMMO(ITEM_BOMBCHU) += AMMO(ITEM_BOMBCHU) < 5 ? 10 : 5; - if (AMMO(ITEM_BOMBCHU) > 50) { - AMMO(ITEM_BOMBCHU) = 50; - } - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_MASTER_SWORD) { - if (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { - gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_TYPE_SWORD]; - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item >= RG_OCARINA_A_BUTTON && item <= RG_OCARINA_C_RIGHT_BUTTON) { - u8 index = item - RG_OCARINA_A_BUTTON; - Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A + index); - - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BRONZE_SCALE) { - Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_QUIVER_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BOMB_BAG_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BULLET_BAG_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_STICK_UPGRADE_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_NUT_UPGRADE_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_MAGIC_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BOMBCHU_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_WALLET_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_SKELETON_KEY) { - Flags_SetRandomizerInf(RAND_INF_HAS_SKELETON_KEY); - 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; - - return temp; -} - u8 Item_CheckObtainability(u8 item) { s16 i; s16 slot = SLOT(item);