worldbox-observer-mod/IdleSpectator/Story/LifeSagaOverview.cs
DazedAnon 6fb62c47d6 feat(saga): turn panel into a story card and snap hover restore
- Drop Evidence stats and Open Lore; keep lens as a quiet eyebrow
- Wrap stake/Cast/Legacy under the portrait; stack Legacy as lines
- End glyph hover immediately without panel-dwell keep-alive
- Re-apply dossier reason/traits/history on exit so the tip does not lag
2026-07-22 03:57:31 -05:00

135 lines
3.9 KiB
C#

using System.Collections.Generic;
namespace IdleSpectator;
/// <summary>
/// Compatibility façade over <see cref="LifeSagaPresentation"/>.
/// Prefer <see cref="LifeSagaPresentation.Build"/> for new UI.
/// </summary>
public static class LifeSagaOverview
{
public static LifeSagaSnapshot BuildSnapshot(LifeSagaSlot slot)
{
var snapshot = new LifeSagaSnapshot();
if (slot == null || slot.UnitId == 0)
{
return snapshot;
}
LifeSagaViewModel model = LifeSagaPresentation.Build(slot.UnitId);
snapshot.UnitId = model.UnitId;
snapshot.Header = model.Name;
snapshot.Subtitle = model.Title;
if (!string.IsNullOrEmpty(model.StakeLine))
{
snapshot.Rows.Add(new LifeSagaSnapshotRow
{
Kind = LifeSagaSnapshotRowKind.Headline,
Text = model.StakeLine
});
}
if (model.Cast.Count > 0)
{
var parts = new List<string>(model.Cast.Count);
for (int i = 0; i < model.Cast.Count; i++)
{
parts.Add(model.Cast[i].Relation + " " + model.Cast[i].Name);
}
snapshot.Rows.Add(new LifeSagaSnapshotRow
{
Kind = LifeSagaSnapshotRowKind.Circle,
Text = string.Join(" · ", parts)
});
}
if (!string.IsNullOrEmpty(model.LensEyebrow))
{
snapshot.Rows.Add(new LifeSagaSnapshotRow
{
Kind = LifeSagaSnapshotRowKind.Current,
Text = model.LensEyebrow
});
}
for (int i = 0; i < model.Legacy.Count; i++)
{
snapshot.Rows.Add(new LifeSagaSnapshotRow
{
Kind = LifeSagaSnapshotRowKind.Chapter,
ChapterKind = ToChapterKind(model.Legacy[i].Kind),
Text = model.Legacy[i].Line
});
}
return snapshot;
}
public static string Build(LifeSagaSlot slot)
{
return LifeSagaPresentation.BuildPlainText(slot);
}
public static float StandoutTraitScore(Actor actor)
{
return UnitDossier.ReadStandoutTraitNames(actor, 1).Count > 0 ? 100f : 0f;
}
private static LifeSagaChapterKind ToChapterKind(LifeSagaFactKind kind)
{
switch (kind)
{
case LifeSagaFactKind.Kill:
case LifeSagaFactKind.RivalEarned:
case LifeSagaFactKind.HardArcCombat:
return LifeSagaChapterKind.Combat;
case LifeSagaFactKind.WarJoin:
case LifeSagaFactKind.WarEnd:
case LifeSagaFactKind.HardArcWar:
return LifeSagaChapterKind.War;
case LifeSagaFactKind.PlotJoin:
case LifeSagaFactKind.PlotEnd:
case LifeSagaFactKind.HardArcPlot:
return LifeSagaChapterKind.Plot;
case LifeSagaFactKind.BondFormed:
case LifeSagaFactKind.HardArcLove:
return LifeSagaChapterKind.Love;
case LifeSagaFactKind.BondBroken:
case LifeSagaFactKind.Death:
case LifeSagaFactKind.HardArcGrief:
return LifeSagaChapterKind.Grief;
default:
return LifeSagaChapterKind.Unknown;
}
}
}
public enum LifeSagaSnapshotRowKind
{
Headline,
Current,
Circle,
Qualities,
Chapter
}
public sealed class LifeSagaSnapshotRow
{
public LifeSagaSnapshotRowKind Kind;
public LifeSagaChapterKind ChapterKind;
public string Text = "";
}
public sealed class LifeSagaSnapshot
{
public long UnitId;
public string Header = "";
public string Subtitle = "";
public readonly List<LifeSagaSnapshotRow> Rows = new List<LifeSagaSnapshotRow>();
public string ToPlainText()
{
return LifeSagaPresentation.BuildPlainText(UnitId);
}
}