|
|
|
|
@ -66,8 +66,8 @@ int AutoWalkTrackerTargetId = -1;
|
|
|
|
|
|
|
|
|
|
/// Maximum Chebyshev distance (in tiles) at which the player is considered
|
|
|
|
|
/// close enough to interact with a tracker target.
|
|
|
|
|
constexpr int TrackerInteractDistanceTiles = 1; |
|
|
|
|
constexpr int TrackerCycleDistanceTiles = 12; |
|
|
|
|
constexpr int TrackerInteractDistanceTiles = 1; |
|
|
|
|
constexpr int TrackerCycleDistanceTiles = 20; |
|
|
|
|
|
|
|
|
|
int LockedTrackerItemId = -1; |
|
|
|
|
int LockedTrackerChestId = -1; |
|
|
|
|
@ -1302,8 +1302,8 @@ void SelectTrackerTargetCategoryRelative(int delta)
|
|
|
|
|
app_fatal("Invalid TrackerTargetCategory"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::string_view TrackerCategoryNoCandidatesFoundMessage(TrackerTargetCategory category) |
|
|
|
|
{ |
|
|
|
|
[[nodiscard]] std::string_view TrackerCategoryNoCandidatesFoundMessage(TrackerTargetCategory category) |
|
|
|
|
{ |
|
|
|
|
switch (category) { |
|
|
|
|
case TrackerTargetCategory::Items: |
|
|
|
|
return _("No items found."); |
|
|
|
|
@ -1335,13 +1335,67 @@ void SelectTrackerTargetCategoryRelative(int delta)
|
|
|
|
|
return _("No quest locations found."); |
|
|
|
|
case TrackerTargetCategory::Portals: |
|
|
|
|
return _("No portals found."); |
|
|
|
|
} |
|
|
|
|
app_fatal("Invalid TrackerTargetCategory"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::string_view TrackerCategoryNoNextMessage(TrackerTargetCategory category) |
|
|
|
|
{ |
|
|
|
|
switch (category) { |
|
|
|
|
} |
|
|
|
|
app_fatal("Invalid TrackerTargetCategory"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[[nodiscard]] constexpr bool TrackerCategorySelectionIsProximityLimited(TrackerTargetCategory category) |
|
|
|
|
{ |
|
|
|
|
return IsAnyOf(category, TrackerTargetCategory::Items, TrackerTargetCategory::Chests, TrackerTargetCategory::Doors, TrackerTargetCategory::Shrines, TrackerTargetCategory::Objects, |
|
|
|
|
TrackerTargetCategory::Breakables, TrackerTargetCategory::Monsters, TrackerTargetCategory::DeadBodies); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[[nodiscard]] bool TrackerCategoryHasAnyTargets(TrackerTargetCategory category, Point playerPosition) |
|
|
|
|
{ |
|
|
|
|
switch (category) { |
|
|
|
|
case TrackerTargetCategory::Items: |
|
|
|
|
return FindNearestGroundItemId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::Chests: |
|
|
|
|
return FindNearestUnopenedChestObjectId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::Doors: |
|
|
|
|
return FindNearestDoorObjectId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::Shrines: |
|
|
|
|
return FindNearestShrineObjectId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::Objects: |
|
|
|
|
return FindNearestMiscInteractableObjectId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::Breakables: |
|
|
|
|
return FindNearestBreakableObjectId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::Monsters: |
|
|
|
|
return FindNearestMonsterId(playerPosition).has_value(); |
|
|
|
|
case TrackerTargetCategory::DeadBodies: |
|
|
|
|
return FindNearestCorpseId(playerPosition).has_value(); |
|
|
|
|
default: |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::string_view TrackerCategoryNoNearbyCandidatesFoundMessage(TrackerTargetCategory category) |
|
|
|
|
{ |
|
|
|
|
switch (category) { |
|
|
|
|
case TrackerTargetCategory::Items: |
|
|
|
|
return _("No nearby items found."); |
|
|
|
|
case TrackerTargetCategory::Chests: |
|
|
|
|
return _("No nearby chests found."); |
|
|
|
|
case TrackerTargetCategory::Doors: |
|
|
|
|
return _("No nearby doors found."); |
|
|
|
|
case TrackerTargetCategory::Shrines: |
|
|
|
|
return _("No nearby shrines found."); |
|
|
|
|
case TrackerTargetCategory::Objects: |
|
|
|
|
return _("No nearby objects found."); |
|
|
|
|
case TrackerTargetCategory::Breakables: |
|
|
|
|
return _("No nearby breakables found."); |
|
|
|
|
case TrackerTargetCategory::Monsters: |
|
|
|
|
return _("No nearby monsters found."); |
|
|
|
|
case TrackerTargetCategory::DeadBodies: |
|
|
|
|
return _("No nearby dead bodies found."); |
|
|
|
|
default: |
|
|
|
|
return TrackerCategoryNoCandidatesFoundMessage(category); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::string_view TrackerCategoryNoNextMessage(TrackerTargetCategory category) |
|
|
|
|
{ |
|
|
|
|
switch (category) { |
|
|
|
|
case TrackerTargetCategory::Items: |
|
|
|
|
return _("No next item."); |
|
|
|
|
case TrackerTargetCategory::Chests: |
|
|
|
|
@ -1441,12 +1495,15 @@ void SelectTrackerTargetRelative(int delta)
|
|
|
|
|
const Point playerPosition = MyPlayer->position.future; |
|
|
|
|
AutoWalkTrackerTargetId = -1; |
|
|
|
|
|
|
|
|
|
const std::vector<TrackerCandidate> candidates = CollectTrackerCandidatesForSelection(SelectedTrackerTargetCategory, playerPosition); |
|
|
|
|
if (candidates.empty()) { |
|
|
|
|
LockedTrackerTargetId(SelectedTrackerTargetCategory) = -1; |
|
|
|
|
SpeakText(TrackerCategoryNoCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const std::vector<TrackerCandidate> candidates = CollectTrackerCandidatesForSelection(SelectedTrackerTargetCategory, playerPosition); |
|
|
|
|
if (candidates.empty()) { |
|
|
|
|
LockedTrackerTargetId(SelectedTrackerTargetCategory) = -1; |
|
|
|
|
if (TrackerCategorySelectionIsProximityLimited(SelectedTrackerTargetCategory) && TrackerCategoryHasAnyTargets(SelectedTrackerTargetCategory, playerPosition)) |
|
|
|
|
SpeakText(TrackerCategoryNoNearbyCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
else |
|
|
|
|
SpeakText(TrackerCategoryNoCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int &lockedTargetId = LockedTrackerTargetId(SelectedTrackerTargetCategory); |
|
|
|
|
if (candidates.size() == 1) { |
|
|
|
|
@ -2809,15 +2866,19 @@ void TrackerPageUpKeyPressed()
|
|
|
|
|
const SDL_Keymod modState = SDL_GetModState(); |
|
|
|
|
const bool cycleCategory = (modState & SDL_KMOD_CTRL) != 0; |
|
|
|
|
|
|
|
|
|
if (cycleCategory) { |
|
|
|
|
SelectTrackerTargetCategoryRelative(-1); |
|
|
|
|
if (MyPlayer != nullptr) { |
|
|
|
|
const Point playerPosition = MyPlayer->position.future; |
|
|
|
|
if (CollectTrackerCandidatesForSelection(SelectedTrackerTargetCategory, playerPosition).empty()) |
|
|
|
|
SpeakText(TrackerCategoryNoCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (cycleCategory) { |
|
|
|
|
SelectTrackerTargetCategoryRelative(-1); |
|
|
|
|
if (MyPlayer != nullptr) { |
|
|
|
|
const Point playerPosition = MyPlayer->position.future; |
|
|
|
|
if (CollectTrackerCandidatesForSelection(SelectedTrackerTargetCategory, playerPosition).empty()) { |
|
|
|
|
if (TrackerCategorySelectionIsProximityLimited(SelectedTrackerTargetCategory) && TrackerCategoryHasAnyTargets(SelectedTrackerTargetCategory, playerPosition)) |
|
|
|
|
SpeakText(TrackerCategoryNoNearbyCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
else |
|
|
|
|
SpeakText(TrackerCategoryNoCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SelectTrackerTargetRelative(-1); |
|
|
|
|
} |
|
|
|
|
@ -2827,15 +2888,19 @@ void TrackerPageDownKeyPressed()
|
|
|
|
|
const SDL_Keymod modState = SDL_GetModState(); |
|
|
|
|
const bool cycleCategory = (modState & SDL_KMOD_CTRL) != 0; |
|
|
|
|
|
|
|
|
|
if (cycleCategory) { |
|
|
|
|
SelectTrackerTargetCategoryRelative(+1); |
|
|
|
|
if (MyPlayer != nullptr) { |
|
|
|
|
const Point playerPosition = MyPlayer->position.future; |
|
|
|
|
if (CollectTrackerCandidatesForSelection(SelectedTrackerTargetCategory, playerPosition).empty()) |
|
|
|
|
SpeakText(TrackerCategoryNoCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (cycleCategory) { |
|
|
|
|
SelectTrackerTargetCategoryRelative(+1); |
|
|
|
|
if (MyPlayer != nullptr) { |
|
|
|
|
const Point playerPosition = MyPlayer->position.future; |
|
|
|
|
if (CollectTrackerCandidatesForSelection(SelectedTrackerTargetCategory, playerPosition).empty()) { |
|
|
|
|
if (TrackerCategorySelectionIsProximityLimited(SelectedTrackerTargetCategory) && TrackerCategoryHasAnyTargets(SelectedTrackerTargetCategory, playerPosition)) |
|
|
|
|
SpeakText(TrackerCategoryNoNearbyCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
else |
|
|
|
|
SpeakText(TrackerCategoryNoCandidatesFoundMessage(SelectedTrackerTargetCategory), true); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SelectTrackerTargetRelative(+1); |
|
|
|
|
} |
|
|
|
|
|