using System; namespace IdleSpectator; /// Builds target-aware happiness clauses from the authored catalog. public static class ActivityHappinessProse { public static string TaskKey(string effectId) { return "happiness:" + (effectId ?? "").Trim(); } public static bool TryParseTaskKey(string key, out string effectId) { effectId = ""; if (string.IsNullOrEmpty(key)) { return false; } const string prefix = "happiness:"; if (key.Length <= prefix.Length || !key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { return false; } effectId = key.Substring(prefix.Length).Trim(); return !string.IsNullOrEmpty(effectId); } public static string Clause( HappinessCatalogEntry entry, string relatedName, out bool usedRelated, out bool authored) { usedRelated = false; authored = entry != null && !entry.IsFallback && EventCatalog.Happiness.HasAuthored(entry.Id); if (entry == null) { return "feels a change in happiness"; } bool hasRelated = !string.IsNullOrEmpty(relatedName); string[] variants = hasRelated && entry.VariantsWithRelated != null && entry.VariantsWithRelated.Length > 0 ? entry.VariantsWithRelated : entry.VariantsWithoutRelated; if (variants == null || variants.Length == 0) { variants = entry.VariantsWithoutRelated; } if (variants == null || variants.Length == 0) { return "feels a change in happiness"; } int idx = Math.Abs((entry.Id + (relatedName ?? "")).GetHashCode()) % variants.Length; string template = variants[idx] ?? ""; usedRelated = hasRelated && template.IndexOf("{related}", StringComparison.Ordinal) >= 0; return ApplyTemplate(template, subjectName: "", relatedName: relatedName ?? ""); } public static string ApplyTemplate(string template, string subjectName, string relatedName) { if (string.IsNullOrEmpty(template)) { return ""; } string result = template; if (!string.IsNullOrEmpty(subjectName)) { result = result.Replace("{subject}", subjectName); } if (!string.IsNullOrEmpty(relatedName)) { result = result.Replace("{related}", relatedName); } else { // Strip unresolved related placeholders defensively. result = result.Replace("{related}", "someone"); } return result; } public static string FallbackClause(string effectId) { string id = string.IsNullOrEmpty(effectId) ? "unknown" : effectId.Replace('_', ' '); return "feels " + id; } }