Item SaveContext Logic (#4237)

* Port initial framework up to latest dev-rando. Includes about 15 items using the SCL structure for tracking.

* Most other item variables ported to SaveContext in UpdateHelpers.

* Removed individual Context retrievals in favor of single local variable in Logic to reference.

* start of some diagnostics.
caught some reverse logic with ApplyItemEffect.

* more diagnostics

* Resolve major logic issue with SetInventory flow in ApplyItemEffect.
Other small logic issues in ApplyItemEffect.

* Added a bit of logging.
Add Double Defense to item effects.

* revert hint gen bypass

* item_list *actually* divorced from logicVar pointers.
Several missed options for ApplyItemEffect, HasItem, and UpdateHelpers added in.
Changed HasItem to a switch block for more performance.
Seeds generate within 10-20 seconds in release mode. Further optimization is assumed possible.

* Some formatting

* Bit more formatting.

* Couple review changes.

* Incorporate progressive upgrades and skeleton key into SCL.
Bit of cleanup.

* Change `inLogic` to static array.

* Fix bug in `BottleCount()` preventing Jabu Jabu from ever being in logic.

* Fix bomb bag HasItem check.

* Fix Gerudo Fortress and Ganon's Castle SmallKeys checks.

* Change all logic use of `bool remove` to be `bool state` and work on the affirmative assumption.

* Forgot the `Set(x)` uses in `Logic::Reset()`.

* Fix fishing pole effect application.

* fishing pole tweak

* Add `RG_BOMB_BAG`, `RG_NUTS` and `RG_STICKS` to `HasItem()`.
Fix silver and gold gauntlet checks in `HasItem()`.
Change Nuts and Sticks helpers to use non-progressive RGs in `UpdateHelpers()`.

* Change mSaveContext to simple pointer.
Set `mSaveContext` to `&gSaveContext` when loading a save file.
Modify `Item::GetGIEntry()` to use rando context's SaveContext pointer instead of the gSaveContext macros.
Utilize `Item::GetGIEntry()` to get real RG of infinite upgrades and set rando infs accordingly, skipping upgrade level incrementing (which was causing overflow of wallets for some reason).

* Rename all remaining references of LogicVar to variants of LogicVal.

* Change final references to song LogicVars to CanUse calls, and remove them.

* Separate equip and rand inf flag maps.
Add Zelda's Letter and Weird Egg rand infs to map.
Consolidate `HasItem` rand inf  lookups using rand inf map and equips using equip flag map.
Maps are static, so can be referenced with `Context::` instead of ctx pointer.
This commit is contained in:
Malkierian 2024-08-01 21:24:24 -07:00 committed by GitHub
parent cab0871fe7
commit aeb85c81aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1713 additions and 532 deletions

View File

@ -94,6 +94,7 @@ extern "C"
extern u16 gEquipMasks[4]; extern u16 gEquipMasks[4];
extern u16 gEquipNegMasks[4]; extern u16 gEquipNegMasks[4];
extern u32 gUpgradeMasks[8]; extern u32 gUpgradeMasks[8];
extern u32 gUpgradeNegMasks[8];
extern u8 gEquipShifts[4]; extern u8 gEquipShifts[4];
extern u8 gUpgradeShifts[8]; extern u8 gUpgradeShifts[8];
extern u16 gUpgradeCapacities[8][4]; extern u16 gUpgradeCapacities[8][4];

View File

@ -311,6 +311,21 @@ typedef enum {
/* 0xFF */ ITEM_NONE = 0xFF /* 0xFF */ ITEM_NONE = 0xFF
} ItemID; } ItemID;
typedef enum {
EQUIP_FLAG_SWORD_KOKIRI = 1 << 0,
EQUIP_FLAG_SWORD_MASTER = 1 << 1,
EQUIP_FLAG_SWORD_BGS = 1 << 2,
EQUIP_FLAG_SHIELD_DEKU = 1 << 4,
EQUIP_FLAG_SHIELD_HYLIAN = 1 << 5,
EQUIP_FLAG_SHIELD_MIRROR = 1 << 6,
EQUIP_FLAG_TUNIC_KOKIRI = 1 << 8,
EQUIP_FLAG_TUNIC_GORON = 1 << 9,
EQUIP_FLAG_TUNIC_ZORA = 1 << 10,
EQUIP_FLAG_BOOTS_KOKIRI = 1 << 12,
EQUIP_FLAG_BOOTS_IRON = 1 << 13,
EQUIP_FLAG_BOOTS_HOVER = 1 << 14,
} EquipmentFlag;
#define ITEM_TRADE_CHILD ITEM_WEIRD_EGG #define ITEM_TRADE_CHILD ITEM_WEIRD_EGG
#define ITEM_TRADE_ADULT ITEM_POCKET_EGG #define ITEM_TRADE_ADULT ITEM_POCKET_EGG

View File

@ -245,7 +245,7 @@ std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<Randomizer
int gsCount = 0; int gsCount = 0;
const int maxGsCount = mode == SearchMode::GeneratePlaythrough ? GetMaxGSCount() : 0; //If generating playthrough want the max that's possibly useful, else doesn't matter const int maxGsCount = mode == SearchMode::GeneratePlaythrough ? GetMaxGSCount() : 0; //If generating playthrough want the max that's possibly useful, else doesn't matter
bool bombchusFound = false; bool bombchusFound = false;
std::vector<std::variant<bool*, uint8_t*>> buyIgnores; std::vector<LogicVal> buyIgnores;
//Variables for search //Variables for search
std::vector<Rando::ItemLocation*> newItemLocations; std::vector<Rando::ItemLocation*> newItemLocations;
@ -365,9 +365,9 @@ std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<Randomizer
else if (IsBombchus(ignore) && IsBombchus(locItem, true)) { else if (IsBombchus(ignore) && IsBombchus(locItem, true)) {
newItemLocations.push_back(location); newItemLocations.push_back(location);
} }
//We want to ignore a specific Buy item. Buy items with different RandomizerGets are recognised by a shared GetLogicVar //We want to ignore a specific Buy item. Buy items with different RandomizerGets are recognised by a shared GetLogicVal
else if (ignore != RG_GOLD_SKULLTULA_TOKEN && IsBombchus(ignore)) { else if (ignore != RG_GOLD_SKULLTULA_TOKEN && IsBombchus(ignore)) {
if ((type == ITEMTYPE_SHOP && Rando::StaticData::GetItemTable()[ignore].GetLogicVar() != location->GetPlacedItem().GetLogicVar()) || type != ITEMTYPE_SHOP) { if ((type == ITEMTYPE_SHOP && Rando::StaticData::GetItemTable()[ignore].GetLogicVal() != location->GetPlacedItem().GetLogicVal()) || type != ITEMTYPE_SHOP) {
newItemLocations.push_back(location); newItemLocations.push_back(location);
} }
} }
@ -408,7 +408,7 @@ std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<Randomizer
// TODO: Reimplement Ammo Drops setting // TODO: Reimplement Ammo Drops setting
else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ !(bombchus && bombchusFound) && type == ITEMTYPE_SHOP) { else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ !(bombchus && bombchusFound) && type == ITEMTYPE_SHOP) {
//Only check each buy item once //Only check each buy item once
auto buyItem = location->GetPlacedItem().GetLogicVar(); auto buyItem = location->GetPlacedItem().GetLogicVal();
//Buy item not in list to ignore, add it to list and write to playthrough //Buy item not in list to ignore, add it to list and write to playthrough
if (std::find(buyIgnores.begin(), buyIgnores.end(), buyItem) == buyIgnores.end()) { if (std::find(buyIgnores.begin(), buyIgnores.end(), buyItem) == buyIgnores.end()) {
exclude = false; exclude = false;
@ -1003,7 +1003,9 @@ void ClearProgress() {
int Fill() { int Fill() {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
int retries = 0; int retries = 0;
SPDLOG_INFO("Starting seed generation...");
while(retries < 5) { while(retries < 5) {
SPDLOG_INFO("Attempt {}...", retries + 1);
placementFailure = false; placementFailure = false;
//showItemProgress = false; //showItemProgress = false;
ctx->playthroughLocations.clear(); ctx->playthroughLocations.clear();
@ -1036,8 +1038,10 @@ int Fill() {
//Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access //Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access
NonShopItems = {}; NonShopItems = {};
if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) {
SPDLOG_INFO("Placing Vanilla Shop Items...");
PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location
} else { } else {
SPDLOG_INFO("Shuffling Shop Items");
int total_replaced = 0; int total_replaced = 0;
if (ctx->GetOption(RSK_SHOPSANITY).IsNot(RO_SHOPSANITY_ZERO_ITEMS)) { //Shopsanity 1-4, random if (ctx->GetOption(RSK_SHOPSANITY).IsNot(RO_SHOPSANITY_ZERO_ITEMS)) { //Shopsanity 1-4, random
//Initialize NonShopItems //Initialize NonShopItems
@ -1080,6 +1084,7 @@ int Fill() {
} }
//Place dungeon rewards //Place dungeon rewards
SPDLOG_INFO("Shuffling and Placing Dungeon Items...");
RandomizeDungeonRewards(); RandomizeDungeonRewards();
//Place dungeon items restricted to their Own Dungeon //Place dungeon items restricted to their Own Dungeon
@ -1111,15 +1116,18 @@ int Fill() {
//Then place dungeon items that are assigned to restrictive location pools //Then place dungeon items that are assigned to restrictive location pools
RandomizeDungeonItems(); RandomizeDungeonItems();
SPDLOG_INFO("Dungeon Items Done");
//Then place Link's Pocket Item if it has to be an advancement item //Then place Link's Pocket Item if it has to be an advancement item
RandomizeLinksPocket(); RandomizeLinksPocket();
SPDLOG_INFO("Shuffling Advancement Items");
//Then place the rest of the advancement items //Then place the rest of the advancement items
std::vector<RandomizerGet> remainingAdvancementItems = std::vector<RandomizerGet> remainingAdvancementItems =
FilterAndEraseFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); FilterAndEraseFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); });
AssumedFill(remainingAdvancementItems, ctx->allLocations, true); AssumedFill(remainingAdvancementItems, ctx->allLocations, true);
//Fast fill for the rest of the pool //Fast fill for the rest of the pool
SPDLOG_INFO("Shuffling Remaining Items");
std::vector<RandomizerGet> remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); std::vector<RandomizerGet> remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; });
FastFill(remainingPool, GetAllEmptyLocations(), false); FastFill(remainingPool, GetAllEmptyLocations(), false);

View File

@ -162,7 +162,7 @@ Rando::Entrance* Area::GetExit(RandomizerRegion exitToReturn) {
} }
bool Area::CanPlantBeanCheck() const { bool Area::CanPlantBeanCheck() const {
return (logic->MagicBean || logic->MagicBeanPack) && BothAgesCheck(); return Rando::Context::GetInstance()->GetAmmo(ITEM_BEAN) > 0 && BothAgesCheck();
} }
bool Area::AllAccountedFor() const { bool Area::AllAccountedFor() const {

View File

@ -207,10 +207,12 @@ void AreaTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Area("Spirit Temple MQ Lower Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Area("Spirit Temple MQ Lower Adult", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true), LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true),
LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer && logic->Ocarina && logic->SongOfTime && logic->EponasSong && logic->SunsSong && logic->SongOfStorms && logic->ZeldasLullaby), LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG)
&& logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)),
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Hammer), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Hammer),
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, true), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, true),
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer && logic->Ocarina && logic->SongOfTime && logic->EponasSong && logic->SunsSong && logic->SongOfStorms && logic->ZeldasLullaby), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->Hammer && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG)
&& logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)),
}, {}); }, {});
areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Area("Spirit Temple MQ Boss Area", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Area("Spirit Temple MQ Boss Area", "Spirit Temple", RA_SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -9,13 +9,12 @@
#include "settings.h" #include "settings.h"
#include "rando_hash.h" #include "rando_hash.h"
#include "fishsanity.h" #include "fishsanity.h"
#include "macros.h"
#include "3drando/hints.hpp" #include "3drando/hints.hpp"
#include <fstream> #include <fstream>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include "luslog.h"
namespace Rando { namespace Rando {
std::weak_ptr<Context> Context::mContext; std::weak_ptr<Context> Context::mContext;
@ -49,6 +48,7 @@ std::shared_ptr<Context> Context::CreateInstance() {
if (mContext.expired()) { if (mContext.expired()) {
auto instance = std::make_shared<Context>(); auto instance = std::make_shared<Context>();
mContext = instance; mContext = instance;
GetInstance()->GetLogic()->SetContext(GetInstance());
return instance; return instance;
} }
return GetInstance(); return GetInstance();
@ -395,6 +395,500 @@ void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
CreateStaticHints(); CreateStaticHints();
} }
std::map<RandomizerGet, uint32_t> Context::RandoGetToEquipFlag = {
{ RG_KOKIRI_SWORD, EQUIP_FLAG_SWORD_KOKIRI },
{ RG_MASTER_SWORD, EQUIP_FLAG_SWORD_MASTER },
{ RG_BIGGORON_SWORD, EQUIP_FLAG_SWORD_BGS },
{ RG_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU },
{ RG_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN },
{ RG_MIRROR_SHIELD, EQUIP_FLAG_SHIELD_MIRROR },
{ RG_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON },
{ RG_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA },
{ RG_BUY_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU },
{ RG_BUY_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN },
{ RG_BUY_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON },
{ RG_BUY_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA },
{ RG_IRON_BOOTS, EQUIP_FLAG_BOOTS_IRON },
{ RG_HOVER_BOOTS, EQUIP_FLAG_BOOTS_HOVER }
};
std::map<RandomizerGet, uint32_t> Context::RandoGetToRandInf = {
{ RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER },
{ RG_WEIRD_EGG, RAND_INF_WEIRD_EGG },
{ 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 },
{ 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_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY },
{ RG_GREG_RUPEE, RAND_INF_GREG_FOUND },
{ RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }
};
std::map<uint32_t, uint32_t> Context::RandoGetToDungeonScene = {
{ RG_FOREST_TEMPLE_SMALL_KEY, SCENE_FOREST_TEMPLE },
{ RG_FIRE_TEMPLE_SMALL_KEY, SCENE_FIRE_TEMPLE },
{ RG_WATER_TEMPLE_SMALL_KEY, SCENE_WATER_TEMPLE },
{ RG_SPIRIT_TEMPLE_SMALL_KEY, SCENE_SPIRIT_TEMPLE },
{ RG_SHADOW_TEMPLE_SMALL_KEY, SCENE_SHADOW_TEMPLE },
{ RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL },
{ RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND },
{ RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT },
{ RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE },
{ RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE },
{ RG_FIRE_TEMPLE_KEY_RING, SCENE_FIRE_TEMPLE },
{ RG_WATER_TEMPLE_KEY_RING, SCENE_WATER_TEMPLE },
{ RG_SPIRIT_TEMPLE_KEY_RING, SCENE_SPIRIT_TEMPLE },
{ RG_SHADOW_TEMPLE_KEY_RING, SCENE_SHADOW_TEMPLE },
{ RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL },
{ RG_GERUDO_TRAINING_GROUNDS_KEY_RING, SCENE_GERUDO_TRAINING_GROUND },
{ RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT },
{ RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE },
{ RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE },
{ RG_FIRE_TEMPLE_BOSS_KEY, SCENE_FIRE_TEMPLE },
{ RG_WATER_TEMPLE_BOSS_KEY, SCENE_WATER_TEMPLE },
{ RG_SPIRIT_TEMPLE_BOSS_KEY, SCENE_SPIRIT_TEMPLE },
{ RG_SHADOW_TEMPLE_BOSS_KEY, SCENE_SHADOW_TEMPLE },
{ RG_GANONS_CASTLE_BOSS_KEY, SCENE_INSIDE_GANONS_CASTLE },
{ RG_DEKU_TREE_MAP, SCENE_DEKU_TREE },
{ RG_DODONGOS_CAVERN_MAP, SCENE_DODONGOS_CAVERN },
{ RG_JABU_JABUS_BELLY_MAP, SCENE_JABU_JABU },
{ RG_FOREST_TEMPLE_MAP, SCENE_FOREST_TEMPLE },
{ RG_FIRE_TEMPLE_MAP, SCENE_FIRE_TEMPLE },
{ RG_WATER_TEMPLE_MAP, SCENE_WATER_TEMPLE },
{ RG_SPIRIT_TEMPLE_MAP, SCENE_SPIRIT_TEMPLE },
{ RG_SHADOW_TEMPLE_MAP, SCENE_SHADOW_TEMPLE },
{ RG_BOTTOM_OF_THE_WELL_MAP, SCENE_BOTTOM_OF_THE_WELL },
{ RG_ICE_CAVERN_MAP, SCENE_ICE_CAVERN },
{ RG_DEKU_TREE_COMPASS, SCENE_DEKU_TREE },
{ RG_DODONGOS_CAVERN_COMPASS, SCENE_DODONGOS_CAVERN },
{ RG_JABU_JABUS_BELLY_COMPASS, SCENE_JABU_JABU },
{ RG_FOREST_TEMPLE_COMPASS, SCENE_FOREST_TEMPLE },
{ RG_FIRE_TEMPLE_COMPASS, SCENE_FIRE_TEMPLE },
{ RG_WATER_TEMPLE_COMPASS, SCENE_WATER_TEMPLE },
{ RG_SPIRIT_TEMPLE_COMPASS, SCENE_SPIRIT_TEMPLE },
{ RG_SHADOW_TEMPLE_COMPASS, SCENE_SHADOW_TEMPLE },
{ RG_BOTTOM_OF_THE_WELL_COMPASS, SCENE_BOTTOM_OF_THE_WELL },
{ RG_ICE_CAVERN_COMPASS, SCENE_ICE_CAVERN },
{ RG_TREASURE_GAME_SMALL_KEY, SCENE_TREASURE_BOX_SHOP }
};
std::map<uint32_t, uint32_t> Context::RandoGetToQuestItem = {
{ RG_FOREST_MEDALLION, QUEST_MEDALLION_FOREST },
{ RG_FIRE_MEDALLION, QUEST_MEDALLION_FIRE },
{ RG_WATER_MEDALLION, QUEST_MEDALLION_WATER },
{ RG_SPIRIT_MEDALLION, QUEST_MEDALLION_SPIRIT },
{ RG_SHADOW_MEDALLION, QUEST_MEDALLION_SHADOW },
{ RG_LIGHT_MEDALLION, QUEST_MEDALLION_LIGHT },
{ RG_MINUET_OF_FOREST, QUEST_SONG_MINUET },
{ RG_BOLERO_OF_FIRE, QUEST_SONG_BOLERO },
{ RG_SERENADE_OF_WATER, QUEST_SONG_SERENADE },
{ RG_REQUIEM_OF_SPIRIT, QUEST_SONG_REQUIEM },
{ RG_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE },
{ RG_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE },
{ RG_ZELDAS_LULLABY, QUEST_SONG_LULLABY },
{ RG_EPONAS_SONG, QUEST_SONG_EPONA },
{ RG_SARIAS_SONG, QUEST_SONG_SARIA },
{ RG_SUNS_SONG, QUEST_SONG_SUN },
{ RG_SONG_OF_TIME, QUEST_SONG_TIME },
{ RG_SONG_OF_STORMS, QUEST_SONG_STORMS },
{ RG_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD },
{ RG_GORON_RUBY, QUEST_GORON_RUBY },
{ RG_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE },
{ RG_STONE_OF_AGONY, QUEST_STONE_OF_AGONY },
{ RG_GERUDO_MEMBERSHIP_CARD, QUEST_GERUDO_CARD },
};
uint32_t HookshotLookup[3] = { ITEM_NONE, ITEM_HOOKSHOT, ITEM_LONGSHOT };
uint32_t OcarinaLookup[3] = { ITEM_NONE, ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME };
void Context::ApplyItemEffect(Item& item, bool state) {
auto randoGet = item.GetRandomizerGet();
if (item.GetGIEntry()->objectId == OBJECT_GI_STICK) {
SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK));
}
if (item.GetGIEntry()->objectId == OBJECT_GI_NUTS) {
SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT));
}
switch (item.GetItemType()) {
case ITEMTYPE_ITEM:
{
switch (randoGet) {
case RG_STONE_OF_AGONY:
case RG_GERUDO_MEMBERSHIP_CARD:
SetQuestItem(RandoGetToQuestItem.at(randoGet), state);
break;
case RG_WEIRD_EGG:
SetRandoInf(RAND_INF_WEIRD_EGG, state);
break;
case RG_ZELDAS_LETTER:
SetRandoInf(RAND_INF_ZELDAS_LETTER, state);
break;
case RG_DOUBLE_DEFENSE:
mSaveContext->isDoubleDefenseAcquired = state;
break;
case RG_POCKET_EGG:
case RG_COJIRO:
case RG_ODD_MUSHROOM:
case RG_ODD_POTION:
case RG_POACHERS_SAW:
case RG_BROKEN_SWORD:
case RG_PRESCRIPTION:
case RG_EYEBALL_FROG:
case RG_EYEDROPS:
case RG_CLAIM_CHECK:
SetAdultTrade(item.GetGIEntry()->itemId, state);
break;
case RG_PROGRESSIVE_HOOKSHOT:
{
uint8_t i;
for (i = 0; i < 3; i++) {
if (CurrentInventory(ITEM_HOOKSHOT) == HookshotLookup[i]) {
break;
}
}
auto newItem = i + (!state ? -1 : 1);
if (newItem < 0) {
newItem = 0;
}
else if (newItem > 2) {
newItem = 2;
}
SetInventory(ITEM_HOOKSHOT, HookshotLookup[newItem]);
} break;
case RG_PROGRESSIVE_STRENGTH:
{
auto currentLevel = CurrentUpgrade(UPG_STRENGTH);
auto newLevel = currentLevel + (!state ? -1 : 1);
SetUpgrade(UPG_STRENGTH, newLevel);
} break;
case RG_PROGRESSIVE_BOMB_BAG:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_BOMB_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_BOMB_BAG, true);
break;
}
auto currentLevel = CurrentUpgrade(UPG_BOMB_BAG);
auto newLevel = currentLevel + (!state ? -1 : 1);
if (currentLevel == 0 && state || currentLevel == 1 && !state) {
SetInventory(ITEM_BOMB, (!state ? ITEM_NONE : ITEM_BOMB));
}
SetUpgrade(UPG_BOMB_BAG, newLevel);
} break;
case RG_PROGRESSIVE_BOW:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_QUIVER_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_QUIVER, true);
break;
}
auto currentLevel = CurrentUpgrade(UPG_QUIVER);
auto newLevel = currentLevel + (!state ? -1 : 1);
if (currentLevel == 0 && state || currentLevel == 1 && !state) {
SetInventory(ITEM_BOW, (!state ? ITEM_NONE : ITEM_BOW));
}
SetUpgrade(UPG_QUIVER, newLevel);
} break;
case RG_PROGRESSIVE_SLINGSHOT:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_BULLET_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_BULLET_BAG, true);
break;
}
auto currentLevel = CurrentUpgrade(UPG_BULLET_BAG);
auto newLevel = currentLevel + (!state ? -1 : 1);
if (currentLevel == 0 && state || currentLevel == 1 && !state) {
SetInventory(ITEM_SLINGSHOT, (!state ? ITEM_NONE : ITEM_SLINGSHOT));
}
SetUpgrade(UPG_BULLET_BAG, newLevel);
} break;
case RG_PROGRESSIVE_WALLET:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_WALLET_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_MONEY, true);
break;
}
auto currentLevel = CurrentUpgrade(UPG_WALLET);
if (!CheckRandoInf(RAND_INF_HAS_WALLET) && state) {
SetRandoInf(RAND_INF_HAS_WALLET, true);
}
else if (currentLevel == 0 && !state) {
SetRandoInf(RAND_INF_HAS_WALLET, false);
}
else {
auto newLevel = currentLevel + (!state ? -1 : 1);
SetUpgrade(UPG_WALLET, newLevel);
}
} break;
case RG_PROGRESSIVE_SCALE:
{
auto currentLevel = CurrentUpgrade(UPG_SCALE);
if (!CheckRandoInf(RAND_INF_CAN_SWIM) && state) {
SetRandoInf(RAND_INF_CAN_SWIM, true);
}
else if (currentLevel == 0 && !state) {
SetRandoInf(RAND_INF_CAN_SWIM, false);
}
else {
auto newLevel = currentLevel + (!state ? -1 : 1);
SetUpgrade(UPG_SCALE, newLevel);
}
} break;
case RG_PROGRESSIVE_NUT_UPGRADE:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_NUT_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE, true);
break;
}
auto currentLevel = CurrentUpgrade(UPG_NUTS);
auto newLevel = currentLevel + (!state ? -1 : 1);
if (currentLevel == 0 && state || currentLevel == 1 && !state) {
SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT));
}
SetUpgrade(UPG_NUTS, newLevel);
} break;
case RG_PROGRESSIVE_STICK_UPGRADE:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_STICK_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE, true);
break;
}
auto currentLevel = CurrentUpgrade(UPG_STICKS);
auto newLevel = currentLevel + (!state ? -1 : 1);
if (currentLevel == 0 && state || currentLevel == 1 && !state) {
SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK));
}
SetUpgrade(UPG_STICKS, newLevel);
} break;
case RG_PROGRESSIVE_BOMBCHUS:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_BOMBCHU_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_BOMBCHUS, true);
break;
}
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
} break;
case RG_PROGRESSIVE_MAGIC_METER:
{
auto realGI = item.GetGIEntry();
if (realGI->itemId == RG_MAGIC_INF && realGI->modIndex == MOD_RANDOMIZER) {
SetRandoInf(RAND_INF_HAS_INFINITE_MAGIC_METER, true);
break;
}
mSaveContext->magicLevel += (!state ? -1 : 1);
} break;
case RG_PROGRESSIVE_OCARINA:
{
uint8_t i;
for (i = 0; i < 3; i++) {
if (CurrentInventory(ITEM_OCARINA_FAIRY) == OcarinaLookup[i]) {
break;
}
}
i += (!state ? -1 : 1);
if (i < 0) {
i = 0;
}
else if (i > 2) {
i = 2;
}
SetInventory(ITEM_OCARINA_FAIRY, OcarinaLookup[i]);
} break;
case RG_HEART_CONTAINER:
mSaveContext->healthCapacity += (!state ? -16 : 16);
break;
case RG_PIECE_OF_HEART:
mSaveContext->healthCapacity += (!state ? -4 : 4);
break;
case RG_BOOMERANG:
case RG_LENS_OF_TRUTH:
case RG_MEGATON_HAMMER:
case RG_DINS_FIRE:
case RG_FARORES_WIND:
case RG_NAYRUS_LOVE:
case RG_FIRE_ARROWS:
case RG_ICE_ARROWS:
case RG_LIGHT_ARROWS:
SetInventory(item.GetGIEntry()->itemId, (!state ? ITEM_NONE : item.GetGIEntry()->itemId));
break;
case RG_MAGIC_BEAN:
case RG_MAGIC_BEAN_PACK:
{
auto change = (item.GetRandomizerGet() == RG_MAGIC_BEAN ? 1 : 10);
auto current = GetAmmo(ITEM_BEAN);
SetAmmo(ITEM_BEAN, current + (!state ? -change : change));
} break;
case RG_EMPTY_BOTTLE:
case RG_BOTTLE_WITH_MILK:
case RG_BOTTLE_WITH_RED_POTION:
case RG_BOTTLE_WITH_GREEN_POTION:
case RG_BOTTLE_WITH_BLUE_POTION:
case RG_BOTTLE_WITH_FAIRY:
case RG_BOTTLE_WITH_FISH:
case RG_BOTTLE_WITH_BLUE_FIRE:
case RG_BOTTLE_WITH_BUGS:
case RG_BOTTLE_WITH_POE:
case RG_BOTTLE_WITH_BIG_POE:
{
uint8_t slot = SLOT_BOTTLE_1;
while (slot != SLOT_BOTTLE_4) {
if (mSaveContext->inventory.items[slot] == ITEM_NONE) {
break;
}
slot++;
}
mSaveContext->inventory.items[slot] = item.GetGIEntry()->itemId;
} break;
case RG_RUTOS_LETTER:
SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER, state);
break;
case RG_GOHMA_SOUL:
case RG_KING_DODONGO_SOUL:
case RG_BARINADE_SOUL:
case RG_PHANTOM_GANON_SOUL:
case RG_VOLVAGIA_SOUL:
case RG_MORPHA_SOUL:
case RG_BONGO_BONGO_SOUL:
case RG_TWINROVA_SOUL:
case RG_GANON_SOUL:
case RG_OCARINA_A_BUTTON:
case RG_OCARINA_C_UP_BUTTON:
case RG_OCARINA_C_DOWN_BUTTON:
case RG_OCARINA_C_LEFT_BUTTON:
case RG_OCARINA_C_RIGHT_BUTTON:
case RG_GREG_RUPEE:
case RG_FISHING_POLE:
SetRandoInf(RandoGetToRandInf.at(randoGet), state);
break;
case RG_TRIFORCE_PIECE:
mSaveContext->triforcePiecesCollected += (!state ? -1 : 1);
break;
case RG_BOMBCHU_5:
case RG_BOMBCHU_10:
case RG_BOMBCHU_20:
case RG_BOMBCHU_DROP:
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
break;
}
}
break;
case ITEMTYPE_EQUIP:
{
RandomizerGet itemRG = item.GetRandomizerGet();
if (itemRG == RG_GIANTS_KNIFE) {
return;
}
uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second;
if (!state) {
mSaveContext->inventory.equipment &= ~equipId;
if (equipId == EQUIP_FLAG_SWORD_BGS) {
mSaveContext->bgsFlag = false;
}
}
else {
mSaveContext->inventory.equipment |= equipId;
if (equipId == EQUIP_FLAG_SWORD_BGS) {
mSaveContext->bgsFlag = true;
}
}
}
break;
case ITEMTYPE_DUNGEONREWARD:
case ITEMTYPE_SONG:
SetQuestItem(RandoGetToQuestItem.find(item.GetRandomizerGet())->second, state);
break;
case ITEMTYPE_MAP:
SetDungeonItem(DUNGEON_MAP, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state);
break;
case ITEMTYPE_COMPASS:
SetDungeonItem(DUNGEON_COMPASS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state);
break;
case ITEMTYPE_BOSSKEY:
SetDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state);
break;
case ITEMTYPE_FORTRESS_SMALLKEY:
case ITEMTYPE_SMALLKEY:
{
auto randoGet = item.GetRandomizerGet();
auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING;
auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second;
auto count = GetSmallKeyCount(dungeonIndex);
if (!state) {
if (keyring) {
count = 0;
}
else {
count -= 1;
}
}
else {
if (keyring) {
count = 10;
}
else {
count += 1;
}
}
SetSmallKeyCount(dungeonIndex, count);
} break;
case ITEMTYPE_TOKEN:
mSaveContext->inventory.gsTokens += (!state ? -1 : 1);
break;
case ITEMTYPE_EVENT:
break;
case ITEMTYPE_DROP:
case ITEMTYPE_REFILL:
case ITEMTYPE_SHOP:
{
RandomizerGet itemRG = item.GetRandomizerGet();
if (itemRG == RG_BUY_HYLIAN_SHIELD || itemRG == RG_BUY_DEKU_SHIELD || itemRG == RG_BUY_GORON_TUNIC || itemRG == RG_BUY_ZORA_TUNIC) {
uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second;
if (!state) {
mSaveContext->inventory.equipment &= ~equipId;
}
else {
mSaveContext->inventory.equipment |= equipId;
}
}
switch (itemRG) {
case RG_DEKU_NUTS_5:
case RG_DEKU_NUTS_10:
case RG_BUY_DEKU_NUTS_5:
case RG_BUY_DEKU_NUTS_10:
SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT));
break;
case RG_DEKU_STICK_1:
case RG_BUY_DEKU_STICK_1:
case RG_STICKS:
SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK));
break;
case RG_BOMBCHU_5:
case RG_BOMBCHU_10:
case RG_BOMBCHU_20:
case RG_BOMBCHU_DROP:
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
break;
}
} break;
}
mLogic->UpdateHelpers();
}
std::shared_ptr<Settings> Context::GetSettings() { std::shared_ptr<Settings> Context::GetSettings() {
return mSettings; return mSettings;
} }
@ -422,7 +916,170 @@ std::shared_ptr<Logic> Context::GetLogic() {
return mLogic; return mLogic;
} }
SaveContext* Context::GetSaveContext() {
if (mSaveContext == nullptr) {
NewSaveContext();
}
return mSaveContext;
}
void Context::SetSaveContext(SaveContext* context) {
mSaveContext = context;
}
void Context::InitSaveContext() {
mSaveContext->totalDays = 0;
mSaveContext->bgsDayCount = 0;
mSaveContext->deaths = 0;
for (int i = 0; i < ARRAY_COUNT(mSaveContext->playerName); i++) {
mSaveContext->playerName[i] = 0x3E;
}
mSaveContext->n64ddFlag = 0;
mSaveContext->healthCapacity = 0x30;
mSaveContext->health = 0x30;
mSaveContext->magicLevel = 0;
mSaveContext->magic = 0x30;
mSaveContext->rupees = 0;
mSaveContext->swordHealth = 0;
mSaveContext->naviTimer = 0;
mSaveContext->isMagicAcquired = 0;
mSaveContext->isDoubleMagicAcquired = 0;
mSaveContext->isDoubleDefenseAcquired = 0;
mSaveContext->bgsFlag = 0;
mSaveContext->ocarinaGameRoundNum = 0;
for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.buttonItems); button++) {
mSaveContext->childEquips.buttonItems[button] = ITEM_NONE;
}
for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.cButtonSlots); button++) {
mSaveContext->childEquips.cButtonSlots[button] = SLOT_NONE;
}
mSaveContext->childEquips.equipment = 0;
for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.buttonItems); button++) {
mSaveContext->adultEquips.buttonItems[button] = ITEM_NONE;
}
for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.cButtonSlots); button++) {
mSaveContext->adultEquips.cButtonSlots[button] = SLOT_NONE;
}
mSaveContext->adultEquips.equipment = 0;
mSaveContext->unk_54 = 0;
mSaveContext->savedSceneNum = SCENE_LINKS_HOUSE;
// Equipment
for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.buttonItems); button++) {
mSaveContext->equips.buttonItems[button] = ITEM_NONE;
}
for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.cButtonSlots); button++) {
mSaveContext->equips.cButtonSlots[button] = SLOT_NONE;
}
mSaveContext->equips.equipment = 0;
// Inventory
for (int item = 0; item < ARRAY_COUNT(mSaveContext->inventory.items); item++) {
mSaveContext->inventory.items[item] = ITEM_NONE;
}
for (int ammo = 0; ammo < ARRAY_COUNT(mSaveContext->inventory.ammo); ammo++) {
mSaveContext->inventory.ammo[ammo] = 0;
}
mSaveContext->inventory.equipment = 0;
mSaveContext->inventory.upgrades = 0;
mSaveContext->inventory.questItems = 0;
for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonItems); dungeon++) {
mSaveContext->inventory.dungeonItems[dungeon] = 0;
}
for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonKeys); dungeon++) {
mSaveContext->inventory.dungeonKeys[dungeon] = 0x0;
}
mSaveContext->inventory.defenseHearts = 0;
mSaveContext->inventory.gsTokens = 0;
for (int scene = 0; scene < ARRAY_COUNT(mSaveContext->sceneFlags); scene++) {
mSaveContext->sceneFlags[scene].chest = 0;
mSaveContext->sceneFlags[scene].swch = 0;
mSaveContext->sceneFlags[scene].clear = 0;
mSaveContext->sceneFlags[scene].collect = 0;
mSaveContext->sceneFlags[scene].unk = 0;
mSaveContext->sceneFlags[scene].rooms = 0;
mSaveContext->sceneFlags[scene].floors = 0;
}
mSaveContext->fw.pos.x = 0;
mSaveContext->fw.pos.y = 0;
mSaveContext->fw.pos.z = 0;
mSaveContext->fw.yaw = 0;
mSaveContext->fw.playerParams = 0;
mSaveContext->fw.entranceIndex = 0;
mSaveContext->fw.roomIndex = 0;
mSaveContext->fw.set = 0;
mSaveContext->fw.tempSwchFlags = 0;
mSaveContext->fw.tempCollectFlags = 0;
for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->gsFlags); flag++) {
mSaveContext->gsFlags[flag] = 0;
}
for (int highscore = 0; highscore < ARRAY_COUNT(mSaveContext->highScores); highscore++) {
mSaveContext->highScores[highscore] = 0;
}
for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->eventChkInf); flag++) {
mSaveContext->eventChkInf[flag] = 0;
}
for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->itemGetInf); flag++) {
mSaveContext->itemGetInf[flag] = 0;
}
for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->infTable); flag++) {
mSaveContext->infTable[flag] = 0;
}
mSaveContext->worldMapAreaData = 0;
mSaveContext->scarecrowLongSongSet = 0;
for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowLongSong); i++) {
mSaveContext->scarecrowLongSong[i].noteIdx = 0;
mSaveContext->scarecrowLongSong[i].unk_01 = 0;
mSaveContext->scarecrowLongSong[i].unk_02 = 0;
mSaveContext->scarecrowLongSong[i].volume = 0;
mSaveContext->scarecrowLongSong[i].vibrato = 0;
mSaveContext->scarecrowLongSong[i].tone = 0;
mSaveContext->scarecrowLongSong[i].semitone = 0;
}
mSaveContext->scarecrowSpawnSongSet = 0;
for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowSpawnSong); i++) {
mSaveContext->scarecrowSpawnSong[i].noteIdx = 0;
mSaveContext->scarecrowSpawnSong[i].unk_01 = 0;
mSaveContext->scarecrowSpawnSong[i].unk_02 = 0;
mSaveContext->scarecrowSpawnSong[i].volume = 0;
mSaveContext->scarecrowSpawnSong[i].vibrato = 0;
mSaveContext->scarecrowSpawnSong[i].tone = 0;
mSaveContext->scarecrowSpawnSong[i].semitone = 0;
}
mSaveContext->horseData.scene = SCENE_HYRULE_FIELD;
mSaveContext->horseData.pos.x = -1840;
mSaveContext->horseData.pos.y = 72;
mSaveContext->horseData.pos.z = 5497;
mSaveContext->horseData.angle = -0x6AD9;
mSaveContext->magicLevel = 0;
mSaveContext->infTable[29] = 1;
mSaveContext->sceneFlags[5].swch = 0x40000000;
// SoH specific
mSaveContext->backupFW = mSaveContext->fw;
mSaveContext->pendingSale = ITEM_NONE;
mSaveContext->pendingSaleMod = MOD_NONE;
mSaveContext->isBossRushPaused = 0;
mSaveContext->pendingIceTrapCount = 0;
// Init with normal quest unless only an MQ rom is provided
mSaveContext->questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
//RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT)
}
void Context::NewSaveContext() {
if (mSaveContext != nullptr && mSaveContext != &gSaveContext) {
free(mSaveContext);
}
mSaveContext = new SaveContext();
InitSaveContext();
}
void Context::ResetLogic() { void Context::ResetLogic() {
NewSaveContext();
mLogic->Reset(); mLogic->Reset();
} }
@ -449,4 +1106,121 @@ Option& Context::GetOption(const RandomizerSettingKey key) const {
TrickOption& Context::GetTrickOption(const RandomizerTrick key) const { TrickOption& Context::GetTrickOption(const RandomizerTrick key) const {
return mSettings->GetTrickOption(key); return mSettings->GetTrickOption(key);
} }
uint8_t Context::InventorySlot(uint32_t item) {
return gItemSlots[item];
}
uint32_t Context::CurrentUpgrade(uint32_t upgrade) {
return (mSaveContext->inventory.upgrades & gUpgradeMasks[upgrade]) >> gUpgradeShifts[upgrade];
}
uint32_t Context::CurrentInventory(uint32_t item) {
return mSaveContext->inventory.items[InventorySlot(item)];
}
void Context::SetUpgrade(uint32_t upgrade, uint8_t level) {
mSaveContext->inventory.upgrades &= gUpgradeNegMasks[upgrade];
mSaveContext->inventory.upgrades |= level << gUpgradeShifts[upgrade];
}
bool Context::CheckInventory(uint32_t item, bool exact) {
auto current = mSaveContext->inventory.items[InventorySlot(item)];
return exact ? (current == item) : (current != ITEM_NONE);
}
void Context::SetInventory(uint32_t itemSlot, uint32_t item) {
mSaveContext->inventory.items[InventorySlot(itemSlot)] = item;
}
bool Context::CheckEquipment(uint32_t equipFlag) {
return (equipFlag & mSaveContext->inventory.equipment);
}
bool Context::CheckQuestItem(uint32_t item) {
return ((1 << item) & mSaveContext->inventory.questItems);
}
bool Context::HasAdultTrade(uint32_t itemID) {
int tradeIndex = itemID - ITEM_POCKET_EGG;
return mSaveContext->adultTradeItems & (1 << tradeIndex);
}
void Context::SetAdultTrade(uint32_t itemID, bool state) {
int tradeIndex = itemID - ITEM_POCKET_EGG;
if (!state) {
mSaveContext->adultTradeItems &= ~(1 << tradeIndex);
}
else {
mSaveContext->adultTradeItems |= (1 << tradeIndex);
}
}
void Context::SetQuestItem(uint32_t item, bool state) {
if (!state) {
mSaveContext->inventory.questItems &= ~(1 << item);
}
else {
mSaveContext->inventory.questItems |= (1 << item);
}
}
uint8_t Context::GetSmallKeyCount(uint32_t dungeonIndex) {
return mSaveContext->inventory.dungeonKeys[dungeonIndex];
}
void Context::SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count) {
mSaveContext->inventory.dungeonKeys[dungeonIndex] = count;
}
bool Context::CheckDungeonItem(uint32_t item, uint32_t dungeonIndex) {
return mSaveContext->inventory.dungeonItems[dungeonIndex] & gBitFlags[item];
}
void Context::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) {
if (!state) {
mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item];
}
else {
mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item];
}
}
bool Context::CheckRandoInf(uint32_t flag) {
return mSaveContext->randomizerInf[flag >> 4] & (1 << (flag & 0xF));
}
void Context::SetRandoInf(uint32_t flag, bool state) {
if (!state) {
mSaveContext->randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
}
else {
mSaveContext->randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
}
}
bool Context::CheckEventChkInf(int32_t flag) {
return mSaveContext->eventChkInf[flag >> 4] & (1 << (flag & 0xF));
}
void Context::SetEventChkInf(int32_t flag, bool state) {
if (!state) {
mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF));
}
else {
mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF));
}
}
uint8_t Context::GetGSCount() {
return mSaveContext->inventory.gsTokens;
}
uint8_t Context::GetAmmo(uint32_t item) {
return mSaveContext->inventory.ammo[gItemSlots[item]];
}
void Context::SetAmmo(uint32_t item, uint8_t count) {
mSaveContext->inventory.ammo[gItemSlots[item]] = count;
}
} // namespace Rando } // namespace Rando

View File

@ -52,6 +52,10 @@ class Context {
void GenerateLocationPool(); void GenerateLocationPool();
static std::vector<RandomizerCheck> GetLocations(const std::vector<RandomizerCheck>& locationPool, static std::vector<RandomizerCheck> GetLocations(const std::vector<RandomizerCheck>& locationPool,
Category categoryInclude, Category categoryExclude = Category::cNull); Category categoryInclude, Category categoryExclude = Category::cNull);
static std::map<uint32_t, uint32_t> RandoGetToQuestItem;
static std::map<uint32_t, uint32_t> RandoGetToDungeonScene;
static std::map<RandomizerGet, uint32_t> RandoGetToEquipFlag;
static std::map<RandomizerGet, uint32_t> RandoGetToRandInf;
void AddExcludedOptions(); void AddExcludedOptions();
void LocationReset(); void LocationReset();
void ClearItemLocations(); void ClearItemLocations();
@ -64,12 +68,17 @@ class Context {
void SetSpoilerLoaded(bool spoilerLoaded = true); void SetSpoilerLoaded(bool spoilerLoaded = true);
bool IsPlandoLoaded() const; bool IsPlandoLoaded() const;
void SetPlandoLoaded(bool plandoLoaded = true); void SetPlandoLoaded(bool plandoLoaded = true);
void ApplyItemEffect(Item& item, bool state);
std::shared_ptr<Settings> GetSettings(); std::shared_ptr<Settings> GetSettings();
std::shared_ptr<EntranceShuffler> GetEntranceShuffler(); std::shared_ptr<EntranceShuffler> GetEntranceShuffler();
std::shared_ptr<Dungeons> GetDungeons(); std::shared_ptr<Dungeons> GetDungeons();
std::shared_ptr<Fishsanity> GetFishsanity(); std::shared_ptr<Fishsanity> GetFishsanity();
DungeonInfo* GetDungeon(size_t key) const; DungeonInfo* GetDungeon(size_t key) const;
std::shared_ptr<Logic> GetLogic(); std::shared_ptr<Logic> GetLogic();
SaveContext* GetSaveContext();
void SetSaveContext(SaveContext* context);
void InitSaveContext();
void NewSaveContext();
void ResetLogic(); void ResetLogic();
std::shared_ptr<Trials> GetTrials(); std::shared_ptr<Trials> GetTrials();
TrialInfo* GetTrial(size_t key) const; TrialInfo* GetTrial(size_t key) const;
@ -92,6 +101,28 @@ class Context {
bool playthroughBeatable = false; bool playthroughBeatable = false;
bool allLocationsReachable = false; bool allLocationsReachable = false;
RandomizerArea GetAreaFromString(std::string str); RandomizerArea GetAreaFromString(std::string str);
uint8_t InventorySlot(uint32_t item);
void SetUpgrade(uint32_t upgrade, uint8_t level);
uint32_t CurrentUpgrade(uint32_t upgrade);
uint32_t CurrentInventory(uint32_t item);
bool CheckInventory(uint32_t item, bool exact);
void SetInventory(uint32_t itemSlot, uint32_t item);
bool CheckEquipment(uint32_t item);
bool CheckQuestItem(uint32_t item);
void SetQuestItem(uint32_t item, bool state);
bool HasAdultTrade(uint32_t item);
void SetAdultTrade(uint32_t item, bool state);
uint8_t GetSmallKeyCount(uint32_t dungeonIndex);
void SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count);
bool CheckDungeonItem(uint32_t item, uint32_t dungeonIndex);
void SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state);
bool CheckRandoInf(uint32_t flag);
void SetRandoInf(uint32_t flag, bool state);
bool CheckEventChkInf(int32_t flag);
uint8_t GetGSCount();
void SetEventChkInf(int32_t flag, bool state);
uint8_t GetAmmo(uint32_t item);
void SetAmmo(uint32_t item, uint8_t count);
private: private:
static std::weak_ptr<Context> mContext; static std::weak_ptr<Context> mContext;
@ -101,6 +132,7 @@ class Context {
std::shared_ptr<EntranceShuffler> mEntranceShuffler; std::shared_ptr<EntranceShuffler> mEntranceShuffler;
std::shared_ptr<Dungeons> mDungeons; std::shared_ptr<Dungeons> mDungeons;
std::shared_ptr<Logic> mLogic; std::shared_ptr<Logic> mLogic;
SaveContext* mSaveContext = nullptr;
std::shared_ptr<Trials> mTrials; std::shared_ptr<Trials> mTrials;
std::shared_ptr<Fishsanity> mFishsanity; std::shared_ptr<Fishsanity> mFishsanity;
bool mSeedGenerated = false; bool mSeedGenerated = false;

View File

@ -14,74 +14,41 @@ namespace Rando {
Item::Item() : randomizerGet(RG_NONE), type(ITEMTYPE_ITEM), getItemId(GI_NONE), advancement(false), hintKey(RHT_NONE), Item::Item() : randomizerGet(RG_NONE), type(ITEMTYPE_ITEM), getItemId(GI_NONE), advancement(false), hintKey(RHT_NONE),
progressive(false), price(0) {} progressive(false), price(0) {}
Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_, Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_,
const bool advancement_, bool* logicVar_, const RandomizerHintTextKey hintKey_, const uint16_t itemId_, const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const uint16_t itemId_,
const uint16_t objectId_, const uint16_t gid_, const uint16_t textId_, const uint16_t field_, const uint16_t objectId_, const uint16_t gid_, const uint16_t textId_, const uint16_t field_,
const int16_t chestAnimation_, const GetItemCategory category_, const uint16_t modIndex_, const int16_t chestAnimation_, const GetItemCategory category_, const uint16_t modIndex_,
const bool progressive_, const uint16_t price_) const bool progressive_, const uint16_t price_)
: randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_), : randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_),
advancement(advancement_), logicVar(logicVar_), hintKey(hintKey_), progressive(progressive_), price(price_) { advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) {
if (modIndex_ == MOD_RANDOMIZER || getItemId > 0x7D) { if (modIndex_ == MOD_RANDOMIZER || getItemId > 0x7D) {
giEntry = std::make_shared<GetItemEntry>(GetItemEntry{itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_RANDOMIZER, static_cast<int16_t>(randomizerGet_), gid_, true, ITEM_FROM_NPC, category_, static_cast<uint16_t>(randomizerGet_), MOD_RANDOMIZER, NULL}); giEntry = std::make_shared<GetItemEntry>(GetItemEntry{ itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_RANDOMIZER, static_cast<int16_t>(randomizerGet_), gid_, true, ITEM_FROM_NPC, category_, static_cast<uint16_t>(randomizerGet_), MOD_RANDOMIZER, NULL });
} else { }
giEntry = std::make_shared<GetItemEntry>(GetItemEntry{itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_VANILLA, getItemId_, gid_, true, ITEM_FROM_NPC, category_, itemId_, modIndex_, NULL}); else {
giEntry = std::make_shared<GetItemEntry>(GetItemEntry{ itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_VANILLA, getItemId_, gid_, true, ITEM_FROM_NPC, category_, itemId_, modIndex_, NULL });
} }
} }
Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_, Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_,
const bool advancement_, uint8_t* logicVar_, const RandomizerHintTextKey hintKey_, const uint16_t itemId_, const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const bool progressive_,
const uint16_t objectId_, const uint16_t gid_, const uint16_t textId_, const uint16_t field_, const uint16_t price_)
const int16_t chestAnimation_, const GetItemCategory category_, const uint16_t modIndex_,
const bool progressive_, const uint16_t price_)
: randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_), : randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_),
advancement(advancement_), logicVar(logicVar_), hintKey(hintKey_), progressive(progressive_), price(price_) { advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) {
if (modIndex_ == MOD_RANDOMIZER || getItemId > 0x7D) {
giEntry = std::make_shared<GetItemEntry>(GetItemEntry{itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_RANDOMIZER, static_cast<int16_t>(randomizerGet_), gid_, true, ITEM_FROM_NPC, category_, static_cast<uint16_t>(randomizerGet_), modIndex_, NULL});
} else {
giEntry = std::make_shared<GetItemEntry>(GetItemEntry{itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_VANILLA, getItemId_, gid_, true, ITEM_FROM_NPC, category_, itemId_, modIndex_, NULL});
}
}
Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_,
const bool advancement_, bool* logicVar_, const RandomizerHintTextKey hintKey_, const bool progressive_,
const uint16_t price_)
: randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_),
advancement(advancement_), logicVar(logicVar_), hintKey(hintKey_), progressive(progressive_), price(price_) {
}
Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_,
const bool advancement_, uint8_t* logicVar_, const RandomizerHintTextKey hintKey_, const bool progressive_,
const uint16_t price_)
: randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_),
advancement(advancement_), logicVar(logicVar_), hintKey(hintKey_), progressive(progressive_), price(price_) {
} }
Item::~Item() = default; Item::~Item() = default;
void Item::ApplyEffect() const { void Item::ApplyEffect() const {
// If this is a key ring, logically add as many keys as we could need auto ctx = Rando::Context::GetInstance();
if (RHT_FOREST_TEMPLE_KEY_RING <= hintKey && hintKey <= RHT_GANONS_CASTLE_KEY_RING) { ctx->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true);
*std::get<uint8_t*>(logicVar) += 10; ctx->GetLogic()->SetInLogic(logicVal, true);
} else { ctx->GetLogic()->UpdateHelpers();
if (std::holds_alternative<bool*>(logicVar)) {
*std::get<bool*>(logicVar) = true;
} else {
*std::get<uint8_t*>(logicVar) += 1;
}
}
Rando::Context::GetInstance()->GetLogic()->UpdateHelpers();
} }
void Item::UndoEffect() const { void Item::UndoEffect() const {
if (RHT_FOREST_TEMPLE_KEY_RING <= hintKey && hintKey <= RHT_GANONS_CASTLE_KEY_RING) { auto ctx = Rando::Context::GetInstance();
*std::get<uint8_t*>(logicVar) -= 10; ctx->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false);
} else { ctx->GetLogic()->SetInLogic(logicVal, false);
if (std::holds_alternative<bool*>(logicVar)) { ctx->GetLogic()->UpdateHelpers();
*std::get<bool*>(logicVar) = false;
} else {
*std::get<uint8_t*>(logicVar) -= 1;
}
}
Rando::Context::GetInstance()->GetLogic()->UpdateHelpers();
} }
const Text& Item::GetName() const { const Text& Item::GetName() const {
@ -100,8 +67,8 @@ ItemType Item::GetItemType() const {
return type; return type;
} }
std::variant<bool*, uint8_t*> Item::GetLogicVar() const { LogicVal Item::GetLogicVal() const {
return logicVar; return logicVal;
} }
RandomizerGet Item::GetRandomizerGet() const { RandomizerGet Item::GetRandomizerGet() const {
@ -116,13 +83,14 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
if (giEntry != nullptr) { if (giEntry != nullptr) {
return giEntry; return giEntry;
} }
auto ctx = Rando::Context::GetInstance();
RandomizerGet actual = RG_NONE; RandomizerGet actual = RG_NONE;
const bool tycoonWallet = const bool tycoonWallet =
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS; OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS;
const u8 infiniteUpgrades = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INFINITE_UPGRADES); const u8 infiniteUpgrades = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INFINITE_UPGRADES);
switch (randomizerGet) { switch (randomizerGet) {
case RG_PROGRESSIVE_STICK_UPGRADE: case RG_PROGRESSIVE_STICK_UPGRADE:
switch (CUR_UPG_VALUE(UPG_STICKS)) { switch (ctx->CurrentUpgrade(UPG_STICKS)) {
case 0: case 0:
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) {
actual = RG_DEKU_STICK_BAG; actual = RG_DEKU_STICK_BAG;
@ -151,7 +119,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_NUT_UPGRADE: case RG_PROGRESSIVE_NUT_UPGRADE:
switch (CUR_UPG_VALUE(UPG_NUTS)) { switch (ctx->CurrentUpgrade(UPG_NUTS)) {
case 0: case 0:
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) {
actual = RG_DEKU_NUT_BAG; actual = RG_DEKU_NUT_BAG;
@ -180,7 +148,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_BOMB_BAG: case RG_PROGRESSIVE_BOMB_BAG:
switch (CUR_UPG_VALUE(UPG_BOMB_BAG)) { switch (ctx->CurrentUpgrade(UPG_BOMB_BAG)) {
case 0: case 0:
actual = RG_BOMB_BAG; actual = RG_BOMB_BAG;
break; break;
@ -207,7 +175,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_BOW: case RG_PROGRESSIVE_BOW:
switch (CUR_UPG_VALUE(UPG_QUIVER)) { switch (ctx->CurrentUpgrade(UPG_QUIVER)) {
case 0: case 0:
actual = RG_FAIRY_BOW; actual = RG_FAIRY_BOW;
break; break;
@ -234,7 +202,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_SLINGSHOT: case RG_PROGRESSIVE_SLINGSHOT:
switch (CUR_UPG_VALUE(UPG_BULLET_BAG)) { switch (ctx->CurrentUpgrade(UPG_BULLET_BAG)) {
case 0: case 0:
actual = RG_FAIRY_SLINGSHOT; actual = RG_FAIRY_SLINGSHOT;
break; break;
@ -261,7 +229,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_OCARINA: case RG_PROGRESSIVE_OCARINA:
switch (INV_CONTENT(ITEM_OCARINA_FAIRY)) { switch (ctx->CurrentInventory(ITEM_OCARINA_FAIRY)) {
case ITEM_NONE: case ITEM_NONE:
actual = RG_FAIRY_OCARINA; actual = RG_FAIRY_OCARINA;
break; break;
@ -274,7 +242,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_HOOKSHOT: case RG_PROGRESSIVE_HOOKSHOT:
switch (INV_CONTENT(ITEM_HOOKSHOT)) { switch (ctx->CurrentInventory(ITEM_HOOKSHOT)) {
case ITEM_NONE: case ITEM_NONE:
actual = RG_HOOKSHOT; actual = RG_HOOKSHOT;
break; break;
@ -287,7 +255,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_STRENGTH: case RG_PROGRESSIVE_STRENGTH:
switch (CUR_UPG_VALUE(UPG_STRENGTH)) { switch (ctx->CurrentUpgrade(UPG_STRENGTH)) {
case 0: case 0:
actual = RG_GORONS_BRACELET; actual = RG_GORONS_BRACELET;
break; break;
@ -303,11 +271,11 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_WALLET: case RG_PROGRESSIVE_WALLET:
if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) { if (!ctx->CheckRandoInf(RAND_INF_HAS_WALLET)) {
actual = RG_CHILD_WALLET; actual = RG_CHILD_WALLET;
break; break;
} }
switch (CUR_UPG_VALUE(UPG_WALLET)) { switch (ctx->CurrentUpgrade(UPG_WALLET)) {
case 0: case 0:
actual = RG_ADULT_WALLET; actual = RG_ADULT_WALLET;
break; break;
@ -330,11 +298,11 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_SCALE: case RG_PROGRESSIVE_SCALE:
if (!Flags_GetRandomizerInf(RAND_INF_CAN_SWIM)) { if (!ctx->CheckRandoInf(RAND_INF_CAN_SWIM)) {
actual = RG_BRONZE_SCALE; actual = RG_BRONZE_SCALE;
break; break;
} }
switch (CUR_UPG_VALUE(UPG_SCALE)) { switch (ctx->CurrentUpgrade(UPG_SCALE)) {
case 0: case 0:
actual = RG_SILVER_SCALE; actual = RG_SILVER_SCALE;
break; break;
@ -347,7 +315,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
} }
break; break;
case RG_PROGRESSIVE_MAGIC_METER: case RG_PROGRESSIVE_MAGIC_METER:
switch (gSaveContext.magicLevel) { switch (ctx->GetSaveContext()->magicLevel) {
case 0: case 0:
actual = RG_MAGIC_SINGLE; actual = RG_MAGIC_SINGLE;
break; break;
@ -370,11 +338,11 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
actual = RG_BIGGORON_SWORD; actual = RG_BIGGORON_SWORD;
break; break;
case RG_PROGRESSIVE_BOMBCHUS: case RG_PROGRESSIVE_BOMBCHUS:
if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { if (ctx->CurrentInventory(ITEM_BOMBCHU) == ITEM_NONE) {
actual = RG_BOMBCHU_20; actual = RG_BOMBCHU_20;
} else if (infiniteUpgrades != RO_INF_UPGRADES_OFF) { } else if (infiniteUpgrades != RO_INF_UPGRADES_OFF) {
actual = RG_BOMBCHU_INF; actual = RG_BOMBCHU_INF;
} else if (AMMO(ITEM_BOMBCHU) < 5) { } else if (ctx->GetAmmo(ITEM_BOMBCHU) < 5) {
actual = RG_BOMBCHU_10; actual = RG_BOMBCHU_10;
} else { } else {
actual = RG_BOMBCHU_5; actual = RG_BOMBCHU_5;

View File

@ -11,6 +11,7 @@
enum ItemType { enum ItemType {
ITEMTYPE_ITEM, ITEMTYPE_ITEM,
ITEMTYPE_EQUIP,
ITEMTYPE_MAP, ITEMTYPE_MAP,
ITEMTYPE_COMPASS, ITEMTYPE_COMPASS,
ITEMTYPE_BOSSKEY, ITEMTYPE_BOSSKEY,
@ -30,17 +31,11 @@ class Item {
public: public:
Item(); Item();
Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_, Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
bool* logicVar_, RandomizerHintTextKey hintKey_, uint16_t itemId_, uint16_t objectId_, uint16_t gid_, LogicVal logicVal_, RandomizerHintTextKey hintKey_, uint16_t itemId_, uint16_t objectId_, uint16_t gid_,
uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t modIndex_,
uint16_t modIndex_, bool progressive_ = false, uint16_t price_ = 0); bool progressive_ = false, uint16_t price_ = 0);
Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_, Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
uint8_t* logicVar_, RandomizerHintTextKey hintKey_, uint16_t itemId_, uint16_t objectId_, uint16_t gid_, LogicVal logicVal_, RandomizerHintTextKey hintKey_, bool progressive_ = false, uint16_t price_ = 0);
uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t modIndex_,
bool progressive_ = false, uint16_t price_ = 0);
Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
bool* logicVar_, RandomizerHintTextKey hintKey_, bool progressive_ = false, uint16_t price_ = 0);
Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
uint8_t* logicVar_, RandomizerHintTextKey hintKey_, bool progressive_ = false, uint16_t price_ = 0);
~Item(); ~Item();
void ApplyEffect() const; void ApplyEffect() const;
@ -51,7 +46,7 @@ class Item {
bool IsAdvancement() const; bool IsAdvancement() const;
int GetItemID() const; int GetItemID() const;
ItemType GetItemType() const; ItemType GetItemType() const;
std::variant<bool*, uint8_t*> GetLogicVar() const; LogicVal GetLogicVal() const;
RandomizerGet GetRandomizerGet() const; RandomizerGet GetRandomizerGet() const;
uint16_t GetPrice() const; uint16_t GetPrice() const;
std::shared_ptr<GetItemEntry> GetGIEntry() const; std::shared_ptr<GetItemEntry> GetGIEntry() const;
@ -73,11 +68,11 @@ class Item {
ItemType type; ItemType type;
int16_t getItemId; int16_t getItemId;
bool advancement; bool advancement;
std::variant<bool*, uint8_t*> logicVar; LogicVal logicVal;
RandomizerHintTextKey hintKey; RandomizerHintTextKey hintKey;
bool progressive; bool progressive;
uint16_t price; uint16_t price;
bool playthrough = false; bool playthrough = false;
std::shared_ptr<GetItemEntry> giEntry; std::shared_ptr<GetItemEntry> giEntry;
}; };
} }

View File

@ -12,331 +12,331 @@ std::unordered_map<std::string, RandomizerGet> Rando::StaticData::itemNameToEnum
void Rando::StaticData::InitItemTable() { void Rando::StaticData::InitItemTable() {
auto logic = Context::GetInstance()->GetLogic(); auto logic = Context::GetInstance()->GetLogic();
itemTable[RG_NONE] = Item(RG_NONE, Text{ "No Item", "Rien", "Kein Artikel" }, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, &logic->noVariable, RHT_NONE, ITEM_NONE, 0, 0, 0, 0, 0, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_NONE] = Item(RG_NONE, Text{ "No Item", "Rien", "Kein Artikel" }, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, ITEM_NONE, 0, 0, 0, 0, 0, ITEM_CATEGORY_JUNK, MOD_NONE);
// Randomizer Get Randomizer Get Name Text Type Get Item ID Adv. Logic Variable Hint Text Key Item ID Object ID Draw ID Text ID field Chest Animation Item Category Mod Index // Randomizer Get Randomizer Get Name Text Type Get Item ID Adv. Logic Value Hint Text Key Item ID Object ID Draw ID Text ID field Chest Animation Item Category Mod Index
itemTable[RG_KOKIRI_SWORD] = Item(RG_KOKIRI_SWORD, Text{ "Kokiri Sword", "Épée Kokiri", "Kokiri-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_KOKIRI, true, &logic->KokiriSword, RHT_KOKIRI_SWORD, ITEM_SWORD_KOKIRI, OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, 0xA4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_KOKIRI_SWORD] = Item(RG_KOKIRI_SWORD, Text{ "Kokiri Sword", "Épée Kokiri", "Kokiri-Schwert" }, ITEMTYPE_EQUIP, GI_SWORD_KOKIRI, true, LOGIC_KOKIRI_SWORD, RHT_KOKIRI_SWORD, ITEM_SWORD_KOKIRI, OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, 0xA4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MASTER_SWORD] = Item(RG_MASTER_SWORD, Text{ "Master Sword", "Épée de Legende", "Espada Master"}, ITEMTYPE_ITEM, 0xE0, true, &logic->MasterSword, RHT_MASTER_SWORD, ITEM_SWORD_MASTER, OBJECT_TOKI_OBJECTS, GID_SWORD_BGS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_MASTER_SWORD] = Item(RG_MASTER_SWORD, Text{ "Master Sword", "Épée de Legende", "Espada Master"}, ITEMTYPE_EQUIP, 0xE0, true, LOGIC_MASTER_SWORD, RHT_MASTER_SWORD, ITEM_SWORD_MASTER, OBJECT_TOKI_OBJECTS, GID_SWORD_BGS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_MASTER_SWORD].SetCustomDrawFunc(Randomizer_DrawMasterSword); itemTable[RG_MASTER_SWORD].SetCustomDrawFunc(Randomizer_DrawMasterSword);
itemTable[RG_GIANTS_KNIFE] = Item(RG_GIANTS_KNIFE, Text{ "Giant's Knife", "Lame des Géants", "Messer des Riesen" }, ITEMTYPE_ITEM, GI_SWORD_KNIFE, true, &logic->noVariable, RHT_GIANTS_KNIFE, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x4B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GIANTS_KNIFE] = Item(RG_GIANTS_KNIFE, Text{ "Giant's Knife", "Lame des Géants", "Messer des Riesen" }, ITEMTYPE_EQUIP, GI_SWORD_KNIFE, true, LOGIC_NONE, RHT_GIANTS_KNIFE, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x4B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BIGGORON_SWORD] = Item(RG_BIGGORON_SWORD, Text{ "Biggoron's Sword", "Épée de Biggoron", "Biggoron-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BGS, true, &logic->BiggoronSword, RHT_BIGGORON_SWORD, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x0C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_BIGGORON_SWORD] = Item(RG_BIGGORON_SWORD, Text{ "Biggoron's Sword", "Épée de Biggoron", "Biggoron-Schwert" }, ITEMTYPE_EQUIP, GI_SWORD_BGS, true, LOGIC_BIGGORON_SWORD, RHT_BIGGORON_SWORD, ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x0C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_DEKU_SHIELD] = Item(RG_DEKU_SHIELD, Text{ "Deku Shield", "Bouclier Mojo", "Deku-Schild" }, ITEMTYPE_ITEM, GI_SHIELD_DEKU, false, &logic->noVariable, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_DEKU_SHIELD] = Item(RG_DEKU_SHIELD, Text{ "Deku Shield", "Bouclier Mojo", "Deku-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_DEKU, false, LOGIC_DEKU_SHIELD, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_HYLIAN_SHIELD] = Item(RG_HYLIAN_SHIELD, Text{ "Hylian Shield", "Bouclier Hylien", "Hylia-Schild" }, ITEMTYPE_ITEM, GI_SHIELD_HYLIAN, false, &logic->noVariable, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_HYLIAN_SHIELD] = Item(RG_HYLIAN_SHIELD, Text{ "Hylian Shield", "Bouclier Hylien", "Hylia-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_HYLIAN, false, LOGIC_HYLIAN_SHIELD, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_MIRROR_SHIELD] = Item(RG_MIRROR_SHIELD, Text{ "Mirror Shield", "Bouclier Miroir", "Spiegel-Schild" }, ITEMTYPE_ITEM, GI_SHIELD_MIRROR, true, &logic->MirrorShield, RHT_MIRROR_SHIELD, ITEM_SHIELD_MIRROR, OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, 0x4E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MIRROR_SHIELD] = Item(RG_MIRROR_SHIELD, Text{ "Mirror Shield", "Bouclier Miroir", "Spiegel-Schild" }, ITEMTYPE_EQUIP, GI_SHIELD_MIRROR, true, LOGIC_MIRROR_SHIELD, RHT_MIRROR_SHIELD, ITEM_SHIELD_MIRROR, OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, 0x4E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GORON_TUNIC] = Item(RG_GORON_TUNIC, Text{ "Goron Tunic", "Tunique Goron", "Goronen-Tunika" }, ITEMTYPE_ITEM, GI_TUNIC_GORON, true, &logic->GoronTunic, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_GORON_TUNIC] = Item(RG_GORON_TUNIC, Text{ "Goron Tunic", "Tunique Goron", "Goronen-Tunika" }, ITEMTYPE_EQUIP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_ZORA_TUNIC] = Item(RG_ZORA_TUNIC, Text{ "Zora Tunic", "Tunique Zora", "Zora-Tunika" }, ITEMTYPE_ITEM, GI_TUNIC_ZORA, true, &logic->ZoraTunic, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_ZORA_TUNIC] = Item(RG_ZORA_TUNIC, Text{ "Zora Tunic", "Tunique Zora", "Zora-Tunika" }, ITEMTYPE_EQUIP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_IRON_BOOTS] = Item(RG_IRON_BOOTS, Text{ "Iron Boots", "Bottes de plomb", "Eisenstiefel" }, ITEMTYPE_ITEM, GI_BOOTS_IRON, true, &logic->IronBoots, RHT_IRON_BOOTS, ITEM_BOOTS_IRON, OBJECT_GI_BOOTS_2, GID_BOOTS_IRON, 0x53, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_IRON_BOOTS] = Item(RG_IRON_BOOTS, Text{ "Iron Boots", "Bottes de plomb", "Eisenstiefel" }, ITEMTYPE_EQUIP, GI_BOOTS_IRON, true, LOGIC_IRON_BOOTS, RHT_IRON_BOOTS, ITEM_BOOTS_IRON, OBJECT_GI_BOOTS_2, GID_BOOTS_IRON, 0x53, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_HOVER_BOOTS] = Item(RG_HOVER_BOOTS, Text{ "Hover Boots", "Bottes de airs", "Gleitstiefel" }, ITEMTYPE_ITEM, GI_BOOTS_HOVER, true, &logic->HoverBoots, RHT_HOVER_BOOTS, ITEM_BOOTS_HOVER, OBJECT_GI_HOVERBOOTS, GID_BOOTS_HOVER, 0x54, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_HOVER_BOOTS] = Item(RG_HOVER_BOOTS, Text{ "Hover Boots", "Bottes de airs", "Gleitstiefel" }, ITEMTYPE_EQUIP, GI_BOOTS_HOVER, true, LOGIC_HOVER_BOOTS, RHT_HOVER_BOOTS, ITEM_BOOTS_HOVER, OBJECT_GI_HOVERBOOTS, GID_BOOTS_HOVER, 0x54, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BOOMERANG] = Item(RG_BOOMERANG, Text{ "Boomerang", "Boomerang", "Bumerang" }, ITEMTYPE_ITEM, GI_BOOMERANG, true, &logic->Boomerang, RHT_BOOMERANG, ITEM_BOOMERANG, OBJECT_GI_BOOMERANG, GID_BOOMERANG, 0x35, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_BOOMERANG] = Item(RG_BOOMERANG, Text{ "Boomerang", "Boomerang", "Bumerang" }, ITEMTYPE_ITEM, GI_BOOMERANG, true, LOGIC_BOOMERANG, RHT_BOOMERANG, ITEM_BOOMERANG, OBJECT_GI_BOOMERANG, GID_BOOMERANG, 0x35, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_LENS_OF_TRUTH] = Item(RG_LENS_OF_TRUTH, Text{ "Lens of Truth", "Monocle de Vérité", "Auge der Wahrheit" }, ITEMTYPE_ITEM, GI_LENS, true, &logic->LensOfTruth, RHT_LENS_OF_TRUTH, ITEM_LENS, OBJECT_GI_GLASSES, GID_LENS, 0x39, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_LENS_OF_TRUTH] = Item(RG_LENS_OF_TRUTH, Text{ "Lens of Truth", "Monocle de Vérité", "Auge der Wahrheit" }, ITEMTYPE_ITEM, GI_LENS, true, LOGIC_LENS_OF_TRUTH, RHT_LENS_OF_TRUTH, ITEM_LENS, OBJECT_GI_GLASSES, GID_LENS, 0x39, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MEGATON_HAMMER] = Item(RG_MEGATON_HAMMER, Text{ "Megaton Hammer", "Masse des Titans", "Stahlhammer" }, ITEMTYPE_ITEM, GI_HAMMER, true, &logic->Hammer, RHT_MEGATON_HAMMER, ITEM_HAMMER, OBJECT_GI_HAMMER, GID_HAMMER, 0x38, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MEGATON_HAMMER] = Item(RG_MEGATON_HAMMER, Text{ "Megaton Hammer", "Masse des Titans", "Stahlhammer" }, ITEMTYPE_ITEM, GI_HAMMER, true, LOGIC_HAMMER, RHT_MEGATON_HAMMER, ITEM_HAMMER, OBJECT_GI_HAMMER, GID_HAMMER, 0x38, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_STONE_OF_AGONY] = Item(RG_STONE_OF_AGONY, Text{ "Stone of Agony", "Pierre de Souffrance", "Stein der Qualen" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, &logic->ShardOfAgony, RHT_STONE_OF_AGONY, ITEM_STONE_OF_AGONY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, 0x68, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_STONE_OF_AGONY] = Item(RG_STONE_OF_AGONY, Text{ "Stone of Agony", "Pierre de Souffrance", "Stein der Qualen" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, LOGIC_STONE_OF_AGONY, RHT_STONE_OF_AGONY, ITEM_STONE_OF_AGONY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, 0x68, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_DINS_FIRE] = Item(RG_DINS_FIRE, Text{ "Din's Fire", "Feu de Din", "Dins Feuerinferno" }, ITEMTYPE_ITEM, GI_DINS_FIRE, true, &logic->DinsFire, RHT_DINS_FIRE, ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_DINS_FIRE] = Item(RG_DINS_FIRE, Text{ "Din's Fire", "Feu de Din", "Dins Feuerinferno" }, ITEMTYPE_ITEM, GI_DINS_FIRE, true, LOGIC_DINS_FIRE, RHT_DINS_FIRE, ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FARORES_WIND] = Item(RG_FARORES_WIND, Text{ "Farore's Wind", "Vent de Farore", "Farores Donnersturm" }, ITEMTYPE_ITEM, GI_FARORES_WIND, true, &logic->FaroresWind, RHT_FARORES_WIND, ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FARORES_WIND] = Item(RG_FARORES_WIND, Text{ "Farore's Wind", "Vent de Farore", "Farores Donnersturm" }, ITEMTYPE_ITEM, GI_FARORES_WIND, true, LOGIC_FARORES_WIND, RHT_FARORES_WIND, ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_NAYRUS_LOVE] = Item(RG_NAYRUS_LOVE, Text{ "Nayru's Love", "Amour de Nayru", "Nayrus Umarmung" }, ITEMTYPE_ITEM, GI_NAYRUS_LOVE, true, &logic->NayrusLove, RHT_NAYRUS_LOVE, ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_NAYRUS_LOVE] = Item(RG_NAYRUS_LOVE, Text{ "Nayru's Love", "Amour de Nayru", "Nayrus Umarmung" }, ITEMTYPE_ITEM, GI_NAYRUS_LOVE, true, LOGIC_NAYRUS_LOVE, RHT_NAYRUS_LOVE, ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuerpfeile" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, &logic->FireArrows, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuerpfeile" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eispfeil" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, &logic->IceArrows, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eispfeil" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Lichtpfeil" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, &logic->LightArrows, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Lichtpfeil" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo Karte" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, &logic->GerudoToken, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo Karte" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, LOGIC_GERUDO_CARD, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{ "Magic Bean", "Haricots Magiques", "Wundererbse" }, ITEMTYPE_ITEM, GI_BEAN, true, &logic->MagicBean, RHT_MAGIC_BEAN, ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{ "Magic Bean", "Haricots Magiques", "Wundererbse" }, ITEMTYPE_ITEM, GI_BEAN, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN, ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MAGIC_BEAN_PACK] = Item(RG_MAGIC_BEAN_PACK, Text{ "Magic Bean Pack", "Paquet de Haricots Magiques", "Wundererbsen-Packung" }, ITEMTYPE_ITEM, RG_MAGIC_BEAN_PACK, true, &logic->MagicBeanPack, RHT_MAGIC_BEAN_PACK, RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_MAGIC_BEAN_PACK] = Item(RG_MAGIC_BEAN_PACK, Text{ "Magic Bean Pack", "Paquet de Haricots Magiques", "Wundererbsen-Packung" }, ITEMTYPE_ITEM, RG_MAGIC_BEAN_PACK, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN_PACK, RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DOUBLE_DEFENSE] = Item(RG_DOUBLE_DEFENSE, Text{ "Double Defense", "Double Défence", "Doppelte Verteidigung" }, ITEMTYPE_ITEM, RG_DOUBLE_DEFENSE, true, &logic->DoubleDefense, RHT_DOUBLE_DEFENSE, RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER,0xE9, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_DOUBLE_DEFENSE] = Item(RG_DOUBLE_DEFENSE, Text{ "Double Defense", "Double Défence", "Doppelte Verteidigung" }, ITEMTYPE_ITEM, RG_DOUBLE_DEFENSE, true, LOGIC_DOUBLE_DEFENSE, RHT_DOUBLE_DEFENSE, RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER,0xE9, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DOUBLE_DEFENSE].SetCustomDrawFunc(Randomizer_DrawDoubleDefense); itemTable[RG_DOUBLE_DEFENSE].SetCustomDrawFunc(Randomizer_DrawDoubleDefense);
// Trade Quest Items // Trade Quest Items
itemTable[RG_WEIRD_EGG] = Item(RG_WEIRD_EGG, Text{ "Weird Egg", "Oeuf Curieux", "Seltsames Ei" }, ITEMTYPE_ITEM, GI_WEIRD_EGG, true, &logic->WeirdEgg, RHT_WEIRD_EGG, ITEM_WEIRD_EGG, OBJECT_GI_EGG, GID_EGG, 0x9A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_WEIRD_EGG] = Item(RG_WEIRD_EGG, Text{ "Weird Egg", "Oeuf Curieux", "Seltsames Ei" }, ITEMTYPE_ITEM, GI_WEIRD_EGG, true, LOGIC_WEIRD_EGG, RHT_WEIRD_EGG, ITEM_WEIRD_EGG, OBJECT_GI_EGG, GID_EGG, 0x9A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ZELDAS_LETTER] = Item(RG_ZELDAS_LETTER, Text{ "Zelda's Letter", "Lettre de Zelda", "Zeldas Brief" }, ITEMTYPE_ITEM, GI_LETTER_ZELDA, true, &logic->ZeldasLetter, RHT_ZELDAS_LETTER, ITEM_LETTER_ZELDA, OBJECT_GI_LETTER, GID_LETTER_ZELDA, 0x69, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ZELDAS_LETTER] = Item(RG_ZELDAS_LETTER, Text{ "Zelda's Letter", "Lettre de Zelda", "Zeldas Brief" }, ITEMTYPE_ITEM, GI_LETTER_ZELDA, true, LOGIC_ZELDAS_LETTER, RHT_ZELDAS_LETTER, ITEM_LETTER_ZELDA, OBJECT_GI_LETTER, GID_LETTER_ZELDA, 0x69, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_POCKET_EGG] = Item(RG_POCKET_EGG, Text{ "Pocket Egg", "Oeuf de poche", "Taschenei" }, ITEMTYPE_ITEM, GI_POCKET_EGG, true, &logic->PocketEgg, RHT_POCKET_EGG, ITEM_POCKET_EGG, OBJECT_GI_EGG, GID_EGG, 0x01, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_POCKET_EGG] = Item(RG_POCKET_EGG, Text{ "Pocket Egg", "Oeuf de poche", "Taschenei" }, ITEMTYPE_ITEM, GI_POCKET_EGG, true, LOGIC_POCKET_EGG, RHT_POCKET_EGG, ITEM_POCKET_EGG, OBJECT_GI_EGG, GID_EGG, 0x01, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_COJIRO] = Item(RG_COJIRO, Text{ "Cojiro", "P'tit Poulet", "Cojiro" }, ITEMTYPE_ITEM, GI_COJIRO, true, &logic->Cojiro, RHT_COJIRO, ITEM_COJIRO, OBJECT_GI_NIWATORI, GID_COJIRO, 0x02, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_COJIRO] = Item(RG_COJIRO, Text{ "Cojiro", "P'tit Poulet", "Cojiro" }, ITEMTYPE_ITEM, GI_COJIRO, true, LOGIC_COJIRO, RHT_COJIRO, ITEM_COJIRO, OBJECT_GI_NIWATORI, GID_COJIRO, 0x02, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champigon Suspect", "Seltsamer Pilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, &logic->OddMushroom, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champigon Suspect", "Seltsamer Pilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ODD_POTION] = Item(RG_ODD_POTION, Text{ "Odd Potion", "Mixture Suspecte", "Seltsamer Trank" }, ITEMTYPE_ITEM, GI_ODD_POTION, true, &logic->OddPoultice, RHT_ODD_POTION, ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ODD_POTION] = Item(RG_ODD_POTION, Text{ "Odd Potion", "Mixture Suspecte", "Seltsamer Trank" }, ITEMTYPE_ITEM, GI_ODD_POTION, true, LOGIC_ODD_POULTICE, RHT_ODD_POTION, ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{ "Poacher's Saw", "Scie du Chasseur", "Wilderer-Säge" }, ITEMTYPE_ITEM, GI_SAW, true, &logic->PoachersSaw, RHT_POACHERS_SAW, ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{ "Poacher's Saw", "Scie du Chasseur", "Wilderer-Säge" }, ITEMTYPE_ITEM, GI_SAW, true, LOGIC_POACHERS_SAW, RHT_POACHERS_SAW, ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Schwert des gebrochenen Goronen" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, &logic->BrokenSword, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Schwert des gebrochenen Goronen" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{ "Prescription", "Ordonnance", "Verschreibung" }, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, &logic->Prescription, RHT_PRESCRIPTION, ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{ "Prescription", "Ordonnance", "Verschreibung" }, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, LOGIC_PRESCRIPTION, RHT_PRESCRIPTION, ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{ "Eyeball Frog", "Crapaud-qui-louche", "Augapfel-Frosch" }, ITEMTYPE_ITEM, GI_FROG, true, &logic->EyeballFrog, RHT_EYEBALL_FROG, ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{ "Eyeball Frog", "Crapaud-qui-louche", "Augapfel-Frosch" }, ITEMTYPE_ITEM, GI_FROG, true, LOGIC_EYEBALL_FROG, RHT_EYEBALL_FROG, ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_EYEDROPS] = Item(RG_EYEDROPS, Text{ "World's Finest Eyedrops", "Super Gouttes", "Supertropfen" }, ITEMTYPE_ITEM, GI_EYEDROPS, true, &logic->Eyedrops, RHT_EYEDROPS, ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EYEDROPS] = Item(RG_EYEDROPS, Text{ "World's Finest Eyedrops", "Super Gouttes", "Supertropfen" }, ITEMTYPE_ITEM, GI_EYEDROPS, true, LOGIC_EYEDROPS, RHT_EYEDROPS, ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_CLAIM_CHECK] = Item(RG_CLAIM_CHECK, Text{ "Claim Check", "Certificat", "Quittung" }, ITEMTYPE_ITEM, GI_CLAIM_CHECK, true, &logic->ClaimCheck, RHT_CLAIM_CHECK, ITEM_CLAIM_CHECK, OBJECT_GI_TICKETSTONE, GID_CLAIM_CHECK, 0x0A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_CLAIM_CHECK] = Item(RG_CLAIM_CHECK, Text{ "Claim Check", "Certificat", "Quittung" }, ITEMTYPE_ITEM, GI_CLAIM_CHECK, true, LOGIC_CLAIM_CHECK, RHT_CLAIM_CHECK, ITEM_CLAIM_CHECK, OBJECT_GI_TICKETSTONE, GID_CLAIM_CHECK, 0x0A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
// Skulltula Token // Skulltula Token
itemTable[RG_GOLD_SKULLTULA_TOKEN] = Item(RG_GOLD_SKULLTULA_TOKEN, Text{ "Gold Skulltula Token", "Symbole de Skulltula d'Or", "Goldenes Skulltula-Symbol" }, ITEMTYPE_TOKEN, GI_SKULL_TOKEN, true, &logic->GoldSkulltulaTokens, RHT_GOLD_SKULLTULA_TOKEN, ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SKULLTULA_TOKEN, MOD_NONE); itemTable[RG_GOLD_SKULLTULA_TOKEN] = Item(RG_GOLD_SKULLTULA_TOKEN, Text{ "Gold Skulltula Token", "Symbole de Skulltula d'Or", "Goldenes Skulltula-Symbol" }, ITEMTYPE_TOKEN, GI_SKULL_TOKEN, true, LOGIC_GOLD_SKULLTULA_TOKENS, RHT_GOLD_SKULLTULA_TOKEN, ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SKULLTULA_TOKEN, MOD_NONE);
// Progressive Items // Progressive Items
itemTable[RG_PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{ "Progressive Hookshot", "Grappin (prog.)", "Progressiver Fanghaken" }, ITEMTYPE_ITEM, 0x80, true, &logic->ProgressiveHookshot, RHT_PROGRESSIVE_HOOKSHOT, true); itemTable[RG_PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{ "Progressive Hookshot", "Grappin (prog.)", "Progressiver Fanghaken" }, ITEMTYPE_ITEM, 0x80, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_PROGRESSIVE_HOOKSHOT, true);
itemTable[RG_PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{ "Strength Upgrade", "Amélioration de Force (prog.)", "Progressives Kraft-Upgrade" }, ITEMTYPE_ITEM, 0x81, true, &logic->ProgressiveStrength, RHT_PROGRESSIVE_STRENGTH, true); itemTable[RG_PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{ "Strength Upgrade", "Amélioration de Force (prog.)", "Progressives Kraft-Upgrade" }, ITEMTYPE_ITEM, 0x81, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_PROGRESSIVE_STRENGTH, true);
itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Progressive Bombentasche" }, ITEMTYPE_ITEM, 0x82, true, &logic->ProgressiveBombBag, RHT_PROGRESSIVE_BOMB_BAG, true); itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Progressive Bombentasche" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, true);
itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Progressiver Bogen" }, ITEMTYPE_ITEM, 0x83, true, &logic->ProgressiveBow, RHT_PROGRESSIVE_BOW, true); itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Progressiver Bogen" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, true);
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_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, 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_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Brieftasche" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, 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_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Skala" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, 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, true, &logic->ProgressiveNutBag, RHT_PROGRESSIVE_NUT_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_PROGRESSIVE_NUT_BAG, 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_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_PROGRESSIVE_STICK_BAG, 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_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_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives magisches Messgerät" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, 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); itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, LOGIC_PROGRESSIVE_OCARINA, RHT_PROGRESSIVE_OCARINA, true);
itemTable[RG_PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{ "Progressive Goron Sword", "Épée Goron (prog.)", "Progressives Goronenschwert" }, ITEMTYPE_ITEM, 0xD4, true, &logic->ProgressiveGiantKnife,RHT_PROGRESSIVE_GORONSWORD, true); itemTable[RG_PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{ "Progressive Goron Sword", "Épée Goron (prog.)", "Progressives Goronenschwert" }, ITEMTYPE_ITEM, 0xD4, true, LOGIC_PROGRESSIVE_GIANT_KNIFE, RHT_PROGRESSIVE_GORONSWORD, true);
// Bottles // Bottles
itemTable[RG_EMPTY_BOTTLE] = Item(RG_EMPTY_BOTTLE, Text{ "Empty Bottle", "Bouteille Vide", "Leere Flasche" }, ITEMTYPE_ITEM, GI_BOTTLE, true, &logic->Bottles, RHT_BOTTLE_WITH_MILK, ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EMPTY_BOTTLE] = Item(RG_EMPTY_BOTTLE, Text{ "Empty Bottle", "Bouteille Vide", "Leere Flasche" }, ITEMTYPE_ITEM, GI_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BOTTLE_WITH_MILK] = Item(RG_BOTTLE_WITH_MILK, Text{ "Bottle with Milk", "Bouteille avec du Lait", "Flasche mit Milch" }, ITEMTYPE_ITEM, GI_MILK_BOTTLE, true, &logic->Bottles, RHT_BOTTLE_WITH_MILK, ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_BOTTLE_WITH_MILK] = Item(RG_BOTTLE_WITH_MILK, Text{ "Bottle with Milk", "Bouteille avec du Lait", "Flasche mit Milch" }, ITEMTYPE_ITEM, GI_MILK_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BOTTLE_WITH_RED_POTION] = Item(RG_BOTTLE_WITH_RED_POTION, Text{ "Bottle with Red Potion", "Bouteille avec une Potion Rouge", "Flasche mit rotem Elixier" }, ITEMTYPE_ITEM, 0x8C, true, &logic->Bottles, RHT_BOTTLE_WITH_RED_POTION, RG_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_RED_POTION] = Item(RG_BOTTLE_WITH_RED_POTION, Text{ "Bottle with Red Potion", "Bouteille avec une Potion Rouge", "Flasche mit rotem Elixier" }, ITEMTYPE_ITEM, 0x8C, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_RED_POTION, RG_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_GREEN_POTION] = Item(RG_BOTTLE_WITH_GREEN_POTION, Text{ "Bottle with Green Potion", "Bouteille avec une Potion Verte", "Flasche mit grünem Elixier" }, ITEMTYPE_ITEM, 0x8D, true, &logic->Bottles, RHT_BOTTLE_WITH_GREEN_POTION,RG_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_GREEN_POTION] = Item(RG_BOTTLE_WITH_GREEN_POTION, Text{ "Bottle with Green Potion", "Bouteille avec une Potion Verte", "Flasche mit grünem Elixier" }, ITEMTYPE_ITEM, 0x8D, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_GREEN_POTION, RG_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_BLUE_POTION] = Item(RG_BOTTLE_WITH_BLUE_POTION, Text{ "Bottle with Blue Potion", "Bouteille avec une Potion Bleue", "Flasche mit blauem Elixier" }, ITEMTYPE_ITEM, 0x8E, true, &logic->Bottles, RHT_BOTTLE_WITH_BLUE_POTION,RG_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_BLUE_POTION] = Item(RG_BOTTLE_WITH_BLUE_POTION, Text{ "Bottle with Blue Potion", "Bouteille avec une Potion Bleue", "Flasche mit blauem Elixier" }, ITEMTYPE_ITEM, 0x8E, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BLUE_POTION, RG_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_FAIRY] = Item(RG_BOTTLE_WITH_FAIRY, Text{ "Bottle with Fairy", "Bouteille avec une Fée", "Flasche mit Fee" }, ITEMTYPE_ITEM, 0x8F, true, &logic->Bottles, RHT_BOTTLE_WITH_FAIRY, RG_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_FAIRY] = Item(RG_BOTTLE_WITH_FAIRY, Text{ "Bottle with Fairy", "Bouteille avec une Fée", "Flasche mit Fee" }, ITEMTYPE_ITEM, 0x8F, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_FAIRY, RG_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_FISH] = Item(RG_BOTTLE_WITH_FISH, Text{ "Bottle with Fish", "Bouteille avec un Poisson", "Flasche mit Fisch" }, ITEMTYPE_ITEM, 0x90, true, &logic->Bottles, RHT_BOTTLE_WITH_FISH, RG_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_FISH] = Item(RG_BOTTLE_WITH_FISH, Text{ "Bottle with Fish", "Bouteille avec un Poisson", "Flasche mit Fisch" }, ITEMTYPE_ITEM, 0x90, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_FISH, RG_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_BLUE_FIRE] = Item(RG_BOTTLE_WITH_BLUE_FIRE, Text{ "Bottle with Blue Fire", "Bouteille avec une Flamme Bleue", "Flasche mit blauem Feuer" }, ITEMTYPE_ITEM, 0x91, true, &logic->Bottles, RHT_BOTTLE_WITH_BLUE_FIRE, RG_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_BLUE_FIRE] = Item(RG_BOTTLE_WITH_BLUE_FIRE, Text{ "Bottle with Blue Fire", "Bouteille avec une Flamme Bleue", "Flasche mit blauem Feuer" }, ITEMTYPE_ITEM, 0x91, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BLUE_FIRE, RG_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_BUGS] = Item(RG_BOTTLE_WITH_BUGS, Text{ "Bottle with Bugs", "Bouteille avec des Insectes", "Flasche mit Wanzen" }, ITEMTYPE_ITEM, 0x92, true, &logic->Bottles, RHT_BOTTLE_WITH_BUGS, RG_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_BUGS] = Item(RG_BOTTLE_WITH_BUGS, Text{ "Bottle with Bugs", "Bouteille avec des Insectes", "Flasche mit Wanzen" }, ITEMTYPE_ITEM, 0x92, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_BUGS, RG_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOTTLE_WITH_POE] = Item(RG_BOTTLE_WITH_POE, Text{ "Bottle with Poe", "Bouteille avec un Esprit", "Flasche mit einem Geist" }, ITEMTYPE_ITEM, 0x94, true, &logic->Bottles, RHT_BOTTLE_WITH_POE, RG_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_POE] = Item(RG_BOTTLE_WITH_POE, Text{ "Bottle with Poe", "Bouteille avec un Esprit", "Flasche mit einem Geist" }, ITEMTYPE_ITEM, 0x94, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_POE, RG_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_RUTOS_LETTER] = Item(RG_RUTOS_LETTER, Text{ "Bottle with Ruto's Letter", "Bouteille avec la Lettre de Ruto", "Flasche mit Rutos Brief" }, ITEMTYPE_ITEM, GI_LETTER_RUTO, true, &logic->RutosLetter, RHT_RUTOS_LETTER, ITEM_LETTER_RUTO, OBJECT_GI_BOTTLE_LETTER,GID_LETTER_RUTO, 0x99, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_RUTOS_LETTER] = Item(RG_RUTOS_LETTER, Text{ "Bottle with Ruto's Letter", "Bouteille avec la Lettre de Ruto", "Flasche mit Rutos Brief" }, ITEMTYPE_ITEM, GI_LETTER_RUTO, true, LOGIC_RUTOS_LETTER, RHT_RUTOS_LETTER, ITEM_LETTER_RUTO, OBJECT_GI_BOTTLE_LETTER,GID_LETTER_RUTO, 0x99, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BOTTLE_WITH_BIG_POE] = Item(RG_BOTTLE_WITH_BIG_POE, Text{ "Bottle with Big Poe", "Bouteille avec une Âme", "Flasche mit Seele" }, ITEMTYPE_ITEM, 0x93, true, &logic->BottleWithBigPoe, RHT_BOTTLE_WITH_BIG_POE, RG_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOTTLE_WITH_BIG_POE] = Item(RG_BOTTLE_WITH_BIG_POE, Text{ "Bottle with Big Poe", "Bouteille avec une Âme", "Flasche mit Seele" }, ITEMTYPE_ITEM, 0x93, true, LOGIC_BOTTLE_WITH_BIG_POE, RHT_BOTTLE_WITH_BIG_POE, RG_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
// Songs // Songs
itemTable[RG_ZELDAS_LULLABY] = Item(RG_ZELDAS_LULLABY, Text{ "Zelda's Lullaby", "Berceuse de Zelda", "Zeldas Wiegenlied" }, ITEMTYPE_SONG, 0xC1, true, &logic->ZeldasLullaby, RHT_ZELDAS_LULLABY, ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ZELDAS_LULLABY] = Item(RG_ZELDAS_LULLABY, Text{ "Zelda's Lullaby", "Berceuse de Zelda", "Zeldas Wiegenlied" }, ITEMTYPE_SONG, 0xC1, true, LOGIC_ZELDAS_LULLABY, RHT_ZELDAS_LULLABY, ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_EPONAS_SONG] = Item(RG_EPONAS_SONG, Text{ "Epona's Song", "Chant d'Epona", "Eponas Lied" }, ITEMTYPE_SONG, 0xC2, true, &logic->EponasSong, RHT_EPONAS_SONG, ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_EPONAS_SONG] = Item(RG_EPONAS_SONG, Text{ "Epona's Song", "Chant d'Epona", "Eponas Lied" }, ITEMTYPE_SONG, 0xC2, true, LOGIC_EPONAS_SONG, RHT_EPONAS_SONG, ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SARIAS_SONG] = Item(RG_SARIAS_SONG, Text{ "Saria's Song", "Chant de Saria", "Sarias Lied" }, ITEMTYPE_SONG, 0xC3, true, &logic->SariasSong, RHT_SARIAS_SONG, ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SARIAS_SONG] = Item(RG_SARIAS_SONG, Text{ "Saria's Song", "Chant de Saria", "Sarias Lied" }, ITEMTYPE_SONG, 0xC3, true, LOGIC_SARIAS_SONG, RHT_SARIAS_SONG, ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SUNS_SONG] = Item(RG_SUNS_SONG, Text{ "Sun's Song", "Chant du Soleil", "Das Lied der Sonne" }, ITEMTYPE_SONG, 0xC4, true, &logic->SunsSong, RHT_SUNS_SONG, ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SUNS_SONG] = Item(RG_SUNS_SONG, Text{ "Sun's Song", "Chant du Soleil", "Das Lied der Sonne" }, ITEMTYPE_SONG, 0xC4, true, LOGIC_SUNS_SONG, RHT_SUNS_SONG, ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SONG_OF_TIME] = Item(RG_SONG_OF_TIME, Text{ "Song of Time", "Chant du Temps", "Das Lied der Zeit" }, ITEMTYPE_SONG, 0xC5, true, &logic->SongOfTime, RHT_SONG_OF_TIME, ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SONG_OF_TIME] = Item(RG_SONG_OF_TIME, Text{ "Song of Time", "Chant du Temps", "Das Lied der Zeit" }, ITEMTYPE_SONG, 0xC5, true, LOGIC_SONG_OF_TIME, RHT_SONG_OF_TIME, ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SONG_OF_STORMS] = Item(RG_SONG_OF_STORMS, Text{ "Song of Storms", "Chant des Tempêtes", "Lied der Stürme" }, ITEMTYPE_SONG, 0xC6, true, &logic->SongOfStorms, RHT_SONG_OF_STORMS, ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SONG_OF_STORMS] = Item(RG_SONG_OF_STORMS, Text{ "Song of Storms", "Chant des Tempêtes", "Lied der Stürme" }, ITEMTYPE_SONG, 0xC6, true, LOGIC_SONG_OF_STORMS, RHT_SONG_OF_STORMS, ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MINUET_OF_FOREST] = Item(RG_MINUET_OF_FOREST, Text{ "Minuet of Forest", "Menuet des Bois", "Wald-Minuett" }, ITEMTYPE_SONG, 0xBB, true, &logic->MinuetOfForest, RHT_MINUET_OF_FOREST, ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_MINUET_OF_FOREST] = Item(RG_MINUET_OF_FOREST, Text{ "Minuet of Forest", "Menuet des Bois", "Wald-Minuett" }, ITEMTYPE_SONG, 0xBB, true, LOGIC_MINUET_OF_FOREST, RHT_MINUET_OF_FOREST, ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BOLERO_OF_FIRE] = Item(RG_BOLERO_OF_FIRE, Text{ "Bolero of Fire", "Boléro du Feu", "Bolero des Feuers" }, ITEMTYPE_SONG, 0xBC, true, &logic->BoleroOfFire, RHT_BOLERO_OF_FIRE, ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_BOLERO_OF_FIRE] = Item(RG_BOLERO_OF_FIRE, Text{ "Bolero of Fire", "Boléro du Feu", "Bolero des Feuers" }, ITEMTYPE_SONG, 0xBC, true, LOGIC_BOLERO_OF_FIRE, RHT_BOLERO_OF_FIRE, ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SERENADE_OF_WATER] = Item(RG_SERENADE_OF_WATER, Text{ "Serenade of Water", "Sérénade de l'Eau", "Serenade des Wassers" }, ITEMTYPE_SONG, 0xBD, true, &logic->SerenadeOfWater, RHT_SERENADE_OF_WATER, ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SERENADE_OF_WATER] = Item(RG_SERENADE_OF_WATER, Text{ "Serenade of Water", "Sérénade de l'Eau", "Serenade des Wassers" }, ITEMTYPE_SONG, 0xBD, true, LOGIC_SERENADE_OF_WATER, RHT_SERENADE_OF_WATER, ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_NOCTURNE_OF_SHADOW] = Item(RG_NOCTURNE_OF_SHADOW, Text{ "Nocturne of Shadow", "Nocturne de l'Ombre", "Nocturne der Schatten " }, ITEMTYPE_SONG, 0xBF, true, &logic->NocturneOfShadow, RHT_NOCTURNE_OF_SHADOW, ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_NOCTURNE_OF_SHADOW] = Item(RG_NOCTURNE_OF_SHADOW, Text{ "Nocturne of Shadow", "Nocturne de l'Ombre", "Nocturne der Schatten " }, ITEMTYPE_SONG, 0xBF, true, LOGIC_NOCTURNE_OF_SHADOW, RHT_NOCTURNE_OF_SHADOW, ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_REQUIEM_OF_SPIRIT] = Item(RG_REQUIEM_OF_SPIRIT, Text{ "Requiem of Spirit", "Requiem des Esprits", "Requiem des Geistes" }, ITEMTYPE_SONG, 0xBE, true, &logic->RequiemOfSpirit, RHT_REQUIEM_OF_SPIRIT, ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_REQUIEM_OF_SPIRIT] = Item(RG_REQUIEM_OF_SPIRIT, Text{ "Requiem of Spirit", "Requiem des Esprits", "Requiem des Geistes" }, ITEMTYPE_SONG, 0xBE, true, LOGIC_REQUIEM_OF_SPIRIT, RHT_REQUIEM_OF_SPIRIT, ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_PRELUDE_OF_LIGHT] = Item(RG_PRELUDE_OF_LIGHT, Text{ "Prelude of Light", "Prélude de la Lumière", "Präludium des Lichts" }, ITEMTYPE_SONG, 0xC0, true, &logic->PreludeOfLight, RHT_PRELUDE_OF_LIGHT, ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_PRELUDE_OF_LIGHT] = Item(RG_PRELUDE_OF_LIGHT, Text{ "Prelude of Light", "Prélude de la Lumière", "Präludium des Lichts" }, ITEMTYPE_SONG, 0xC0, true, LOGIC_PRELUDE_OF_LIGHT, RHT_PRELUDE_OF_LIGHT, ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
// Maps and Compasses // Maps and Compasses
itemTable[RG_DEKU_TREE_MAP] = Item(RG_DEKU_TREE_MAP, Text{ "Great Deku Tree Map", "Carte de l'Arbre Mojo", "Karte des Deku-Baums" }, ITEMTYPE_MAP, 0xA5, false, &logic->noVariable, RHT_DEKU_TREE_MAP, RG_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_DEKU_TREE_MAP] = Item(RG_DEKU_TREE_MAP, Text{ "Great Deku Tree Map", "Carte de l'Arbre Mojo", "Karte des Deku-Baums" }, ITEMTYPE_MAP, 0xA5, false, LOGIC_MAP_DEKU_TREE, RHT_DEKU_TREE_MAP, RG_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DODONGOS_CAVERN_MAP] = Item(RG_DODONGOS_CAVERN_MAP, Text{ "Dodongo's Cavern Map", "Carte de la Caverne Dodongo", "Karte der Dodongo-Höhle" }, ITEMTYPE_MAP, 0xA6, false, &logic->noVariable, RHT_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_DODONGOS_CAVERN_MAP] = Item(RG_DODONGOS_CAVERN_MAP, Text{ "Dodongo's Cavern Map", "Carte de la Caverne Dodongo", "Karte der Dodongo-Höhle" }, ITEMTYPE_MAP, 0xA6, false, LOGIC_MAP_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_JABU_JABUS_BELLY_MAP] = Item(RG_JABU_JABUS_BELLY_MAP, Text{ "Jabu-Jabu's Belly Map", "Carte du Ventre de Jabu-Jabu", "Karte des Jabu-Jabu-Bauchs" }, ITEMTYPE_MAP, 0xA7, false, &logic->noVariable, RHT_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_JABU_JABUS_BELLY_MAP] = Item(RG_JABU_JABUS_BELLY_MAP, Text{ "Jabu-Jabu's Belly Map", "Carte du Ventre de Jabu-Jabu", "Karte des Jabu-Jabu-Bauchs" }, ITEMTYPE_MAP, 0xA7, false, LOGIC_MAP_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_MAP] = Item(RG_FOREST_TEMPLE_MAP, Text{ "Forest Temple Map", "Carte du Temple de la Forêt", "Waldtempel Karte" }, ITEMTYPE_MAP, 0xA8, false, &logic->noVariable, RHT_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_FOREST_TEMPLE_MAP] = Item(RG_FOREST_TEMPLE_MAP, Text{ "Forest Temple Map", "Carte du Temple de la Forêt", "Waldtempel Karte" }, ITEMTYPE_MAP, 0xA8, false, LOGIC_MAP_FOREST_TEMPLE, RHT_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_FIRE_TEMPLE_MAP] = Item(RG_FIRE_TEMPLE_MAP, Text{ "Fire Temple Map", "Carte due Temple de Feu", "Feuertempel Karte" }, ITEMTYPE_MAP, 0xA9, false, &logic->noVariable, RHT_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_FIRE_TEMPLE_MAP] = Item(RG_FIRE_TEMPLE_MAP, Text{ "Fire Temple Map", "Carte due Temple de Feu", "Feuertempel Karte" }, ITEMTYPE_MAP, 0xA9, false, LOGIC_MAP_FIRE_TEMPLE, RHT_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_WATER_TEMPLE_MAP] = Item(RG_WATER_TEMPLE_MAP, Text{ "Water Temple Map", "Carte du Temple de l'Eau", "Wassertempel-Karte" }, ITEMTYPE_MAP, 0xAA, false, &logic->noVariable, RHT_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_WATER_TEMPLE_MAP] = Item(RG_WATER_TEMPLE_MAP, Text{ "Water Temple Map", "Carte du Temple de l'Eau", "Wassertempel-Karte" }, ITEMTYPE_MAP, 0xAA, false, LOGIC_MAP_WATER_TEMPLE, RHT_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SPIRIT_TEMPLE_MAP] = Item(RG_SPIRIT_TEMPLE_MAP, Text{ "Spirit Temple Map", "Carte due Temple de l'Esprit", "Geistertempel Karte" }, ITEMTYPE_MAP, 0xAB, false, &logic->noVariable, RHT_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_SPIRIT_TEMPLE_MAP] = Item(RG_SPIRIT_TEMPLE_MAP, Text{ "Spirit Temple Map", "Carte due Temple de l'Esprit", "Geistertempel Karte" }, ITEMTYPE_MAP, 0xAB, false, LOGIC_MAP_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SHADOW_TEMPLE_MAP] = Item(RG_SHADOW_TEMPLE_MAP, Text{ "Shadow Temple Map", "Carte du Temple de l'Ombre", "Karte des Schattentempels" }, ITEMTYPE_MAP, 0xAC, false, &logic->noVariable, RHT_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_SHADOW_TEMPLE_MAP] = Item(RG_SHADOW_TEMPLE_MAP, Text{ "Shadow Temple Map", "Carte du Temple de l'Ombre", "Karte des Schattentempels" }, ITEMTYPE_MAP, 0xAC, false, LOGIC_MAP_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOTTOM_OF_THE_WELL_MAP] = Item(RG_BOTTOM_OF_THE_WELL_MAP, Text{ "Bottom of the Well Map", "Carte du Puits", "Boden des Brunnens Karte" }, ITEMTYPE_MAP, 0xAD, false, &logic->noVariable, RHT_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOTTOM_OF_THE_WELL_MAP] = Item(RG_BOTTOM_OF_THE_WELL_MAP, Text{ "Bottom of the Well Map", "Carte du Puits", "Boden des Brunnens Karte" }, ITEMTYPE_MAP, 0xAD, false, LOGIC_MAP_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_ICE_CAVERN_MAP] = Item(RG_ICE_CAVERN_MAP, Text{ "Ice Cavern Map", "Carte de la Caverne Polaire", "Eishöhle Karte" }, ITEMTYPE_MAP, 0xAE, false, &logic->noVariable, RHT_ICE_CAVERN_MAP, RG_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_ICE_CAVERN_MAP] = Item(RG_ICE_CAVERN_MAP, Text{ "Ice Cavern Map", "Carte de la Caverne Polaire", "Eishöhle Karte" }, ITEMTYPE_MAP, 0xAE, false, LOGIC_MAP_ICE_CAVERN, RHT_ICE_CAVERN_MAP, RG_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DEKU_TREE_COMPASS] = Item(RG_DEKU_TREE_COMPASS, Text{ "Great Deku Tree Compass", "Boussole de l'Arbre Mojo", "Kompass des Deku-Baums" }, ITEMTYPE_COMPASS, 0x9B, false, &logic->noVariable, RHT_DEKU_TREE_COMPASS, RG_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_DEKU_TREE_COMPASS] = Item(RG_DEKU_TREE_COMPASS, Text{ "Great Deku Tree Compass", "Boussole de l'Arbre Mojo", "Kompass des Deku-Baums" }, ITEMTYPE_COMPASS, 0x9B, false, LOGIC_COMPASS_DEKU_TREE, RHT_DEKU_TREE_COMPASS, RG_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DEKU_TREE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_DEKU_TREE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_DODONGOS_CAVERN_COMPASS] = Item(RG_DODONGOS_CAVERN_COMPASS, Text{ "Dodongo's Cavern Compass", "Boussole de la Caverne Dodongo", "Kompass der Dodongo-Höhle" }, ITEMTYPE_COMPASS, 0x9C, false, &logic->noVariable, RHT_DODONGOS_CAVERN_COMPASS,RG_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_DODONGOS_CAVERN_COMPASS] = Item(RG_DODONGOS_CAVERN_COMPASS, Text{ "Dodongo's Cavern Compass", "Boussole de la Caverne Dodongo", "Kompass der Dodongo-Höhle" }, ITEMTYPE_COMPASS, 0x9C, false, LOGIC_COMPASS_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_COMPASS, RG_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DODONGOS_CAVERN_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_DODONGOS_CAVERN_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_JABU_JABUS_BELLY_COMPASS] = Item(RG_JABU_JABUS_BELLY_COMPASS, Text{ "Jabu-Jabu's Belly Compass", "Boussole du Ventre de Jabu-Jabu", "Kompass des Jabu-Jabu-Bauchs" }, ITEMTYPE_COMPASS, 0x9D, false, &logic->noVariable, RHT_JABU_JABUS_BELLY_COMPASS,RG_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_JABU_JABUS_BELLY_COMPASS] = Item(RG_JABU_JABUS_BELLY_COMPASS, Text{ "Jabu-Jabu's Belly Compass", "Boussole du Ventre de Jabu-Jabu", "Kompass des Jabu-Jabu-Bauchs" }, ITEMTYPE_COMPASS, 0x9D, false, LOGIC_COMPASS_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_COMPASS, RG_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_JABU_JABUS_BELLY_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_JABU_JABUS_BELLY_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_FOREST_TEMPLE_COMPASS] = Item(RG_FOREST_TEMPLE_COMPASS, Text{ "Forest Temple Compass", "Boussole du Temple de la Forêt", "Waldtempel-Kompass" }, ITEMTYPE_COMPASS, 0x9E, false, &logic->noVariable, RHT_FOREST_TEMPLE_COMPASS, RG_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_FOREST_TEMPLE_COMPASS] = Item(RG_FOREST_TEMPLE_COMPASS, Text{ "Forest Temple Compass", "Boussole du Temple de la Forêt", "Waldtempel-Kompass" }, ITEMTYPE_COMPASS, 0x9E, false, LOGIC_COMPASS_FOREST_TEMPLE, RHT_FOREST_TEMPLE_COMPASS, RG_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_FOREST_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_FIRE_TEMPLE_COMPASS] = Item(RG_FIRE_TEMPLE_COMPASS, Text{ "Fire Temple Compass", "Boussole du Temple du Feu", "Feuertempel-Kompass" }, ITEMTYPE_COMPASS, 0x9F, false, &logic->noVariable, RHT_FIRE_TEMPLE_COMPASS, RG_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_FIRE_TEMPLE_COMPASS] = Item(RG_FIRE_TEMPLE_COMPASS, Text{ "Fire Temple Compass", "Boussole du Temple du Feu", "Feuertempel-Kompass" }, ITEMTYPE_COMPASS, 0x9F, false, LOGIC_COMPASS_FIRE_TEMPLE, RHT_FIRE_TEMPLE_COMPASS, RG_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_FIRE_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_FIRE_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_WATER_TEMPLE_COMPASS] = Item(RG_WATER_TEMPLE_COMPASS, Text{ "Water Temple Compass", "Boussole du Temple de l'Eau", "Wassertempel-Kompass" }, ITEMTYPE_COMPASS, 0xA0, false, &logic->noVariable, RHT_WATER_TEMPLE_COMPASS, RG_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_WATER_TEMPLE_COMPASS] = Item(RG_WATER_TEMPLE_COMPASS, Text{ "Water Temple Compass", "Boussole du Temple de l'Eau", "Wassertempel-Kompass" }, ITEMTYPE_COMPASS, 0xA0, false, LOGIC_COMPASS_WATER_TEMPLE, RHT_WATER_TEMPLE_COMPASS, RG_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_WATER_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_WATER_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_SPIRIT_TEMPLE_COMPASS] = Item(RG_SPIRIT_TEMPLE_COMPASS, Text{ "Spirit Temple Compass", "Boussole due Temple de l'Esprit", "Geistiger Tempelkompass" }, ITEMTYPE_COMPASS, 0xA1, false, &logic->noVariable, RHT_SPIRIT_TEMPLE_COMPASS, RG_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_SPIRIT_TEMPLE_COMPASS] = Item(RG_SPIRIT_TEMPLE_COMPASS, Text{ "Spirit Temple Compass", "Boussole due Temple de l'Esprit", "Geistiger Tempelkompass" }, ITEMTYPE_COMPASS, 0xA1, false, LOGIC_COMPASS_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_COMPASS, RG_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SPIRIT_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_SPIRIT_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_SHADOW_TEMPLE_COMPASS] = Item(RG_SHADOW_TEMPLE_COMPASS, Text{ "Shadow Temple Compass", "Boussole du Temple de l'Ombre", "Kompass des Schattentempels" }, ITEMTYPE_COMPASS, 0xA2, false, &logic->noVariable, RHT_SHADOW_TEMPLE_COMPASS, RG_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_SHADOW_TEMPLE_COMPASS] = Item(RG_SHADOW_TEMPLE_COMPASS, Text{ "Shadow Temple Compass", "Boussole du Temple de l'Ombre", "Kompass des Schattentempels" }, ITEMTYPE_COMPASS, 0xA2, false, LOGIC_COMPASS_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_COMPASS, RG_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SHADOW_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_SHADOW_TEMPLE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS] = Item(RG_BOTTOM_OF_THE_WELL_COMPASS, Text{ "Bottom of the Well Compass", "Boussole du Puits", "Boden des Brunnenkompasses" }, ITEMTYPE_COMPASS, 0xA3, false, &logic->noVariable, RHT_BOTTOM_OF_THE_WELL_COMPASS,RG_BOTTOM_OF_THE_WELL_COMPASS,OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS] = Item(RG_BOTTOM_OF_THE_WELL_COMPASS, Text{ "Bottom of the Well Compass", "Boussole du Puits", "Boden des Brunnenkompasses" }, ITEMTYPE_COMPASS, 0xA3, false, LOGIC_COMPASS_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_COMPASS, RG_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_BOTTOM_OF_THE_WELL_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_ICE_CAVERN_COMPASS] = Item(RG_ICE_CAVERN_COMPASS, Text{ "Ice Cavern Compass", "Boussole de la Caverne Polaire", "Eishöhlenkompass" }, ITEMTYPE_COMPASS, 0xA4, false, &logic->noVariable, RHT_ICE_CAVERN_COMPASS, RG_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_ICE_CAVERN_COMPASS] = Item(RG_ICE_CAVERN_COMPASS, Text{ "Ice Cavern Compass", "Boussole de la Caverne Polaire", "Eishöhlenkompass" }, ITEMTYPE_COMPASS, 0xA4, false, LOGIC_COMPASS_ICE_CAVERN, RHT_ICE_CAVERN_COMPASS, RG_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_ICE_CAVERN_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass); itemTable[RG_ICE_CAVERN_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
// Boss Keys // Boss Keys
itemTable[RG_FOREST_TEMPLE_BOSS_KEY] = Item(RG_FOREST_TEMPLE_BOSS_KEY, Text{ "Forest Temple Boss Key", "Clé d'Or du Temple de la Forêt", "Waldtempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x95, true, &logic->BossKeyForestTemple, RHT_FOREST_TEMPLE_BOSS_KEY, RG_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER); itemTable[RG_FOREST_TEMPLE_BOSS_KEY] = Item(RG_FOREST_TEMPLE_BOSS_KEY, Text{ "Forest Temple Boss Key", "Clé d'Or du Temple de la Forêt", "Waldtempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x95, true, LOGIC_BOSS_KEY_FOREST_TEMPLE, RHT_FOREST_TEMPLE_BOSS_KEY, RG_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); itemTable[RG_FOREST_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey);
itemTable[RG_FIRE_TEMPLE_BOSS_KEY] = Item(RG_FIRE_TEMPLE_BOSS_KEY, Text{ "Fire Temple Boss Key", "Clé d'Or du Temple du Feu", "Feuertempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x96, true, &logic->BossKeyFireTemple, RHT_FIRE_TEMPLE_BOSS_KEY, RG_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER); itemTable[RG_FIRE_TEMPLE_BOSS_KEY] = Item(RG_FIRE_TEMPLE_BOSS_KEY, Text{ "Fire Temple Boss Key", "Clé d'Or du Temple du Feu", "Feuertempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x96, true, LOGIC_BOSS_KEY_FIRE_TEMPLE, RHT_FIRE_TEMPLE_BOSS_KEY, RG_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER);
itemTable[RG_FIRE_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); itemTable[RG_FIRE_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey);
itemTable[RG_WATER_TEMPLE_BOSS_KEY] = Item(RG_WATER_TEMPLE_BOSS_KEY, Text{ "Water Temple Boss Key", "Clé d'Or du Temple de l'Eau", "Wassertempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x97, true, &logic->BossKeyWaterTemple, RHT_WATER_TEMPLE_BOSS_KEY, RG_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER); itemTable[RG_WATER_TEMPLE_BOSS_KEY] = Item(RG_WATER_TEMPLE_BOSS_KEY, Text{ "Water Temple Boss Key", "Clé d'Or du Temple de l'Eau", "Wassertempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x97, true, LOGIC_BOSS_KEY_WATER_TEMPLE, RHT_WATER_TEMPLE_BOSS_KEY, RG_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER);
itemTable[RG_WATER_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); itemTable[RG_WATER_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey);
itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY] = Item(RG_SPIRIT_TEMPLE_BOSS_KEY, Text{ "Spirit Temple Boss Key", "Clé d'Or du Temple de l'Esprit", "Geistertempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x98, true, &logic->BossKeySpiritTemple, RHT_SPIRIT_TEMPLE_BOSS_KEY, RG_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER); itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY] = Item(RG_SPIRIT_TEMPLE_BOSS_KEY, Text{ "Spirit Temple Boss Key", "Clé d'Or du Temple de l'Esprit", "Geistertempel-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x98, true, LOGIC_BOSS_KEY_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOSS_KEY, RG_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER);
itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); itemTable[RG_SPIRIT_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey);
itemTable[RG_SHADOW_TEMPLE_BOSS_KEY] = Item( RG_SHADOW_TEMPLE_BOSS_KEY, Text{ "Shadow Temple Boss Key", "Clé d'Or du Temple de l'Ombre", "Schlüssel für den Boss des Schattentempels" }, ITEMTYPE_BOSSKEY, 0x99, true, &logic->BossKeyShadowTemple, RHT_SHADOW_TEMPLE_BOSS_KEY, RG_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER); itemTable[RG_SHADOW_TEMPLE_BOSS_KEY] = Item( RG_SHADOW_TEMPLE_BOSS_KEY, Text{ "Shadow Temple Boss Key", "Clé d'Or du Temple de l'Ombre", "Schlüssel für den Boss des Schattentempels" }, ITEMTYPE_BOSSKEY, 0x99, true, LOGIC_BOSS_KEY_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_BOSS_KEY, RG_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER);
itemTable[RG_SHADOW_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); itemTable[RG_SHADOW_TEMPLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey);
itemTable[RG_GANONS_CASTLE_BOSS_KEY] = Item(RG_GANONS_CASTLE_BOSS_KEY, Text{ "Ganon's Castle Boss Key", "Clé d'Or du Château de Ganon", "Ganons Schloss-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x9A, true, &logic->BossKeyGanonsCastle, RHT_GANONS_CASTLE_BOSS_KEY, RG_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER); itemTable[RG_GANONS_CASTLE_BOSS_KEY] = Item(RG_GANONS_CASTLE_BOSS_KEY, Text{ "Ganon's Castle Boss Key", "Clé d'Or du Château de Ganon", "Ganons Schloss-Boss-Schlüssel" }, ITEMTYPE_BOSSKEY, 0x9A, true, LOGIC_BOSS_KEY_GANONS_CASTLE, RHT_GANONS_CASTLE_BOSS_KEY, RG_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_BOSS_KEY,MOD_RANDOMIZER);
itemTable[RG_GANONS_CASTLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey); itemTable[RG_GANONS_CASTLE_BOSS_KEY].SetCustomDrawFunc(Randomizer_DrawBossKey);
itemTable[RG_FOREST_TEMPLE_SMALL_KEY] = Item(RG_FOREST_TEMPLE_SMALL_KEY, Text{ "Forest Temple Small Key", "Petite Clé du Temple de la Forêt", "Waldtempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xAF, true, &logic->ForestTempleKeys, RHT_FOREST_TEMPLE_SMALL_KEY,RG_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_FOREST_TEMPLE_SMALL_KEY] = Item(RG_FOREST_TEMPLE_SMALL_KEY, Text{ "Forest Temple Small Key", "Petite Clé du Temple de la Forêt", "Waldtempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xAF, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_FOREST_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_FIRE_TEMPLE_SMALL_KEY] = Item(RG_FIRE_TEMPLE_SMALL_KEY, Text{ "Fire Temple Small Key", "Petite Clé du Temple du Feu", "Feuertempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB0, true, &logic->FireTempleKeys, RHT_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_FIRE_TEMPLE_SMALL_KEY] = Item(RG_FIRE_TEMPLE_SMALL_KEY, Text{ "Fire Temple Small Key", "Petite Clé du Temple du Feu", "Feuertempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB0, true, LOGIC_FIRE_TEMPLE_KEYS, RHT_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_FIRE_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_FIRE_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_WATER_TEMPLE_SMALL_KEY] = Item(RG_WATER_TEMPLE_SMALL_KEY, Text{ "Water Temple Small Key", "Petite Clé du Temple de l'Eau", "Wassertempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB1, true, &logic->WaterTempleKeys, RHT_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_WATER_TEMPLE_SMALL_KEY] = Item(RG_WATER_TEMPLE_SMALL_KEY, Text{ "Water Temple Small Key", "Petite Clé du Temple de l'Eau", "Wassertempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB1, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_WATER_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_WATER_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY] = Item(RG_SPIRIT_TEMPLE_SMALL_KEY, Text{ "Spirit Temple Small Key", "Petite Clé du Temple de l'Esprit", "Geisttempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB2, true, &logic->SpiritTempleKeys, RHT_SPIRIT_TEMPLE_SMALL_KEY,RG_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY] = Item(RG_SPIRIT_TEMPLE_SMALL_KEY, Text{ "Spirit Temple Small Key", "Petite Clé du Temple de l'Esprit", "Geisttempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB2, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_SPIRIT_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_SHADOW_TEMPLE_SMALL_KEY] = Item(RG_SHADOW_TEMPLE_SMALL_KEY, Text{ "Shadow Temple Small Key", "Petite Clé du Temple de l'Ombre", "Schattentempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB3, true, &logic->ShadowTempleKeys, RHT_SHADOW_TEMPLE_SMALL_KEY,RG_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_SHADOW_TEMPLE_SMALL_KEY] = Item(RG_SHADOW_TEMPLE_SMALL_KEY, Text{ "Shadow Temple Small Key", "Petite Clé du Temple de l'Ombre", "Schattentempel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB3, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_SHADOW_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_SHADOW_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY] = Item(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, Text{ "Bottom of the Well Small Key", "Petite Clé du Puits", "Boden des Brunnens Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB4, true, &logic->BottomOfTheWellKeys, RHT_BOTTOM_OF_THE_WELL_SMALL_KEY,RG_BOTTOM_OF_THE_WELL_SMALL_KEY,OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY] = Item(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, Text{ "Bottom of the Well Small Key", "Petite Clé du Puits", "Boden des Brunnens Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB4, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, Text{ "Training Grounds Small Key", "Petite Clé du Gymnase Gerudo", "Trainingsgelände Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB5, true, &logic->GerudoTrainingGroundsKeys, RHT_GERUDO_TRAINING_GROUNDS_SMALL_KEY,RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY,OBJECT_GI_KEY,GID_KEY_SMALL,TEXT_RANDOMIZER_CUSTOM_ITEM,0x80, CHEST_ANIM_SHORT,ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, Text{ "Training Grounds Small Key", "Petite Clé du Gymnase Gerudo", "Trainingsgelände Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB5, true, LOGIC_GERUDO_TRAINING_GROUNDS_KEYS, RHT_GERUDO_TRAINING_GROUNDS_SMALL_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{ "Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs", "Gerudo-Festung Kleiner Schlüssel" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, &logic->GerudoFortressKeys, RHT_GERUDO_FORTRESS_SMALL_KEY,RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{ "Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs", "Gerudo-Festung Kleiner Schlüssel" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_SMALL_KEY, RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GERUDO_FORTRESS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GERUDO_FORTRESS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Ganons Schloss Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB7, true, &logic->GanonsCastleKeys, RHT_GANONS_CASTLE_SMALL_KEY,RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Ganons Schloss Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Truhenspiel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, &logic->TreasureGameKeys, RHT_TREASURE_GAME_SMALL_KEY,ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE); itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Truhenspiel Kleiner Schlüssel" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_SMALL_KEY, ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE);
// Key Rings // Key Rings
itemTable[RG_FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{ "Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Waldtempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD5, true, &logic->ForestTempleKeys, RHT_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{ "Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Waldtempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD5, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_FOREST_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_FIRE_TEMPLE_KEY_RING] = Item(RG_FIRE_TEMPLE_KEY_RING, Text{ "Fire Temple Key Ring", "Trousseau du Temple du Feu", "Feuertempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD6, true, &logic->FireTempleKeys, RHT_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_FIRE_TEMPLE_KEY_RING] = Item(RG_FIRE_TEMPLE_KEY_RING, Text{ "Fire Temple Key Ring", "Trousseau du Temple du Feu", "Feuertempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD6, true, LOGIC_FIRE_TEMPLE_KEYS, RHT_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_FIRE_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_FIRE_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_WATER_TEMPLE_KEY_RING] = Item(RG_WATER_TEMPLE_KEY_RING, Text{ "Water Temple Key Ring", "Trousseau du Temple de l'Eau", "Wassertempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD7, true, &logic->WaterTempleKeys, RHT_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_WATER_TEMPLE_KEY_RING] = Item(RG_WATER_TEMPLE_KEY_RING, Text{ "Water Temple Key Ring", "Trousseau du Temple de l'Eau", "Wassertempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD7, true, LOGIC_WATER_TEMPLE_KEYS, RHT_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_WATER_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_WATER_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_SPIRIT_TEMPLE_KEY_RING] = Item(RG_SPIRIT_TEMPLE_KEY_RING, Text{ "Spirit Temple Key Ring", "Trousseau du Temple de l'Esprit", "Geisttempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD8, true, &logic->SpiritTempleKeys, RHT_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_SPIRIT_TEMPLE_KEY_RING] = Item(RG_SPIRIT_TEMPLE_KEY_RING, Text{ "Spirit Temple Key Ring", "Trousseau du Temple de l'Esprit", "Geisttempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD8, true, LOGIC_SPIRIT_TEMPLE_KEYS, RHT_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_SPIRIT_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_SPIRIT_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_SHADOW_TEMPLE_KEY_RING] = Item(RG_SHADOW_TEMPLE_KEY_RING, Text{ "Shadow Temple Key Ring", "Trousseau du Temple de l'Ombre", "Schattentempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD9, true, &logic->ShadowTempleKeys, RHT_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_SHADOW_TEMPLE_KEY_RING] = Item(RG_SHADOW_TEMPLE_KEY_RING, Text{ "Shadow Temple Key Ring", "Trousseau du Temple de l'Ombre", "Schattentempel Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xD9, true, LOGIC_SHADOW_TEMPLE_KEYS, RHT_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_SHADOW_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_SHADOW_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{ "Bottom of the Well Key Ring", "Trousseau du Puits", "Boden des Brunnens Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xDA, true, &logic->BottomOfTheWellKeys, RHT_BOTTOM_OF_THE_WELL_KEY_RING,RG_BOTTOM_OF_THE_WELL_KEY_RING,OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{ "Bottom of the Well Key Ring", "Trousseau du Puits", "Boden des Brunnens Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xDA, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_KEY_RING, RG_BOTTOM_OF_THE_WELL_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_GERUDO_TRAINING_GROUNDS_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, Text{ "Training Grounds Key Ring", "Trousseau du Gymnase Gerudo", "Trainingsgelände Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xDB, true, &logic->GerudoTrainingGroundsKeys, RHT_GERUDO_TRAINING_GROUNDS_KEY_RING,RG_GERUDO_TRAINING_GROUNDS_KEY_RING,OBJECT_GI_KEY,GID_KEY_SMALL,TEXT_RANDOMIZER_CUSTOM_ITEM,0x80, CHEST_ANIM_SHORT,ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_TRAINING_GROUNDS_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, Text{ "Training Grounds Key Ring", "Trousseau du Gymnase Gerudo", "Trainingsgelände Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xDB, true, LOGIC_GERUDO_TRAINING_GROUNDS_KEYS, RHT_GERUDO_TRAINING_GROUNDS_KEY_RING, RG_GERUDO_TRAINING_GROUNDS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GERUDO_TRAINING_GROUNDS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_GERUDO_TRAINING_GROUNDS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_GERUDO_FORTRESS_KEY_RING] = Item(RG_GERUDO_FORTRESS_KEY_RING, Text{ "Gerudo Fortress Key Ring", "Trousseau du Repaire des Voleurs", "Gerudo Festung Schlüsselanhänger" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xDC, true, &logic->GerudoFortressKeys, RHT_GERUDO_FORTRESS_KEY_RING,RG_GERUDO_FORTRESS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_FORTRESS_KEY_RING] = Item(RG_GERUDO_FORTRESS_KEY_RING, Text{ "Gerudo Fortress Key Ring", "Trousseau du Repaire des Voleurs", "Gerudo Festung Schlüsselanhänger" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xDC, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_KEY_RING, RG_GERUDO_FORTRESS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GERUDO_FORTRESS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_GERUDO_FORTRESS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
itemTable[RG_GANONS_CASTLE_KEY_RING] = Item(RG_GANONS_CASTLE_KEY_RING, Text{ "Ganon's Castle Key Ring", "Trousseau du Château de Ganon", "Ganons Schloss Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xDD, true, &logic->GanonsCastleKeys, RHT_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GANONS_CASTLE_KEY_RING] = Item(RG_GANONS_CASTLE_KEY_RING, Text{ "Ganon's Castle Key Ring", "Trousseau du Château de Ganon", "Ganons Schloss Schlüsselanhänger" }, ITEMTYPE_SMALLKEY, 0xDD, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GANONS_CASTLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_GANONS_CASTLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);
// Dungeon Rewards // Dungeon Rewards
itemTable[RG_KOKIRI_EMERALD] = Item(RG_KOKIRI_EMERALD, Text{ "Kokiri's Emerald", "Émeraude Kokiri", "Kokiri-Smaragd" }, ITEMTYPE_DUNGEONREWARD, 0xCB, true, &logic->KokiriEmerald, RHT_KOKIRI_EMERALD, ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_KOKIRI_EMERALD] = Item(RG_KOKIRI_EMERALD, Text{ "Kokiri's Emerald", "Émeraude Kokiri", "Kokiri-Smaragd" }, ITEMTYPE_DUNGEONREWARD, 0xCB, true, LOGIC_KOKIRI_EMERALD, RHT_KOKIRI_EMERALD, ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GORON_RUBY] = Item(RG_GORON_RUBY, Text{ "Goron's Ruby", "Rubis Goron", "Goronen-Rubin" }, ITEMTYPE_DUNGEONREWARD, 0xCC, true, &logic->GoronRuby, RHT_GORON_RUBY, ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GORON_RUBY] = Item(RG_GORON_RUBY, Text{ "Goron's Ruby", "Rubis Goron", "Goronen-Rubin" }, ITEMTYPE_DUNGEONREWARD, 0xCC, true, LOGIC_GORON_RUBY, RHT_GORON_RUBY, ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ZORA_SAPPHIRE] = Item(RG_ZORA_SAPPHIRE, Text{ "Zora's Sapphire", "Saphir Zora", "Zora-Saphir" }, ITEMTYPE_DUNGEONREWARD, 0xCD, true, &logic->ZoraSapphire, RHT_ZORA_SAPPHIRE, ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ZORA_SAPPHIRE] = Item(RG_ZORA_SAPPHIRE, Text{ "Zora's Sapphire", "Saphir Zora", "Zora-Saphir" }, ITEMTYPE_DUNGEONREWARD, 0xCD, true, LOGIC_ZORA_SAPPHIRE, RHT_ZORA_SAPPHIRE, ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FOREST_MEDALLION] = Item(RG_FOREST_MEDALLION, Text{ "Forest Medallion", "Médaillon de la Forêt", "Wald Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xCE, true, &logic->ForestMedallion, RHT_FOREST_MEDALLION, ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST,0x3E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FOREST_MEDALLION] = Item(RG_FOREST_MEDALLION, Text{ "Forest Medallion", "Médaillon de la Forêt", "Wald Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xCE, true, LOGIC_FOREST_MEDALLION, RHT_FOREST_MEDALLION, ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST,0x3E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FIRE_MEDALLION] = Item(RG_FIRE_MEDALLION, Text{ "Fire Medallion", "Médaillon du Feu", "Feuer Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xCF, true, &logic->FireMedallion, RHT_FIRE_MEDALLION, ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FIRE_MEDALLION] = Item(RG_FIRE_MEDALLION, Text{ "Fire Medallion", "Médaillon du Feu", "Feuer Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xCF, true, LOGIC_FIRE_MEDALLION, RHT_FIRE_MEDALLION, ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_WATER_MEDALLION] = Item(RG_WATER_MEDALLION, Text{ "Water Medallion", "Médaillon de l'Eau", "Wasser Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD0, true, &logic->WaterMedallion, RHT_WATER_MEDALLION, ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER,0x3D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_WATER_MEDALLION] = Item(RG_WATER_MEDALLION, Text{ "Water Medallion", "Médaillon de l'Eau", "Wasser Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD0, true, LOGIC_WATER_MEDALLION, RHT_WATER_MEDALLION, ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER,0x3D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SPIRIT_MEDALLION] = Item(RG_SPIRIT_MEDALLION, Text{ "Spirit Medallion", "Médaillon de l'Esprit", "Geist Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD1, true, &logic->SpiritMedallion, RHT_SPIRIT_MEDALLION, ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT,0x3F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SPIRIT_MEDALLION] = Item(RG_SPIRIT_MEDALLION, Text{ "Spirit Medallion", "Médaillon de l'Esprit", "Geist Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD1, true, LOGIC_SPIRIT_MEDALLION, RHT_SPIRIT_MEDALLION, ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT,0x3F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SHADOW_MEDALLION] = Item(RG_SHADOW_MEDALLION, Text{ "Shadow Medallion", "Médaillon de l'Ombre", "Schatten Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD2, true, &logic->ShadowMedallion, RHT_SHADOW_MEDALLION, ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW,0x41, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SHADOW_MEDALLION] = Item(RG_SHADOW_MEDALLION, Text{ "Shadow Medallion", "Médaillon de l'Ombre", "Schatten Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD2, true, LOGIC_SHADOW_MEDALLION, RHT_SHADOW_MEDALLION, ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW,0x41, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_LIGHT_MEDALLION] = Item(RG_LIGHT_MEDALLION, Text{ "Light Medallion", "Médaillon de la Lumière", "Licht Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD3, true, &logic->LightMedallion, RHT_LIGHT_MEDALLION, ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT,0x40, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_LIGHT_MEDALLION] = Item(RG_LIGHT_MEDALLION, Text{ "Light Medallion", "Médaillon de la Lumière", "Licht Medaillon" }, ITEMTYPE_DUNGEONREWARD, 0xD3, true, LOGIC_LIGHT_MEDALLION, RHT_LIGHT_MEDALLION, ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT,0x40, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
// Generic Items // Generic Items
itemTable[RG_RECOVERY_HEART] = Item(RG_RECOVERY_HEART, Text{ "Recovery Heart", "Coeur de Vie", "Herz" }, ITEMTYPE_ITEM, GI_HEART, false, &logic->noVariable, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_RECOVERY_HEART] = Item(RG_RECOVERY_HEART, Text{ "Recovery Heart", "Coeur de Vie", "Herz" }, ITEMTYPE_ITEM, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_GREEN_RUPEE] = Item(RG_GREEN_RUPEE, Text{ "Green Rupee", "Rubis Vert", "Grüne Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, false, &logic->noVariable, RHT_GREEN_RUPEE, ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0x6F, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_GREEN_RUPEE] = Item(RG_GREEN_RUPEE, Text{ "Green Rupee", "Rubis Vert", "Grüne Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_GREEN_RUPEE, ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0x6F, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_GREG_RUPEE] = Item(RG_GREG_RUPEE, Text{ "Greg the Green Rupee", "Rubis Greg", "Greg Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, true, &logic->Greg, RHT_GREG_RUPEE, RG_GREG_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GREG_RUPEE] = Item(RG_GREG_RUPEE, Text{ "Greg the Green Rupee", "Rubis Greg", "Greg Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN, true, LOGIC_GREG, RHT_GREG_RUPEE, RG_GREG_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BLUE_RUPEE] = Item(RG_BLUE_RUPEE, Text{ "Blue Rupee", "Rubis Bleu", "Blaue Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_BLUE, false, &logic->noVariable, RHT_BLUE_RUPEE, ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xCC, 0x01, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BLUE_RUPEE] = Item(RG_BLUE_RUPEE, Text{ "Blue Rupee", "Rubis Bleu", "Blaue Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_BLUE, false, LOGIC_NONE, RHT_BLUE_RUPEE, ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xCC, 0x01, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_RED_RUPEE] = Item(RG_RED_RUPEE, Text{ "Red Rupee", "Rubis Rouge", "Rote Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_RED, false, &logic->noVariable, RHT_RED_RUPEE, ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF0, 0x02, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_RED_RUPEE] = Item(RG_RED_RUPEE, Text{ "Red Rupee", "Rubis Rouge", "Rote Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_RED, false, LOGIC_NONE, RHT_RED_RUPEE, ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF0, 0x02, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_PURPLE_RUPEE] = Item(RG_PURPLE_RUPEE, Text{ "Purple Rupee", "Rubis Pourpre", "Lila Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_PURPLE, false, &logic->noVariable, RHT_PURPLE_RUPEE, ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF1, 0x14, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_PURPLE_RUPEE] = Item(RG_PURPLE_RUPEE, Text{ "Purple Rupee", "Rubis Pourpre", "Lila Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_PURPLE, false, LOGIC_NONE, RHT_PURPLE_RUPEE, ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF1, 0x14, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_HUGE_RUPEE] = Item(RG_HUGE_RUPEE, Text{ "Huge Rupee", "Énorme Rubis", "Riesige Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_GOLD, false, &logic->noVariable, RHT_HUGE_RUPEE, ITEM_RUPEE_GOLD, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0xF2, 0x13, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_HUGE_RUPEE] = Item(RG_HUGE_RUPEE, Text{ "Huge Rupee", "Énorme Rubis", "Riesige Rupie" }, ITEMTYPE_ITEM, GI_RUPEE_GOLD, false, LOGIC_NONE, RHT_HUGE_RUPEE, ITEM_RUPEE_GOLD, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0xF2, 0x13, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_PIECE_OF_HEART] = Item(RG_PIECE_OF_HEART, Text{ "Piece of Heart", "Quart de Coeur", "Herzstück" }, ITEMTYPE_ITEM, GI_HEART_PIECE, true, &logic->PieceOfHeart, RHT_PIECE_OF_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xC2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_PIECE_OF_HEART] = Item(RG_PIECE_OF_HEART, Text{ "Piece of Heart", "Quart de Coeur", "Herzstück" }, ITEMTYPE_ITEM, GI_HEART_PIECE, true, LOGIC_PIECE_OF_HEART, RHT_PIECE_OF_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xC2, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_HEART_CONTAINER] = Item(RG_HEART_CONTAINER, Text{ "Heart Container", "Réceptacle de Coeur", "Herz-Container" }, ITEMTYPE_ITEM, GI_HEART_CONTAINER_2,true, &logic->HeartContainer, RHT_HEART_CONTAINER, ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER,0xC6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_HEART_CONTAINER] = Item(RG_HEART_CONTAINER, Text{ "Heart Container", "Réceptacle de Coeur", "Herz-Container" }, ITEMTYPE_ITEM, GI_HEART_CONTAINER_2, true, LOGIC_HEART_CONTAINER, RHT_HEART_CONTAINER, ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER,0xC6, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_ICE_TRAP] = Item(RG_ICE_TRAP, Text{ "Ice Trap", "Piège de Glace", "Eisfalle" }, ITEMTYPE_ITEM, RG_ICE_TRAP, false, &logic->noVariable, RHT_ICE_TRAP, RG_ICE_TRAP, OBJECT_GI_RUPY, GID_RUPEE_GOLD, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ICE_TRAP] = Item(RG_ICE_TRAP, Text{ "Ice Trap", "Piège de Glace", "Eisfalle" }, ITEMTYPE_ITEM, RG_ICE_TRAP, false, LOGIC_NONE, RHT_ICE_TRAP, RG_ICE_TRAP, OBJECT_GI_RUPY, GID_RUPEE_GOLD, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_MILK] = Item(RG_MILK, Text{ "Milk", "Lait", "Milch" }, ITEMTYPE_ITEM, GI_MILK, false, &logic->noVariable, RHT_NONE, ITEM_MILK, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_MILK] = Item(RG_MILK, Text{ "Milk", "Lait", "Milch" }, ITEMTYPE_ITEM, GI_MILK, false, LOGIC_NONE, RHT_NONE, ITEM_MILK, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_FISH] = Item(RG_FISH, Text{ "Fish", "Poisson", "Pez" }, ITEMTYPE_ITEM, GI_FISH, false, &logic->noVariable, RHT_NONE, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_FISH] = Item(RG_FISH, Text{ "Fish", "Poisson", "Pez" }, ITEMTYPE_ITEM, GI_FISH, false, LOGIC_NONE, RHT_NONE, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE);
// Refills // Refills
itemTable[RG_BOMBS_5] = Item(RG_BOMBS_5, Text{ "Bombs (5)", "Bombes (5)", "Bomben (5)" }, ITEMTYPE_REFILL, GI_BOMBS_5, false, &logic->noVariable, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_5] = Item(RG_BOMBS_5, Text{ "Bombs (5)", "Bombes (5)", "Bomben (5)" }, ITEMTYPE_REFILL, GI_BOMBS_5, false, LOGIC_NONE, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBS_10] = Item(RG_BOMBS_10, Text{ "Bombs (10)", "Bombes (10)", "Bomben (10)" }, ITEMTYPE_REFILL, GI_BOMBS_10, false, &logic->noVariable, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_10] = Item(RG_BOMBS_10, Text{ "Bombs (10)", "Bombes (10)", "Bomben (10)" }, ITEMTYPE_REFILL, GI_BOMBS_10, false, LOGIC_NONE, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBS_20] = Item(RG_BOMBS_20, Text{ "Bombs (20)", "Bombes (20)", "Bomben (20)" }, ITEMTYPE_REFILL, GI_BOMBS_20, false, &logic->noVariable, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBS_20] = Item(RG_BOMBS_20, Text{ "Bombs (20)", "Bombes (20)", "Bomben (20)" }, ITEMTYPE_REFILL, GI_BOMBS_20, false, LOGIC_NONE, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_5] = Item(RG_BOMBCHU_5, Text{ "Bombchus (5)", "Missiles (5)", "Bombchus (5)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_5, true, &logic->Bombchus5, RHT_BOMBCHU_5, ITEM_BOMBCHUS_5, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_5] = Item(RG_BOMBCHU_5, Text{ "Bombchus (5)", "Missiles (5)", "Bombchus (5)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_5, true, LOGIC_BOMBCHUS_5, RHT_BOMBCHU_5, ITEM_BOMBCHUS_5, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_10] = Item(RG_BOMBCHU_10, Text{ "Bombchus (10)", "Missiles (10)", "Bombchus (10)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_10, true, &logic->Bombchus10, RHT_BOMBCHU_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_10] = Item(RG_BOMBCHU_10, Text{ "Bombchus (10)", "Missiles (10)", "Bombchus (10)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_10, true, LOGIC_BOMBCHUS_10, RHT_BOMBCHU_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_20] = Item(RG_BOMBCHU_20, Text{ "Bombchus (20)", "Missiles (20)", "Bombchus (20)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_20, true, &logic->Bombchus20, RHT_BOMBCHU_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_20] = Item(RG_BOMBCHU_20, Text{ "Bombchus (20)", "Missiles (20)", "Bombchus (20)" }, ITEMTYPE_REFILL, GI_BOMBCHUS_20, true, LOGIC_BOMBCHUS_20, RHT_BOMBCHU_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BOMBCHU_DROP] = Item(RG_BOMBCHU_DROP, Text{ "Bombchu Drop", "Drop Missiles", "Bombchus" }, ITEMTYPE_DROP, GI_BOMBCHUS_10, true, &logic->BombchuDrop, RHT_NONE, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BOMBCHU_DROP] = Item(RG_BOMBCHU_DROP, Text{ "Bombchu Drop", "Drop Missiles", "Bombchus" }, ITEMTYPE_DROP, GI_BOMBCHUS_10, true, LOGIC_BOMBCHU_DROP, RHT_NONE, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_ARROWS_5] = Item(RG_ARROWS_5, Text{ "Arrows (5)", "Flèches (5)", "Pfeile (5)" }, ITEMTYPE_REFILL, GI_ARROWS_SMALL, false, &logic->noVariable, RHT_ARROWS_5, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_ARROWS_5] = Item(RG_ARROWS_5, Text{ "Arrows (5)", "Flèches (5)", "Pfeile (5)" }, ITEMTYPE_REFILL, GI_ARROWS_SMALL, false, LOGIC_NONE, RHT_ARROWS_5, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_ARROWS_10] = Item(RG_ARROWS_10, Text{ "Arrows (10)", "Flèches (10)", "Pfeile (10)" }, ITEMTYPE_REFILL, GI_ARROWS_MEDIUM, false, &logic->noVariable, RHT_ARROWS_10, ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_ARROWS_10] = Item(RG_ARROWS_10, Text{ "Arrows (10)", "Flèches (10)", "Pfeile (10)" }, ITEMTYPE_REFILL, GI_ARROWS_MEDIUM, false, LOGIC_NONE, RHT_ARROWS_10, ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_ARROWS_30] = Item(RG_ARROWS_30, Text{ "Arrows (30)", "Flèches (30)", "Pfeile (30)" }, ITEMTYPE_REFILL, GI_ARROWS_LARGE, false, &logic->noVariable, RHT_ARROWS_30, ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_ARROWS_30] = Item(RG_ARROWS_30, Text{ "Arrows (30)", "Flèches (30)", "Pfeile (30)" }, ITEMTYPE_REFILL, GI_ARROWS_LARGE, false, LOGIC_NONE, RHT_ARROWS_30, ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_DEKU_NUTS_5] = Item(RG_DEKU_NUTS_5, Text{ "Deku Nuts (5)", "Noix Mojo (5)", "Deku-Nüsse (5)" }, ITEMTYPE_REFILL, GI_NUTS_5, false, &logic->noVariable, RHT_DEKU_NUTS_5, ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_DEKU_NUTS_5] = Item(RG_DEKU_NUTS_5, Text{ "Deku Nuts (5)", "Noix Mojo (5)", "Deku-Nüsse (5)" }, ITEMTYPE_REFILL, GI_NUTS_5, false, LOGIC_NONE, RHT_DEKU_NUTS_5, ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_DEKU_NUTS_10] = Item(RG_DEKU_NUTS_10, Text{ "Deku Nuts (10)", "Noix Mojo (10)", "Deku-Nüsse (10)" }, ITEMTYPE_REFILL, GI_NUTS_10, false, &logic->noVariable, RHT_DEKU_NUTS_10, ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_DEKU_NUTS_10] = Item(RG_DEKU_NUTS_10, Text{ "Deku Nuts (10)", "Noix Mojo (10)", "Deku-Nüsse (10)" }, ITEMTYPE_REFILL, GI_NUTS_10, false, LOGIC_NONE, RHT_DEKU_NUTS_10, ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_DEKU_SEEDS_30] = Item(RG_DEKU_SEEDS_30, Text{ "Deku Seeds (30)", "Graines Mojo (30)", "Deku-Samen (30)" }, ITEMTYPE_REFILL, GI_SEEDS_30, false, &logic->noVariable, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_DEKU_SEEDS_30] = Item(RG_DEKU_SEEDS_30, Text{ "Deku Seeds (30)", "Graines Mojo (30)", "Deku-Samen (30)" }, ITEMTYPE_REFILL, GI_SEEDS_30, false, LOGIC_NONE, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_DEKU_STICK_1] = Item(RG_DEKU_STICK_1, Text{ "Deku Stick (1)", "Bâton Mojo (1)", "Deku-Stick (1)" }, ITEMTYPE_REFILL, GI_STICKS_1, false, &logic->noVariable, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_DEKU_STICK_1] = Item(RG_DEKU_STICK_1, Text{ "Deku Stick (1)", "Bâton Mojo (1)", "Deku-Stick (1)" }, ITEMTYPE_REFILL, GI_STICKS_1, false, LOGIC_NONE, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_RED_POTION_REFILL] = Item(RG_RED_POTION_REFILL, Text{ "Red Potion Refill", "Recharge de Potion Rouge", "Rotes Elixier Nachfüllpackung" }, ITEMTYPE_REFILL, GI_POTION_RED, false, &logic->noVariable, RHT_NONE, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_RED_POTION_REFILL] = Item(RG_RED_POTION_REFILL, Text{ "Red Potion Refill", "Recharge de Potion Rouge", "Rotes Elixier Nachfüllpackung" }, ITEMTYPE_REFILL, GI_POTION_RED, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_GREEN_POTION_REFILL] = Item(RG_GREEN_POTION_REFILL, Text{ "Green Potion Refill", "Recharge de Potion Verte", "Grünes Elixier Nachfüllpackung" }, ITEMTYPE_REFILL, GI_POTION_GREEN, false, &logic->noVariable, RHT_NONE, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_GREEN_POTION_REFILL] = Item(RG_GREEN_POTION_REFILL, Text{ "Green Potion Refill", "Recharge de Potion Verte", "Grünes Elixier Nachfüllpackung" }, ITEMTYPE_REFILL, GI_POTION_GREEN, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE);
itemTable[RG_BLUE_POTION_REFILL] = Item(RG_BLUE_POTION_REFILL, Text{ "Blue Potion Refill", "Recharge de Potion Bleue", "Blaues Elixier Nachfüllpackung" }, ITEMTYPE_REFILL, GI_POTION_BLUE, false, &logic->noVariable, RHT_NONE, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE); itemTable[RG_BLUE_POTION_REFILL] = Item(RG_BLUE_POTION_REFILL, Text{ "Blue Potion Refill", "Recharge de Potion Bleue", "Blaues Elixier Nachfüllpackung" }, ITEMTYPE_REFILL, GI_POTION_BLUE, false, LOGIC_NONE, RHT_NONE, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE);
// Treasure Game // Treasure Game
itemTable[RG_TREASURE_GAME_HEART] = Item(RG_TREASURE_GAME_HEART, Text{ "Piece of Heart (WINNER)", "Quart de Coeur (Chasse-aux-Trésors)", "Herzstück (Schatztruhen-Minispiel)" }, ITEMTYPE_ITEM, GI_HEART_PIECE_WIN, true, &logic->PieceOfHeart, RHT_TREASURE_GAME_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xFA, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_TREASURE_GAME_HEART] = Item(RG_TREASURE_GAME_HEART, Text{ "Piece of Heart (WINNER)", "Quart de Coeur (Chasse-aux-Trésors)", "Herzstück (Schatztruhen-Minispiel)" }, ITEMTYPE_ITEM, GI_HEART_PIECE_WIN, true, LOGIC_PIECE_OF_HEART, RHT_TREASURE_GAME_HEART, ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xFA, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_TREASURE_GAME_GREEN_RUPEE] = Item(RG_TREASURE_GAME_GREEN_RUPEE, Text{ "Green Rupee (LOSER)", "Rubis Vert (Chasse-aux-Trésors)", "Grüne Rupie (Schatztruhe-Minispiel)" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN_LOSE,false, &logic->noVariable, RHT_TREASURE_GAME_GREEN_RUPEE,ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0xF4, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_TREASURE_GAME_GREEN_RUPEE] = Item(RG_TREASURE_GAME_GREEN_RUPEE, Text{ "Green Rupee (LOSER)", "Rubis Vert (Chasse-aux-Trésors)", "Grüne Rupie (Schatztruhe-Minispiel)" }, ITEMTYPE_ITEM, GI_RUPEE_GREEN_LOSE, false, LOGIC_NONE, RHT_TREASURE_GAME_GREEN_RUPEE,ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0xF4, 0x00, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE);
// Shop // Shop
itemTable[RG_BUY_DEKU_NUTS_5] = Item(RG_BUY_DEKU_NUTS_5, Text{ "Buy Deku Nut (5)", "Acheter: Noix Mojo (5)", "Deku-Nuss kaufen (5)" }, ITEMTYPE_SHOP, GI_NUTS_5_2, true, &logic->Nuts, RHT_DEKU_NUTS_5, ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 15); itemTable[RG_BUY_DEKU_NUTS_5] = Item(RG_BUY_DEKU_NUTS_5, Text{ "Buy Deku Nut (5)", "Acheter: Noix Mojo (5)", "Deku-Nuss kaufen (5)" }, ITEMTYPE_SHOP, GI_NUTS_5_2, true, LOGIC_NUTS, RHT_DEKU_NUTS_5, ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 15);
itemTable[RG_BUY_ARROWS_30] = Item(RG_BUY_ARROWS_30, Text{ "Buy Arrows (30)", "Acheter: Flèches (30)", "Pfeile kaufen (30)" }, ITEMTYPE_SHOP, GI_ARROWS_MEDIUM, true, &logic->BuyArrow, RHT_ARROWS_30, ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 60); itemTable[RG_BUY_ARROWS_30] = Item(RG_BUY_ARROWS_30, Text{ "Buy Arrows (30)", "Acheter: Flèches (30)", "Pfeile kaufen (30)" }, ITEMTYPE_SHOP, GI_ARROWS_MEDIUM, true, LOGIC_BUY_ARROW, RHT_ARROWS_30, ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 60);
itemTable[RG_BUY_ARROWS_50] = Item(RG_BUY_ARROWS_50, Text{ "Buy Arrows (50)", "Acheter: Flèches (50)", "Pfeile kaufen (50)" }, ITEMTYPE_SHOP, GI_ARROWS_LARGE, true, &logic->BuyArrow, RHT_ARROWS_30, ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 90); itemTable[RG_BUY_ARROWS_50] = Item(RG_BUY_ARROWS_50, Text{ "Buy Arrows (50)", "Acheter: Flèches (50)", "Pfeile kaufen (50)" }, ITEMTYPE_SHOP, GI_ARROWS_LARGE, true, LOGIC_BUY_ARROW, RHT_ARROWS_30, ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 90);
itemTable[RG_BUY_BOMBS_525] = Item(RG_BUY_BOMBS_525, Text{ "Buy Bombs (5) [25]", "Acheter: Bombes (5) [25]", "Bomben kaufen (5) [25]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, &logic->BuyBomb, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 25); itemTable[RG_BUY_BOMBS_525] = Item(RG_BUY_BOMBS_525, Text{ "Buy Bombs (5) [25]", "Acheter: Bombes (5) [25]", "Bomben kaufen (5) [25]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, LOGIC_BUY_BOMB, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 25);
itemTable[RG_BUY_DEKU_NUTS_10] = Item(RG_BUY_DEKU_NUTS_10, Text{ "Buy Deku Nut (10)", "Acheter: Noix Mojo (10)", "Deku-Nuss kaufen (10)" }, ITEMTYPE_SHOP, GI_NUTS_10, true, &logic->Nuts, RHT_DEKU_NUTS_10, ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30); itemTable[RG_BUY_DEKU_NUTS_10] = Item(RG_BUY_DEKU_NUTS_10, Text{ "Buy Deku Nut (10)", "Acheter: Noix Mojo (10)", "Deku-Nuss kaufen (10)" }, ITEMTYPE_SHOP, GI_NUTS_10, true, LOGIC_NUTS, RHT_DEKU_NUTS_10, ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
itemTable[RG_BUY_DEKU_STICK_1] = Item(RG_BUY_DEKU_STICK_1, Text{ "Buy Deku Stick (1)", "Acheter: Bâton Mojo (1)", "Deku-Stick kaufen (1)" }, ITEMTYPE_SHOP, GI_STICKS_1, true, &logic->Sticks, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 10); itemTable[RG_BUY_DEKU_STICK_1] = Item(RG_BUY_DEKU_STICK_1, Text{ "Buy Deku Stick (1)", "Acheter: Bâton Mojo (1)", "Deku-Stick kaufen (1)" }, ITEMTYPE_SHOP, GI_STICKS_1, true, LOGIC_STICKS, RHT_DEKU_STICK_1, ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 10);
itemTable[RG_BUY_BOMBS_10] = Item(RG_BUY_BOMBS_10, Text{ "Buy Bombs (10)", "Acheter: Bombes (10)", "Bomben kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBS_10, true, &logic->BuyBomb, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); itemTable[RG_BUY_BOMBS_10] = Item(RG_BUY_BOMBS_10, Text{ "Buy Bombs (10)", "Acheter: Bombes (10)", "Bomben kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBS_10, true, LOGIC_BUY_BOMB, RHT_BOMBS_10, ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50);
itemTable[RG_BUY_FISH] = Item(RG_BUY_FISH, Text{ "Buy Fish", "Acheter: Poisson", "Fisch kaufen" }, ITEMTYPE_SHOP, GI_FISH, true, &logic->FishAccess, RHT_BOTTLE_WITH_FISH, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 200); itemTable[RG_BUY_FISH] = Item(RG_BUY_FISH, Text{ "Buy Fish", "Acheter: Poisson", "Fisch kaufen" }, ITEMTYPE_SHOP, GI_FISH, true, LOGIC_FISH_ACCESS, RHT_BOTTLE_WITH_FISH, ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 200);
itemTable[RG_BUY_RED_POTION_30] = Item(RG_BUY_RED_POTION_30, Text{ "Buy Red Potion [30]", "Acheter: Potion Rouge [30]", "Rotes Elixier kaufen [30]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, &logic->noVariable, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30); itemTable[RG_BUY_RED_POTION_30] = Item(RG_BUY_RED_POTION_30, Text{ "Buy Red Potion [30]", "Acheter: Potion Rouge [30]", "Rotes Elixier kaufen [30]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
itemTable[RG_BUY_GREEN_POTION] = Item(RG_BUY_GREEN_POTION, Text{ "Buy Green Potion", "Acheter: Potion Verte", "Grünes Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_GREEN, true, &logic->BuyMagicPotion, RHT_BOTTLE_WITH_GREEN_POTION,ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30); itemTable[RG_BUY_GREEN_POTION] = Item(RG_BUY_GREEN_POTION, Text{ "Buy Green Potion", "Acheter: Potion Verte", "Grünes Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_GREEN, true, LOGIC_BUY_MAGIC_POTION, RHT_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
itemTable[RG_BUY_BLUE_POTION] = Item(RG_BUY_BLUE_POTION, Text{ "Buy Blue Potion", "Acheter: Potion Bleue", "Blaues Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_BLUE, true, &logic->BuyMagicPotion, RHT_BOTTLE_WITH_BLUE_POTION,ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 100); itemTable[RG_BUY_BLUE_POTION] = Item(RG_BUY_BLUE_POTION, Text{ "Buy Blue Potion", "Acheter: Potion Bleue", "Blaues Elixier kaufen" }, ITEMTYPE_SHOP, GI_POTION_BLUE, true, LOGIC_BUY_MAGIC_POTION, RHT_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 100);
itemTable[RG_BUY_HYLIAN_SHIELD] = Item(RG_BUY_HYLIAN_SHIELD, Text{ "Buy Hylian Shield", "Acheter: Bouclier Hylien", "Hylianischer Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_HYLIAN, true, &logic->HylianShield, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, false, 80); itemTable[RG_BUY_HYLIAN_SHIELD] = Item(RG_BUY_HYLIAN_SHIELD, Text{ "Buy Hylian Shield", "Acheter: Bouclier Hylien", "Hylianischer Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_HYLIAN, true, LOGIC_HYLIAN_SHIELD, RHT_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, false, 80);
itemTable[RG_BUY_DEKU_SHIELD] = Item(RG_BUY_DEKU_SHIELD, Text{ "Buy Deku Shield", "Acheter: Bouclier Mojo", "Deku-Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_DEKU, true, &logic->DekuShield, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, false, 40); itemTable[RG_BUY_DEKU_SHIELD] = Item(RG_BUY_DEKU_SHIELD, Text{ "Buy Deku Shield", "Acheter: Bouclier Mojo", "Deku-Schild kaufen" }, ITEMTYPE_SHOP, GI_SHIELD_DEKU, true, LOGIC_DEKU_SHIELD, RHT_DEKU_SHIELD, ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE, false, 40);
itemTable[RG_BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{ "Buy Goron Tunic", "Acheter: Tunique Goron", "Goronen-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_GORON, true, &logic->GoronTunic, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 200); itemTable[RG_BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{ "Buy Goron Tunic", "Acheter: Tunique Goron", "Goronen-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_GORON, true, LOGIC_GORON_TUNIC, RHT_GORON_TUNIC, ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 200);
itemTable[RG_BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{ "Buy Zora Tunic", "Acheter: Tunique Zora", "Zora-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_ZORA, true, &logic->ZoraTunic, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 300); itemTable[RG_BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{ "Buy Zora Tunic", "Acheter: Tunique Zora", "Zora-Tunika kaufen" }, ITEMTYPE_SHOP, GI_TUNIC_ZORA, true, LOGIC_ZORA_TUNIC, RHT_ZORA_TUNIC, ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE, false, 300);
itemTable[RG_BUY_HEART] = Item(RG_BUY_HEART, Text{ "Buy Heart", "Acheter: Coeur de Vie", "Herz kaufen" }, ITEMTYPE_SHOP, GI_HEART, false, &logic->noVariable, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 10); itemTable[RG_BUY_HEART] = Item(RG_BUY_HEART, Text{ "Buy Heart", "Acheter: Coeur de Vie", "Herz kaufen" }, ITEMTYPE_SHOP, GI_HEART, false, LOGIC_NONE, RHT_RECOVERY_HEART, ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 10);
itemTable[RG_BUY_BOMBCHU_10] = Item(RG_BUY_BOMBCHU_10, Text{ "Buy Bombchu (10)", "Acheter: Missiles (10)", "Bomchu kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_10, true, &logic->BuyBombchus, RHT_BOMBCHU_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 99); itemTable[RG_BUY_BOMBCHU_10] = Item(RG_BUY_BOMBCHU_10, Text{ "Buy Bombchu (10)", "Acheter: Missiles (10)", "Bomchu kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_10, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHU_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 99);
itemTable[RG_BUY_BOMBCHU_20] = Item(RG_BUY_BOMBCHU_20, Text{ "Buy Bombchu (20)", "Acheter: Missiles (20)", "Bomchu kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_20, true, &logic->BuyBombchus, RHT_BOMBCHU_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 180); itemTable[RG_BUY_BOMBCHU_20] = Item(RG_BUY_BOMBCHU_20, Text{ "Buy Bombchu (20)", "Acheter: Missiles (20)", "Bomchu kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_20, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHU_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 180);
itemTable[RG_BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{ "Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Deku-Samen kaufen (30)" }, ITEMTYPE_SHOP, GI_SEEDS_30, true, &logic->BuySeed, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30); itemTable[RG_BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{ "Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Deku-Samen kaufen (30)" }, ITEMTYPE_SHOP, GI_SEEDS_30, true, LOGIC_BUY_SEED, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, &logic->noVariable, RHT_NONE, false, 0); itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, LOGIC_NONE, RHT_NONE, false, 0);
itemTable[RG_BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{ "Buy Blue Fire", "Acheter: Flamme Bleue", "Blaues Feuer kaufen" }, ITEMTYPE_SHOP, GI_BLUE_FIRE, true, &logic->BlueFireAccess, RHT_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 300); itemTable[RG_BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{ "Buy Blue Fire", "Acheter: Flamme Bleue", "Blaues Feuer kaufen" }, ITEMTYPE_SHOP, GI_BLUE_FIRE, true, LOGIC_BLUE_FIRE_ACCESS, RHT_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 300);
itemTable[RG_BUY_BOTTLE_BUG] = Item(RG_BUY_BOTTLE_BUG, Text{ "Buy Bottle Bug", "Acheter: Insecte en bouteille", "Flaschenkäfer kaufen" }, ITEMTYPE_SHOP, GI_BUGS, true, &logic->BugsAccess, RHT_BOTTLE_WITH_BUGS, ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); itemTable[RG_BUY_BOTTLE_BUG] = Item(RG_BUY_BOTTLE_BUG, Text{ "Buy Bottle Bug", "Acheter: Insecte en bouteille", "Flaschenkäfer kaufen" }, ITEMTYPE_SHOP, GI_BUGS, true, LOGIC_BUGS_ACCESS, RHT_BOTTLE_WITH_BUGS, ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50);
itemTable[RG_BUY_POE] = Item(RG_BUY_POE, Text{ "Buy Poe", "Acheter: Esprit", "Geist kaufen" }, ITEMTYPE_SHOP, RG_BUY_POE, false, &logic->noVariable, RHT_BOTTLE_WITH_BIG_POE, ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30); itemTable[RG_BUY_POE] = Item(RG_BUY_POE, Text{ "Buy Poe", "Acheter: Esprit", "Geist kaufen" }, ITEMTYPE_SHOP, RG_BUY_POE, false, LOGIC_NONE, RHT_BOTTLE_WITH_BIG_POE, ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
itemTable[RG_BUY_FAIRYS_SPIRIT] = Item(RG_BUY_FAIRYS_SPIRIT, Text{ "Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Feengeist kaufen" }, ITEMTYPE_SHOP, GI_FAIRY, true, &logic->FairyAccess, RHT_BOTTLE_WITH_FAIRY, ITEM_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); itemTable[RG_BUY_FAIRYS_SPIRIT] = Item(RG_BUY_FAIRYS_SPIRIT, Text{ "Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Feengeist kaufen" }, ITEMTYPE_SHOP, GI_FAIRY, true, LOGIC_FAIRY_ACCESS, RHT_BOTTLE_WITH_FAIRY, ITEM_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50);
itemTable[RG_BUY_ARROWS_10] = Item(RG_BUY_ARROWS_10, Text{ "Buy Arrows (10)", "Acheter: Flèches (10)", "Pfeile kaufen (10)" }, ITEMTYPE_SHOP, GI_ARROWS_SMALL, true, &logic->BuyArrow, RHT_ARROWS_10, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 20); itemTable[RG_BUY_ARROWS_10] = Item(RG_BUY_ARROWS_10, Text{ "Buy Arrows (10)", "Acheter: Flèches (10)", "Pfeile kaufen (10)" }, ITEMTYPE_SHOP, GI_ARROWS_SMALL, true, LOGIC_BUY_ARROW, RHT_ARROWS_10, ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 20);
itemTable[RG_BUY_BOMBS_20] = Item(RG_BUY_BOMBS_20, Text{ "Buy Bombs (20)", "Acheter: Bombes (20)", "Bomben kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBS_20, true, &logic->BuyBomb, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 80); itemTable[RG_BUY_BOMBS_20] = Item(RG_BUY_BOMBS_20, Text{ "Buy Bombs (20)", "Acheter: Bombes (20)", "Bomben kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBS_20, true, LOGIC_BUY_BOMB, RHT_BOMBS_20, ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 80);
itemTable[RG_BUY_BOMBS_30] = Item(RG_BUY_BOMBS_30, Text{ "Buy Bombs (30)", "Acheter: Bombes (30)", "Bomben kaufen (30)" }, ITEMTYPE_SHOP, GI_BOMBS_30, true, &logic->BuyBomb, RHT_BOMBS_20, ITEM_BOMBS_30, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 120); itemTable[RG_BUY_BOMBS_30] = Item(RG_BUY_BOMBS_30, Text{ "Buy Bombs (30)", "Acheter: Bombes (30)", "Bomben kaufen (30)" }, ITEMTYPE_SHOP, GI_BOMBS_30, true, LOGIC_BUY_BOMB, RHT_BOMBS_20, ITEM_BOMBS_30, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 120);
itemTable[RG_BUY_BOMBS_535] = Item(RG_BUY_BOMBS_535, Text{ "Buy Bombs (5) [35]", "Acheter: Bombes (5) [35]", "Bomben kaufen (5) [35]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, &logic->BuyBomb, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 35); itemTable[RG_BUY_BOMBS_535] = Item(RG_BUY_BOMBS_535, Text{ "Buy Bombs (5) [35]", "Acheter: Bombes (5) [35]", "Bomben kaufen (5) [35]" }, ITEMTYPE_SHOP, GI_BOMBS_5, true, LOGIC_BUY_BOMB, RHT_BOMBS_5, ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 35);
itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, &logic->noVariable, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 40); itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 40);
itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, &logic->noVariable, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50);
// Misc. // Misc.
itemTable[RG_GOHMA_SOUL] = Item(RG_GOHMA_SOUL, Text{ "Gohma's Soul", "", "" }, ITEMTYPE_ITEM, 0xE0, true, &logic->CanSummonGohma, RHT_GOHMA_SOUL, RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GOHMA_SOUL] = Item(RG_GOHMA_SOUL, Text{ "Gohma's Soul", "", "" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_CAN_SUMMON_GOHMA, RHT_GOHMA_SOUL, RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_GOHMA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_GOHMA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_KING_DODONGO_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{ "King Dodongo's Soul", "", "" }, ITEMTYPE_ITEM, 0xE1, true, &logic->CanSummonKingDodongo,RHT_KING_DODONGO_SOUL, RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_KING_DODONGO_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{ "King Dodongo's Soul", "", "" }, ITEMTYPE_ITEM, 0xE1, true, LOGIC_CAN_SUMMON_KINGDODONGO, RHT_KING_DODONGO_SOUL, RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_KING_DODONGO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_KING_DODONGO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_BARINADE_SOUL] = Item(RG_BARINADE_SOUL, Text{ "Barinade's Soul", "", "" }, ITEMTYPE_ITEM, 0xE2, true, &logic->CanSummonBarinade, RHT_BARINADE_SOUL, RG_BARINADE_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BARINADE_SOUL] = Item(RG_BARINADE_SOUL, Text{ "Barinade's Soul", "", "" }, ITEMTYPE_ITEM, 0xE2, true, LOGIC_CAN_SUMMON_BARINADE, RHT_BARINADE_SOUL, RG_BARINADE_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BARINADE_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_BARINADE_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_PHANTOM_GANON_SOUL] = Item(RG_PHANTOM_GANON_SOUL, Text{ "Phantom Ganon's Soul", "", "" }, ITEMTYPE_ITEM, 0xE3, true, &logic->CanSummonPhantomGanon,RHT_PHANTOM_GANON_SOUL, RG_PHANTOM_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_PHANTOM_GANON_SOUL] = Item(RG_PHANTOM_GANON_SOUL, Text{ "Phantom Ganon's Soul", "", "" }, ITEMTYPE_ITEM, 0xE3, true, LOGIC_CAN_SUMMON_PHANTOMGANON, RHT_PHANTOM_GANON_SOUL, RG_PHANTOM_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_PHANTOM_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_PHANTOM_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_VOLVAGIA_SOUL] = Item(RG_VOLVAGIA_SOUL, Text{ "Volvagia's Soul", "", "" }, ITEMTYPE_ITEM, 0xE4, true, &logic->CanSummonVolvagia, RHT_VOLVAGIA_SOUL, RG_VOLVAGIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_VOLVAGIA_SOUL] = Item(RG_VOLVAGIA_SOUL, Text{ "Volvagia's Soul", "", "" }, ITEMTYPE_ITEM, 0xE4, true, LOGIC_CAN_SUMMON_VOLVAGIA, RHT_VOLVAGIA_SOUL, RG_VOLVAGIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_VOLVAGIA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_VOLVAGIA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_MORPHA_SOUL] = Item(RG_MORPHA_SOUL, Text{ "Morpha's Soul", "", "" }, ITEMTYPE_ITEM, 0xE5, true, &logic->CanSummonMorpha, RHT_MORPHA_SOUL, RG_MORPHA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_MORPHA_SOUL] = Item(RG_MORPHA_SOUL, Text{ "Morpha's Soul", "", "" }, ITEMTYPE_ITEM, 0xE5, true, LOGIC_CAN_SUMMON_MORPHA, RHT_MORPHA_SOUL, RG_MORPHA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_MORPHA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_MORPHA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_BONGO_BONGO_SOUL] = Item(RG_BONGO_BONGO_SOUL, Text{ "Bongo Bongo's Soul", "", "" }, ITEMTYPE_ITEM, 0xE6, true, &logic->CanSummonBongoBongo, RHT_BONGO_BONGO_SOUL, RG_BONGO_BONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BONGO_BONGO_SOUL] = Item(RG_BONGO_BONGO_SOUL, Text{ "Bongo Bongo's Soul", "", "" }, ITEMTYPE_ITEM, 0xE6, true, LOGIC_CAN_SUMMON_BONGOBONGO, RHT_BONGO_BONGO_SOUL, RG_BONGO_BONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BONGO_BONGO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_BONGO_BONGO_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_TWINROVA_SOUL] = Item(RG_TWINROVA_SOUL, Text{ "Twinrova's Soul", "", "" }, ITEMTYPE_ITEM, 0xE7, true, &logic->CanSummonTwinrova, RHT_TWINROVA_SOUL, RG_TWINROVA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_TWINROVA_SOUL] = Item(RG_TWINROVA_SOUL, Text{ "Twinrova's Soul", "", "" }, ITEMTYPE_ITEM, 0xE7, true, LOGIC_CAN_SUMMON_TWINROVA, RHT_TWINROVA_SOUL, RG_TWINROVA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_TWINROVA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_TWINROVA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_GANON_SOUL] = Item(RG_GANON_SOUL, Text{ "Ganon's Soul", "", "" }, ITEMTYPE_ITEM, 0xE8, true, &logic->CanSummonGanon, RHT_GANON_SOUL, RG_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GANON_SOUL] = Item(RG_GANON_SOUL, Text{ "Ganon's Soul", "", "" }, ITEMTYPE_ITEM, 0xE8, true, LOGIC_CAN_SUMMON_GANON, RHT_GANON_SOUL, RG_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Caña de Pescar" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, &logic->FishingPole, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Caña de Pescar" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, LOGIC_FISHING_POLE, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_FISHING_POLE].SetCustomDrawFunc(Randomizer_DrawFishingPoleGI); itemTable[RG_FISHING_POLE].SetCustomDrawFunc(Randomizer_DrawFishingPoleGI);
itemTable[RG_OCARINA_A_BUTTON] = Item(RG_OCARINA_A_BUTTON, Text{ "Ocarina A Button", "Touche A de l'Ocarina", "Botón A de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, &logic->OcarinaAButton, RHT_OCARINA_A_BUTTON, RG_OCARINA_A_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_A_BUTTON] = Item(RG_OCARINA_A_BUTTON, Text{ "Ocarina A Button", "Touche A de l'Ocarina", "Botón A de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_A_BUTTON, RHT_OCARINA_A_BUTTON, RG_OCARINA_A_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_OCARINA_A_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); itemTable[RG_OCARINA_A_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
itemTable[RG_OCARINA_C_UP_BUTTON] = Item(RG_OCARINA_C_UP_BUTTON, Text{ "Ocarina C Up Button", "Touche C-Haut de l'Ocarina", "Botón C superior de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, &logic->OcarinaCUpButton, RHT_OCARINA_C_UP_BUTTON, RG_OCARINA_C_UP_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_UP_BUTTON] = Item(RG_OCARINA_C_UP_BUTTON, Text{ "Ocarina C Up Button", "Touche C-Haut de l'Ocarina", "Botón C superior de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_UP_BUTTON, RHT_OCARINA_C_UP_BUTTON, RG_OCARINA_C_UP_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_OCARINA_C_UP_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); itemTable[RG_OCARINA_C_UP_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
itemTable[RG_OCARINA_C_DOWN_BUTTON] = Item(RG_OCARINA_C_DOWN_BUTTON, Text{ "Ocarina C Down Button", "Touche C-Bas de l'Ocarina", "Botón C inferior de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, &logic->OcarinaCDownButton, RHT_OCARINA_C_DOWN_BUTTON, RG_OCARINA_C_DOWN_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_DOWN_BUTTON] = Item(RG_OCARINA_C_DOWN_BUTTON, Text{ "Ocarina C Down Button", "Touche C-Bas de l'Ocarina", "Botón C inferior de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_DOWN_BUTTON, RHT_OCARINA_C_DOWN_BUTTON, RG_OCARINA_C_DOWN_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_OCARINA_C_DOWN_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); itemTable[RG_OCARINA_C_DOWN_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
itemTable[RG_OCARINA_C_LEFT_BUTTON] = Item(RG_OCARINA_C_LEFT_BUTTON, Text{ "Ocarina C Left Button", "Touche C-Gauche de l'Ocarina", "Botón C izquierdo de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, &logic->OcarinaCLeftButton, RHT_OCARINA_C_LEFT_BUTTON, RG_OCARINA_C_LEFT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_LEFT_BUTTON] = Item(RG_OCARINA_C_LEFT_BUTTON, Text{ "Ocarina C Left Button", "Touche C-Gauche de l'Ocarina", "Botón C izquierdo de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_LEFT_BUTTON, RG_OCARINA_C_LEFT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_OCARINA_C_LEFT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); itemTable[RG_OCARINA_C_LEFT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "Botón C derecho de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, &logic->OcarinaCRightButton, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "Botón C derecho de Ocarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
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] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, 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_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale);
itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, &logic->ProgressiveBow, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOMB_BAG_INF] = Item(RG_BOMB_BAG_INF, Text{ "Infinite Bomb Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BOMB_BAG_INF, true, &logic->ProgressiveBombBag, RHT_BOMB_BAG_INF, RG_BOMB_BAG_INF, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOMB_BAG_INF] = Item(RG_BOMB_BAG_INF, Text{ "Infinite Bomb Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BOMB_BAG_INF, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG_INF, RG_BOMB_BAG_INF, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BULLET_BAG_INF] = Item(RG_BULLET_BAG_INF, Text{ "Infinite Bullet Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BULLET_BAG_INF, true, &logic->ProgressiveBulletBag, RHT_BULLET_BAG_INF, RG_BULLET_BAG_INF, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BULLET_BAG_INF] = Item(RG_BULLET_BAG_INF, Text{ "Infinite Bullet Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BULLET_BAG_INF, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BULLET_BAG_INF, RG_BULLET_BAG_INF, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_STICK_UPGRADE_INF] = Item(RG_STICK_UPGRADE_INF, Text{ "Infinite Stick Capacity", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_STICK_UPGRADE_INF, true, &logic->noVariable, RHT_STICK_UPGRADE_INF, RG_STICK_UPGRADE_INF, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_STICK_UPGRADE_INF] = Item(RG_STICK_UPGRADE_INF, Text{ "Infinite Stick Capacity", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_STICK_UPGRADE_INF, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_STICK_UPGRADE_INF, RG_STICK_UPGRADE_INF, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_NUT_UPGRADE_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Nut Capacity", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_NUT_UPGRADE_INF, true, &logic->noVariable, RHT_NUT_UPGRADE_INF, RG_NUT_UPGRADE_INF, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_NUT_UPGRADE_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Nut Capacity", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_NUT_UPGRADE_INF, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NUT_UPGRADE_INF, RG_NUT_UPGRADE_INF, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_MAGIC_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Magic Meter", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MAGIC_INF, true, &logic->ProgressiveMagic, RHT_MAGIC_INF, RG_MAGIC_INF, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_MAGIC_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Magic Meter", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_MAGIC_INF, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_INF, RG_MAGIC_INF, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_INF] = Item(RG_BOMBCHU_INF, Text{ "Infinite Bombchus", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BOMBCHU_INF, true, &logic->Bombchus, RHT_BOMBCHU_INF, RG_BOMBCHU_INF, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_INF] = Item(RG_BOMBCHU_INF, Text{ "Infinite Bombchus", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BOMBCHU_INF, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_INF, RG_BOMBCHU_INF, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_WALLET_INF] = Item(RG_WALLET_INF, Text{ "Infinite Wallet", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_WALLET_INF, true, &logic->ProgressiveWallet, RHT_WALLET_INF, RG_WALLET_INF, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_WALLET_INF] = Item(RG_WALLET_INF, Text{ "Infinite Wallet", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_WALLET_INF, true, LOGIC_PROGRESSIVE_WALLET, RHT_WALLET_INF, RG_WALLET_INF, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SKELETON_KEY] = Item(RG_SKELETON_KEY, Text{ "Skeleton Key", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, &logic->SkeletonKey, RHT_SKELETON_KEY, RG_SKELETON_KEY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_SKELETON_KEY] = Item(RG_SKELETON_KEY, Text{ "Skeleton Key", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, LOGIC_SKELETON_KEY, RHT_SKELETON_KEY, RG_SKELETON_KEY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_SKELETON_KEY].SetCustomDrawFunc(Randomizer_DrawSkeletonKey); itemTable[RG_SKELETON_KEY].SetCustomDrawFunc(Randomizer_DrawSkeletonKey);
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_STICK_BAG] = Item(RG_DEKU_STICK_BAG, Text{ "Deku Stick Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, LOGIC_PROGRESSIVE_STICK_BAG, 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_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, 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_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, LOGIC_NONE, RHT_NONE);
itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, &logic->noVariable, RHT_NONE); itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, LOGIC_NONE, RHT_NONE);
// Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen) // Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen)
itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, &logic->ProgressiveHookshot, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_LONGSHOT] = Item(RG_LONGSHOT, Text{ "Longshot", "Super-Grappin", "Enterhaken" }, ITEMTYPE_ITEM, GI_LONGSHOT, true, &logic->ProgressiveHookshot, RHT_LONGSHOT, ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_LONGSHOT] = Item(RG_LONGSHOT, Text{ "Longshot", "Super-Grappin", "Enterhaken" }, ITEMTYPE_ITEM, GI_LONGSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_LONGSHOT, ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FAIRY_OCARINA] = Item(RG_FAIRY_OCARINA, Text{ "Fairy Ocarina", "Ocarina des fées", "Feen-Okarina" }, ITEMTYPE_ITEM, GI_OCARINA_FAIRY, true, &logic->ProgressiveOcarina, RHT_FAIRY_OCARINA, ITEM_OCARINA_FAIRY, OBJECT_GI_OCARINA_0, GID_OCARINA_FAIRY, 0x4A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FAIRY_OCARINA] = Item(RG_FAIRY_OCARINA, Text{ "Fairy Ocarina", "Ocarina des fées", "Feen-Okarina" }, ITEMTYPE_ITEM, GI_OCARINA_FAIRY, true, LOGIC_PROGRESSIVE_OCARINA, RHT_FAIRY_OCARINA, ITEM_OCARINA_FAIRY, OBJECT_GI_OCARINA_0, GID_OCARINA_FAIRY, 0x4A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_OCARINA_OF_TIME] = Item(RG_OCARINA_OF_TIME, Text{ "Ocarina of Time", "Ocarina du Temps", "Okarina der Zeit" }, ITEMTYPE_ITEM, GI_OCARINA_OOT, true, &logic->ProgressiveOcarina, RHT_OCARINA_OF_TIME, ITEM_OCARINA_TIME, OBJECT_GI_OCARINA, GID_OCARINA_TIME, 0x3A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_OCARINA_OF_TIME] = Item(RG_OCARINA_OF_TIME, Text{ "Ocarina of Time", "Ocarina du Temps", "Okarina der Zeit" }, ITEMTYPE_ITEM, GI_OCARINA_OOT, true, LOGIC_PROGRESSIVE_OCARINA, RHT_OCARINA_OF_TIME, ITEM_OCARINA_TIME, OBJECT_GI_OCARINA, GID_OCARINA_TIME, 0x3A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BOMB_BAG] = Item(RG_BOMB_BAG, Text{ "Bomb Bag", "Sac de Bombes", "Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_20, true, &logic->ProgressiveBombBag, RHT_BOMB_BAG, ITEM_BOMB_BAG_20, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, 0x58, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_BOMB_BAG] = Item(RG_BOMB_BAG, Text{ "Bomb Bag", "Sac de Bombes", "Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_20, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BOMB_BAG, ITEM_BOMB_BAG_20, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, 0x58, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BIG_BOMB_BAG] = Item(RG_BIG_BOMB_BAG, Text{ "Big Bomb Bag", "Grand Sac de Bombes", "Große Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_30, true, &logic->ProgressiveBombBag, RHT_BIG_BOMB_BAG, ITEM_BOMB_BAG_30, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, 0x59, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_BIG_BOMB_BAG] = Item(RG_BIG_BOMB_BAG, Text{ "Big Bomb Bag", "Grand Sac de Bombes", "Große Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_30, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BIG_BOMB_BAG, ITEM_BOMB_BAG_30, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, 0x59, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_BIGGEST_BOMB_BAG] = Item(RG_BIGGEST_BOMB_BAG, Text{ "Biggest Bomb Bag", "Énorme Sac de Bombes", "Größte Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_40, true, &logic->ProgressiveBombBag, RHT_BIGGEST_BOMB_BAG, ITEM_BOMB_BAG_40, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, 0x5A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_BIGGEST_BOMB_BAG] = Item(RG_BIGGEST_BOMB_BAG, Text{ "Biggest Bomb Bag", "Énorme Sac de Bombes", "Größte Bombentasche" }, ITEMTYPE_ITEM, GI_BOMB_BAG_40, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_BIGGEST_BOMB_BAG, ITEM_BOMB_BAG_40, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, 0x5A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_FAIRY_BOW] = Item(RG_FAIRY_BOW, Text{ "Fairy Bow", "Arc des Fées", "Feen-Bogen" }, ITEMTYPE_ITEM, GI_BOW, true, &logic->ProgressiveBow, RHT_FAIRY_BOW, ITEM_BOW, OBJECT_GI_BOW, GID_BOW, 0x31, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FAIRY_BOW] = Item(RG_FAIRY_BOW, Text{ "Fairy Bow", "Arc des Fées", "Feen-Bogen" }, ITEMTYPE_ITEM, GI_BOW, true, LOGIC_PROGRESSIVE_BOW, RHT_FAIRY_BOW, ITEM_BOW, OBJECT_GI_BOW, GID_BOW, 0x31, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BIG_QUIVER] = Item(RG_BIG_QUIVER, Text{ "Big Quiver", "Grand carquois", "Großer Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_40, true, &logic->ProgressiveBow, RHT_BIG_QUIVER, ITEM_QUIVER_40, OBJECT_GI_ARROWCASE, GID_QUIVER_40, 0x56, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_BIG_QUIVER] = Item(RG_BIG_QUIVER, Text{ "Big Quiver", "Grand carquois", "Großer Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_40, true, LOGIC_PROGRESSIVE_BOW, RHT_BIG_QUIVER, ITEM_QUIVER_40, OBJECT_GI_ARROWCASE, GID_QUIVER_40, 0x56, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_BIGGEST_QUIVER] = Item(RG_BIGGEST_QUIVER, Text{ "Biggest Quiver", "Énorme carquois", "Größter Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_50, true, &logic->ProgressiveBow, RHT_BIGGEST_QUIVER, ITEM_QUIVER_50, OBJECT_GI_ARROWCASE, GID_QUIVER_50, 0x57, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_BIGGEST_QUIVER] = Item(RG_BIGGEST_QUIVER, Text{ "Biggest Quiver", "Énorme carquois", "Größter Köcher" }, ITEMTYPE_ITEM, GI_QUIVER_50, true, LOGIC_PROGRESSIVE_BOW, RHT_BIGGEST_QUIVER, ITEM_QUIVER_50, OBJECT_GI_ARROWCASE, GID_QUIVER_50, 0x57, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_FAIRY_SLINGSHOT] = Item(RG_FAIRY_SLINGSHOT, Text{ "Fairy Slingshot", "Lance-Pierre des Fées", "Feen-Schleuder" }, ITEMTYPE_ITEM, GI_SLINGSHOT, true, &logic->ProgressiveBulletBag,RHT_FAIRY_SLINGSHOT, ITEM_SLINGSHOT, OBJECT_GI_PACHINKO, GID_SLINGSHOT, 0x30, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_FAIRY_SLINGSHOT] = Item(RG_FAIRY_SLINGSHOT, Text{ "Fairy Slingshot", "Lance-Pierre des Fées", "Feen-Schleuder" }, ITEMTYPE_ITEM, GI_SLINGSHOT, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_FAIRY_SLINGSHOT, ITEM_SLINGSHOT, OBJECT_GI_PACHINKO, GID_SLINGSHOT, 0x30, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BIG_BULLET_BAG] = Item(RG_BIG_BULLET_BAG, Text{ "Big Deku Seed Bullet Bag", "Grand sac de graines mojo", "Großer Deku-Samenkugelsack" }, ITEMTYPE_ITEM, GI_BULLET_BAG_40, true, &logic->ProgressiveBulletBag,RHT_BIG_BULLET_BAG, ITEM_BULLET_BAG_40, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_BIG_BULLET_BAG] = Item(RG_BIG_BULLET_BAG, Text{ "Big Deku Seed Bullet Bag", "Grand sac de graines mojo", "Großer Deku-Samenkugelsack" }, ITEMTYPE_ITEM, GI_BULLET_BAG_40, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BIG_BULLET_BAG, ITEM_BULLET_BAG_40, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_BIGGEST_BULLET_BAG] = Item(RG_BIGGEST_BULLET_BAG, Text{ "Biggest Deku Seed Bullet Bag", "Énorme sac de graines mojo", "Größte Deku-Samenkugelsack" }, ITEMTYPE_ITEM, GI_BULLET_BAG_50, true, &logic->ProgressiveBulletBag,RHT_BIGGEST_BULLET_BAG, ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_BIGGEST_BULLET_BAG] = Item(RG_BIGGEST_BULLET_BAG, Text{ "Biggest Deku Seed Bullet Bag", "Énorme sac de graines mojo", "Größte Deku-Samenkugelsack" }, ITEMTYPE_ITEM, GI_BULLET_BAG_50, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_BIGGEST_BULLET_BAG, ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_GORONS_BRACELET] = Item(RG_GORONS_BRACELET, Text{ "Goron's Bracelet", "Bracelet Goron", "Goronen-Armband" }, ITEMTYPE_ITEM, GI_BRACELET, true, &logic->ProgressiveStrength, RHT_GORONS_BRACELET, ITEM_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, 0x79, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GORONS_BRACELET] = Item(RG_GORONS_BRACELET, Text{ "Goron's Bracelet", "Bracelet Goron", "Goronen-Armband" }, ITEMTYPE_ITEM, GI_BRACELET, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_GORONS_BRACELET, ITEM_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, 0x79, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SILVER_GAUNTLETS] = Item(RG_SILVER_GAUNTLETS, Text{ "Silver Gauntlets", "Gantelets d'argent", "Silberne Fehdehandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_SILVER,true, &logic->ProgressiveStrength, RHT_SILVER_GAUNTLETS, ITEM_GAUNTLETS_SILVER, OBJECT_GI_GLOVES, GID_GAUNTLETS_SILVER,0x5B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SILVER_GAUNTLETS] = Item(RG_SILVER_GAUNTLETS, Text{ "Silver Gauntlets", "Gantelets d'argent", "Silberne Fehdehandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_SILVER, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_SILVER_GAUNTLETS, ITEM_GAUNTLETS_SILVER, OBJECT_GI_GLOVES, GID_GAUNTLETS_SILVER, 0x5B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{ "Golden Gauntlets", "Gantelets d'or", "Goldene Fehdehandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_GOLD, true, &logic->ProgressiveStrength, RHT_GOLDEN_GAUNTLETS, ITEM_GAUNTLETS_GOLD, OBJECT_GI_GLOVES, GID_GAUNTLETS_GOLD, 0x5C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{ "Golden Gauntlets", "Gantelets d'or", "Goldene Fehdehandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_GOLD, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_GOLDEN_GAUNTLETS, ITEM_GAUNTLETS_GOLD, OBJECT_GI_GLOVES, GID_GAUNTLETS_GOLD, 0x5C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SILVER_SCALE] = Item(RG_SILVER_SCALE, Text{ "Silver Scale", "Écaille d'argent", "Silberne Skala" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, &logic->ProgressiveScale, RHT_SILVER_SCALE, ITEM_SCALE_SILVER, OBJECT_GI_SCALE, GID_SCALE_SILVER, 0xCD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_SILVER_SCALE] = Item(RG_SILVER_SCALE, Text{ "Silver Scale", "Écaille d'argent", "Silberne Skala" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_SILVER_SCALE, ITEM_SCALE_SILVER, OBJECT_GI_SCALE, GID_SCALE_SILVER, 0xCD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GOLDEN_SCALE] = Item(RG_GOLDEN_SCALE, Text{ "Golden Scale", "Écaille d'or", "Goldene Skala" }, ITEMTYPE_ITEM, GI_SCALE_GOLD, true, &logic->ProgressiveScale, RHT_GOLDEN_SCALE, ITEM_SCALE_GOLDEN, OBJECT_GI_SCALE, GID_SCALE_GOLDEN, 0xCE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_GOLDEN_SCALE] = Item(RG_GOLDEN_SCALE, Text{ "Golden Scale", "Écaille d'or", "Goldene Skala" }, ITEMTYPE_ITEM, GI_SCALE_GOLD, true, LOGIC_PROGRESSIVE_SCALE, RHT_GOLDEN_SCALE, ITEM_SCALE_GOLDEN, OBJECT_GI_SCALE, GID_SCALE_GOLDEN, 0xCE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Erwachsene Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_ADULT, true, &logic->ProgressiveWallet, RHT_ADULT_WALLET, ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Erwachsene Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_ADULT, true, LOGIC_PROGRESSIVE_WALLET, RHT_ADULT_WALLET, ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
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_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesige Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, LOGIC_PROGRESSIVE_WALLET, 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_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Reiche Geldbörse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, LOGIC_PROGRESSIVE_WALLET, 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_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_PROGRESSIVE_WALLET, 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, 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_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_PROGRESSIVE_NUT_BAG, 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_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_PROGRESSIVE_NUT_BAG, 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_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_PROGRESSIVE_STICK_BAG, 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_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_PROGRESSIVE_STICK_BAG, 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_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magisches Messgerät" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, 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_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbesserte Magieanzeige" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, 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); itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce Piece" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_TRIFORCE_PIECES, 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);
// Init itemNameToEnum // Init itemNameToEnum
for (auto& item : itemTable) { for (auto& item : itemTable) {

View File

@ -8,6 +8,7 @@
#include "dungeon.h" #include "dungeon.h"
#include "context.h" #include "context.h"
#include <spdlog/spdlog.h>
namespace Rando { namespace Rando {
bool Logic::IsMagicItem(RandomizerGet item) { bool Logic::IsMagicItem(RandomizerGet item) {
@ -24,52 +25,187 @@ namespace Rando {
} }
bool Logic::HasItem(RandomizerGet itemName) { bool Logic::HasItem(RandomizerGet itemName) {
return (itemName == RG_DINS_FIRE && DinsFire) || switch (itemName) {
(itemName == RG_FARORES_WIND && FaroresWind) || case RG_FAIRY_OCARINA:
(itemName == RG_NAYRUS_LOVE && NayrusLove) || return ctx->CheckInventory(ITEM_OCARINA_FAIRY, false);
(itemName == RG_LENS_OF_TRUTH && LensOfTruth) || case RG_OCARINA_OF_TIME:
(itemName == RG_FAIRY_BOW && Bow) || return ctx->CheckInventory(ITEM_OCARINA_TIME, true);
(itemName == RG_MEGATON_HAMMER && Hammer) || case RG_DINS_FIRE:
(itemName == RG_IRON_BOOTS && IronBoots) || return ctx->CheckInventory(ITEM_DINS_FIRE, true);
(itemName == RG_HOVER_BOOTS && HoverBoots) || case RG_FARORES_WIND:
(itemName == RG_HOOKSHOT && Hookshot) || return ctx->CheckInventory(ITEM_FARORES_WIND, true);
(itemName == RG_LONGSHOT && Longshot) || case RG_NAYRUS_LOVE:
(itemName == RG_SILVER_GAUNTLETS && SilverGauntlets) || return ctx->CheckInventory(ITEM_NAYRUS_LOVE, true);
(itemName == RG_GOLDEN_GAUNTLETS && GoldenGauntlets) || case RG_LENS_OF_TRUTH:
(itemName == RG_GORON_TUNIC && GoronTunic) || return ctx->CheckInventory(ITEM_LENS, true);
(itemName == RG_ZORA_TUNIC && ZoraTunic) || case RG_FAIRY_BOW:
(itemName == RG_SCARECROW && Scarecrow) || return ctx->CheckInventory(ITEM_BOW, true);
(itemName == RG_DISTANT_SCARECROW && DistantScarecrow) || case RG_MEGATON_HAMMER:
(itemName == RG_HYLIAN_SHIELD && HylianShield) || return ctx->CheckInventory(ITEM_HAMMER, true);
(itemName == RG_MIRROR_SHIELD && MirrorShield) || case RG_HOOKSHOT:
(itemName == RG_MASTER_SWORD && MasterSword) || return ctx->CheckInventory(ITEM_HOOKSHOT, false);
(itemName == RG_BIGGORON_SWORD && BiggoronSword) || case RG_LONGSHOT:
(itemName == RG_FAIRY_SLINGSHOT && Slingshot) || return ctx->CheckInventory(ITEM_LONGSHOT, true);
(itemName == RG_BOOMERANG && Boomerang) || case RG_PROGRESSIVE_STICK_UPGRADE:
(itemName == RG_KOKIRI_SWORD && KokiriSword) || case RG_STICKS:
(itemName == RG_STICKS && Sticks) || return ctx->CurrentUpgrade(UPG_STICKS);
(itemName == RG_DEKU_SHIELD && DekuShield) || case RG_FIRE_ARROWS:
(itemName == RG_FIRE_ARROWS && FireArrows) || return ctx->CheckInventory(ITEM_ARROW_FIRE, true);
(itemName == RG_ICE_ARROWS && IceArrows) || case RG_ICE_ARROWS:
(itemName == RG_LIGHT_ARROWS && LightArrows) || return ctx->CheckInventory(ITEM_ARROW_ICE, true);
(itemName == RG_OCARINA_A_BUTTON && OcarinaAButton) || case RG_LIGHT_ARROWS:
(itemName == RG_OCARINA_C_LEFT_BUTTON && OcarinaCLeftButton) || return ctx->CheckInventory(ITEM_ARROW_LIGHT, true);
(itemName == RG_OCARINA_C_RIGHT_BUTTON && OcarinaCRightButton) || case RG_PROGRESSIVE_BOMBCHUS:
(itemName == RG_OCARINA_C_DOWN_BUTTON && OcarinaCDownButton) || return ctx->CheckInventory(ITEM_BOMBCHU, true);
(itemName == RG_OCARINA_C_UP_BUTTON && OcarinaCUpButton) || case RG_FAIRY_SLINGSHOT:
(itemName == RG_FISHING_POLE && FishingPole) || return ctx->CheckInventory(ITEM_SLINGSHOT, true);
(itemName == RG_ZELDAS_LULLABY && ZeldasLullaby) || case RG_BOOMERANG:
(itemName == RG_EPONAS_SONG && EponasSong) || return ctx->CheckInventory(ITEM_BOOMERANG, true);
(itemName == RG_SARIAS_SONG && SariasSong) || case RG_PROGRESSIVE_NUT_UPGRADE:
(itemName == RG_SUNS_SONG && SunsSong) || case RG_NUTS:
(itemName == RG_SONG_OF_TIME && SongOfTime) || return ctx->CurrentUpgrade(UPG_NUTS);
(itemName == RG_SONG_OF_STORMS && SongOfStorms) || case RG_SCARECROW:
(itemName == RG_MINUET_OF_FOREST && MinuetOfForest) || return Scarecrow;
(itemName == RG_BOLERO_OF_FIRE && BoleroOfFire) || case RG_DISTANT_SCARECROW:
(itemName == RG_SERENADE_OF_WATER && SerenadeOfWater) || return DistantScarecrow;
(itemName == RG_REQUIEM_OF_SPIRIT && RequiemOfSpirit) || case RG_KOKIRI_SWORD:
(itemName == RG_NOCTURNE_OF_SHADOW && NocturneOfShadow) || case RG_DEKU_SHIELD:
(itemName == RG_PRELUDE_OF_LIGHT && PreludeOfLight); case RG_GORON_TUNIC:
case RG_ZORA_TUNIC:
case RG_HYLIAN_SHIELD:
case RG_MIRROR_SHIELD:
case RG_MASTER_SWORD:
case RG_BIGGORON_SWORD:
case RG_IRON_BOOTS:
case RG_HOVER_BOOTS:
return ctx->CheckEquipment(Context::RandoGetToEquipFlag.at(itemName));
case RG_GORONS_BRACELET:
return ctx->CurrentUpgrade(UPG_STRENGTH);
case RG_SILVER_GAUNTLETS:
return ctx->CurrentUpgrade(UPG_STRENGTH) >= 2;
case RG_GOLDEN_GAUNTLETS:
return ctx->CurrentUpgrade(UPG_STRENGTH) >= 3;
case RG_PROGRESSIVE_BOMB_BAG:
case RG_BOMB_BAG:
return ctx->CurrentUpgrade(UPG_BOMB_BAG);
case RG_MAGIC_SINGLE:
return ctx->GetSaveContext()->magicLevel >= 1;
// Songs
case RG_ZELDAS_LULLABY:
case RG_EPONAS_SONG:
case RG_SARIAS_SONG:
case RG_SUNS_SONG:
case RG_SONG_OF_TIME:
case RG_SONG_OF_STORMS:
case RG_MINUET_OF_FOREST:
case RG_BOLERO_OF_FIRE:
case RG_SERENADE_OF_WATER:
case RG_REQUIEM_OF_SPIRIT:
case RG_NOCTURNE_OF_SHADOW:
case RG_PRELUDE_OF_LIGHT:
// Dungeon Rewards
case RG_KOKIRI_EMERALD:
case RG_GORON_RUBY:
case RG_ZORA_SAPPHIRE:
case RG_FOREST_MEDALLION:
case RG_FIRE_MEDALLION:
case RG_WATER_MEDALLION:
case RG_SPIRIT_MEDALLION:
case RG_SHADOW_MEDALLION:
case RG_LIGHT_MEDALLION:
// Misc Quest Items
case RG_STONE_OF_AGONY:
case RG_GERUDO_MEMBERSHIP_CARD:
return ctx->CheckQuestItem(Context::RandoGetToQuestItem.at(itemName));
case RG_RUTOS_LETTER:
return ctx->CheckEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER);
case RG_DOUBLE_DEFENSE:
return ctx->GetSaveContext()->isDoubleDefenseAcquired;
case RG_FISHING_POLE:
case RG_ZELDAS_LETTER:
case RG_WEIRD_EGG:
case RG_GREG_RUPEE:
// Ocarina Buttons
case RG_OCARINA_A_BUTTON:
case RG_OCARINA_C_LEFT_BUTTON:
case RG_OCARINA_C_RIGHT_BUTTON:
case RG_OCARINA_C_DOWN_BUTTON:
case RG_OCARINA_C_UP_BUTTON:
// Boss Souls
case RG_GOHMA_SOUL:
case RG_KING_DODONGO_SOUL:
case RG_BARINADE_SOUL:
case RG_PHANTOM_GANON_SOUL:
case RG_VOLVAGIA_SOUL:
case RG_MORPHA_SOUL:
case RG_BONGO_BONGO_SOUL:
case RG_TWINROVA_SOUL:
case RG_GANON_SOUL:
case RG_SKELETON_KEY:
return ctx->CheckRandoInf(Context::RandoGetToRandInf.at(itemName));
// Boss Keys
case RG_FOREST_TEMPLE_BOSS_KEY:
case RG_FIRE_TEMPLE_BOSS_KEY:
case RG_WATER_TEMPLE_BOSS_KEY:
case RG_SPIRIT_TEMPLE_BOSS_KEY:
case RG_SHADOW_TEMPLE_BOSS_KEY:
case RG_GANONS_CASTLE_BOSS_KEY:
return ctx->CheckDungeonItem(DUNGEON_KEY_BOSS, Context::RandoGetToDungeonScene.at(itemName));
// Maps
case RG_DEKU_TREE_MAP:
case RG_DODONGOS_CAVERN_MAP:
case RG_JABU_JABUS_BELLY_MAP:
case RG_FOREST_TEMPLE_MAP:
case RG_FIRE_TEMPLE_MAP:
case RG_WATER_TEMPLE_MAP:
case RG_SPIRIT_TEMPLE_MAP:
case RG_SHADOW_TEMPLE_MAP:
case RG_BOTTOM_OF_THE_WELL_MAP:
case RG_ICE_CAVERN_MAP:
return ctx->CheckDungeonItem(DUNGEON_MAP, Context::RandoGetToDungeonScene.at(itemName));
// Compasses
case RG_DEKU_TREE_COMPASS:
case RG_DODONGOS_CAVERN_COMPASS:
case RG_JABU_JABUS_BELLY_COMPASS:
case RG_FOREST_TEMPLE_COMPASS:
case RG_FIRE_TEMPLE_COMPASS:
case RG_WATER_TEMPLE_COMPASS:
case RG_SPIRIT_TEMPLE_COMPASS:
case RG_SHADOW_TEMPLE_COMPASS:
case RG_BOTTOM_OF_THE_WELL_COMPASS:
case RG_ICE_CAVERN_COMPASS:
return ctx->CheckDungeonItem(DUNGEON_COMPASS, Context::RandoGetToDungeonScene.at(itemName));
// Wallets
case RG_CHILD_WALLET:
return ctx->CheckRandoInf(RAND_INF_HAS_WALLET);
case RG_ADULT_WALLET:
return ctx->CurrentUpgrade(UPG_WALLET) >= 1;
case RG_GIANT_WALLET:
return ctx->CurrentUpgrade(UPG_WALLET) >= 2;
case RG_TYCOON_WALLET:
return ctx->CurrentUpgrade(UPG_WALLET) >= 3;
// Scales
case RG_BRONZE_SCALE:
return ctx->CheckRandoInf(RAND_INF_CAN_SWIM);
case RG_SILVER_SCALE:
return ctx->CurrentUpgrade(UPG_SCALE) >= 1;
case RG_GOLDEN_SCALE:
return ctx->CurrentUpgrade(UPG_SCALE) >= 2;
case RG_POCKET_EGG:
case RG_COJIRO:
case RG_ODD_MUSHROOM:
case RG_ODD_POTION:
case RG_POACHERS_SAW:
case RG_BROKEN_SWORD:
case RG_PRESCRIPTION:
case RG_EYEBALL_FROG:
case RG_EYEDROPS:
case RG_CLAIM_CHECK:
return ctx->HasAdultTrade(StaticData::RetrieveItem(itemName).GetGIEntry()->itemId);
}
SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", static_cast<uint32_t>(itemName));
assert(false);
return false;
} }
//Can the passed in item be used? //Can the passed in item be used?
@ -124,37 +260,62 @@ namespace Rando {
return IsChild;// || StickAsAdult; return IsChild;// || StickAsAdult;
case RG_DEKU_SHIELD: case RG_DEKU_SHIELD:
return IsChild;// || DekuShieldAsAdult; return IsChild;// || DekuShieldAsAdult;
case RG_WEIRD_EGG:
return IsChild;
case RG_RUTOS_LETTER:
return IsChild;
// Adult Trade
case RG_POCKET_EGG:
return IsAdult;
case RG_COJIRO:
return IsAdult;
case RG_ODD_MUSHROOM:
return IsAdult;
case RG_ODD_POTION:
return IsAdult;
case RG_POACHERS_SAW:
return IsAdult;
case RG_BROKEN_SWORD:
return IsAdult;
case RG_PRESCRIPTION:
return IsAdult;
case RG_EYEBALL_FROG:
return IsAdult;
case RG_EYEDROPS:
return IsAdult;
case RG_CLAIM_CHECK:
return IsAdult;
// Songs // Songs
case RG_ZELDAS_LULLABY: case RG_ZELDAS_LULLABY:
return Ocarina && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCUpButton; return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON);
case RG_EPONAS_SONG: case RG_EPONAS_SONG:
return Ocarina && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCUpButton; return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON);
case RG_SARIAS_SONG: case RG_SARIAS_SONG:
return Ocarina && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_SUNS_SONG: case RG_SUNS_SONG:
return Ocarina && OcarinaCRightButton && OcarinaCUpButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_SONG_OF_TIME: case RG_SONG_OF_TIME:
return Ocarina && OcarinaAButton && OcarinaCRightButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_SONG_OF_STORMS: case RG_SONG_OF_STORMS:
return Ocarina && OcarinaAButton && OcarinaCUpButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_MINUET_OF_FOREST: case RG_MINUET_OF_FOREST:
return Ocarina && OcarinaAButton && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCUpButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON);
case RG_BOLERO_OF_FIRE: case RG_BOLERO_OF_FIRE:
return Ocarina && OcarinaAButton && OcarinaCRightButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_SERENADE_OF_WATER: case RG_SERENADE_OF_WATER:
return Ocarina && OcarinaAButton && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_REQUIEM_OF_SPIRIT: case RG_REQUIEM_OF_SPIRIT:
return Ocarina && OcarinaAButton && OcarinaCRightButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_NOCTURNE_OF_SHADOW: case RG_NOCTURNE_OF_SHADOW:
return Ocarina && OcarinaAButton && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCDownButton; return Ocarina && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON);
case RG_PRELUDE_OF_LIGHT: case RG_PRELUDE_OF_LIGHT:
return Ocarina && OcarinaCLeftButton && OcarinaCRightButton && OcarinaCUpButton; return Ocarina && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON);
// Misc. Items // Misc. Items
// TODO: Once child wallet shuffle is added, this will need to be updated to account for the fishing pond entry fee.
case RG_FISHING_POLE: case RG_FISHING_POLE:
return true; // as long as you have enough rubies return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies
// Magic items // Magic items
default: default:
@ -171,31 +332,23 @@ namespace Rando {
} }
bool Logic::HasBossSoul(RandomizerGet itemName) { bool Logic::HasBossSoul(RandomizerGet itemName) {
auto ctx = Rando::Context::GetInstance();
if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) {
return true; return true;
} }
switch(itemName) { switch(itemName) {
case RG_GOHMA_SOUL: case RG_GOHMA_SOUL:
return CanSummonGohma;
case RG_KING_DODONGO_SOUL: case RG_KING_DODONGO_SOUL:
return CanSummonKingDodongo;
case RG_BARINADE_SOUL: case RG_BARINADE_SOUL:
return CanSummonBarinade;
case RG_PHANTOM_GANON_SOUL: case RG_PHANTOM_GANON_SOUL:
return CanSummonPhantomGanon;
case RG_VOLVAGIA_SOUL: case RG_VOLVAGIA_SOUL:
return CanSummonVolvagia;
case RG_MORPHA_SOUL: case RG_MORPHA_SOUL:
return CanSummonMorpha;
case RG_BONGO_BONGO_SOUL: case RG_BONGO_BONGO_SOUL:
return CanSummonBongoBongo;
case RG_TWINROVA_SOUL: case RG_TWINROVA_SOUL:
return CanSummonTwinrova; return HasItem(itemName);
case RG_GANON_SOUL: case RG_GANON_SOUL:
return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? CanSummonGanon : true; return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? HasItem(RG_GANON_SOUL) : true;
default: default:
break; return false;
} }
} }
@ -223,7 +376,7 @@ namespace Rando {
case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list
return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || (IsChild && (HasItem(RG_STICKS) || return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || (IsChild && (HasItem(RG_STICKS) ||
HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle || Nuts || Ocarina || HasItem(RG_LENS_OF_TRUTH) || HasExplosives || HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle || Nuts || Ocarina || HasItem(RG_LENS_OF_TRUTH) || HasExplosives ||
(MagicBean || MagicBeanPack) || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap; ctx->GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap;
} }
//Shouldn't be reached //Shouldn't be reached
@ -254,33 +407,116 @@ namespace Rando {
} }
uint8_t Logic::BottleCount() {
uint8_t count = 0;
for (int i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_4; i++) {
uint8_t item = ctx->GetSaveContext()->inventory.items[i];
if (item != ITEM_NONE && (item != ITEM_LETTER_RUTO || (item == ITEM_LETTER_RUTO && DeliverLetter)) && item != ITEM_BIG_POE) {
count++;
}
}
return count;
}
// Updates all logic helpers. Should be called whenever a non-helper is changed // Updates all logic helpers. Should be called whenever a non-helper is changed
void Logic::UpdateHelpers() { void Logic::UpdateHelpers() {
auto ctx = Rando::Context::GetInstance(); OcarinaButtons = (HasItem(RG_OCARINA_A_BUTTON) ? 1 : 0) +
OcarinaButtons = (OcarinaAButton ? 1 : 0) + (HasItem(RG_OCARINA_C_LEFT_BUTTON) ? 1 : 0) +
(OcarinaCLeftButton ? 1 : 0) + (HasItem(RG_OCARINA_C_RIGHT_BUTTON) ? 1 : 0) +
(OcarinaCRightButton ? 1 : 0) + (HasItem(RG_OCARINA_C_UP_BUTTON) ? 1 : 0) +
(OcarinaCUpButton ? 1 : 0) + (HasItem(RG_OCARINA_C_DOWN_BUTTON) ? 1 : 0);
(OcarinaCDownButton ? 1 : 0); ZeldasLetter = HasItem(RG_ZELDAS_LETTER);
NumBottles = ((NoBottles) ? 0 : (Bottles + ((DeliverLetter) ? 1 : 0))); WeirdEgg = CanUse(RG_WEIRD_EGG);
Bombchus = HasItem(RG_PROGRESSIVE_BOMBCHUS);
BuySeed = GetInLogic(LOGIC_BUY_SEED);
BuyArrow = GetInLogic(LOGIC_BUY_ARROW);
BuyBomb = GetInLogic(LOGIC_BUY_BOMB);
BuyMagicPotion = GetInLogic(LOGIC_BUY_MAGIC_POTION);
BuyBombchus = GetInLogic(LOGIC_BUY_BOMBCHUS);
MagicBean = ctx->GetAmmo(ITEM_BEAN) > 0;
RutosLetter = CanUse(RG_RUTOS_LETTER);
Boomerang = CanUse(RG_BOOMERANG);
DinsFire = CanUse(RG_DINS_FIRE);
FaroresWind = CanUse(RG_FARORES_WIND);
NayrusLove = CanUse(RG_NAYRUS_LOVE);
LensOfTruth = CanUse(RG_LENS_OF_TRUTH);
ShardOfAgony = HasItem(RG_STONE_OF_AGONY);
//SkullMask = false;
//MaskOfTruth = false;
//Adult logic
Hammer = CanUse(RG_MEGATON_HAMMER);
IronBoots = CanUse(RG_IRON_BOOTS);
HoverBoots = CanUse(RG_HOVER_BOOTS);
DekuShield = CanUse(RG_DEKU_SHIELD);
HylianShield = CanUse(RG_HYLIAN_SHIELD);
MirrorShield = CanUse(RG_MIRROR_SHIELD);
GoronTunic = CanUse(RG_GORON_TUNIC);
ZoraTunic = CanUse(RG_ZORA_TUNIC);
//Epona = false;
//BigPoe = false;
GerudoToken = HasItem(RG_GERUDO_MEMBERSHIP_CARD);
FireArrows = CanUse(RG_FIRE_ARROWS);
IceArrows = CanUse(RG_ICE_ARROWS);
LightArrows = CanUse(RG_LIGHT_ARROWS);
KokiriSword = CanUse(RG_KOKIRI_SWORD);
MasterSword = CanUse(RG_MASTER_SWORD);
BiggoronSword = CanUse(RG_MASTER_SWORD);
NumBottles = ((NoBottles) ? 0 : BottleCount());
HasBottle = NumBottles >= 1; HasBottle = NumBottles >= 1;
Slingshot = (ProgressiveBulletBag >= 1) && (BuySeed || AmmoCanDrop); Slingshot = CanUse(RG_FAIRY_SLINGSHOT) && (BuySeed || AmmoCanDrop);
Ocarina = ProgressiveOcarina >= 1; Ocarina = HasItem(RG_FAIRY_OCARINA);
OcarinaOfTime = ProgressiveOcarina >= 2; OcarinaOfTime = HasItem(RG_OCARINA_OF_TIME);
MagicMeter = (ProgressiveMagic >= 1) && (AmmoCanDrop || (HasBottle && BuyMagicPotion)); MagicMeter = HasItem(RG_MAGIC_SINGLE) && (AmmoCanDrop || (HasBottle && BuyMagicPotion));
BombBag = (ProgressiveBombBag >= 1) && (BuyBomb || AmmoCanDrop); BombBag = HasItem(RG_BOMB_BAG) && (BuyBomb || AmmoCanDrop);
Hookshot = ProgressiveHookshot >= 1; Hookshot = CanUse(RG_HOOKSHOT);
Longshot = ProgressiveHookshot >= 2; Longshot = CanUse(RG_LONGSHOT);
Bow = (ProgressiveBow >= 1) && (BuyArrow || AmmoCanDrop); Bow = CanUse(RG_FAIRY_BOW) && (BuyArrow || AmmoCanDrop);
GoronBracelet = ProgressiveStrength >= 1; GoronBracelet = HasItem(RG_GORONS_BRACELET);
SilverGauntlets = ProgressiveStrength >= 2; SilverGauntlets = HasItem(RG_SILVER_GAUNTLETS);
GoldenGauntlets = ProgressiveStrength >= 3; GoldenGauntlets = HasItem(RG_GOLDEN_GAUNTLETS);
Swim = ProgressiveScale >= 1; Swim = HasItem(RG_BRONZE_SCALE);
SilverScale = ProgressiveScale >= 2; SilverScale = HasItem(RG_SILVER_SCALE);
GoldScale = ProgressiveScale >= 3; GoldScale = HasItem(RG_GOLDEN_SCALE);
ChildsWallet = ProgressiveWallet >= 1; ChildsWallet = HasItem(RG_CHILD_WALLET);
AdultsWallet = ProgressiveWallet >= 2; AdultsWallet = HasItem(RG_ADULT_WALLET);
BiggoronSword = BiggoronSword || ProgressiveGiantKnife >= 2; BiggoronSword = HasItem(RG_BIGGORON_SWORD);
ProgressiveScale = ctx->CurrentUpgrade(UPG_SCALE) + HasItem(RG_BRONZE_SCALE);
ProgressiveWallet = ctx->CurrentUpgrade(UPG_WALLET) + HasItem(RG_CHILD_WALLET);
CanSummonGohma = HasBossSoul(RG_GOHMA_SOUL);
CanSummonKingDodongo = HasBossSoul(RG_KING_DODONGO_SOUL);
CanSummonBarinade = HasBossSoul(RG_BARINADE_SOUL);
CanSummonPhantomGanon = HasBossSoul(RG_PHANTOM_GANON_SOUL);
CanSummonVolvagia = HasBossSoul(RG_VOLVAGIA_SOUL);
CanSummonMorpha = HasBossSoul(RG_MORPHA_SOUL);
CanSummonBongoBongo = HasBossSoul(RG_BONGO_BONGO_SOUL);
CanSummonTwinrova = HasBossSoul(RG_TWINROVA_SOUL);
CanSummonGanon = HasBossSoul(RG_GANON_SOUL);
// Boss Keys
BossKeyForestTemple = HasItem(RG_FOREST_TEMPLE_BOSS_KEY);
BossKeyFireTemple = HasItem(RG_FIRE_TEMPLE_BOSS_KEY);
BossKeyWaterTemple = HasItem(RG_WATER_TEMPLE_BOSS_KEY);
BossKeySpiritTemple = HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);
BossKeyShadowTemple = HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);
BossKeyGanonsCastle = HasItem(RG_GANONS_CASTLE_BOSS_KEY);
KokiriEmerald = HasItem(RG_KOKIRI_EMERALD);
GoronRuby = HasItem(RG_GORON_RUBY);
ZoraSapphire = HasItem(RG_ZORA_SAPPHIRE);
ForestMedallion = HasItem(RG_FOREST_MEDALLION);
FireMedallion = HasItem(RG_FIRE_MEDALLION);
WaterMedallion = HasItem(RG_WATER_MEDALLION);
SpiritMedallion = HasItem(RG_SPIRIT_MEDALLION);
ShadowMedallion = HasItem(RG_SHADOW_MEDALLION);
LightMedallion = HasItem(RG_LIGHT_MEDALLION);
DoubleDefense = HasItem(RG_DOUBLE_DEFENSE);
TriforcePieces = ctx->GetSaveContext()->triforcePiecesCollected;
Greg = HasItem(RG_GREG_RUPEE);
GoldSkulltulaTokens = ctx->GetGSCount();
//you need at least 2 buttons for scarecrow song //you need at least 2 buttons for scarecrow song
ScarecrowSong = ScarecrowSong || (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && Ocarina && OcarinaButtons >= 2) || (ChildScarecrow && AdultScarecrow); ScarecrowSong = ScarecrowSong || (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && Ocarina && OcarinaButtons >= 2) || (ChildScarecrow && AdultScarecrow);
@ -290,21 +526,22 @@ namespace Rando {
//Drop Access //Drop Access
DekuStickDrop = StickPot || DekuBabaSticks; DekuStickDrop = StickPot || DekuBabaSticks;
DekuNutDrop = (NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop; DekuNutDrop = (NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop;
BugsAccess = BugShrub || WanderingBugs || BugRock; BugsAccess = BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS);
FishAccess = LoneFish || FishGroup; FishAccess = LoneFish || FishGroup || GetInLogic(LOGIC_FISH_ACCESS);
FairyAccess = FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond; FairyAccess = FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS);
//refills //refills
Bombs = BombBag; Bombs = HasItem(RG_PROGRESSIVE_BOMB_BAG);
Nuts = (ProgressiveNutBag != 0 && DekuNutDrop) || Nuts; Nuts = DekuNutDrop || HasItem(RG_NUTS);
Sticks = (ProgressiveStickBag != 0 && DekuStickDrop) || Sticks; Sticks = DekuStickDrop || HasItem(RG_STICKS);
Bugs = HasBottle && BugsAccess; Bugs = HasBottle && BugsAccess;
BlueFireAccess = BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS);
BlueFire = (HasBottle && BlueFireAccess) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); BlueFire = (HasBottle && BlueFireAccess) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS));
Fish = HasBottle && FishAccess; Fish = HasBottle && FishAccess;
Fairy = HasBottle && FairyAccess; Fairy = HasBottle && FairyAccess;
FoundBombchus = (BombchuDrop || Bombchus || Bombchus5 || Bombchus10 || Bombchus20) && (BombBag || ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)); FoundBombchus = Bombchus && (BombBag || ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC));
CanPlayBowling = ChildsWallet && ((ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && FoundBombchus) || (!ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && BombBag)); CanPlayBowling = ChildsWallet && ((ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && FoundBombchus) || (!ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && BombBag));
// TODO: Implement Ammo Drop Setting in place of bombchu drops // TODO: Implement Ammo Drop Setting in place of bombchu drops
HasBombchus = (BuyBombchus || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/) && FoundBombchus)); HasBombchus = (BuyBombchus || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/) && FoundBombchus));
@ -314,15 +551,16 @@ namespace Rando {
HasBoots = IronBoots || HoverBoots; HasBoots = IronBoots || HoverBoots;
//Unshuffled adult trade quest //Unshuffled adult trade quest
Eyedrops = Eyedrops || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && ClaimCheck); ClaimCheck = CanUse(RG_CLAIM_CHECK);
EyeballFrog = EyeballFrog || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Eyedrops); Eyedrops = CanUse(RG_EYEDROPS) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && ClaimCheck);
Prescription = Prescription || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && EyeballFrog); EyeballFrog = CanUse(RG_EYEBALL_FROG) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Eyedrops);
BrokenSword = BrokenSword || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Prescription); Prescription = CanUse(RG_PRESCRIPTION) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && EyeballFrog);
PoachersSaw = PoachersSaw || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && BrokenSword); BrokenSword = CanUse(RG_BROKEN_SWORD) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Prescription);
OddPoultice = OddPoultice || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && PoachersSaw); PoachersSaw = CanUse(RG_POACHERS_SAW) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && BrokenSword);
OddMushroom = OddMushroom || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && OddPoultice); OddPoultice = CanUse(RG_ODD_POTION) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && PoachersSaw);
Cojiro = Cojiro || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && OddMushroom); OddMushroom = CanUse(RG_ODD_MUSHROOM) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && OddPoultice);
PocketEgg = PocketEgg || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Cojiro); Cojiro = CanUse(RG_COJIRO) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && OddMushroom);
PocketEgg = CanUse(RG_POCKET_EGG) || (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && Cojiro);
// IsChild = Age == AGE_CHILD; // IsChild = Age == AGE_CHILD;
// IsAdult = Age == AGE_ADULT; // IsAdult = Age == AGE_ADULT;
@ -340,7 +578,7 @@ namespace Rando {
CanRideEpona = IsAdult && Epona && CanUse(RG_EPONAS_SONG); CanRideEpona = IsAdult && Epona && CanUse(RG_EPONAS_SONG);
CanSummonGossipFairyWithoutSuns = CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); CanSummonGossipFairyWithoutSuns = CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME);
CanSummonGossipFairy = CanSummonGossipFairyWithoutSuns || CanUse(RG_SUNS_SONG); CanSummonGossipFairy = CanSummonGossipFairyWithoutSuns || CanUse(RG_SUNS_SONG);
Hearts = BaseHearts + HeartContainer + (PieceOfHeart >> 2); Hearts = ctx->GetSaveContext()->healthCapacity / 16;
EffectiveHealth = ((Hearts << (2 + DoubleDefense)) >> Multiplier) + ((Hearts << (2 + DoubleDefense)) % (1 << Multiplier) > 0); //Number of half heart hits to die, ranges from 1 to 160 EffectiveHealth = ((Hearts << (2 + DoubleDefense)) >> Multiplier) + ((Hearts << (2 + DoubleDefense)) % (1 << Multiplier) > 0); //Number of half heart hits to die, ranges from 1 to 160
FireTimer = CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0; FireTimer = CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0;
WaterTimer = CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0; WaterTimer = CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts * 8) : 0;
@ -348,14 +586,13 @@ namespace Rando {
CanSurviveDamage = !NeedNayrusLove || CanUse(RG_NAYRUS_LOVE); CanSurviveDamage = !NeedNayrusLove || CanUse(RG_NAYRUS_LOVE);
CanTakeDamage = Fairy || CanSurviveDamage; CanTakeDamage = Fairy || CanSurviveDamage;
CanTakeDamageTwice = (Fairy && NumBottles >= 2) || ((EffectiveHealth == 2) && (CanUse(RG_NAYRUS_LOVE) || Fairy)) || (EffectiveHealth > 2); CanTakeDamageTwice = (Fairy && NumBottles >= 2) || ((EffectiveHealth == 2) && (CanUse(RG_NAYRUS_LOVE) || Fairy)) || (EffectiveHealth > 2);
//CanPlantBean = IsChild && (MagicBean || MagicBeanPack);
CanOpenBombGrotto = CanBlastOrSmash && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); CanOpenBombGrotto = CanBlastOrSmash && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY));
CanOpenStormGrotto = CanUse(RG_SONG_OF_STORMS) && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); CanOpenStormGrotto = CanUse(RG_SONG_OF_STORMS) && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY));
HookshotOrBoomerang = CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); HookshotOrBoomerang = CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG);
CanGetNightTimeGS = (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); CanGetNightTimeGS = (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG));
CanBreakUpperBeehives = HookshotOrBoomerang || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && HasBombchus); CanBreakUpperBeehives = HookshotOrBoomerang || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && HasBombchus);
CanBreakLowerBeehives = CanBreakUpperBeehives || Bombs; CanBreakLowerBeehives = CanBreakUpperBeehives || Bombs;
CanFish = ChildsWallet && (CanUse(RG_FISHING_POLE) || !ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)); CanFish = ChildsWallet && (HasItem(RG_FISHING_POLE) || !ctx->GetOption(RSK_SHUFFLE_FISHING_POLE));
CanGetChildFish = CanFish && (IsChild || (IsAdult && !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))); CanGetChildFish = CanFish && (IsChild || (IsAdult && !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)));
CanGetAdultFish = CanFish && IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT); CanGetAdultFish = CanFish && IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT);
@ -365,8 +602,8 @@ namespace Rando {
HasFireSourceWithTorch = HasFireSource || CanUse(RG_STICKS); HasFireSourceWithTorch = HasFireSource || CanUse(RG_STICKS);
//Gerudo Fortress //Gerudo Fortress
CanFinishGerudoFortress = (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && GerudoFortressKeys >= 4 && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (GerudoToken || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || CanFinishGerudoFortress = (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (GerudoToken || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) ||
(ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && GerudoFortressKeys >= 1 && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) || (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) ||
(ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_NORMAL) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_FAST)); (ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_NORMAL) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_FAST));
HasShield = CanUse(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); //Mirror shield can't reflect attacks HasShield = CanUse(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); //Mirror shield can't reflect attacks
@ -411,7 +648,7 @@ namespace Rando {
} }
bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) { bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) {
if (SkeletonKey) { if (HasItem(RG_SKELETON_KEY)) {
return true; return true;
} }
switch (dungeon) { switch (dungeon) {
@ -420,55 +657,58 @@ namespace Rando {
(GetDifficultyValueFromString(GlitchHover) >= static_cast<uint8_t>(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE)))) { (GetDifficultyValueFromString(GlitchHover) >= static_cast<uint8_t>(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE)))) {
return ForestTempleKeys >= requiredAmountGlitched; return ForestTempleKeys >= requiredAmountGlitched;
}*/ }*/
return ForestTempleKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_FOREST_TEMPLE) >= requiredAmountGlitchless;
case RR_FIRE_TEMPLE: case RR_FIRE_TEMPLE:
/*if (IsGlitched && (GetDifficultyValueFromString(GlitchLedgeClip) >= static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >= static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE))) { /*if (IsGlitched && (GetDifficultyValueFromString(GlitchLedgeClip) >= static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >= static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE))) {
return FireTempleKeys >= requiredAmountGlitched; return FireTempleKeys >= requiredAmountGlitched;
}*/ }*/
return FireTempleKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless;
case RR_WATER_TEMPLE: case RR_WATER_TEMPLE:
/*if (IsGlitched && (false)) { /*if (IsGlitched && (false)) {
return WaterTempleKeys >= requiredAmountGlitched; return WaterTempleKeys >= requiredAmountGlitched;
}*/ }*/
return WaterTempleKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_WATER_TEMPLE) >= requiredAmountGlitchless;
case RR_SPIRIT_TEMPLE: case RR_SPIRIT_TEMPLE:
/*if (IsGlitched && (false)) { /*if (IsGlitched && (false)) {
return SpiritTempleKeys >= requiredAmountGlitched; return SpiritTempleKeys >= requiredAmountGlitched;
}*/ }*/
return SpiritTempleKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_SPIRIT_TEMPLE) >= requiredAmountGlitchless;
case RR_SHADOW_TEMPLE: case RR_SHADOW_TEMPLE:
/*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= static_cast<uint8_t>(GlitchDifficulty::NOVICE))) { /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= static_cast<uint8_t>(GlitchDifficulty::NOVICE))) {
return ShadowTempleKeys >= requiredAmountGlitched; return ShadowTempleKeys >= requiredAmountGlitched;
}*/ }*/
return ShadowTempleKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_SHADOW_TEMPLE) >= requiredAmountGlitchless;
case RR_BOTTOM_OF_THE_WELL: case RR_BOTTOM_OF_THE_WELL:
/*if (IsGlitched && (false)) { /*if (IsGlitched && (false)) {
return BottomOfTheWellKeys >= requiredAmountGlitched; return BottomOfTheWellKeys >= requiredAmountGlitched;
}*/ }*/
return BottomOfTheWellKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless;
case RR_GERUDO_TRAINING_GROUNDS: case RR_GERUDO_TRAINING_GROUNDS:
/*if (IsGlitched && (false)) { /*if (IsGlitched && (false)) {
return GerudoTrainingGroundsKeys >= requiredAmountGlitched; return GerudoTrainingGroundsKeys >= requiredAmountGlitched;
}*/ }*/
return GerudoTrainingGroundsKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_GERUDO_TRAINING_GROUND) >= requiredAmountGlitchless;
case RR_GANONS_CASTLE: case RR_GANONS_CASTLE:
/*if (IsGlitched && (false)) { /*if (IsGlitched && (false)) {
return GanonsCastleKeys >= requiredAmountGlitched; return GanonsCastleKeys >= requiredAmountGlitched;
}*/ }*/
return GanonsCastleKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_INSIDE_GANONS_CASTLE) >= requiredAmountGlitchless;
case RR_MARKET_TREASURE_CHEST_GAME: case RR_MARKET_TREASURE_CHEST_GAME:
/*if (IsGlitched && (false)) { /*if (IsGlitched && (false)) {
return TreasureGameKeys >= requiredAmountGlitched; return TreasureGameKeys >= requiredAmountGlitched;
}*/ }*/
return TreasureGameKeys >= requiredAmountGlitchless; return ctx->GetSmallKeyCount(SCENE_TREASURE_BOX_SHOP) >= requiredAmountGlitchless;
case RR_GERUDO_FORTRESS:
return ctx->GetSmallKeyCount(SCENE_THIEVES_HIDEOUT) >= requiredAmountGlitchless;
default: default:
return false; return false;
@ -504,8 +744,21 @@ namespace Rando {
return false; return false;
} }
void Logic::SetContext(std::shared_ptr<Context> _ctx) {
ctx = _ctx;
}
bool Logic::GetInLogic(LogicVal logicVal) {
return inLogic[logicVal];
}
void Logic::SetInLogic(LogicVal logicVal, bool value) {
inLogic[logicVal] = value;
}
void Logic::Reset() { void Logic::Reset() {
auto ctx = Rando::Context::GetInstance(); ctx->NewSaveContext();
memset(inLogic, false, sizeof(inLogic));
//Settings-dependent variables //Settings-dependent variables
IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) ||
ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) ||
@ -522,7 +775,6 @@ namespace Rando {
Bombchus10 = false; Bombchus10 = false;
Bombchus20 = false; Bombchus20 = false;
MagicBean = false; MagicBean = false;
MagicBeanPack = false;
RutosLetter = false; RutosLetter = false;
Boomerang = false; Boomerang = false;
DinsFire = false; DinsFire = false;
@ -541,7 +793,7 @@ namespace Rando {
GoronTunic = false; GoronTunic = false;
ZoraTunic = false; ZoraTunic = false;
Epona = false; Epona = false;
BigPoe = false; //BigPoe = false;
GerudoToken = false; GerudoToken = false;
FireArrows = false; FireArrows = false;
IceArrows = false; IceArrows = false;
@ -573,20 +825,6 @@ namespace Rando {
EyedropsAccess = false; EyedropsAccess = false;
DisableTradeRevert = false; DisableTradeRevert = false;
//Songs
ZeldasLullaby = false;
SariasSong = false;
SunsSong = false;
SongOfStorms = false;
EponasSong = false;
SongOfTime = false;
MinuetOfForest = false;
BoleroOfFire = false;
SerenadeOfWater = false;
RequiemOfSpirit = false;
NocturneOfShadow = false;
PreludeOfLight = false;
//Stones and Meddallions //Stones and Meddallions
ForestMedallion = false; ForestMedallion = false;
FireMedallion = false; FireMedallion = false;
@ -622,40 +860,41 @@ namespace Rando {
GregInLacsLogic = false; GregInLacsLogic = false;
//Ocarina C Buttons //Ocarina C Buttons
OcarinaAButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1; bool ocBtnShuffle = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true);
OcarinaCLeftButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1; ctx->SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle);
OcarinaCRightButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1; ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle);
OcarinaCUpButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1; ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle);
OcarinaCDownButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1; ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle);
ctx->SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle);
//Progressive Items //Progressive Items
ProgressiveStickBag = ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1; ctx->SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1);
ProgressiveNutBag = ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1; ctx->SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1);
ProgressiveBulletBag = 0; ProgressiveBulletBag = 0;
ProgressiveBombBag = 0; ProgressiveBombBag = 0;
ProgressiveMagic = 0; ProgressiveMagic = 0;
//If we're not shuffling swim, we start with it (scale 1) //If we're not shuffling swim, we start with it (scale 1)
ProgressiveScale = ctx->GetOption(RSK_SHUFFLE_SWIM).Is(true) ? 0 : 1; ProgressiveScale = 0;
if (ctx->GetOption(RSK_SHUFFLE_SWIM).Is(false)) {
ProgressiveScale = 1;
ctx->SetRandoInf(RAND_INF_CAN_SWIM, true);
}
ProgressiveHookshot = 0; ProgressiveHookshot = 0;
ProgressiveBow = 0; ProgressiveBow = 0;
//If we're not shuffling child's wallet, we start with it (wallet 1) //If we're not shuffling child's wallet, we start with it (wallet 1)
ProgressiveWallet = ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(true) ? 0 : 1; ProgressiveWallet = 0;
if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) {
ProgressiveWallet = 1;
ctx->SetRandoInf(RAND_INF_HAS_WALLET, true);
}
ProgressiveStrength = 0; ProgressiveStrength = 0;
ProgressiveOcarina = 0; ProgressiveOcarina = 0;
ProgressiveGiantKnife = 0; ProgressiveGiantKnife = 0;
//Keys
ForestTempleKeys = 0;
//If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla FiT //If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla FiT
FireTempleKeys = IsKeysanity || ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ() ? 0 : 1; if (!IsKeysanity && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) {
WaterTempleKeys = 0; ctx->SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1);
SpiritTempleKeys = 0; }
ShadowTempleKeys = 0;
GanonsCastleKeys = 0;
GerudoFortressKeys = 0;
GerudoTrainingGroundsKeys = 0;
BottomOfTheWellKeys = 0;
TreasureGameKeys = 0;
//Boss Keys //Boss Keys
BossKeyForestTemple = 0; BossKeyForestTemple = 0;
@ -676,9 +915,6 @@ namespace Rando {
//Triforce Pieces //Triforce Pieces
TriforcePieces = 0; TriforcePieces = 0;
//Skeleton Key
SkeletonKey = false;
//Boss Souls //Boss Souls
CanSummonGohma = false; CanSummonGohma = false;
CanSummonKingDodongo = false; CanSummonKingDodongo = false;
@ -830,6 +1066,7 @@ namespace Rando {
AtDay = false; AtDay = false;
AtNight = false; AtNight = false;
Age = ctx->GetSettings()->ResolvedStartingAge(); Age = ctx->GetSettings()->ResolvedStartingAge();
ctx->GetSaveContext()->linkAge = !Age;
//Events //Events
ShowedMidoSwordAndShield = false; ShowedMidoSwordAndShield = false;

View File

@ -40,7 +40,6 @@ class Logic {
bool Bombchus10 = false; bool Bombchus10 = false;
bool Bombchus20 = false; bool Bombchus20 = false;
bool MagicBean = false; bool MagicBean = false;
bool MagicBeanPack = false;
bool RutosLetter = false; bool RutosLetter = false;
bool Boomerang = false; bool Boomerang = false;
bool DinsFire = false; bool DinsFire = false;
@ -59,7 +58,7 @@ class Logic {
bool GoronTunic = false; bool GoronTunic = false;
bool ZoraTunic = false; bool ZoraTunic = false;
bool Epona = false; bool Epona = false;
bool BigPoe = false; //bool BigPoe = false; //unused
bool GerudoToken = false; bool GerudoToken = false;
bool FireArrows = false; bool FireArrows = false;
bool IceArrows = false; bool IceArrows = false;
@ -91,20 +90,6 @@ class Logic {
bool EyedropsAccess = false; bool EyedropsAccess = false;
bool DisableTradeRevert = false; bool DisableTradeRevert = false;
// Songs
bool ZeldasLullaby = false;
bool SariasSong = false;
bool SunsSong = false;
bool SongOfStorms = false;
bool EponasSong = false;
bool SongOfTime = false;
bool MinuetOfForest = false;
bool BoleroOfFire = false;
bool SerenadeOfWater = false;
bool RequiemOfSpirit = false;
bool NocturneOfShadow = false;
bool PreludeOfLight = false;
// Stones and Meddallions // Stones and Meddallions
bool ForestMedallion = false; bool ForestMedallion = false;
bool FireMedallion = false; bool FireMedallion = false;
@ -140,8 +125,6 @@ class Logic {
bool GregInLacsLogic = false; bool GregInLacsLogic = false;
// Progressive Items // Progressive Items
uint8_t ProgressiveStickBag = 0;
uint8_t ProgressiveNutBag = 0;
uint8_t ProgressiveBulletBag = 0; uint8_t ProgressiveBulletBag = 0;
uint8_t ProgressiveBombBag = 0; uint8_t ProgressiveBombBag = 0;
uint8_t ProgressiveMagic = 0; uint8_t ProgressiveMagic = 0;
@ -171,9 +154,6 @@ class Logic {
// Triforce Pieces // Triforce Pieces
uint8_t TriforcePieces = 0; uint8_t TriforcePieces = 0;
// Skeleton Key
bool SkeletonKey = false;
// Boss Keys // Boss Keys
bool BossKeyForestTemple = false; bool BossKeyForestTemple = false;
bool BossKeyFireTemple = false; bool BossKeyFireTemple = false;
@ -422,6 +402,7 @@ class Logic {
void UpdateHelpers(); void UpdateHelpers();
bool CanUse(RandomizerGet itemName); bool CanUse(RandomizerGet itemName);
bool HasProjectile(HasProjectileAge age); bool HasProjectile(HasProjectileAge age);
bool HasItem(RandomizerGet itemName);
bool HasBossSoul(RandomizerGet itemName); bool HasBossSoul(RandomizerGet itemName);
bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount);
bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched);
@ -430,11 +411,16 @@ class Logic {
bool CanKillEnemy(std::string enemy); bool CanKillEnemy(std::string enemy);
bool CanPassEnemy(std::string enemy); bool CanPassEnemy(std::string enemy);
bool EventsUpdated(); bool EventsUpdated();
uint8_t BottleCount();
void Reset(); void Reset();
void SetContext(std::shared_ptr<Context> _ctx);
bool GetInLogic(LogicVal logicVal);
void SetInLogic(LogicVal logicVal, bool remove);
private: private:
static bool IsMagicItem(RandomizerGet item); static bool IsMagicItem(RandomizerGet item);
static bool IsMagicArrow(RandomizerGet item); static bool IsMagicArrow(RandomizerGet item);
bool HasItem(RandomizerGet itemName); std::shared_ptr<Context> ctx;
bool inLogic[LOGIC_MAX];
}; // class Logic }; // class Logic
} // namespace Rando } // namespace Rando

View File

@ -53,6 +53,156 @@ typedef enum {
HINT_TYPE_MAX HINT_TYPE_MAX
} HintType; } HintType;
typedef enum {
LOGIC_NONE,
LOGIC_KOKIRI_SWORD,
LOGIC_MASTER_SWORD,
LOGIC_BIGGORON_SWORD,
LOGIC_DEKU_SHIELD,
LOGIC_HYLIAN_SHIELD,
LOGIC_MIRROR_SHIELD,
LOGIC_GORON_TUNIC,
LOGIC_ZORA_TUNIC,
LOGIC_IRON_BOOTS,
LOGIC_HOVER_BOOTS,
LOGIC_BOOMERANG,
LOGIC_LENS_OF_TRUTH,
LOGIC_HAMMER,
LOGIC_STONE_OF_AGONY,
LOGIC_DINS_FIRE,
LOGIC_FARORES_WIND,
LOGIC_NAYRUS_LOVE,
LOGIC_FIRE_ARROWS,
LOGIC_ICE_ARROWS,
LOGIC_LIGHT_ARROWS,
LOGIC_GERUDO_CARD,
LOGIC_MAGIC_BEAN,
LOGIC_MAGIC_BEANPACK,
LOGIC_DOUBLE_DEFENSE,
LOGIC_WEIRD_EGG,
LOGIC_ZELDAS_LETTER,
LOGIC_POCKET_EGG,
LOGIC_COJIRO,
LOGIC_ODD_MUSHROOM,
LOGIC_ODD_POULTICE,
LOGIC_POACHERS_SAW,
LOGIC_BROKEN_SWORD,
LOGIC_PRESCRIPTION,
LOGIC_EYEBALL_FROG,
LOGIC_EYEDROPS,
LOGIC_CLAIM_CHECK,
LOGIC_GOLD_SKULLTULA_TOKENS,
LOGIC_PROGRESSIVE_HOOKSHOT,
LOGIC_PROGRESSIVE_STRENGTH,
LOGIC_PROGRESSIVE_BOMB_BAG,
LOGIC_PROGRESSIVE_BOW,
LOGIC_PROGRESSIVE_BULLET_BAG,
LOGIC_PROGRESSIVE_STICK_BAG,
LOGIC_PROGRESSIVE_NUT_BAG,
LOGIC_PROGRESSIVE_WALLET,
LOGIC_PROGRESSIVE_SCALE,
LOGIC_BOMBCHUS,
LOGIC_PROGRESSIVE_MAGIC,
LOGIC_PROGRESSIVE_OCARINA,
LOGIC_PROGRESSIVE_GIANT_KNIFE,
LOGIC_BOTTLES,
LOGIC_RUTOS_LETTER,
LOGIC_BOTTLE_WITH_BIG_POE,
LOGIC_ZELDAS_LULLABY,
LOGIC_EPONAS_SONG,
LOGIC_SARIAS_SONG,
LOGIC_SUNS_SONG,
LOGIC_SONG_OF_TIME,
LOGIC_SONG_OF_STORMS,
LOGIC_MINUET_OF_FOREST,
LOGIC_BOLERO_OF_FIRE,
LOGIC_SERENADE_OF_WATER,
LOGIC_NOCTURNE_OF_SHADOW,
LOGIC_REQUIEM_OF_SPIRIT,
LOGIC_PRELUDE_OF_LIGHT,
LOGIC_MAP_DEKU_TREE,
LOGIC_MAP_DODONGOS_CAVERN,
LOGIC_MAP_JABU_JABUS_BELLY,
LOGIC_MAP_FOREST_TEMPLE,
LOGIC_MAP_FIRE_TEMPLE,
LOGIC_MAP_WATER_TEMPLE,
LOGIC_MAP_SPIRIT_TEMPLE,
LOGIC_MAP_SHADOW_TEMPLE,
LOGIC_MAP_BOTTOM_OF_THE_WELL,
LOGIC_MAP_ICE_CAVERN,
LOGIC_COMPASS_DEKU_TREE,
LOGIC_COMPASS_DODONGOS_CAVERN,
LOGIC_COMPASS_JABU_JABUS_BELLY,
LOGIC_COMPASS_FOREST_TEMPLE,
LOGIC_COMPASS_FIRE_TEMPLE,
LOGIC_COMPASS_WATER_TEMPLE,
LOGIC_COMPASS_SPIRIT_TEMPLE,
LOGIC_COMPASS_SHADOW_TEMPLE,
LOGIC_COMPASS_BOTTOM_OF_THE_WELL,
LOGIC_COMPASS_ICE_CAVERN,
LOGIC_BOSS_KEY_FOREST_TEMPLE,
LOGIC_BOSS_KEY_FIRE_TEMPLE,
LOGIC_BOSS_KEY_WATER_TEMPLE,
LOGIC_BOSS_KEY_SPIRIT_TEMPLE,
LOGIC_BOSS_KEY_SHADOW_TEMPLE,
LOGIC_BOSS_KEY_GANONS_CASTLE,
LOGIC_FOREST_TEMPLE_KEYS,
LOGIC_FIRE_TEMPLE_KEYS,
LOGIC_WATER_TEMPLE_KEYS,
LOGIC_SPIRIT_TEMPLE_KEYS,
LOGIC_SHADOW_TEMPLE_KEYS,
LOGIC_BOTTOM_OF_THE_WELL_KEYS,
LOGIC_GERUDO_TRAINING_GROUNDS_KEYS,
LOGIC_GERUDO_FORTRESS_KEYS,
LOGIC_GANONS_CASTLE_KEYS,
LOGIC_TREASURE_GAME_KEYS,
LOGIC_SKELETON_KEY,
LOGIC_KOKIRI_EMERALD,
LOGIC_GORON_RUBY,
LOGIC_ZORA_SAPPHIRE,
LOGIC_FOREST_MEDALLION,
LOGIC_FIRE_MEDALLION,
LOGIC_WATER_MEDALLION,
LOGIC_SPIRIT_MEDALLION,
LOGIC_SHADOW_MEDALLION,
LOGIC_LIGHT_MEDALLION,
LOGIC_GREG,
LOGIC_PIECE_OF_HEART,
LOGIC_HEART_CONTAINER,
LOGIC_BOMBCHUS_5,
LOGIC_BOMBCHUS_10,
LOGIC_BOMBCHUS_20,
LOGIC_BOMBCHU_DROP,
LOGIC_NUTS,
LOGIC_BUY_ARROW,
LOGIC_BUY_BOMB,
LOGIC_STICKS,
LOGIC_FISH_ACCESS,
LOGIC_BUY_MAGIC_POTION,
LOGIC_BUY_BOMBCHUS,
LOGIC_BUY_SEED,
LOGIC_BLUE_FIRE_ACCESS,
LOGIC_BUGS_ACCESS,
LOGIC_FAIRY_ACCESS,
LOGIC_CAN_SUMMON_GOHMA,
LOGIC_CAN_SUMMON_KINGDODONGO,
LOGIC_CAN_SUMMON_BARINADE,
LOGIC_CAN_SUMMON_PHANTOMGANON,
LOGIC_CAN_SUMMON_VOLVAGIA,
LOGIC_CAN_SUMMON_MORPHA,
LOGIC_CAN_SUMMON_BONGOBONGO,
LOGIC_CAN_SUMMON_TWINROVA,
LOGIC_CAN_SUMMON_GANON,
LOGIC_FISHING_POLE,
LOGIC_OCARINA_A_BUTTON,
LOGIC_OCARINA_C_UP_BUTTON,
LOGIC_OCARINA_C_DOWN_BUTTON,
LOGIC_OCARINA_C_LEFT_BUTTON,
LOGIC_OCARINA_C_RIGHT_BUTTON,
LOGIC_TRIFORCE_PIECES,
LOGIC_MAX
} LogicVal;
typedef enum { typedef enum {
RA_NONE, RA_NONE,
RA_LINKS_POCKET, RA_LINKS_POCKET,
@ -2024,6 +2174,7 @@ typedef enum {
// Logic Only // Logic Only
RG_DISTANT_SCARECROW, RG_DISTANT_SCARECROW,
RG_STICKS, RG_STICKS,
RG_NUTS,
RG_MAX RG_MAX
} RandomizerGet; } RandomizerGet;

View File

@ -295,6 +295,17 @@ typedef enum {
RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS, RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS,
RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN, RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN,
RAND_INF_ZELDAS_LETTER,
RAND_INF_WEIRD_EGG,
RAND_INF_CHILD_TRADES_MASK_KEATON,
RAND_INF_CHILD_TRADES_MASK_SKULL,
RAND_INF_CHILD_TRADES_MASK_SPOOKY,
RAND_INF_CHILD_TRADES_MASK_BUNNY,
RAND_INF_CHILD_TRADES_MASK_GORON,
RAND_INF_CHILD_TRADES_MASK_ZORA,
RAND_INF_CHILD_TRADES_MASK_GERUDO,
RAND_INF_CHILD_TRADES_MASK_TRUTH,
// If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16)
RAND_INF_MAX, RAND_INF_MAX,

View File

@ -2843,8 +2843,9 @@ extern "C" void Save_SaveGlobal(void) {
extern "C" void Save_LoadFile(void) { extern "C" void Save_LoadFile(void) {
if (gSaveContext.questId == QUEST_RANDOMIZER) { if (gSaveContext.questId == QUEST_RANDOMIZER) {
// Reset rando context for rando saves. // Reset rando context for rando saves.
OTRGlobals::Instance->gRandoContext.reset(); OTRGlobals::Instance->gRandoContext.reset();
OTRGlobals::Instance->gRandoContext = Rando::Context::CreateInstance(); OTRGlobals::Instance->gRandoContext = Rando::Context::CreateInstance();
OTRGlobals::Instance->gRandoContext->SetSaveContext(&gSaveContext);
OTRGlobals::Instance->gRandoContext->AddExcludedOptions(); OTRGlobals::Instance->gRandoContext->AddExcludedOptions();
OTRGlobals::Instance->gRandoContext->GetSettings()->CreateOptions(); OTRGlobals::Instance->gRandoContext->GetSettings()->CreateOptions();
} }