Implement favorites filtering for Fallen characters in Chronicle and HUD. Added functionality to track and manage favorite subjects across death events, enhancing user experience. Updated test scenarios to validate new favorite handling and interactions.
This commit is contained in:
parent
0b23a15618
commit
94de8a3b5b
6 changed files with 266 additions and 54 deletions
|
|
@ -453,12 +453,20 @@ public static class AgentHarness
|
||||||
case "lore_favorites":
|
case "lore_favorites":
|
||||||
{
|
{
|
||||||
Chronicle.ShowHud();
|
Chronicle.ShowHud();
|
||||||
ChronicleHud.SetTab(ChronicleHud.LoreTab.Living);
|
|
||||||
string v = (cmd.value ?? "true").Trim().ToLowerInvariant();
|
string v = (cmd.value ?? "true").Trim().ToLowerInvariant();
|
||||||
bool on = v != "false" && v != "0" && v != "off";
|
bool on = v != "false" && v != "0" && v != "off";
|
||||||
ChronicleHud.SetFavoritesOnly(on);
|
ChronicleHud.SetFavoritesOnly(on);
|
||||||
|
// Filter is a list view - leave detail if we were in one.
|
||||||
|
if (ChronicleHud.DetailUnitId != 0)
|
||||||
|
{
|
||||||
|
ChronicleHud.ClearUnitDetail();
|
||||||
|
}
|
||||||
|
|
||||||
_cmdOk++;
|
_cmdOk++;
|
||||||
Emit(cmd, ok: true, detail: $"favoritesOnly={ChronicleHud.FavoritesOnly}");
|
Emit(
|
||||||
|
cmd,
|
||||||
|
ok: true,
|
||||||
|
detail: $"favoritesOnly={ChronicleHud.FavoritesOnly} tab={ChronicleHud.ActiveTab}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -549,34 +557,44 @@ public static class AgentHarness
|
||||||
long killerId = 0;
|
long killerId = 0;
|
||||||
Vector3 deathPos = Vector3.zero;
|
Vector3 deathPos = Vector3.zero;
|
||||||
string mode = (cmd.tier ?? "").Trim().ToLowerInvariant();
|
string mode = (cmd.tier ?? "").Trim().ToLowerInvariant();
|
||||||
|
bool favorite = mode.IndexOf("fav", System.StringComparison.Ordinal) >= 0;
|
||||||
Actor focus = MoveCamera.hasFocusUnit() ? MoveCamera._focus_unit : null;
|
Actor focus = MoveCamera.hasFocusUnit() ? MoveCamera._focus_unit : null;
|
||||||
if (mode == "killer" && focus != null && focus.isAlive())
|
if (mode.IndexOf("killer", System.StringComparison.Ordinal) >= 0
|
||||||
|
&& focus != null
|
||||||
|
&& focus.isAlive())
|
||||||
{
|
{
|
||||||
killerId = focus.getID();
|
killerId = focus.getID();
|
||||||
deathPos = focus.current_position;
|
deathPos = focus.current_position;
|
||||||
}
|
}
|
||||||
else if (mode == "place")
|
else if (mode.IndexOf("place", System.StringComparison.Ordinal) >= 0
|
||||||
|
|| favorite
|
||||||
|
|| string.IsNullOrEmpty(mode))
|
||||||
{
|
{
|
||||||
if (focus != null)
|
if (mode.IndexOf("place", System.StringComparison.Ordinal) >= 0 || favorite)
|
||||||
{
|
{
|
||||||
deathPos = focus.current_position;
|
if (focus != null)
|
||||||
}
|
{
|
||||||
else if (MoveCamera.instance != null)
|
deathPos = focus.current_position;
|
||||||
{
|
}
|
||||||
deathPos = MoveCamera.instance.transform.position;
|
else if (MoveCamera.instance != null)
|
||||||
deathPos.z = 0f;
|
{
|
||||||
}
|
deathPos = MoveCamera.instance.transform.position;
|
||||||
|
deathPos.z = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (deathPos == Vector3.zero)
|
if (deathPos == Vector3.zero)
|
||||||
{
|
{
|
||||||
deathPos = new Vector3(48f, 48f, 0f);
|
deathPos = new Vector3(48f, 48f, 0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long id = Chronicle.ForceOrphanHistory(
|
long id = Chronicle.ForceOrphanHistory(
|
||||||
name, species, n, prefix, attackType, killerId, deathPos);
|
name, species, n, prefix, attackType, killerId, deathPos, favorite);
|
||||||
DeathManner manner = Chronicle.LatestDeathMannerFor(id);
|
DeathManner manner = Chronicle.LatestDeathMannerFor(id);
|
||||||
bool ok = id != 0 && Chronicle.HistoryCountFor(id) >= n;
|
bool ok = id != 0
|
||||||
|
&& Chronicle.HistoryCountFor(id) >= n
|
||||||
|
&& (!favorite || Chronicle.IsFavoriteSubject(id));
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
_cmdOk++;
|
_cmdOk++;
|
||||||
|
|
@ -590,7 +608,7 @@ public static class AgentHarness
|
||||||
cmd,
|
cmd,
|
||||||
ok,
|
ok,
|
||||||
detail:
|
detail:
|
||||||
$"orphanId={id} hist={Chronicle.HistoryCountFor(id)} want={n} manner={manner} killer={killerId} mode={mode}");
|
$"orphanId={id} hist={Chronicle.HistoryCountFor(id)} want={n} manner={manner} killer={killerId} mode={mode} fav={Chronicle.IsFavoriteSubject(id)}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1742,13 +1760,36 @@ public static class AgentHarness
|
||||||
bool fav = false;
|
bool fav = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fav = unit != null && unit.isFavorite();
|
fav = unit != null && unit.isAlive() && unit.isFavorite();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fav)
|
||||||
|
{
|
||||||
|
long id = WatchCaption.CurrentUnitId;
|
||||||
|
if (id == 0)
|
||||||
|
{
|
||||||
|
id = ChronicleHud.DetailUnitId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0 && unit != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
id = unit.getID();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fav = Chronicle.IsFavoriteSubject(id);
|
||||||
|
}
|
||||||
|
|
||||||
string wantRaw = (cmd.value ?? "true").Trim().ToLowerInvariant();
|
string wantRaw = (cmd.value ?? "true").Trim().ToLowerInvariant();
|
||||||
bool want = wantRaw != "false" && wantRaw != "0" && wantRaw != "off";
|
bool want = wantRaw != "false" && wantRaw != "0" && wantRaw != "off";
|
||||||
pass = fav == want;
|
pass = fav == want;
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ public static class Chronicle
|
||||||
private static readonly HashSet<string> LoverPairKeys = new HashSet<string>();
|
private static readonly HashSet<string> LoverPairKeys = new HashSet<string>();
|
||||||
private static readonly HashSet<string> FriendPairKeys = new HashSet<string>();
|
private static readonly HashSet<string> FriendPairKeys = new HashSet<string>();
|
||||||
private static readonly HashSet<long> DeathLogged = new HashSet<long>();
|
private static readonly HashSet<long> DeathLogged = new HashSet<long>();
|
||||||
|
private static readonly HashSet<long> FavoriteIds = new HashSet<long>();
|
||||||
private static readonly Dictionary<long, UnitDossier> FinalDossiers =
|
private static readonly Dictionary<long, UnitDossier> FinalDossiers =
|
||||||
new Dictionary<long, UnitDossier>();
|
new Dictionary<long, UnitDossier>();
|
||||||
private static readonly HashSet<string> LandmarkDedupe = new HashSet<string>();
|
private static readonly HashSet<string> LandmarkDedupe = new HashSet<string>();
|
||||||
|
|
@ -244,6 +245,82 @@ public static class Chronicle
|
||||||
|
|
||||||
public static int FinalDossierCount => FinalDossiers.Count;
|
public static int FinalDossierCount => FinalDossiers.Count;
|
||||||
|
|
||||||
|
public static bool IsFavoriteSubject(long unitId)
|
||||||
|
{
|
||||||
|
return unitId != 0 && FavoriteIds.Contains(unitId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Track favorites across death so Fallen can filter like Living.</summary>
|
||||||
|
public static void SetFavoriteSubject(long unitId, bool favorite)
|
||||||
|
{
|
||||||
|
if (unitId == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool had = FavoriteIds.Contains(unitId);
|
||||||
|
if (favorite == had)
|
||||||
|
{
|
||||||
|
if (FinalDossiers.TryGetValue(unitId, out UnitDossier existing) && existing != null)
|
||||||
|
{
|
||||||
|
existing.IsFavorite = favorite;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (favorite)
|
||||||
|
{
|
||||||
|
FavoriteIds.Add(unitId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FavoriteIds.Remove(unitId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FinalDossiers.TryGetValue(unitId, out UnitDossier dossier) && dossier != null)
|
||||||
|
{
|
||||||
|
dossier.IsFavorite = favorite;
|
||||||
|
}
|
||||||
|
|
||||||
|
BumpRevision();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SyncFavoriteFromActor(Actor actor)
|
||||||
|
{
|
||||||
|
if (actor == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long id = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
id = actor.getID();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fav = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fav = actor.isAlive() && actor.isFavorite();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
fav = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFavoriteSubject(id, fav);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Harness / tuning: change subject cap and prune immediately.</summary>
|
/// <summary>Harness / tuning: change subject cap and prune immediately.</summary>
|
||||||
public static void SetMaxHistorySubjects(int max)
|
public static void SetMaxHistorySubjects(int max)
|
||||||
{
|
{
|
||||||
|
|
@ -534,6 +611,7 @@ public static class Chronicle
|
||||||
LoverPairKeys.Clear();
|
LoverPairKeys.Clear();
|
||||||
FriendPairKeys.Clear();
|
FriendPairKeys.Clear();
|
||||||
DeathLogged.Clear();
|
DeathLogged.Clear();
|
||||||
|
FavoriteIds.Clear();
|
||||||
FinalDossiers.Clear();
|
FinalDossiers.Clear();
|
||||||
LandmarkDedupe.Clear();
|
LandmarkDedupe.Clear();
|
||||||
LandmarksPerAge.Clear();
|
LandmarksPerAge.Clear();
|
||||||
|
|
@ -587,7 +665,8 @@ public static class Chronicle
|
||||||
public static void ShowHud()
|
public static void ShowHud()
|
||||||
{
|
{
|
||||||
EnsureWindow();
|
EnsureWindow();
|
||||||
if (ChronicleHud.DetailUnitId == 0)
|
// Default into Living only when opening from World with no detail pinned.
|
||||||
|
if (ChronicleHud.DetailUnitId == 0 && ChronicleHud.ActiveTab == ChronicleHud.LoreTab.World)
|
||||||
{
|
{
|
||||||
ChronicleHud.SetTab(ChronicleHud.LoreTab.Living);
|
ChronicleHud.SetTab(ChronicleHud.LoreTab.Living);
|
||||||
}
|
}
|
||||||
|
|
@ -706,6 +785,7 @@ public static class Chronicle
|
||||||
}
|
}
|
||||||
|
|
||||||
NoteFocusId(id);
|
NoteFocusId(id);
|
||||||
|
SyncFavoriteFromActor(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void NoteFocusId(long id)
|
private static void NoteFocusId(long id)
|
||||||
|
|
@ -867,6 +947,15 @@ public static class Chronicle
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fav)
|
||||||
|
{
|
||||||
|
FavoriteIds.Add(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FavoriteIds.Remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
string name = SafeName(actor);
|
string name = SafeName(actor);
|
||||||
string species = SpeciesOf(actor);
|
string species = SpeciesOf(actor);
|
||||||
if (!string.IsNullOrEmpty(needle))
|
if (!string.IsNullOrEmpty(needle))
|
||||||
|
|
@ -982,7 +1071,13 @@ public static class Chronicle
|
||||||
|
|
||||||
if (favoritesOnly)
|
if (favoritesOnly)
|
||||||
{
|
{
|
||||||
continue;
|
if (!IsFavoriteSubject(id)
|
||||||
|
&& !(FinalDossiers.TryGetValue(id, out UnitDossier favDossier)
|
||||||
|
&& favDossier != null
|
||||||
|
&& favDossier.IsFavorite))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IReadOnlyList<ChronicleEntry> snap = SnapshotForSubject(id);
|
IReadOnlyList<ChronicleEntry> snap = SnapshotForSubject(id);
|
||||||
|
|
@ -1003,13 +1098,21 @@ public static class Chronicle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fallenFav = IsFavoriteSubject(id);
|
||||||
|
if (!fallenFav
|
||||||
|
&& FinalDossiers.TryGetValue(id, out UnitDossier archived)
|
||||||
|
&& archived != null)
|
||||||
|
{
|
||||||
|
fallenFav = archived.IsFavorite;
|
||||||
|
}
|
||||||
|
|
||||||
byId[id] = new ChronicleCharacterSummary
|
byId[id] = new ChronicleCharacterSummary
|
||||||
{
|
{
|
||||||
UnitId = id,
|
UnitId = id,
|
||||||
Name = name,
|
Name = name,
|
||||||
SpeciesId = species,
|
SpeciesId = species,
|
||||||
HistoryCount = snap.Count,
|
HistoryCount = snap.Count,
|
||||||
IsFavorite = false,
|
IsFavorite = fallenFav,
|
||||||
IsAlive = false,
|
IsAlive = false,
|
||||||
IsRecent = false,
|
IsRecent = false,
|
||||||
DeathManner = LatestDeathMannerFor(id),
|
DeathManner = LatestDeathMannerFor(id),
|
||||||
|
|
@ -1021,6 +1124,12 @@ public static class Chronicle
|
||||||
var list = new List<ChronicleCharacterSummary>(byId.Values);
|
var list = new List<ChronicleCharacterSummary>(byId.Values);
|
||||||
list.Sort((a, b) =>
|
list.Sort((a, b) =>
|
||||||
{
|
{
|
||||||
|
// Favorites first on both Living and Fallen.
|
||||||
|
if (a.IsFavorite != b.IsFavorite)
|
||||||
|
{
|
||||||
|
return a.IsFavorite ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (wantFallen || (!a.IsAlive && !b.IsAlive))
|
if (wantFallen || (!a.IsAlive && !b.IsAlive))
|
||||||
{
|
{
|
||||||
// Fallen: most recent event first.
|
// Fallen: most recent event first.
|
||||||
|
|
@ -1037,12 +1146,7 @@ public static class Chronicle
|
||||||
return string.Compare(a.Title, b.Title, System.StringComparison.OrdinalIgnoreCase);
|
return string.Compare(a.Title, b.Title, System.StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Living: favorites, recently watched, event count, name.
|
// Living: recently watched, event count, name.
|
||||||
if (a.IsFavorite != b.IsFavorite)
|
|
||||||
{
|
|
||||||
return a.IsFavorite ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ra = a.IsRecent && a.RecentIndex >= 0 ? a.RecentIndex : int.MaxValue;
|
int ra = a.IsRecent && a.RecentIndex >= 0 ? a.RecentIndex : int.MaxValue;
|
||||||
int rb = b.IsRecent && b.RecentIndex >= 0 ? b.RecentIndex : int.MaxValue;
|
int rb = b.IsRecent && b.RecentIndex >= 0 ? b.RecentIndex : int.MaxValue;
|
||||||
if (ra != rb)
|
if (ra != rb)
|
||||||
|
|
@ -1270,7 +1374,8 @@ public static class Chronicle
|
||||||
string labelPrefix = "Fallen",
|
string labelPrefix = "Fallen",
|
||||||
AttackType attackType = AttackType.Age,
|
AttackType attackType = AttackType.Age,
|
||||||
long killerId = 0,
|
long killerId = 0,
|
||||||
Vector3 deathPos = default)
|
Vector3 deathPos = default,
|
||||||
|
bool favorite = false)
|
||||||
{
|
{
|
||||||
count = Mathf.Clamp(count, 1, MaxHistoryPerUnit);
|
count = Mathf.Clamp(count, 1, MaxHistoryPerUnit);
|
||||||
long id;
|
long id;
|
||||||
|
|
@ -1362,7 +1467,14 @@ public static class Chronicle
|
||||||
|
|
||||||
BumpRevision();
|
BumpRevision();
|
||||||
|
|
||||||
FinalDossiers[id] = UnitDossier.FromFallenArchive(id, who, sp, manner);
|
UnitDossier archived = UnitDossier.FromFallenArchive(id, who, sp, manner);
|
||||||
|
archived.IsFavorite = favorite;
|
||||||
|
FinalDossiers[id] = archived;
|
||||||
|
if (favorite)
|
||||||
|
{
|
||||||
|
FavoriteIds.Add(id);
|
||||||
|
}
|
||||||
|
|
||||||
PruneFinalDossiers();
|
PruneFinalDossiers();
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
@ -1615,6 +1727,11 @@ public static class Chronicle
|
||||||
}
|
}
|
||||||
|
|
||||||
FinalDossiers[id] = dossier;
|
FinalDossiers[id] = dossier;
|
||||||
|
if (dossier.IsFavorite)
|
||||||
|
{
|
||||||
|
FavoriteIds.Add(id);
|
||||||
|
}
|
||||||
|
|
||||||
PruneFinalDossiers();
|
PruneFinalDossiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1946,6 +2063,7 @@ public static class Chronicle
|
||||||
Histories.Remove(id);
|
Histories.Remove(id);
|
||||||
DeathLogged.Remove(id);
|
DeathLogged.Remove(id);
|
||||||
FinalDossiers.Remove(id);
|
FinalDossiers.Remove(id);
|
||||||
|
FavoriteIds.Remove(id);
|
||||||
need--;
|
need--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -848,20 +848,17 @@ public static class ChronicleHud
|
||||||
|
|
||||||
if (_favFilterBtn != null)
|
if (_favFilterBtn != null)
|
||||||
{
|
{
|
||||||
// Favorites filter is Living-only.
|
_favFilterBtn.gameObject.SetActive(chars && !detail);
|
||||||
_favFilterBtn.gameObject.SetActive(_tab == LoreTab.Living && !detail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_refreshBtn != null)
|
if (_refreshBtn != null)
|
||||||
{
|
{
|
||||||
_refreshBtn.gameObject.SetActive(chars && !detail);
|
_refreshBtn.gameObject.SetActive(chars && !detail);
|
||||||
// On Fallen (no fav), park refresh on the far right.
|
|
||||||
RectTransform refreshRt = _refreshBtn.GetComponent<RectTransform>();
|
RectTransform refreshRt = _refreshBtn.GetComponent<RectTransform>();
|
||||||
if (refreshRt != null)
|
if (refreshRt != null)
|
||||||
{
|
{
|
||||||
refreshRt.anchoredPosition = _tab == LoreTab.Living
|
// Search | Refresh | Fav on both Living and Fallen.
|
||||||
? new Vector2(-19f, 0f)
|
refreshRt.anchoredPosition = new Vector2(-19f, 0f);
|
||||||
: Vector2.zero;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1165,7 +1162,7 @@ public static class ChronicleHud
|
||||||
Chronicle.CharacterListScope scope = _tab == LoreTab.Fallen
|
Chronicle.CharacterListScope scope = _tab == LoreTab.Fallen
|
||||||
? Chronicle.CharacterListScope.Fallen
|
? Chronicle.CharacterListScope.Fallen
|
||||||
: Chronicle.CharacterListScope.Living;
|
: Chronicle.CharacterListScope.Living;
|
||||||
bool favOnly = scope == Chronicle.CharacterListScope.Living && _favoritesOnly;
|
bool favOnly = _favoritesOnly;
|
||||||
List<ChronicleCharacterSummary> list = Chronicle.ListCharacters(_searchText, favOnly, scope: scope);
|
List<ChronicleCharacterSummary> list = Chronicle.ListCharacters(_searchText, favOnly, scope: scope);
|
||||||
_lastCharFingerprint = CharacterFingerprint();
|
_lastCharFingerprint = CharacterFingerprint();
|
||||||
_builtAtRevision = Chronicle.HistoryRevision;
|
_builtAtRevision = Chronicle.HistoryRevision;
|
||||||
|
|
@ -1175,7 +1172,7 @@ public static class ChronicleHud
|
||||||
{
|
{
|
||||||
if (scope == Chronicle.CharacterListScope.Fallen)
|
if (scope == Chronicle.CharacterListScope.Fallen)
|
||||||
{
|
{
|
||||||
AddEmpty("No fallen yet");
|
AddEmpty(favOnly ? "No favorite fallen" : "No fallen yet");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1197,9 +1194,7 @@ public static class ChronicleHud
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope == Chronicle.CharacterListScope.Living
|
if ((favOnly || row.IsFavorite) && !wroteFavoritesHeader)
|
||||||
&& (favOnly || row.IsFavorite)
|
|
||||||
&& !wroteFavoritesHeader)
|
|
||||||
{
|
{
|
||||||
AddSection("Favorites");
|
AddSection("Favorites");
|
||||||
wroteFavoritesHeader = true;
|
wroteFavoritesHeader = true;
|
||||||
|
|
|
||||||
|
|
@ -689,6 +689,21 @@ internal static class HarnessScenarios
|
||||||
Step("ch18ft5f", "lore_refresh"),
|
Step("ch18ft5f", "lore_refresh"),
|
||||||
Step("ch18ft5g", "assert", expect: "lore_list_stale", value: "false"),
|
Step("ch18ft5g", "assert", expect: "lore_list_stale", value: "false"),
|
||||||
Step("ch18ft5h", "assert", expect: "fallen_list_top", value: "FreshFallen"),
|
Step("ch18ft5h", "assert", expect: "fallen_list_top", value: "FreshFallen"),
|
||||||
|
// Favorite filter on Fallen (same star control as Living).
|
||||||
|
Step(
|
||||||
|
"ch18ft5i",
|
||||||
|
"chronicle_orphan",
|
||||||
|
label: "FavFallen",
|
||||||
|
asset: "human",
|
||||||
|
value: "Fav",
|
||||||
|
count: 1,
|
||||||
|
expect: "Age",
|
||||||
|
tier: "place+fav"),
|
||||||
|
Step("ch18ft5j", "lore_favorites", value: "true"),
|
||||||
|
Step("ch18ft5k", "lore_refresh"),
|
||||||
|
Step("ch18ft5l", "assert", expect: "fallen_list_top", value: "FavFallen"),
|
||||||
|
Step("ch18ft5m", "lore_favorites", value: "false"),
|
||||||
|
Step("ch18ft5n", "lore_refresh"),
|
||||||
Step("ch18ft6", "screenshot", value: "hud-lore-fallen-tab.png"),
|
Step("ch18ft6", "screenshot", value: "hud-lore-fallen-tab.png"),
|
||||||
Step("ch18ft7", "wait", wait: 0.55f),
|
Step("ch18ft7", "wait", wait: 0.55f),
|
||||||
Step("ch18q12", "lore_tab", value: "world"),
|
Step("ch18q12", "lore_tab", value: "world"),
|
||||||
|
|
|
||||||
|
|
@ -224,23 +224,45 @@ public static class WatchCaption
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor == null || !actor.isAlive())
|
if (actor != null && actor.isAlive())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
actor.switchFavorite();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Chronicle.SyncFavoriteFromActor(actor);
|
||||||
|
RefreshFavoriteVisual(actor);
|
||||||
|
LogService.LogInfo(
|
||||||
|
$"[IdleSpectator] Favorite toggled name={SafeActorName(actor)} favorite={actor.isFavorite()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallen / archive: track in Chronicle so the Fallen filter stays consistent.
|
||||||
|
long id = _current != null ? _current.UnitId : 0;
|
||||||
|
if (id == 0)
|
||||||
|
{
|
||||||
|
id = Chronicle.CurrentHistorySubjectId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
bool next = !Chronicle.IsFavoriteSubject(id);
|
||||||
|
Chronicle.SetFavoriteSubject(id, next);
|
||||||
|
if (_current != null && _current.UnitId == id)
|
||||||
{
|
{
|
||||||
actor.switchFavorite();
|
_current.IsFavorite = next;
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshFavoriteVisual(actor);
|
RefreshFavoriteVisual(null);
|
||||||
LogService.LogInfo(
|
LogService.LogInfo($"[IdleSpectator] Favorite toggled fallen id={id} favorite={next}");
|
||||||
$"[IdleSpectator] Favorite toggled name={SafeActorName(actor)} favorite={actor.isFavorite()}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PinWhilePaused()
|
public static void PinWhilePaused()
|
||||||
|
|
@ -1266,13 +1288,34 @@ public static class WatchCaption
|
||||||
bool fav = false;
|
bool fav = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fav = actor != null && actor.isAlive() && actor.isFavorite();
|
if (actor != null && actor.isAlive() && actor.isFavorite())
|
||||||
|
{
|
||||||
|
fav = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
fav = false;
|
fav = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fav)
|
||||||
|
{
|
||||||
|
long id = _current != null ? _current.UnitId : 0;
|
||||||
|
if (id == 0 && actor != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
id = actor.getID();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fav = Chronicle.IsFavoriteSubject(id) || (_current != null && _current.IsFavorite);
|
||||||
|
}
|
||||||
|
|
||||||
HudIcons.Apply(_favoriteIcon, HudIcons.Favorite());
|
HudIcons.Apply(_favoriteIcon, HudIcons.Favorite());
|
||||||
_favoriteIcon.color = fav
|
_favoriteIcon.color = fav
|
||||||
? new Color(1f, 0.85f, 0.25f, 1f)
|
? new Color(1f, 0.85f, 0.25f, 1f)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "IdleSpectator",
|
"name": "IdleSpectator",
|
||||||
"author": "dazed",
|
"author": "dazed",
|
||||||
"version": "0.12.22",
|
"version": "0.12.24",
|
||||||
"description": "AFK Idle Spectator (I) + Lore (L). Subject soft cap 100k.",
|
"description": "AFK Idle Spectator (I) + Lore (L). Fallen favorites filter.",
|
||||||
"GUID": "com.dazed.idlespectator"
|
"GUID": "com.dazed.idlespectator"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue