128 lines
5.1 KiB
C#
128 lines
5.1 KiB
C#
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Snapshot of live actor facts for activity prose. Only observed fields - never invent events.
|
|
/// Species / taxonomy / flags come from <see cref="Actor.asset"/> for every unit in the game.
|
|
/// </summary>
|
|
public sealed class ActivityContext
|
|
{
|
|
public string ActorName = "";
|
|
/// <summary>Raw actor asset id (frog, human, beetle, ...).</summary>
|
|
public string SpeciesId = "";
|
|
/// <summary>Recovered living/body source for meaningful transformed variants.</summary>
|
|
public string BaseSpeciesId = "";
|
|
/// <summary>Readable species word for prose (locale / asset id).</summary>
|
|
public string SpeciesLabel = "";
|
|
public string Family = ActivityVoiceFamilies.Default;
|
|
public string ModifierTag = "";
|
|
public ProseVoice Voice;
|
|
public string TaxonomicKingdom = "";
|
|
public string TaxonomicPhylum = "";
|
|
public string TaxonomicClass = "";
|
|
public string TaxonomicOrder = "";
|
|
public string TaxonomicFamily = "";
|
|
public string TaxonomicGenus = "";
|
|
public string TaxonomicSpecies = "";
|
|
public bool IsHumanoid;
|
|
public bool IsCiv;
|
|
/// <summary>From <see cref="ActorAsset.default_animal"/> - animal tone when not civ humanoid.</summary>
|
|
public bool IsAnimal;
|
|
public int Age;
|
|
public bool IsChild;
|
|
public string JobId = "";
|
|
public string CityName = "";
|
|
public string KingdomName = "";
|
|
public bool IsKing;
|
|
public bool IsLeader;
|
|
public bool IsWarrior;
|
|
/// <summary>Observed role noun: king / leader / warrior when flags are true.</summary>
|
|
public string RoleLabel = "";
|
|
public string TargetName = "";
|
|
public bool TargetIsActor;
|
|
/// <summary>Building, city, kingdom, or soft place label for clauses.</summary>
|
|
public string PlaceLabel = "";
|
|
public string CarryingLabel = "";
|
|
public bool InCombat;
|
|
public bool HasAttackTarget;
|
|
/// <summary>Observed trait id - salts prose variety only; never spelled in the activity line.</summary>
|
|
public string TopTraitId = "";
|
|
/// <summary>Humanized trait label for salt/debug - dossier chips show the trait to the player.</summary>
|
|
public string TopTraitLabel = "";
|
|
/// <summary>Locomotion / body manner from live taxonomy/flags (insect, amphibian, flying, ...).</summary>
|
|
public string MannerTag = "default";
|
|
public string TaskKey = "";
|
|
|
|
public static ActivityContext Empty { get; } = new ActivityContext();
|
|
|
|
/// <summary>Harness / ForceNote: minimal context; species resolved from live library when present.</summary>
|
|
public static ActivityContext ForHarness(
|
|
string actorName,
|
|
string targetName,
|
|
string speciesId = "",
|
|
string place = "",
|
|
string carrying = "",
|
|
string jobId = "",
|
|
string taskKey = "",
|
|
string traitId = "",
|
|
bool isChild = false,
|
|
bool inCombat = false,
|
|
bool isKing = false,
|
|
bool isLeader = false,
|
|
bool isWarrior = false)
|
|
{
|
|
ActivityContext ctx = new ActivityContext
|
|
{
|
|
ActorName = actorName ?? "",
|
|
TargetName = targetName ?? "",
|
|
TargetIsActor = !string.IsNullOrEmpty(targetName),
|
|
SpeciesId = speciesId ?? "",
|
|
PlaceLabel = place ?? "",
|
|
CarryingLabel = carrying ?? "",
|
|
JobId = jobId ?? "",
|
|
TaskKey = taskKey ?? "",
|
|
TopTraitId = traitId ?? "",
|
|
IsChild = isChild,
|
|
InCombat = inCombat,
|
|
HasAttackTarget = inCombat && !string.IsNullOrEmpty(targetName),
|
|
IsKing = isKing,
|
|
IsLeader = isLeader,
|
|
IsWarrior = isWarrior
|
|
};
|
|
|
|
ActorAsset asset = ActivityAssetCatalog.TryGetActorAsset(ctx.SpeciesId);
|
|
if (asset != null)
|
|
{
|
|
ActivityVoiceResolver.ApplyToContext(ctx, asset);
|
|
ctx.SpeciesLabel = ActivityAssetCatalog.SpeciesDisplayLabel(asset);
|
|
}
|
|
else
|
|
{
|
|
ctx.SpeciesLabel = ActivityAssetCatalog.SpeciesDisplayLabel(ctx.SpeciesId);
|
|
ctx.Voice = ActivityVoiceResolver.Resolve(ctx.SpeciesId);
|
|
ctx.BaseSpeciesId = ctx.Voice.BaseSpeciesId;
|
|
ctx.Family = ctx.Voice.BaseFamily;
|
|
ctx.MannerTag = ActivityVoiceResolver.TagName(ctx.Voice.EffectiveActionTag);
|
|
ctx.ModifierTag = ActivityVoiceResolver.ModifierName(ctx.Voice.Modifier);
|
|
ctx.IsCiv = ctx.Voice.BaseIsCiv;
|
|
ctx.IsHumanoid = ctx.Voice.BaseIsHumanoid;
|
|
ctx.IsAnimal = ctx.Voice.BaseIsAnimal;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(taskKey)
|
|
&& taskKey.StartsWith("child_", System.StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
ctx.IsChild = true;
|
|
}
|
|
|
|
// Strip species-like place labels the same way live BuildContext does.
|
|
if (!string.IsNullOrEmpty(ctx.PlaceLabel)
|
|
&& ActivityInterestTable.LooksLikeSpeciesPublic(ctx.PlaceLabel, ctx.SpeciesId))
|
|
{
|
|
ctx.PlaceLabel = "";
|
|
}
|
|
|
|
ctx.RoleLabel = ActivityInterestTable.DeriveRoleLabel(ctx.IsKing, ctx.IsLeader, ctx.IsWarrior);
|
|
ctx.TopTraitLabel = ActivityInterestTable.TraitLabelFromId(ctx.TopTraitId);
|
|
return ctx;
|
|
}
|
|
}
|