mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-12 12:18:32 -04:00
Rando: Mark checks as seen in the Check Tracker from explicit item hints (#6946)
Only apply with clear hints & when hint is for a unique RHT
This commit is contained in:
@@ -185,7 +185,7 @@ RANDO_ENUM_END(RandomizerCheckArea)
|
||||
// Check tracker check visibility categories
|
||||
RANDO_ENUM_BEGIN(RandomizerCheckStatus)
|
||||
RANDO_ENUM_ITEM(RCSHOW_UNCHECKED)
|
||||
RANDO_ENUM_ITEM(RCSHOW_SEEN)
|
||||
RANDO_ENUM_ITEM(RCSHOW_SEEN_OR_HINTED)
|
||||
RANDO_ENUM_ITEM(RCSHOW_IDENTIFIED)
|
||||
RANDO_ENUM_ITEM(RCSHOW_SCUMMED)
|
||||
RANDO_ENUM_ITEM(RCSHOW_COLLECTED)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
#include "overlays/actors/ovl_En_GirlA/z_en_girla.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
@@ -313,7 +314,7 @@ bool IsCheckHidden(RandomizerCheck rc) {
|
||||
bool available = itemLocation->IsAvailable();
|
||||
bool skipped = itemLocation->GetIsSkipped();
|
||||
bool obtained = itemLocation->HasObtained();
|
||||
bool seen = status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED;
|
||||
bool seen = status == RCSHOW_SEEN_OR_HINTED || status == RCSHOW_IDENTIFIED;
|
||||
bool scummed = status == RCSHOW_SCUMMED;
|
||||
bool unchecked = status == RCSHOW_UNCHECKED;
|
||||
|
||||
@@ -510,7 +511,7 @@ void SetShopSeen(uint32_t sceneNum, bool prices) {
|
||||
bool statusChanged = false;
|
||||
for (int i = start; i < start + 8; i++) {
|
||||
if (OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetCheckStatus() == RCSHOW_UNCHECKED) {
|
||||
OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetCheckStatus(RCSHOW_SEEN);
|
||||
OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetCheckStatus(RCSHOW_SEEN_OR_HINTED);
|
||||
statusChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -519,6 +520,72 @@ void SetShopSeen(uint32_t sceneNum, bool prices) {
|
||||
}
|
||||
}
|
||||
|
||||
// Items share hint text keys: all six jabber nuts are "the ability to speak".
|
||||
// Counted once on first use.
|
||||
static bool HintNamesItemUniquely(RandomizerGet rg) {
|
||||
static const auto keyUses = [] {
|
||||
std::array<uint16_t, RHT_MAX> uses{};
|
||||
for (const auto& item : Rando::StaticData::GetItemTable()) {
|
||||
uses[item.GetHintKey()]++;
|
||||
}
|
||||
return uses;
|
||||
}();
|
||||
return keyUses[Rando::StaticData::RetrieveItem(rg).GetHintKey()] == 1;
|
||||
}
|
||||
|
||||
// Only HINT_TYPE_ITEM hints name a check's item outright; other types stay
|
||||
// ambiguous. Marks Seen, not Identified, since hints never state a price.
|
||||
static bool ApplyItemHintToChecks(RandomizerHint hintKey) {
|
||||
// Ambiguous/obscure hints reuse the same phrase across items (all four swords are
|
||||
// just "a sword"), so only clear hints are safe to mark - skip anything else
|
||||
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_HINT_CLARITY) != RO_HINT_CLARITY_CLEAR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hintKey == RH_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The hint-revealed hook can fire for hints the seed has disabled.
|
||||
auto hint = OTRGlobals::Instance->gRandoContext->GetHint(hintKey);
|
||||
if (!hint->IsEnabled() || hint->GetHintType() != HINT_TYPE_ITEM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loop over hinted locations, apply the ones which are unambiguous
|
||||
bool changed = false;
|
||||
for (RandomizerCheck rc : hint->GetHintedLocations()) {
|
||||
if (rc == RC_UNKNOWN_CHECK) {
|
||||
continue;
|
||||
}
|
||||
auto loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||
// Ice traps hint, and display, as their disguise.
|
||||
RandomizerGet named = loc->GetPlacedRandomizerGet();
|
||||
auto& overrides = OTRGlobals::Instance->gRandoContext->overrides;
|
||||
if (named == RG_ICE_TRAP && overrides.contains(rc)) {
|
||||
named = overrides[rc].LooksLike();
|
||||
}
|
||||
if (!HintNamesItemUniquely(named)) {
|
||||
// The hint could mean several items, no spoilers!
|
||||
continue;
|
||||
}
|
||||
if (loc->GetCheckStatus() == RCSHOW_UNCHECKED) {
|
||||
loc->SetCheckStatus(RCSHOW_SEEN_OR_HINTED);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void CheckTrackerHintRevealed(RandomizerHint hintKey) {
|
||||
if (!GameInteractor::IsSaveLoaded() || !IS_RANDO) {
|
||||
return;
|
||||
}
|
||||
if (ApplyItemHintToChecks(hintKey)) {
|
||||
SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckTrackerLoadGame(int32_t fileNum) {
|
||||
if (IS_BOSS_RUSH) {
|
||||
return;
|
||||
@@ -626,7 +693,7 @@ void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) {
|
||||
slot = RC_KAK_BAZAAR_ITEM_1 + cursorSlot;
|
||||
}
|
||||
auto status = OTRGlobals::Instance->gRandoContext->GetItemLocation(slot)->GetCheckStatus();
|
||||
if (status == RCSHOW_SEEN) {
|
||||
if (status == RCSHOW_SEEN_OR_HINTED) {
|
||||
OTRGlobals::Instance->gRandoContext->GetItemLocation(slot)->SetCheckStatus(RCSHOW_IDENTIFIED);
|
||||
SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true);
|
||||
RecalculateAvailableChecks();
|
||||
@@ -868,9 +935,11 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) {
|
||||
}
|
||||
|
||||
void CheckTrackerDialogMessage() {
|
||||
// These dialogues state the price, so a Seen check upgrades to Identified.
|
||||
auto identifyCheck = [](RandomizerCheck rc) {
|
||||
auto loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||
if (loc->GetCheckStatus() == RCSHOW_UNCHECKED) {
|
||||
RandomizerCheckStatus status = loc->GetCheckStatus();
|
||||
if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN_OR_HINTED) {
|
||||
loc->SetCheckStatus(RCSHOW_IDENTIFIED);
|
||||
RecalculateAvailableChecks();
|
||||
}
|
||||
@@ -1319,13 +1388,14 @@ bool ShouldShowCheck(RandomizerCheck check) {
|
||||
Rando::StaticData::GetLocation(check)->GetName() + " " +
|
||||
RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea()));
|
||||
if (itemLoc->HasObtained() || itemLoc->GetCheckStatus() == RCSHOW_SCUMMED ||
|
||||
(!mystery && (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED || itemLoc->GetCheckStatus() == RCSHOW_SEEN) &&
|
||||
(!mystery &&
|
||||
(itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED || itemLoc->GetCheckStatus() == RCSHOW_SEEN_OR_HINTED) &&
|
||||
itemLoc->GetPlacedRandomizerGet() != RG_ICE_TRAP)) {
|
||||
search += " " + itemLoc->GetPlacedItemName().GetForLanguage(gSaveContext.language);
|
||||
} else if (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED && !mystery) {
|
||||
search +=
|
||||
OTRGlobals::Instance->gRandoContext->overrides[check].GetTrickName().GetForLanguage(gSaveContext.language);
|
||||
} else if (itemLoc->GetCheckStatus() == RCSHOW_SEEN && !mystery) {
|
||||
} else if (itemLoc->GetCheckStatus() == RCSHOW_SEEN_OR_HINTED && !mystery) {
|
||||
search += Rando::StaticData::RetrieveItem(OTRGlobals::Instance->gRandoContext->overrides[check].LooksLike())
|
||||
.GetName()
|
||||
.GetForLanguage(gSaveContext.language);
|
||||
@@ -1937,7 +2007,7 @@ void DrawLocation(RandomizerCheck rc) {
|
||||
? Color_Skipped_Extra
|
||||
: Color_Skipped_Main;
|
||||
extraColor = Color_Skipped_Extra;
|
||||
} else if (status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED) {
|
||||
} else if (status == RCSHOW_SEEN_OR_HINTED || status == RCSHOW_IDENTIFIED) {
|
||||
if (!showHidden && hideSeen) {
|
||||
return;
|
||||
}
|
||||
@@ -1980,7 +2050,7 @@ void DrawLocation(RandomizerCheck rc) {
|
||||
// Draw button - for Skipped/Seen/Scummed/Unchecked only
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4.0f, 3.0f });
|
||||
float sz = ImGui::GetFrameHeight();
|
||||
if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED ||
|
||||
if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN_OR_HINTED || status == RCSHOW_IDENTIFIED ||
|
||||
status == RCSHOW_SCUMMED || skipped) {
|
||||
if (UIWidgets::StateButton(std::to_string(rc).c_str(), skipped ? ICON_FA_PLUS : ICON_FA_TIMES, ImVec2(sz, sz),
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR))) {
|
||||
@@ -2051,7 +2121,7 @@ void DrawLocation(RandomizerCheck rc) {
|
||||
}
|
||||
break;
|
||||
case RCSHOW_IDENTIFIED:
|
||||
case RCSHOW_SEEN:
|
||||
case RCSHOW_SEEN_OR_HINTED:
|
||||
if (IS_RANDO) {
|
||||
const auto checkType = loc->GetRCType();
|
||||
const bool hideMerchantName =
|
||||
@@ -2444,6 +2514,7 @@ void CheckTrackerWindow::InitElement() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneFlagSet>(CheckTrackerSceneFlagSet);
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnFlagSet>(CheckTrackerFlagSet);
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnDialogMessage>(CheckTrackerDialogMessage);
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnRandoHintRevealed>(CheckTrackerHintRevealed);
|
||||
}
|
||||
|
||||
void CheckTrackerWindow::UpdateElement() {
|
||||
|
||||
Reference in New Issue
Block a user