SCL Consolidation, Area -> Region (#4356)

* Move all `SaveContext` operations to `Logic` to prepare for encapsulation.

* Rename `Area` to `Region`, `areaTable` to `regionTable`, and all local variables named variants of area to region that were of the `RandomizerRegion` or `Region` types.

* Fix mistaken renames.

* Rename PT_AREA_RESET to PT_REGION_RESET after rebasing on performance timer commit.
Change include path for the timer to absolute rather than relative.
This commit is contained in:
Malkierian 2024-09-23 17:10:29 -07:00 committed by GitHub
commit 0f02201108
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 1554 additions and 1559 deletions

View file

@ -395,498 +395,6 @@ void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
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:
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:
SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU));
break;
}
} break;
}
mLogic->UpdateHelpers();
}
std::shared_ptr<Settings> Context::GetSettings() {
return mSettings;
}
@ -914,173 +422,6 @@ std::shared_ptr<Logic> Context::GetLogic() {
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() {
NewSaveContext();
mLogic->Reset();
}
std::shared_ptr<Trials> Context::GetTrials() {
return mTrials;
}
@ -1105,121 +446,4 @@ TrickOption& Context::GetTrickOption(const RandomizerTrick key) const {
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