192 lines
8.3 KiB
C#
192 lines
8.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Authored milestone-style gain/loss phrases for every live WorldBox status asset.
|
|
/// Runtime fallback is HUD-only safety; the harness audit requires authored coverage.
|
|
/// </summary>
|
|
public static class ActivityStatusProse
|
|
{
|
|
private static readonly Dictionary<string, (string gain, string loss)> Authored =
|
|
new Dictionary<string, (string, string)>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
["afterglow"] = ("Basks in an afterglow", "Lets the afterglow fade"),
|
|
["angry"] = ("Flies into a fury", "Cools off"),
|
|
["ash_fever"] = ("Catches ash fever", "Recovers from ash fever"),
|
|
["being_suspicious"] = ("Starts acting suspicious", "Stops looking so suspicious"),
|
|
["budding"] = ("Begins budding", "Splits off a bud offspring"),
|
|
["burning"] = ("Catches fire", "Stops burning"),
|
|
["caffeinated"] = ("Gets a caffeine rush", "Comes down from caffeine"),
|
|
["confused"] = ("Becomes confused", "Regains clarity"),
|
|
["cough"] = ("Starts coughing", "Stops coughing"),
|
|
["crying"] = ("Breaks into tears", "Dries their eyes"),
|
|
["cursed"] = ("Is cursed", "Shakes off the curse"),
|
|
["dash"] = ("Dashes forward", "Ends the dash"),
|
|
["dodge"] = ("Dodges aside", "Stops dodging"),
|
|
["drowning"] = ("Starts drowning", "Gets air again"),
|
|
["egg"] = ("Becomes an egg", "Hatches from an egg"),
|
|
["enchanted"] = ("Becomes enchanted", "Loses the enchantment"),
|
|
["fell_in_love"] = ("Falls in love", "Lets the infatuation pass"),
|
|
["festive_spirit"] = ("Catches the festive spirit", "Settles out of the festive mood"),
|
|
["flicked"] = ("Gets flicked", "Recovers from the flick"),
|
|
["frozen"] = ("Freezes solid", "Thaws out"),
|
|
["had_bad_dream"] = ("Has a bad dream", "Lets a bad dream fade"),
|
|
["had_good_dream"] = ("Has a good dream", "Lets a good dream fade"),
|
|
["had_nightmare"] = ("Has a nightmare", "Lets a nightmare fade"),
|
|
["handsome_migrant"] = ("Turns heads as a handsome migrant", "Stops drawing migrant attention"),
|
|
["inspired"] = ("Feels inspired", "Comes down from inspiration"),
|
|
["invincible"] = ("Becomes invincible", "Loses invincibility"),
|
|
["just_ate"] = ("Just finished eating", "Is ready to eat again"),
|
|
["laughing"] = ("Bursts out laughing", "Stops laughing"),
|
|
["magnetized"] = ("Becomes magnetized", "Loses the magnetic pull"),
|
|
["motivated"] = ("Feels motivated", "Loses motivation"),
|
|
["on_guard"] = ("Goes on guard", "Drops guard"),
|
|
["poisoned"] = ("Is poisoned", "Purges the poison"),
|
|
["possessed"] = ("Is possessed", "Breaks free of possession"),
|
|
["possessed_follower"] = ("Is converted into a possessed follower", "Breaks free of follower possession"),
|
|
["powerup"] = ("Powers up", "Loses the power-up"),
|
|
["pregnant"] = ("Becomes pregnant", "Gives birth"),
|
|
["pregnant_parthenogenesis"] = ("Becomes pregnant by parthenogenesis", "Gives birth alone"),
|
|
["rage"] = ("Enters a rage", "Leaves the rage behind"),
|
|
["recovery_combat_action"] = ("Needs a moment after combat", "Is ready for combat again"),
|
|
["recovery_plot"] = ("Needs a moment after a plot", "Is ready to plot again"),
|
|
["recovery_social"] = ("Needs a moment after socializing", "Is ready to socialize again"),
|
|
["recovery_spell"] = ("Needs a moment after casting", "Is ready to cast again"),
|
|
["shield"] = ("Raises a shield", "Drops the shield"),
|
|
["singing"] = ("Starts singing", "Stops singing"),
|
|
["sleeping"] = ("Falls asleep", "Wakes up"),
|
|
["slowness"] = ("Is slowed", "Regains normal speed"),
|
|
["soul_harvested"] = ("Has their soul harvested", "Recovers from soul harvest"),
|
|
["spell_boost"] = ("Gains a spell boost", "Loses the spell boost"),
|
|
["spell_silence"] = ("Is silenced", "Can cast again"),
|
|
["starving"] = ("Is starving", "Is no longer starving"),
|
|
["strange_urge"] = ("Feels a strange urge", "The strange urge passes"),
|
|
["stunned"] = ("Is stunned", "Shakes off the stun"),
|
|
["surprised"] = ("Is surprised", "Recovers from surprise"),
|
|
["swearing"] = ("Starts swearing", "Stops swearing"),
|
|
["taking_roots"] = ("Starts taking root", "Finishes rooting and sprouts offspring"),
|
|
["tantrum"] = ("Throws a tantrum", "Calms down from the tantrum"),
|
|
["uprooting"] = ("Emerges as a young plant", "Settles after emerging"),
|
|
["voices_in_my_head"] = ("Hears voices", "The voices fall quiet"),
|
|
};
|
|
|
|
public static bool HasAuthored(string statusId)
|
|
{
|
|
return !string.IsNullOrEmpty(statusId) && Authored.ContainsKey(statusId.Trim());
|
|
}
|
|
|
|
public static IEnumerable<string> AuthoredIds => Authored.Keys;
|
|
|
|
/// <summary>
|
|
/// Phrase without actor name. Authored when possible; otherwise localized/humanized fallback.
|
|
/// </summary>
|
|
public static string Phrase(string statusId, bool gained, out bool authored)
|
|
{
|
|
authored = false;
|
|
string id = (statusId ?? "").Trim();
|
|
if (string.IsNullOrEmpty(id))
|
|
{
|
|
return gained ? "gains an unknown status" : "loses an unknown status";
|
|
}
|
|
|
|
if (Authored.TryGetValue(id, out (string gain, string loss) pair))
|
|
{
|
|
authored = true;
|
|
string phrase = gained ? pair.gain : pair.loss;
|
|
return string.IsNullOrEmpty(phrase)
|
|
? FallbackPhrase(id, gained)
|
|
: phrase;
|
|
}
|
|
|
|
return FallbackPhrase(id, gained);
|
|
}
|
|
|
|
public static string FallbackPhrase(string statusId, bool gained)
|
|
{
|
|
string title = StatusLabelFromId(statusId);
|
|
if (string.IsNullOrEmpty(title))
|
|
{
|
|
title = HumanizeId(statusId);
|
|
}
|
|
|
|
return gained ? ("Becomes " + title) : ("Is no longer " + title);
|
|
}
|
|
|
|
public static string StatusLabelFromId(string statusId)
|
|
{
|
|
if (string.IsNullOrEmpty(statusId))
|
|
{
|
|
return "";
|
|
}
|
|
|
|
try
|
|
{
|
|
StatusAsset asset = AssetManager.status?.get(statusId.Trim());
|
|
if (asset != null)
|
|
{
|
|
string locale = asset.getLocaleID();
|
|
if (!string.IsNullOrEmpty(locale))
|
|
{
|
|
string localized = LocalizedTextManager.getText(locale);
|
|
if (!string.IsNullOrEmpty(localized)
|
|
&& !localized.Equals(locale, StringComparison.Ordinal)
|
|
&& localized.IndexOf('_') < 0)
|
|
{
|
|
return localized.Trim().ToLowerInvariant();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Localization may be unavailable during early boot.
|
|
}
|
|
|
|
return HumanizeId(statusId);
|
|
}
|
|
|
|
public static string HumanizeId(string statusId)
|
|
{
|
|
if (string.IsNullOrEmpty(statusId))
|
|
{
|
|
return "unknown status";
|
|
}
|
|
|
|
return statusId.Replace('_', ' ').Trim().ToLowerInvariant();
|
|
}
|
|
|
|
public static string TaskKey(string statusId, bool gained)
|
|
{
|
|
string id = string.IsNullOrEmpty(statusId) ? "unknown" : statusId.Trim();
|
|
return (gained ? "status_gain:" : "status_loss:") + id;
|
|
}
|
|
|
|
public static bool TryParseTaskKey(string key, out string statusId, out bool gained)
|
|
{
|
|
statusId = "";
|
|
gained = false;
|
|
if (string.IsNullOrEmpty(key))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
string k = key.Trim();
|
|
if (k.StartsWith("status_gain:", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
gained = true;
|
|
statusId = k.Substring("status_gain:".Length).Trim();
|
|
return !string.IsNullOrEmpty(statusId);
|
|
}
|
|
|
|
if (k.StartsWith("status_loss:", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
gained = false;
|
|
statusId = k.Substring("status_loss:".Length).Trim();
|
|
return !string.IsNullOrEmpty(statusId);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|