Merge branch 'develop' into merge-develop

# Conflicts:
#	soh/soh/Enhancements/custom-message/CustomMessageTypes.h
#	soh/soh/Enhancements/debugger/debugSaveEditor.h
#	soh/soh/Enhancements/item-tables/ItemTableTypes.h
#	soh/soh/Enhancements/mods.cpp
#	soh/soh/Enhancements/randomizer/3drando/entrance.cpp
#	soh/soh/Enhancements/randomizer/3drando/item_location.cpp
#	soh/soh/Enhancements/randomizer/3drando/keys.hpp
#	soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp
#	soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp
#	soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp
#	soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp
#	soh/soh/Enhancements/randomizer/3drando/menu.cpp
#	soh/soh/Enhancements/randomizer/3drando/playthrough.cpp
#	soh/soh/Enhancements/randomizer/3drando/settings.cpp
#	soh/soh/Enhancements/randomizer/3drando/settings.hpp
#	soh/soh/Enhancements/randomizer/randomizer.cpp
#	soh/soh/Enhancements/randomizer/randomizerTypes.h
#	soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp
#	soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
#	soh/soh/Enhancements/randomizer/randomizer_entrance.c
#	soh/soh/OTRGlobals.cpp
#	soh/src/code/z_sram.c
#	soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
This commit is contained in:
Christopher Leggett 2023-12-10 12:49:15 -05:00
commit d58968d196
No known key found for this signature in database
GPG key ID: 7093AE5FF7037D79
777 changed files with 25309 additions and 19999 deletions

View file

@ -76,7 +76,6 @@ bool showLinksPocket;
bool fortressFast;
bool fortressNormal;
bool bypassRandoCheck = true;
// persistent during gameplay
bool initialized;
bool doAreaScroll;
@ -84,14 +83,6 @@ bool previousShowHidden = false;
bool hideShopRightChecks = true;
bool hideTriforceCompleted = true;
bool checkCollected = false;
int checkLoops = 0;
int checkCounter = 0;
u16 savedFrames = 0;
bool messageCloseCheck = false;
bool pendingSaleCheck = false;
bool transitionCheck = false;
std::map<uint32_t, RandomizerCheck> startingShopItem = { { SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 },
{ SCENE_BAZAAR, RC_MARKET_BAZAAR_ITEM_1 },
{ SCENE_POTION_SHOP_MARKET, RC_MARKET_POTION_SHOP_ITEM_1 },
@ -100,7 +91,7 @@ std::map<uint32_t, RandomizerCheck> startingShopItem = { { SCENE_KOKIRI_SHOP, RC
{ SCENE_ZORA_SHOP, RC_ZD_SHOP_ITEM_1 },
{ SCENE_GORON_SHOP, RC_GC_SHOP_ITEM_1 } };
std::map<SceneID, RandomizerCheckArea> RCAreaFromSceneID = {
std::map<SceneID, RandomizerCheckArea> DungeonRCAreasBySceneID = {
{SCENE_DEKU_TREE, RCAREA_DEKU_TREE},
{SCENE_DODONGOS_CAVERN, RCAREA_DODONGOS_CAVERN},
{SCENE_JABU_JABU, RCAREA_JABU_JABUS_BELLY},
@ -122,12 +113,9 @@ bool showVOrMQ;
s8 areaChecksGotten[32]; //| "Kokiri Forest (4/9)"
bool optCollapseAll; // A bool that will collapse all checks once
bool optExpandAll; // A bool that will expand all checks once
RandomizerCheck lastItemGetCheck = RC_UNKNOWN_CHECK;
RandomizerCheck lastLocationChecked = RC_UNKNOWN_CHECK;
RandomizerCheckArea previousArea = RCAREA_INVALID;
RandomizerCheckArea currentArea = RCAREA_INVALID;
std::vector<RandomizerCheckArea> checkAreas;
std::vector<GetItemEntry> itemsReceived;
OSContPad* trackerButtonsPressed;
void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0);
@ -199,10 +187,6 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green
std::vector<uint32_t> buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L,
BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT };
void SetLastItemGetRC(RandomizerCheck rc) {
lastItemGetCheck = rc;
}
void DefaultCheckData(RandomizerCheck rc) {
gSaveContext.checkTrackerData[rc].status = RCSHOW_UNCHECKED;
gSaveContext.checkTrackerData[rc].skipped = 0;
@ -253,9 +237,6 @@ void SetCheckCollected(RandomizerCheck rc) {
} else {
gSaveContext.checkTrackerData[rc].skipped = false;
}
if (!checkAreas.empty()) {
checkAreas.erase(checkAreas.begin());
}
SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true);
doAreaScroll = true;
@ -360,32 +341,18 @@ bool vector_contains_scene(std::vector<SceneID> vec, const int16_t scene) {
std::vector<SceneID> skipScenes = {SCENE_GANON_BOSS, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, SCENE_GANON_BOSS, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR};
bool EvaluateCheck(RandomizerCheck rc) {
if (HasItemBeenCollected(rc) && gSaveContext.checkTrackerData[rc].status != RCSHOW_COLLECTED &&
gSaveContext.checkTrackerData[rc].status != RCSHOW_SAVED) {
SetCheckCollected(rc);
return true;
}
return false;
}
bool CheckByArea(RandomizerCheckArea area = RCAREA_INVALID) {
if (area == RCAREA_INVALID) {
area = checkAreas.front();
}
if (area != RCAREA_INVALID) {
auto areaChecks = checksByArea.find(area)->second;
if (checkCounter >= areaChecks.size()) {
checkCounter = 0;
checkLoops++;
}
auto rc = areaChecks.at(checkCounter);
return EvaluateCheck(rc);
void ClearAreaChecksAndTotals() {
for (auto& [rcArea, vec] : checksByArea) {
vec.clear();
areaChecksGotten[rcArea] = 0;
}
}
void SetShopSeen(uint32_t sceneNum, bool prices) {
RandomizerCheck start = startingShopItem.find(sceneNum)->second;
if (sceneNum == SCENE_POTION_SHOP_KAKARIKO && !LINK_IS_ADULT) {
return;
}
if (GetCheckArea() == RCAREA_KAKARIKO_VILLAGE && sceneNum == SCENE_BAZAAR) {
start = RC_KAK_BAZAAR_ITEM_1;
}
@ -452,10 +419,61 @@ bool HasItemBeenCollected(RandomizerCheck rc) {
return false;
}
void CheckTrackerDialogClosed() {
if (messageCloseCheck) {
messageCloseCheck = false;
void CheckTrackerLoadGame(int32_t fileNum) {
LoadSettings();
TrySetAreas();
for (auto& entry : Rando::StaticData::GetLocationTable()) {
RandomizerCheck rc = entry.GetRandomizerCheck();
RandomizerCheckTrackerData rcTrackerData = gSaveContext.checkTrackerData[rc];
if (rc == RC_UNKNOWN_CHECK || rc == RC_MAX || rc == RC_LINKS_POCKET ||
!Rando::StaticData::GetLocation(rc) != RC_UNKNOWN_CHECK)
continue;
Rando::Location* entry2;
if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) {
entry2 = Rando::StaticData::GetLocation(rc);
} else {
entry2 = Rando::StaticData::GetLocation(rc);
}
if (!IsVisibleInCheckTracker(entry2->GetRandomizerCheck())) continue;
checksByArea.find(entry2->GetArea())->second.push_back(entry2->GetRandomizerCheck());
if (rcTrackerData.status == RCSHOW_SAVED || rcTrackerData.skipped) {
areaChecksGotten[entry2->GetArea()]++;
}
if (areaChecksGotten[entry2->GetArea()] != 0 || RandomizerCheckObjects::AreaIsOverworld(entry2->GetArea())) {
areasSpoiled |= (1 << entry2->GetArea());
}
}
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING && IS_RANDO) {
s8 startingAge = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_AGE);
RandomizerCheckArea startingArea;
switch (startingAge) {
case RO_AGE_CHILD:
startingArea = RCAREA_KOKIRI_FOREST;
break;
case RO_AGE_ADULT:
startingArea = RCAREA_MARKET;
break;
default:
startingArea = RCAREA_KOKIRI_FOREST;
break;
}
checksByArea.find(startingArea)->second.push_back(RC_LINKS_POCKET);
areaChecksGotten[startingArea]++;
}
showVOrMQ = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_RANDOM_NUMBER ||
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) < 12));
LinksPocket();
SongFromImpa();
GiftFromSages();
initialized = true;
UpdateAllOrdering();
UpdateInventoryChecks();
}
void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) {
@ -479,10 +497,6 @@ void CheckTrackerTransition(uint32_t sceneNum) {
if (!GameInteractor::IsSaveLoaded()) {
return;
}
gSaveContext;
if (transitionCheck) {
transitionCheck = false;
}
doAreaScroll = true;
previousArea = currentArea;
currentArea = GetCheckArea();
@ -503,28 +517,12 @@ void CheckTrackerFrame() {
if (!GameInteractor::IsSaveLoaded()) {
return;
}
if (!checkAreas.empty() && !transitionCheck && !messageCloseCheck && !pendingSaleCheck) {
for (int i = 0; i < 10; i++) {
if (CheckByArea()) {
checkCounter = 0;
break;
} else {
checkCounter++;
}
// TODO: Move to OnAmmoChange hook once it gets added.
if (gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_COLLECTED &&
gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_SAVED) {
if (BEANS_BOUGHT >= 10) {
SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN);
}
if (checkLoops > 15) {
checkAreas.erase(checkAreas.begin());
checkLoops = 0;
}
}
if (savedFrames > 0 && !pendingSaleCheck && !messageCloseCheck) {
savedFrames--;
}
}
void CheckTrackerSaleEnd(GetItemEntry giEntry) {
if (pendingSaleCheck) {
pendingSaleCheck = false;
}
}
@ -536,7 +534,7 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) {
// Vanilla special item checks
if (!IS_RANDO) {
if (giEntry.itemId == ITEM_SHIELD_DEKU) {
SetCheckCollected(RC_KF_SHOP_ITEM_3);
SetCheckCollected(RC_KF_SHOP_ITEM_1);
return;
}else if (giEntry.itemId == ITEM_KOKIRI_EMERALD) {
SetCheckCollected(RC_QUEEN_GOHMA);
@ -565,16 +563,19 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) {
} else if (giEntry.itemId == ITEM_MEDALLION_LIGHT) {
SetCheckCollected(RC_GIFT_FROM_SAGES);
return;
} else if (giEntry.itemId == ITEM_SONG_LULLABY) {
SetCheckCollected(RC_SONG_FROM_IMPA);
return;
} else if (giEntry.itemId == ITEM_SONG_EPONA) {
SetCheckCollected(RC_SONG_FROM_MALON);
return;
} else if (giEntry.itemId == ITEM_SONG_SARIA) {
SetCheckCollected(RC_SONG_FROM_SARIA);
return;
} else if (giEntry.itemId == ITEM_SONG_SUN) {
} else if (giEntry.itemId == ITEM_BEAN) {
SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN);
return;
} else if (giEntry.itemId == ITEM_BRACELET) {
SetCheckCollected(RC_GC_DARUNIAS_JOY);
return;
}/* else if (giEntry.itemId == ITEM_SONG_SUN) {
SetCheckCollected(RC_SONG_FROM_ROYAL_FAMILYS_TOMB);
return;
} else if (giEntry.itemId == ITEM_SONG_TIME) {
@ -601,42 +602,127 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) {
} else if (giEntry.itemId == ITEM_SONG_PRELUDE) {
SetCheckCollected(RC_SHEIK_AT_TEMPLE);
return;
} else if (giEntry.itemId == ITEM_BRACELET) {
SetCheckCollected(RC_GC_DARUNIAS_JOY);
return;
} else if (giEntry.itemId == ITEM_LETTER_ZELDA) {
SetCheckCollected(RC_HC_ZELDAS_LETTER);
return;
} else if (giEntry.itemId == ITEM_WEIRD_EGG) {
SetCheckCollected(RC_HC_MALON_EGG);
return;
} else if (giEntry.itemId == ITEM_BEAN) {
SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN);
}*/
}
}
void CheckTrackerSceneFlagSet(int16_t sceneNum, int16_t flagType, int32_t flag) {
if (flagType != FLAG_SCENE_TREASURE && flagType != FLAG_SCENE_COLLECTIBLE) {
return;
}
if (sceneNum == SCENE_GRAVEYARD && flag == 0x19 && flagType == FLAG_SCENE_COLLECTIBLE) { // Gravedigging tour special case
SetCheckCollected(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR);
return;
}
for (auto& loc : Rando::StaticData::GetLocationTable) {
if (!IsVisibleInCheckTracker(loc.GetRandomizerCheck())) {
continue;
}
SpoilerCollectionCheckType checkMatchType = flagType == FLAG_SCENE_TREASURE ? SpoilerCollectionCheckType::SPOILER_CHK_CHEST : SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE;
Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck();
if (scCheck.scene == sceneNum && scCheck.flag == flag && scCheck.type == checkMatchType) {
SetCheckCollected(loc.GetRandomizerCheck());
return;
}
}
auto checkArea = GetCheckArea();
if (gSaveContext.pendingSale != ITEM_NONE) {
pendingSaleCheck = true;
checkAreas.push_back(checkArea);
}
void CheckTrackerFlagSet(int16_t flagType, int32_t flag) {
SpoilerCollectionCheckType checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_NONE;
switch (flagType) {
case FLAG_GS_TOKEN:
checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA;
break;
case FLAG_EVENT_CHECK_INF:
if ((flag == EVENTCHKINF_CARPENTERS_FREE(0) || flag == EVENTCHKINF_CARPENTERS_FREE(1) ||
flag == EVENTCHKINF_CARPENTERS_FREE(2) || flag == EVENTCHKINF_CARPENTERS_FREE(3))
&& GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {
SetCheckCollected(RC_GF_GERUDO_MEMBERSHIP_CARD);
return;
}
checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF;
break;
case FLAG_INF_TABLE:
if (flag == INFTABLE_190) {
SetCheckCollected(RC_GF_HBA_1000_POINTS);
return;
} else if (flag == INFTABLE_11E) {
SetCheckCollected(RC_GC_ROLLING_GORON_AS_CHILD);
return;
} else if (flag == INFTABLE_GORON_CITY_DOORS_UNLOCKED) {
SetCheckCollected(RC_GC_ROLLING_GORON_AS_ADULT);
return;
} else if (flag == INFTABLE_139) {
SetCheckCollected(RC_ZD_KING_ZORA_THAWED);
return;
} else if (flag == INFTABLE_191) {
SetCheckCollected(RC_MARKET_LOST_DOG);
return;
}
if (!IS_RANDO) {
if (flag == INFTABLE_192) {
SetCheckCollected(RC_LW_DEKU_SCRUB_NEAR_BRIDGE);
return;
} else if (flag == INFTABLE_193) {
SetCheckCollected(RC_LW_DEKU_SCRUB_GROTTO_FRONT);
return;
}
}
break;
case FLAG_ITEM_GET_INF:
if (!IS_RANDO) {
if (flag == ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE) {
SetCheckCollected(RC_DEKU_THEATER_SKULL_MASK);
return;
} else if (flag == ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE) {
SetCheckCollected(RC_DEKU_THEATER_MASK_OF_TRUTH);
return;
} else if (flag == ITEMGETINF_0B) {
SetCheckCollected(RC_HF_DEKU_SCRUB_GROTTO);
return;
}
}
checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF;
break;
case FLAG_RANDOMIZER_INF:
checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF;
break;
}
if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_NONE) {
return;
}
if (scene == SCENE_DESERT_COLOSSUS && (gSaveContext.entranceIndex == 485 || gSaveContext.entranceIndex == 489)) {
checkAreas.push_back(RCAREA_SPIRIT_TEMPLE);
return;
}
if (GET_PLAYER(gPlayState) == nullptr) {
transitionCheck = true;
return;
}
if (gPlayState->msgCtx.msgMode != MSGMODE_NONE) {
checkAreas.push_back(checkArea);
messageCloseCheck = true;
return;
}
if (IS_RANDO || (!IS_RANDO && giEntry.getItemCategory != ITEM_CATEGORY_JUNK)) {
checkAreas.push_back(checkArea);
checkCollected = true;
for (auto& loc : Rando::StaticData::GetLocationTable()) {
if ((!IS_RANDO && ((loc.GetQuest() == RCQUEST_MQ && !IS_MASTER_QUEST) ||
(loc.GetQuest() == RCQUEST_VANILLA && IS_MASTER_QUEST))) ||
(IS_RANDO && ((OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsMQ() &&
loc.GetQuest() == RCQUEST_VANILLA) ||
OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsVanilla() &&
loc.GetQuest() == RCQUEST_MQ))) {
continue;
}
Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck();
SpoilerCollectionCheckType scCheckType = scCheck.type;
if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF &&
(scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_COW ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SCRUB ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD ||
scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF)) {
if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)) {
SetCheckCollected(loc.GetRandomizerCheck());
return;
}
continue;
}
int16_t checkFlag = scCheck.flag;
if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA) {
checkFlag = loc.GetActorParams();
}
if (checkFlag == flag && scCheck.type == checkMatchType) {
SetCheckCollected(loc.GetRandomizerCheck());
return;
}
}
}
@ -654,7 +740,7 @@ void InitTrackerData(bool isDebug) {
void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) {
SaveManager::Instance->SaveArray("checks", ARRAY_COUNT(saveContext->checkTrackerData), [&](size_t i) {
if (saveContext->checkTrackerData[i].status == RCSHOW_COLLECTED) {
if (gameSave || savedFrames > 0) {
if (gameSave) {
gSaveContext.checkTrackerData[i].status = saveContext->checkTrackerData[i].status = RCSHOW_SAVED;
UpdateAllOrdering();
UpdateInventoryChecks();
@ -673,15 +759,9 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) {
void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) {
SaveTrackerData(saveContext, sectionID, fullSave);
if (fullSave) {
savedFrames = 40;
}
}
void LoadFile() {
Teardown();
LoadSettings();
TrySetAreas();
SaveManager::Instance->LoadArray("checks", RC_MAX, [](size_t i) {
SaveManager::Instance->LoadStruct("", [&]() {
SaveManager::Instance->LoadData("status", gSaveContext.checkTrackerData[i].status);
@ -689,71 +769,14 @@ void LoadFile() {
SaveManager::Instance->LoadData("price", gSaveContext.checkTrackerData[i].price);
SaveManager::Instance->LoadData("hintItem", gSaveContext.checkTrackerData[i].hintItem);
});
RandomizerCheckTrackerData entry = gSaveContext.checkTrackerData[i];
RandomizerCheck rc = static_cast<RandomizerCheck>(i);
if (rc == RC_UNKNOWN_CHECK || rc == RC_MAX)
return;
Rando::Location* entry2;
if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) {
entry2 = Rando::StaticData::GetLocation(rc);
} else {
entry2 = Rando::StaticData::GetLocation(rc);
}
if (!IsVisibleInCheckTracker(entry2->GetRandomizerCheck())) return;
if (entry2->GetRandomizerCheck() != RC_LINKS_POCKET) {
// RC_LINKS_POCKET is a special case because it's RCAREA is different depending on starting age.
checksByArea.find(entry2->GetArea())->second.push_back(entry2->GetRandomizerCheck());
}
if (entry.status == RCSHOW_SAVED || entry.skipped) {
areaChecksGotten[entry2->GetArea()]++;
}
if (areaChecksGotten[entry2->GetArea()] != 0 || RandomizerCheckObjects::AreaIsOverworld(entry2->GetArea())) {
areasSpoiled |= (1 << entry2->GetArea());
}
});
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING && IS_RANDO) {
s8 startingAge = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_AGE);
RandomizerCheckArea startingArea;
switch (startingAge) {
case RO_AGE_CHILD:
startingArea = RCAREA_KOKIRI_FOREST;
break;
case RO_AGE_ADULT:
startingArea = RCAREA_MARKET;
break;
default:
startingArea = RCAREA_KOKIRI_FOREST;
break;
}
checksByArea.find(startingArea)->second.push_back(RC_LINKS_POCKET);
areaChecksGotten[startingArea]++;
}
showVOrMQ = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_RANDOM_NUMBER ||
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) < 12));
LinksPocket();
SongFromImpa();
GiftFromSages();
initialized = true;
UpdateAllOrdering();
UpdateInventoryChecks();
}
void Teardown() {
initialized = false;
for (auto& [rcArea, vec] : checksByArea) {
vec.clear();
areaChecksGotten[rcArea] = 0;
}
ClearAreaChecksAndTotals();
checksByArea.clear();
areasSpoiled = 0;
checkCollected = false;
checkLoops = 0;
lastLocationChecked = RC_UNKNOWN_CHECK;
}
@ -923,7 +946,11 @@ void CheckTrackerWindow::DrawElement() {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f,
extraColor.b / 255.0f, extraColor.a / 255.0f));
isThisAreaSpoiled = areasSpoiled & areaMask || CVarGetInteger("gCheckTrackerOptionMQSpoilers", 0);
isThisAreaSpoiled = areasSpoiled & areaMask || CVarGetInteger("gCheckTrackerOptionMQSpoilers", 0) || !IS_RANDO ||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_NONE ||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SELECTION ||
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12);
if (isThisAreaSpoiled) {
if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) {
@ -1058,7 +1085,7 @@ void LoadSettings() {
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING
:false;
hideShopRightChecks = IS_RANDO ? CVarGetInteger("gCheckTrackerOptionHideRightShopChecks", 1) : false;
hideTriforceCompleted = IS_RANDO ?
hideTriforceCompleted = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != RO_GENERIC_ON : false;
if (IS_RANDO) {
@ -1103,7 +1130,7 @@ void LoadSettings() {
bool IsVisibleInCheckTracker(RandomizerCheck rc) {
Rando::Location* loc = Rando::StaticData::GetLocation(rc);
if (IS_RANDO) {
if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) {
return
(loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations
(loc->GetRCType() != RCTYPE_GOSSIP_STONE) && //TODO: Don't show hints until tracker supports them
@ -1155,8 +1182,8 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) {
}
else if (loc->IsVanillaCompletion()) {
return (loc->GetQuest() == RCQUEST_BOTH ||
loc->GetQuest() == RCQUEST_MQ && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsMQ() ||
loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla() ||
(loc->GetQuest() == RCQUEST_MQ && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsMQ()) ||
(loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla()) ||
rc == RC_GIFT_FROM_SAGES) && rc != RC_LINKS_POCKET;
}
return false;
@ -1164,9 +1191,11 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) {
void UpdateInventoryChecks() {
//For all the areas with compasses, if you have one, spoil the area
for (u8 i = SCENE_DEKU_TREE; i <= SCENE_GERUDO_TRAINING_GROUND; i++)
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, i))
areasSpoiled |= (1 << RCAreaFromSceneID.at((SceneID)i));
for (auto [scene, area] : DungeonRCAreasBySceneID) {
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, scene)) {
areasSpoiled |= (1 << area);
}
}
}
void UpdateAreaFullyChecked(RandomizerCheckArea area) {
@ -1554,14 +1583,16 @@ void CheckTrackerWindow::InitElement() {
SaveManager::Instance->AddInitFunction(InitTrackerData);
sectionId = SaveManager::Instance->AddSaveFunction("trackerData", 1, SaveFile, true, -1);
SaveManager::Instance->AddLoadFunction("trackerData", 1, LoadFile);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>(CheckTrackerLoadGame);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnExitGame>([](uint32_t fileNum) {
Teardown();
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>(CheckTrackerItemReceive);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSaleEnd>(CheckTrackerSaleEnd);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>(CheckTrackerFrame);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnTransitionEnd>(CheckTrackerTransition);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnShopSlotChange>(CheckTrackerShopSlotChange);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneFlagSet>(CheckTrackerSceneFlagSet);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnFlagSet>(CheckTrackerFlagSet);
//LocationTable_Init();
}