diff --git a/code/include/rnd/item_upgrade.h b/code/include/rnd/item_upgrade.h index 7055caa0..3a49ad2a 100644 --- a/code/include/rnd/item_upgrade.h +++ b/code/include/rnd/item_upgrade.h @@ -14,6 +14,8 @@ namespace rnd { GetItemID ItemUpgrade_Sword(game::SaveData*, GetItemID); GetItemID ItemUpgrade_ArrowsToRupee(game::SaveData*, GetItemID); GetItemID ItemUpgrade_BombsToRupee(game::SaveData*, GetItemID); + GetItemID ItemUpgrade_RefillBottle(game::SaveData*, GetItemID); + GetItemID ItemUpgrade_CheckShield(game::SaveData*, GetItemID); // GetItemID ItemUpgrade_LetterToBottle(game::SaveData*, GetItemID); } // namespace rnd diff --git a/code/source/rnd/item_override.cpp b/code/source/rnd/item_override.cpp index bda3f166..fc85bb5b 100644 --- a/code/source/rnd/item_override.cpp +++ b/code/source/rnd/item_override.cpp @@ -44,9 +44,9 @@ namespace rnd { rItemOverrides[0].value.getItemId = 0x26; rItemOverrides[0].value.looksLikeItemId = 0x26; rItemOverrides[1].key.scene = 0x6F; - rItemOverrides[1].key.type = ItemOverride_Type::OVR_COLLECTABLE; - rItemOverrides[1].value.getItemId = 0x34; - rItemOverrides[1].value.looksLikeItemId = 0x34; + rItemOverrides[1].key.type = ItemOverride_Type::OVR_CHEST; + rItemOverrides[1].value.getItemId = 0x32; + rItemOverrides[1].value.looksLikeItemId = 0x32; rItemOverrides[2].key.scene = 0x12; rItemOverrides[2].key.type = ItemOverride_Type::OVR_COLLECTABLE; rItemOverrides[2].value.getItemId = 0x37; @@ -105,15 +105,15 @@ namespace rnd { } ItemOverride ItemOverride_Lookup(game::act::Actor* actor, u16 scene, s16 getItemId) { - ItemOverride_Key key = ItemOverride_GetSearchKey(actor, scene, getItemId); - if (key.all == 0) { - return (ItemOverride){0}; - } // #if defined ENABLE_DEBUG || defined DEBUG_PRINT // rnd::util::Print( // "%s: Our param values:\nActor Type %#04x\nGet Item ID: %#04x\nActor ID: %#06x\n", // __func__, actor->actor_type, getItemId, actor->id); // #endif + ItemOverride_Key key = ItemOverride_GetSearchKey(actor, scene, getItemId); + if (key.all == 0) { + return (ItemOverride){0}; + } return ItemOverride_LookupByKey(key); } @@ -141,7 +141,6 @@ namespace rnd { u16 resolvedGetItemId = ItemTable_ResolveUpgrades(override.value.getItemId); ItemRow* itemRow = ItemTable_GetItemRow(resolvedGetItemId); - // XXX: Maybe create function for progressive items so that the item drawn is correct? u8 looksLikeItemId = ItemOverride_SetProgressiveItemDraw(override); rActiveItemOverride = override; @@ -492,6 +491,20 @@ namespace rnd { gExtSaveData.givenItemChecks.enMtnDeedGivenItem = 1; } else if (storedGetItemId == rnd::GetItemID::GI_OCEAN_TITLE_DEED) { gExtSaveData.givenItemChecks.enOcnDeedGivenItem = 1; + } else if (storedGetItemId == GetItemID::GI_BOTTLE_MILK) { + gExtSaveData.givenItemChecks.bottleMilkGiven = 1; + } else if (storedGetItemId == GetItemID::GI_BOTTLE_GOLD_DUST || + (s16)storedGetItemId == -(s16)GetItemID::GI_BOTTLE_GOLD_DUST) { + gExtSaveData.givenItemChecks.bottleGoldDustGiven = 1; + } else if (storedGetItemId == GetItemID::GI_BOTTLE_CHATEAU_ROMANI || + (s16)storedGetItemId == -(s16)GetItemID::GI_BOTTLE_CHATEAU_ROMANI) { + gExtSaveData.givenItemChecks.bottleChateuGiven = 1; + } else if (storedGetItemId == GetItemID::GI_BOTTLE_SEAHORSE || + (s16)storedGetItemId == -(s16)GetItemID::GI_BOTTLE_SEAHORSE) { + gExtSaveData.givenItemChecks.bottleSeahorseGiven = 1; + } else if (storedGetItemId == GetItemID::GI_BOTTLE_MYSTERY_MILK || + (s16)storedGetItemId == -(s16)GetItemID::GI_BOTTLE_MYSTERY_MILK) { + gExtSaveData.givenItemChecks.bottleMysteryMilkGiven = 1; } } @@ -550,31 +563,42 @@ namespace rnd { return; } - void ItemOverride_SetBottleRefill(game::act::Player* player, s16 refItemId, bool isChest = false) { + u16 ItemOverride_SetBottleRefill(game::act::Player* player, u16 refItemId) { switch (refItemId) { case 0x60: - player->get_item_id = isChest ? -(s16)GetItemID::GI_BOTTLE_MILK_REFILL : (s16)GetItemID::GI_BOTTLE_MILK_REFILL; + if (gExtSaveData.givenItemChecks.bottleMilkGiven == 1) { + storedGetItemId = GetItemID::GI_BOTTLE_MILK_REFILL; + return 0x92; + } break; case 0x6A: - player->get_item_id = - isChest ? -(s16)GetItemID::GI_BOTTLE_GOLD_DUST_REFILL : (s16)GetItemID::GI_BOTTLE_GOLD_DUST_REFILL; + if (gExtSaveData.givenItemChecks.bottleGoldDustGiven == 1) { + storedGetItemId = GetItemID::GI_BOTTLE_GOLD_DUST_REFILL; + return 0x93; + } break; case 0x6F: - player->get_item_id = - isChest ? -(s16)GetItemID::GI_BOTTLE_CHATEAU_ROMANI_REFILL : (s16)GetItemID::GI_BOTTLE_CHATEAU_ROMANI_REFILL; + if (gExtSaveData.givenItemChecks.bottleChateuGiven == 1) { + storedGetItemId = GetItemID::GI_BOTTLE_CHATEAU_ROMANI_REFILL; + return 0x91; + } break; case 0x6E: - player->get_item_id = - isChest ? -(s16)GetItemID::GI_BOTTLE_SEAHORSE_REFILL : (s16)GetItemID::GI_BOTTLE_SEAHORSE_REFILL; + if (gExtSaveData.givenItemChecks.bottleSeahorseGiven == 1) { + storedGetItemId = GetItemID::GI_BOTTLE_SEAHORSE_REFILL; + return 0x95; + } break; case 0x70: - player->get_item_id = isChest ? -(s16)GetItemID::GI_BOTTLE_MYSTERY_MILK : (s16)GetItemID::GI_BOTTLE_MYSTERY_MILK; + if (gExtSaveData.givenItemChecks.bottleMysteryMilkGiven == 0) { + storedGetItemId = GetItemID::GI_BOTTLE_MYSTERY_MILK_REFILL; + return 0x94; + } break; default: - player->get_item_id = isChest ? -(s16)GetItemID::GI_RUPEE_BLUE : (s16)GetItemID::GI_RUPEE_BLUE; - break; + return (u16)GetItemID::GI_RUPEE_BLUE; } - return; + return (u16)refItemId; } u8 ItemOverride_SetProgressiveItemDraw(ItemOverride override) { @@ -600,7 +624,8 @@ namespace rnd { else return 0x09; } - return override.value.looksLikeItemId; + // No override, use the base item. + return 0x00; } extern "C" { @@ -672,89 +697,47 @@ namespace rnd { return; } else if (override.key.type == ItemOverride_Type::OVR_CHEST && gExtSaveData.chestRewarded[override.key.scene][override.key.flag] == 1) { - // Override was already given, use base game's item code - // If we're a bottled item in our override, we've been received before. Give a refill. - u16 refItemId = override.value.getItemId; -#if defined ENABLE_DEBUG || defined DEBUG_PRINT - rnd::util::Print("%s: Our ref item id is %#04x\n", __func__, refItemId); -#endif - ItemOverride_Clear(); - ItemOverride_SetBottleRefill(player, (s16)refItemId, true); - return; - } else if (override.value.getItemId > 0x45 && override.value.getItemId < 0x4B) { - // This check is mainly to ensure we do not have repeatable progressive items within these base items. - // This is to ensure fairness and allows us to place these items without second guessing in logic. - // Let's be a bit rude and give them fishing passes. + // Override was already given, give a blue rupee instead. + override.value.getItemId = 0x02; + override.value.looksLikeItemId = 0x02; + } + + // This check is mainly to ensure we do not have repeatable progressive items within these base items. + // This is to ensure fairness and allows us to place these items without second guessing in logic. + // Let's be a bit rude and give them fishing passes. + if (override.value.getItemId > 0x45 || override.value.getItemId < 0x4A) { if (incomingGetItemId == (s16)GetItemID::GI_MOONS_TEAR && gExtSaveData.givenItemChecks.enObjMoonStoneGivenItem == 1) { player->get_item_id = (s16)GetItemID::GI_FISHING_HOLE_PASS; + ItemOverride_Clear(); return; } else if (incomingGetItemId == (s16)GetItemID::GI_TOWN_TITLE_DEED && gExtSaveData.givenItemChecks.enTownDeedGivenItem == 1) { player->get_item_id = (s16)GetItemID::GI_FISHING_HOLE_PASS; + ItemOverride_Clear(); return; } else if (incomingGetItemId == (s16)GetItemID::GI_SWAMP_TITLE_DEED && gExtSaveData.givenItemChecks.enSwampDeedGivenItem == 1) { player->get_item_id = (s16)GetItemID::GI_FISHING_HOLE_PASS; + ItemOverride_Clear(); return; } else if (incomingGetItemId == (s16)GetItemID::GI_MOUNTAIN_TITLE_DEED && gExtSaveData.givenItemChecks.enMtnDeedGivenItem == 1) { player->get_item_id = (s16)GetItemID::GI_FISHING_HOLE_PASS; + ItemOverride_Clear(); return; } else if (incomingGetItemId == (s16)GetItemID::GI_OCEAN_TITLE_DEED && gExtSaveData.givenItemChecks.enOcnDeedGivenItem == 1) { player->get_item_id = (s16)GetItemID::GI_FISHING_HOLE_PASS; + ItemOverride_Clear(); return; } - } else if (override.key.type != ItemOverride_Type::OVR_CHEST && - (override.value.getItemId == 0x60 || - (override.value.getItemId > 0x69 && override.value.getItemId < 0x71))) { - switch (override.value.getItemId) { - case 0x60: - if (gExtSaveData.givenItemChecks.bottleMilkGiven == 0) { - gExtSaveData.givenItemChecks.bottleMilkGiven = 1; - } else { - ItemOverride_SetBottleRefill(player, (s16) override.value.getItemId); - return; - } - break; - case 0x6A: - if (gExtSaveData.givenItemChecks.bottleGoldDustGiven == 0) { - gExtSaveData.givenItemChecks.bottleGoldDustGiven = 1; - } else { - ItemOverride_SetBottleRefill(player, (s16) override.value.getItemId); - return; - } - break; - case 0x6F: - if (gExtSaveData.givenItemChecks.bottleGoldDustGiven == 0) { - gExtSaveData.givenItemChecks.bottleGoldDustGiven = 1; - } else { - ItemOverride_SetBottleRefill(player, (s16) override.value.getItemId); - return; - } - break; - case 0x6E: - if (gExtSaveData.givenItemChecks.bottleSeahorseGiven == 0) { - gExtSaveData.givenItemChecks.bottleSeahorseGiven = 1; - } else { - ItemOverride_SetBottleRefill(player, (s16) override.value.getItemId); - return; - } - break; - case 0x70: - if (gExtSaveData.givenItemChecks.bottleMysteryMilkGiven == 0) { - gExtSaveData.givenItemChecks.bottleMysteryMilkGiven = 1; - } else { - ItemOverride_SetBottleRefill(player, (s16) override.value.getItemId); - return; - } - break; - default: - player->get_item_id = -(s16)GetItemID::GI_RUPEE_BLUE; - break; - } - return; + } + + // If we are a bottled item, store the GID to write the ext data. This will ensure through + // ItemUpgrade_BottleRefill that we get a refill on a bottle instead of a new bottle. + if (override.value.getItemId == 0x60 || (override.value.getItemId > 0x69 && override.value.getItemId < 0x71)) { + storedGetItemId = (GetItemID) override.value.getItemId; } ItemOverride_Activate(override); s16 baseItemId = rActiveItemRow->baseItemId; diff --git a/code/source/rnd/item_table.cpp b/code/source/rnd/item_table.cpp index 8827e8c4..3c4a8f0a 100644 --- a/code/source/rnd/item_table.cpp +++ b/code/source/rnd/item_table.cpp @@ -282,7 +282,7 @@ namespace rnd { [0x32] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::HeroShield, 0x0032, 0x000B3, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_HERO_SHIELD, - (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1), // Hero Sheild + (rnd::upgradeFunc)ItemUpgrade_CheckShield, ItemEffect_None, (s16)-1, (s16)-1), // Hero Sheild [0x33] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::MirrorShield, 0x0033, 0x000C3, @@ -504,9 +504,10 @@ namespace rnd { (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_BOTTLE_DEKU_PRINCESS, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Deku Princess - [0x60] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::Milk, 0x0060, 0x00B6, - (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_MILK_FULL, - (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Milk + [0x60] = + ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::Milk, 0x0060, 0x00B6, (s8)0xFF, + (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_MILK_FULL, + (rnd::upgradeFunc)ItemUpgrade_RefillBottle, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Milk [0x61] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::Milk, 0x0061, 0x00B6, (s8)0xFF, @@ -550,10 +551,10 @@ namespace rnd { (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_BOTTLE_ZORA_EGG, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Zora Egg - [0x6A] = - ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::GoldDust, 0x006A, 0x01E9, - (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_GOLD_DUST, - (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Gold Dust + [0x6A] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::GoldDust, 0x006A, 0x01E9, + (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_GOLD_DUST, + (rnd::upgradeFunc)ItemUpgrade_RefillBottle, ItemEffect_None, (s16)-1, + (s16)-1), // Bottle With Gold Dust [0x6B] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::MagicalMushroom, 0x006B, 0x021D, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, @@ -572,12 +573,12 @@ namespace rnd { [0x6E] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::SeaHorse, 0x006E, 0x01E9, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_BOTTLE_SEAHORSE, - (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, + (rnd::upgradeFunc)ItemUpgrade_RefillBottle, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Sea Horse - Gold Dust Object [0x6F] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::ChateauRomani, 0x006F, 0x0227, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, - (s32)DrawGraphicItemID::DI_BOTTLE_CHATEAU_ROMANI, (rnd::upgradeFunc)ItemUpgrade_None, + (s32)DrawGraphicItemID::DI_BOTTLE_CHATEAU_ROMANI, (rnd::upgradeFunc)ItemUpgrade_RefillBottle, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Chateau Romani // XXX: Trade Item, may have to change values? Seems rather individual and leads to fishing @@ -585,7 +586,7 @@ namespace rnd { [0x70] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::MysteryMilk, 0x00CE, 0x00B6, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s32)DrawGraphicItemID::DI_BOTTLE_MYSTERY_MILK, - (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, + (rnd::upgradeFunc)ItemUpgrade_RefillBottle, ItemEffect_None, (s16)-1, (s16)-1), // Bottle With Mystery Milk [0x71] = diff --git a/code/source/rnd/item_upgrade.cpp b/code/source/rnd/item_upgrade.cpp index 411aa9a0..99d4f2b0 100644 --- a/code/source/rnd/item_upgrade.cpp +++ b/code/source/rnd/item_upgrade.cpp @@ -87,6 +87,57 @@ namespace rnd { getItemId; } + GetItemID ItemUpgrade_RefillBottle(game::SaveData* saveCtx, GetItemID getItemId) { + switch (getItemId) { + case GetItemID::GI_BOTTLE_MILK: + if (gExtSaveData.givenItemChecks.bottleMilkGiven == 1) { + return GetItemID::GI_BOTTLE_MILK_REFILL; + } + break; + case GetItemID::GI_BOTTLE_GOLD_DUST: + if (gExtSaveData.givenItemChecks.bottleGoldDustGiven == 1) { +#if defined ENABLE_DEBUG || defined DEBUG_PRINT + rnd::util::Print("%s: Gold dust given, overriding for refill.\n", __func__); +#endif + return GetItemID::GI_BOTTLE_GOLD_DUST_REFILL; + } + break; + case GetItemID::GI_BOTTLE_SEAHORSE: + if (gExtSaveData.givenItemChecks.bottleSeahorseGiven == 1) { + return GetItemID::GI_BOTTLE_SEAHORSE_REFILL; + } + break; + case GetItemID::GI_BOTTLE_CHATEAU_ROMANI: + if (gExtSaveData.givenItemChecks.bottleChateuGiven == 1) { + return GetItemID::GI_BOTTLE_CHATEAU_ROMANI_REFILL; + } + break; + case GetItemID::GI_BOTTLE_MYSTERY_MILK: + if (gExtSaveData.givenItemChecks.bottleMysteryMilkGiven == 1) { + return GetItemID::GI_BOTTLE_MYSTERY_MILK_REFILL; + } + break; + default: + return getItemId; + } + return getItemId; + } + + GetItemID ItemUpgrade_CheckShield(game::SaveData* saveCtx, GetItemID getItemId) { + switch(saveCtx->equipment.sword_shield.shield) { + case game::ShieldType::NoShield: + return getItemId; + case game::ShieldType::HeroShield: + return getItemId; + case game::ShieldType::MirrorShield: + if (getItemId == GetItemID::GI_SHIELD_HERO) + return GetItemID::GI_RUPEE_SILVER; // Give siler rupee, close enough to same cost. + else return getItemId; + default: + return getItemId; + } + } + // TODO: Trade quest items. /* game::ItemId ItemUpgrade_LetterToBottle(game::SaveData *saveCtx, GetItemId GetItemId) {