using Theriapolis.Core.Data; namespace Theriapolis.Core.Rules.Reputation; /// /// Phase 6 M2 — top-level aggregate of every reputation track owned by /// the player. Hangs off PlayScreen as a parallel-to-Character record /// (deliberate separation: Character is what the player is, /// PlayerReputation is what the world thinks of them). /// /// Round-trips through . /// public sealed class PlayerReputation { public FactionStanding Factions { get; } = new(); public Dictionary Personal { get; } = new(System.StringComparer.OrdinalIgnoreCase); public RepLedger Ledger { get; } = new(); /// Get-or-create the per-NPC personal disposition record for . public PersonalDisposition PersonalFor(string roleTag) { if (!Personal.TryGetValue(roleTag, out var p)) { p = new PersonalDisposition { RoleTag = roleTag }; Personal[roleTag] = p; } return p; } /// /// Submit a reputation event. Updates faction standing (with opposition /// cascade), the addressed NPC's personal disposition, and the ledger. /// public void Submit(RepEvent ev, IReadOnlyDictionary factions) { if (!string.IsNullOrEmpty(ev.FactionId) && ev.Magnitude != 0) Factions.Apply(ev.FactionId, ev.Magnitude, factions); if (!string.IsNullOrEmpty(ev.RoleTag)) PersonalFor(ev.RoleTag).Apply(ev); Ledger.Append(ev); } }