mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-01-30 23:10:14 -05:00
Move & refactor Randomizer_Item_Give (#4492)
This commit is contained in:
parent
b706532754
commit
6bd3b1d160
@ -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<RandomizerGet, RandomizerInf> 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);
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user