Refactor activity action handling to incorporate terrain context in ActivityActionComposer and ActivityActionLexicon. Updated methods to enhance action phrasing based on the observed terrain, improving the clarity of activity prose. Added ActivityTerrain enum and terrain resolution logic in ActivityInterestTable and ActivityContext. Incremented version in mod.json to reflect these changes.
This commit is contained in:
parent
7439b3e7e6
commit
74bc7cf98f
9 changed files with 210 additions and 37 deletions
|
|
@ -109,7 +109,7 @@ public static class ActivityActionComposer
|
|||
verb = string.IsNullOrEmpty(humanized) ? "move" : humanized.ToLowerInvariant();
|
||||
}
|
||||
|
||||
string[] bag = ActivityActionLexicon.GetBag(voice, verb, hasTarget);
|
||||
string[] bag = ActivityActionLexicon.GetBag(voice, verb, hasTarget, ctx.Terrain);
|
||||
return Pick(bag, voice, verb, subjectId, lineIndex);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ namespace IdleSpectator;
|
|||
/// <summary>Phrase fragments keyed by the already-resolved voice. No ActorAsset lookup.</summary>
|
||||
public static class ActivityActionLexicon
|
||||
{
|
||||
public static string[] GetBag(ProseVoice voice, string verb, bool hasTarget)
|
||||
public static string[] GetBag(
|
||||
ProseVoice voice,
|
||||
string verb,
|
||||
bool hasTarget,
|
||||
ActivityTerrain terrain = ActivityTerrain.Unknown)
|
||||
{
|
||||
voice ??= ProseVoice.Unknown();
|
||||
string v = string.IsNullOrEmpty(verb) ? "move" : verb;
|
||||
|
|
@ -24,7 +28,7 @@ public static class ActivityActionLexicon
|
|||
string[] profile = ProfileBag(voice.ProfileTag, v, hasTarget);
|
||||
if (profile != null) return profile;
|
||||
|
||||
string[] body = BodyBag(voice.BaseBodyTag, v, hasTarget);
|
||||
string[] body = BodyBag(voice.BaseBodyTag, v, hasTarget, terrain);
|
||||
return body ?? GenericBag(v, hasTarget);
|
||||
}
|
||||
|
||||
|
|
@ -53,8 +57,8 @@ public static class ActivityActionLexicon
|
|||
"move" => new[] { "shuffles ahead in soft, uneven steps{place_at}", "creeps forward as spores drift{place_at}" },
|
||||
"wait" => new[] { "rests while spores drift around it{place_at}", "waits while faint spores drift{place_at}" },
|
||||
"play" => new[] { "puffs through an odd little game{place_at}", "bobs about in playful bursts of spores{place_at}" },
|
||||
"eat" => new[] { "feeds through the damp earth{place_at}", "draws a slow meal from decay{place_at}" },
|
||||
"sleep" => new[] { "settles into a damp, quiet rest{place_at}", "folds down among drifting spores{place_at}" },
|
||||
"eat" => new[] { "feeds slowly on decaying matter{place_at}", "draws a slow meal from decay{place_at}" },
|
||||
"sleep" => new[] { "settles into a soft, quiet rest{place_at}", "folds down among drifting spores{place_at}" },
|
||||
_ => GenericBag(verb, hasTarget)
|
||||
};
|
||||
case ActivityModifier.Tumor:
|
||||
|
|
@ -98,13 +102,13 @@ public static class ActivityActionLexicon
|
|||
{
|
||||
return body switch
|
||||
{
|
||||
ActivityBodyTag.Canine => new[] { "pads ahead with a stiff, uneven gait{place_at}", "sniffs the ground and shambles on{place_at}" },
|
||||
ActivityBodyTag.Canine => new[] { "pads ahead with a stiff, uneven gait{place_at}", "sniffs ahead and shambles on{place_at}" },
|
||||
ActivityBodyTag.Feline => new[] { "slinks ahead in eerie silence{place_at}", "pads forward with stiff precision{place_at}" },
|
||||
ActivityBodyTag.Insect => new[] { "skitters ahead on stiff little legs{place_at}", "crawls forward in twitching bursts{place_at}" },
|
||||
ActivityBodyTag.Plant => new[] { "creeps ahead in withered motion{place_at}", "drags dead growth across the ground{place_at}" },
|
||||
ActivityBodyTag.Plant => new[] { "creeps ahead in withered motion{place_at}", "drags dead growth behind it{place_at}" },
|
||||
ActivityBodyTag.Dragon => new[] { "lumbers ahead with the weight of a fallen giant{place_at}", "advances like ruin given motion{place_at}" },
|
||||
ActivityBodyTag.Bird => new[] { "flutters ahead on lifeless wings{place_at}", "hops forward in ragged, uneven motions{place_at}" },
|
||||
_ => new[] { "shambles forward over uneven ground{place_at}", "drifts along in restless undeath{place_at}" }
|
||||
_ => new[] { "shambles forward in uneven steps{place_at}", "drifts along in restless undeath{place_at}" }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +137,7 @@ public static class ActivityActionLexicon
|
|||
"sleep" => new[] { "coils into a guarded sleep{place_at}", "rests with one eye on the world{place_at}" },
|
||||
"eat" => new[] { "feeds with terrifying appetite{place_at}", "devours a meal at leisure{place_at}" },
|
||||
"laugh" => new[] { "rumbles with deep laughter{place_at}", "laughs in a dangerous rolling growl{place_at}" },
|
||||
"hunt" => Targeted(hasTarget, "descends on {target}{place_at}", "watches {target} from above{place_at}", "circles in search of prey{place_at}", "hunts across a wide range{place_at}"),
|
||||
"hunt" => Targeted(hasTarget, "descends on {target}{place_at}", "keeps {target} in sight{place_at}", "circles in search of prey{place_at}", "hunts across a wide range{place_at}"),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
|
@ -193,27 +197,36 @@ public static class ActivityActionLexicon
|
|||
return null;
|
||||
}
|
||||
|
||||
private static string[] BodyBag(ActivityBodyTag body, string verb, bool hasTarget)
|
||||
private static string[] BodyBag(
|
||||
ActivityBodyTag body,
|
||||
string verb,
|
||||
bool hasTarget,
|
||||
ActivityTerrain terrain)
|
||||
{
|
||||
if (verb == "move")
|
||||
{
|
||||
return body switch
|
||||
{
|
||||
ActivityBodyTag.Humanoid => new[] { "walks along, taking in the surroundings{place_at}", "wanders ahead at an easy pace{place_at}" },
|
||||
ActivityBodyTag.Canine => new[] { "trots along without hurry{place_at}", "roams ahead with nose to the ground{place_at}" },
|
||||
ActivityBodyTag.Canine => new[] { "trots along without hurry{place_at}", "roams ahead, following a scent{place_at}" },
|
||||
ActivityBodyTag.Feline => new[] { "pads softly along{place_at}", "slinks ahead at an easy pace{place_at}" },
|
||||
ActivityBodyTag.Bird => new[] { "flutters onward through the air{place_at}", "hops and flaps along nearby{place_at}" },
|
||||
ActivityBodyTag.Insect => new[] { "scuttles along without hurry{place_at}", "skitters across the ground{place_at}" },
|
||||
ActivityBodyTag.Bird => new[] { "flutters steadily onward{place_at}", "hops and flaps along nearby{place_at}" },
|
||||
ActivityBodyTag.Insect => new[] { "scuttles along without hurry{place_at}", "skitters quickly forward{place_at}" },
|
||||
ActivityBodyTag.Arachnid => new[] { "skitters onward on many legs{place_at}", "creeps ahead with careful steps{place_at}" },
|
||||
ActivityBodyTag.Amphibian => new[] { "hops from patch to patch{place_at}", "bounces along in damp, springy steps{place_at}" },
|
||||
ActivityBodyTag.Aquatic => new[] { "glides through the water{place_at}", "swims onward with easy strokes{place_at}" },
|
||||
ActivityBodyTag.Reptile => new[] { "slides along without hurry{place_at}", "creeps forward close to the ground{place_at}" },
|
||||
ActivityBodyTag.Amphibian => new[] { "hops from patch to patch{place_at}", "bounces along in springy steps{place_at}" },
|
||||
ActivityBodyTag.Aquatic => AquaticTerrainBag(
|
||||
terrain,
|
||||
"glides through the water{place_at}",
|
||||
"swims onward with easy strokes{place_at}",
|
||||
"moves forward in a smooth, winding motion{place_at}",
|
||||
"twists steadily onward{place_at}"),
|
||||
ActivityBodyTag.Reptile => new[] { "slides along without hurry{place_at}", "creeps forward in a low crawl{place_at}" },
|
||||
ActivityBodyTag.Livestock => new[] { "ambles along without hurry{place_at}", "wanders in slow, heavy steps{place_at}" },
|
||||
ActivityBodyTag.Plant => new[] { "creeps along as stems and leaves sway{place_at}", "eases forward in slow, leafy steps{place_at}" },
|
||||
ActivityBodyTag.Fungi => new[] { "drifts along in soft, uneven steps{place_at}", "spreads forward as spores trail behind{place_at}" },
|
||||
ActivityBodyTag.Protist => new[] { "oozes onward without hurry{place_at}", "pulses along in slow ripples{place_at}" },
|
||||
ActivityBodyTag.Machina => new[] { "moves ahead in measured steps{place_at}", "tracks a precise course{place_at}" },
|
||||
ActivityBodyTag.Mythic => new[] { "drifts forward as if barely touching the ground{place_at}", "moves with an uncanny grace{place_at}" },
|
||||
ActivityBodyTag.Mythic => new[] { "drifts forward without a sound{place_at}", "moves with an uncanny grace{place_at}" },
|
||||
ActivityBodyTag.Gregalia => new[] { "lopes onward with an uneven gait{place_at}", "wanders in twitchy, restless steps{place_at}" },
|
||||
ActivityBodyTag.Primate => new[] { "lopes onward with nimble curiosity{place_at}", "moves ahead in quick clever steps{place_at}" },
|
||||
ActivityBodyTag.Rodent => new[] { "scurries onward without hurry{place_at}", "pads ahead in quick little steps{place_at}" },
|
||||
|
|
@ -221,11 +234,11 @@ public static class ActivityActionLexicon
|
|||
ActivityBodyTag.Seal => new[] { "slides forward on its belly{place_at}", "bounds ahead with a sleek, rolling motion{place_at}" },
|
||||
ActivityBodyTag.Procyonid => new[] { "pads onward, nosing around{place_at}", "scampers ahead in nimble steps{place_at}" },
|
||||
ActivityBodyTag.Hyaenid => new[] { "lopes onward with rough confidence{place_at}", "trots ahead in rangy strides{place_at}" },
|
||||
ActivityBodyTag.Armadillo => new[] { "trundles onward close to the ground{place_at}", "scurries ahead in armored little steps{place_at}" },
|
||||
ActivityBodyTag.Crawler => new[] { "writhes forward across the ground{place_at}", "crawls ahead without hurry{place_at}" },
|
||||
ActivityBodyTag.Armadillo => new[] { "trundles onward with its body held low{place_at}", "scurries ahead in armored little steps{place_at}" },
|
||||
ActivityBodyTag.Crawler => new[] { "writhes steadily forward{place_at}", "crawls ahead without hurry{place_at}" },
|
||||
ActivityBodyTag.Cold => new[] { "moves onward in a breath of cold{place_at}", "drifts ahead with wintry calm{place_at}" },
|
||||
ActivityBodyTag.Crystal => new[] { "glides onward with crystalline precision{place_at}", "moves in stiff, glittering steps{place_at}" },
|
||||
ActivityBodyTag.Crab => new[] { "scuttles sideways across the ground{place_at}", "sidesteps onward behind a hard shell{place_at}" },
|
||||
ActivityBodyTag.Crab => new[] { "scuttles sideways{place_at}", "sidesteps onward behind a hard shell{place_at}" },
|
||||
_ => GenericBag(verb, hasTarget)
|
||||
};
|
||||
}
|
||||
|
|
@ -239,8 +252,14 @@ public static class ActivityActionLexicon
|
|||
ActivityBodyTag.Bird => new[] { "flutters through playful arcs{place_at}", "hops and wings about in play{place_at}" },
|
||||
ActivityBodyTag.Insect => new[] { "scuttles through a tiny game{place_at}", "darts about in quick bursts of play{place_at}" },
|
||||
ActivityBodyTag.Arachnid => new[] { "skitters through a restless game{place_at}", "darts about on many legs{place_at}" },
|
||||
ActivityBodyTag.Amphibian => new[] { "hops about in damp play{place_at}", "bounces through a lively game{place_at}" },
|
||||
ActivityBodyTag.Aquatic => new[] { "splashes through play in the water{place_at}", "darts and circles in play{place_at}" },
|
||||
ActivityBodyTag.Amphibian => new[] { "hops about in lively play{place_at}", "bounces through a lively game{place_at}" },
|
||||
ActivityBodyTag.Aquatic => AquaticTerrainBag(
|
||||
terrain,
|
||||
"splashes through play in the water{place_at}",
|
||||
"darts and circles through the water{place_at}",
|
||||
"twists and darts through play{place_at}",
|
||||
"wriggles through an energetic game{place_at}"),
|
||||
ActivityBodyTag.Crab => new[] { "scuttles through a lively game{place_at}", "sidesteps and spins in play{place_at}" },
|
||||
ActivityBodyTag.Reptile => new[] { "slides and coils in play{place_at}", "plays in slow, winding motions{place_at}" },
|
||||
ActivityBodyTag.Livestock => new[] { "stomps about in clumsy play{place_at}", "frolics in heavy, eager bursts{place_at}" },
|
||||
ActivityBodyTag.Plant => new[] { "sways through a slow game{place_at}", "twists and rustles in play{place_at}" },
|
||||
|
|
@ -260,7 +279,12 @@ public static class ActivityActionLexicon
|
|||
ActivityBodyTag.Amphibian => new[] { "crouches low and waits{place_at}", "sits still, ready to spring{place_at}" },
|
||||
ActivityBodyTag.Feline => new[] { "settles into a watchful crouch{place_at}", "waits without looking away{place_at}" },
|
||||
ActivityBodyTag.Canine => new[] { "waits with alert ears{place_at}", "holds a restless pause{place_at}" },
|
||||
ActivityBodyTag.Aquatic => new[] { "hovers in the water and waits{place_at}", "drifts almost motionless{place_at}" },
|
||||
ActivityBodyTag.Aquatic => AquaticTerrainBag(
|
||||
terrain,
|
||||
"hovers in the water and waits{place_at}",
|
||||
"drifts almost motionless in the water{place_at}",
|
||||
"rests almost motionless{place_at}",
|
||||
"waits with only a faint twitch{place_at}"),
|
||||
ActivityBodyTag.Bird => new[] { "perches and waits{place_at}", "holds a light watchful pause{place_at}" },
|
||||
ActivityBodyTag.Plant => new[] { "holds a rooted pause{place_at}", "stands still with leaves barely stirring{place_at}" },
|
||||
ActivityBodyTag.Machina => new[] { "idles in a watchful hold{place_at}", "stays still and scans the surroundings{place_at}" },
|
||||
|
|
@ -272,11 +296,11 @@ public static class ActivityActionLexicon
|
|||
{
|
||||
return body switch
|
||||
{
|
||||
ActivityBodyTag.Canine => Targeted(hasTarget, "hunts {target} with nose to the ground{place_at}", "follows {target}'s trail{place_at}", "follows the scent of prey{place_at}", "hunts with nose to the ground{place_at}"),
|
||||
ActivityBodyTag.Feline => Targeted(hasTarget, "hunts {target} in silence{place_at}", "stalks {target} from cover{place_at}", "hunts without making a sound{place_at}", "stalks prey from cover{place_at}"),
|
||||
ActivityBodyTag.Bird => Targeted(hasTarget, "hunts {target} from above{place_at}", "circles after {target}{place_at}", "hunts from above{place_at}", "circles after prey{place_at}"),
|
||||
ActivityBodyTag.Canine => Targeted(hasTarget, "hunts {target} by scent{place_at}", "follows {target}'s trail{place_at}", "follows the scent of prey{place_at}", "hunts by scent{place_at}"),
|
||||
ActivityBodyTag.Feline => Targeted(hasTarget, "hunts {target} in silence{place_at}", "stalks {target} without a sound{place_at}", "hunts without making a sound{place_at}", "stalks prey in silence{place_at}"),
|
||||
ActivityBodyTag.Bird => Targeted(hasTarget, "tracks {target} with sharp eyes{place_at}", "circles after {target}{place_at}", "searches keenly for prey{place_at}", "circles after prey{place_at}"),
|
||||
ActivityBodyTag.Insect => Targeted(hasTarget, "scuttles after {target}{place_at}", "darts toward {target}{place_at}", "searches for prey in quick bursts{place_at}", "scuttles after prey{place_at}"),
|
||||
ActivityBodyTag.Reptile => Targeted(hasTarget, "slides after {target}{place_at}", "creeps closer to {target}{place_at}", "waits low for prey to approach{place_at}", "stalks prey close to the ground{place_at}"),
|
||||
ActivityBodyTag.Reptile => Targeted(hasTarget, "slides after {target}{place_at}", "creeps closer to {target}{place_at}", "waits low for prey to approach{place_at}", "stalks prey in a low crawl{place_at}"),
|
||||
_ => Targeted(hasTarget, "pursues {target}{place_at}", "closes in on {target}{place_at}", "searches for prey{place_at}", "moves quietly on the hunt{place_at}")
|
||||
};
|
||||
}
|
||||
|
|
@ -298,7 +322,12 @@ public static class ActivityActionLexicon
|
|||
ActivityBodyTag.Canine => new[] { "curls into sleep{place_at}", "settles into deep rest{place_at}" },
|
||||
ActivityBodyTag.Feline => new[] { "curls into a neat sleep{place_at}", "settles into quiet rest{place_at}" },
|
||||
ActivityBodyTag.Bird => new[] { "tucks into sleep{place_at}", "roosts into rest{place_at}" },
|
||||
ActivityBodyTag.Aquatic => new[] { "drifts into rest in the water{place_at}", "settles into wet quiet{place_at}" },
|
||||
ActivityBodyTag.Aquatic => AquaticTerrainBag(
|
||||
terrain,
|
||||
"drifts into rest in the water{place_at}",
|
||||
"settles almost motionless in the water{place_at}",
|
||||
"goes still to rest{place_at}",
|
||||
"settles into a quiet sleep{place_at}"),
|
||||
ActivityBodyTag.Plant => new[] { "settles into leafy rest{place_at}", "goes completely still{place_at}" },
|
||||
_ => new[] { "settles into deep sleep{place_at}", "rests after the day's demands{place_at}" }
|
||||
},
|
||||
|
|
@ -367,4 +396,16 @@ public static class ActivityActionLexicon
|
|||
? new[] { withTargetA, withTargetB }
|
||||
: new[] { noTargetA, noTargetB };
|
||||
}
|
||||
|
||||
private static string[] AquaticTerrainBag(
|
||||
ActivityTerrain terrain,
|
||||
string liquidA,
|
||||
string liquidB,
|
||||
string nonLiquidA,
|
||||
string nonLiquidB)
|
||||
{
|
||||
return terrain == ActivityTerrain.Liquid
|
||||
? new[] { liquidA, liquidB }
|
||||
: new[] { nonLiquidA, nonLiquidB };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
namespace IdleSpectator;
|
||||
|
||||
public enum ActivityTerrain
|
||||
{
|
||||
Unknown,
|
||||
Land,
|
||||
Liquid
|
||||
}
|
||||
|
||||
/// <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.
|
||||
|
|
@ -41,6 +48,8 @@ public sealed class ActivityContext
|
|||
public bool TargetIsActor;
|
||||
/// <summary>Building, city, kingdom, or soft place label for clauses.</summary>
|
||||
public string PlaceLabel = "";
|
||||
/// <summary>Observed terrain under the actor when this snapshot was captured.</summary>
|
||||
public ActivityTerrain Terrain;
|
||||
public string CarryingLabel = "";
|
||||
public bool InCombat;
|
||||
public bool HasAttackTarget;
|
||||
|
|
@ -68,7 +77,8 @@ public sealed class ActivityContext
|
|||
bool inCombat = false,
|
||||
bool isKing = false,
|
||||
bool isLeader = false,
|
||||
bool isWarrior = false)
|
||||
bool isWarrior = false,
|
||||
ActivityTerrain terrain = ActivityTerrain.Unknown)
|
||||
{
|
||||
ActivityContext ctx = new ActivityContext
|
||||
{
|
||||
|
|
@ -81,6 +91,7 @@ public sealed class ActivityContext
|
|||
JobId = jobId ?? "",
|
||||
TaskKey = taskKey ?? "",
|
||||
TopTraitId = traitId ?? "",
|
||||
Terrain = terrain,
|
||||
IsChild = isChild,
|
||||
InCombat = inCombat,
|
||||
HasAttackTarget = inCombat && !string.IsNullOrEmpty(targetName),
|
||||
|
|
|
|||
|
|
@ -382,6 +382,7 @@ public static class ActivityInterestTable
|
|||
|
||||
ctx.TaskKey = taskKeyHint ?? SafeTaskId(actor);
|
||||
ctx.JobId = SafeJobId(actor);
|
||||
ctx.Terrain = ResolveTerrain(actor);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -463,6 +464,34 @@ public static class ActivityInterestTable
|
|||
return ctx;
|
||||
}
|
||||
|
||||
private static ActivityTerrain ResolveTerrain(Actor actor)
|
||||
{
|
||||
try
|
||||
{
|
||||
WorldTile tile = actor?.current_tile;
|
||||
if (tile?.Type == null)
|
||||
{
|
||||
return ActivityTerrain.Unknown;
|
||||
}
|
||||
|
||||
if (tile.Type.liquid)
|
||||
{
|
||||
return ActivityTerrain.Liquid;
|
||||
}
|
||||
|
||||
if (tile.Type.ground)
|
||||
{
|
||||
return ActivityTerrain.Land;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// A missing or changing tile is not safe evidence for environmental prose.
|
||||
}
|
||||
|
||||
return ActivityTerrain.Unknown;
|
||||
}
|
||||
|
||||
public static string DeriveRoleLabel(bool isKing, bool isLeader, bool isWarrior)
|
||||
{
|
||||
if (isKing)
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ public static class ActivityVoiceFamilies
|
|||
public const string Arachnid = "arachnid";
|
||||
public const string Amphibian = "amphibian";
|
||||
public const string Aquatic = "aquatic";
|
||||
public const string Crustacean = "crustacean";
|
||||
public const string Reptile = "reptile";
|
||||
public const string Livestock = "livestock";
|
||||
public const string Plant = "plant";
|
||||
|
|
|
|||
|
|
@ -42,6 +42,21 @@ public static class ActivityVoiceHarness
|
|||
"patient citrus"
|
||||
};
|
||||
|
||||
private static readonly string[] UngroundedTerrainFragments =
|
||||
{
|
||||
"through the water",
|
||||
"in the water",
|
||||
"through the air",
|
||||
"across the ground",
|
||||
"over uneven ground",
|
||||
"from above",
|
||||
"from cover",
|
||||
"close to the ground",
|
||||
"nose to the ground",
|
||||
"damp play",
|
||||
"wet quiet"
|
||||
};
|
||||
|
||||
public static ActivityVoiceAuditResult RunAudit(string outputDirectory)
|
||||
{
|
||||
List<string> ids = ActivityAssetCatalog.EnumerateLiveActorAssetIds();
|
||||
|
|
@ -58,6 +73,7 @@ public static class ActivityVoiceHarness
|
|||
int collisions = 0;
|
||||
int vehicleMismatch = 0;
|
||||
int awkwardProse = 0;
|
||||
int terrainLeaks = 0;
|
||||
string sample = "";
|
||||
string vehicleFingerprint = null;
|
||||
var fingerprints = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
|
|
@ -114,6 +130,14 @@ public static class ActivityVoiceHarness
|
|||
awkwardProse++;
|
||||
AddSample(ref sample, id + ":awkward=" + awkward);
|
||||
}
|
||||
string terrainLeak = voice.AssetKind == ActivityAssetKind.Vehicle
|
||||
? ""
|
||||
: FindPhrase(fingerprint, UngroundedTerrainFragments);
|
||||
if (!string.IsNullOrEmpty(terrainLeak))
|
||||
{
|
||||
terrainLeaks++;
|
||||
AddSample(ref sample, id + ":terrain=" + terrainLeak);
|
||||
}
|
||||
|
||||
if (voice.AssetKind == ActivityAssetKind.Vehicle)
|
||||
{
|
||||
|
|
@ -173,6 +197,7 @@ public static class ActivityVoiceHarness
|
|||
&& collisions == 0
|
||||
&& vehicleMismatch == 0
|
||||
&& awkwardProse == 0
|
||||
&& terrainLeaks == 0
|
||||
&& pairFail == 0
|
||||
&& liveContextOk;
|
||||
return new ActivityVoiceAuditResult
|
||||
|
|
@ -189,6 +214,7 @@ public static class ActivityVoiceHarness
|
|||
+ " collisions=" + collisions
|
||||
+ " vehicleMismatch=" + vehicleMismatch
|
||||
+ " awkwardProse=" + awkwardProse
|
||||
+ " terrainLeaks=" + terrainLeaks
|
||||
+ " pairFail=" + pairFail
|
||||
+ " liveContextOk=" + liveContextOk
|
||||
+ " sample='" + sample + "'"
|
||||
|
|
@ -196,11 +222,16 @@ public static class ActivityVoiceHarness
|
|||
}
|
||||
|
||||
private static string FindAwkwardPhrase(string fingerprint)
|
||||
{
|
||||
return FindPhrase(fingerprint, AwkwardProseFragments);
|
||||
}
|
||||
|
||||
private static string FindPhrase(string fingerprint, string[] phrases)
|
||||
{
|
||||
string text = fingerprint ?? "";
|
||||
for (int i = 0; i < AwkwardProseFragments.Length; i++)
|
||||
for (int i = 0; i < phrases.Length; i++)
|
||||
{
|
||||
string phrase = AwkwardProseFragments[i];
|
||||
string phrase = phrases[i];
|
||||
if (text.IndexOf(phrase, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return phrase;
|
||||
|
|
@ -222,6 +253,13 @@ public static class ActivityVoiceHarness
|
|||
}
|
||||
|
||||
ActivityContext ctx = ActivityInterestTable.BuildContext(actor, "move");
|
||||
ActivityTerrain expectedTerrain = actor.current_tile?.Type == null
|
||||
? ActivityTerrain.Unknown
|
||||
: actor.current_tile.Type.liquid
|
||||
? ActivityTerrain.Liquid
|
||||
: actor.current_tile.Type.ground
|
||||
? ActivityTerrain.Land
|
||||
: ActivityTerrain.Unknown;
|
||||
ActivityProse.Format(
|
||||
ActivityKind.TaskStart,
|
||||
"move",
|
||||
|
|
@ -234,6 +272,7 @@ public static class ActivityVoiceHarness
|
|||
bool ok = ctx.Voice != null
|
||||
&& ctx.Voice.LiveSpeciesId == (actor.asset.id ?? "")
|
||||
&& ctx.Voice.EffectiveActionTag != ActivityBodyTag.Default
|
||||
&& ctx.Terrain == expectedTerrain
|
||||
&& !string.IsNullOrEmpty(line);
|
||||
if (!ok)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -279,8 +279,8 @@ public static class ActivityVoiceResolver
|
|||
|| EqualsIgnore(taxOrder, "scorpiones")
|
||||
|| EqualsIgnore(taxOrder, "araneae")) return ActivityBodyTag.Arachnid;
|
||||
if (EqualsIgnore(taxClass, "amphibia")) return ActivityBodyTag.Amphibian;
|
||||
if (EqualsIgnore(taxClass, "malacostraca")
|
||||
|| EqualsIgnore(taxClass, "actinopterygii")
|
||||
if (EqualsIgnore(taxClass, "malacostraca")) return ActivityBodyTag.Crab;
|
||||
if (EqualsIgnore(taxClass, "actinopterygii")
|
||||
|| EqualsIgnore(taxClass, "chondrichthyes")
|
||||
|| EqualsIgnore(taxClass, "cephalopoda")
|
||||
|| EqualsIgnore(taxOrder, "testudines")) return ActivityBodyTag.Aquatic;
|
||||
|
|
@ -342,6 +342,7 @@ public static class ActivityVoiceResolver
|
|||
ActivityBodyTag.Amphibian => ActivityVoiceFamilies.Amphibian,
|
||||
ActivityBodyTag.Aquatic => ActivityVoiceFamilies.Aquatic,
|
||||
ActivityBodyTag.Seal => ActivityVoiceFamilies.Aquatic,
|
||||
ActivityBodyTag.Crab => ActivityVoiceFamilies.Crustacean,
|
||||
ActivityBodyTag.Reptile => ActivityVoiceFamilies.Reptile,
|
||||
ActivityBodyTag.Livestock => ActivityVoiceFamilies.Livestock,
|
||||
ActivityBodyTag.Plant => ActivityVoiceFamilies.Plant,
|
||||
|
|
@ -352,7 +353,6 @@ public static class ActivityVoiceResolver
|
|||
ActivityBodyTag.Dragon => ActivityVoiceFamilies.Mythic,
|
||||
ActivityBodyTag.Cold => ActivityVoiceFamilies.Mythic,
|
||||
ActivityBodyTag.Crystal => ActivityVoiceFamilies.Special,
|
||||
ActivityBodyTag.Crab => ActivityVoiceFamilies.Special,
|
||||
ActivityBodyTag.Alien => ActivityVoiceFamilies.Special,
|
||||
ActivityBodyTag.Construct => ActivityVoiceFamilies.Special,
|
||||
ActivityBodyTag.Tumor => ActivityVoiceFamilies.Special,
|
||||
|
|
|
|||
|
|
@ -2523,6 +2523,45 @@ public static class AgentHarness
|
|||
1,
|
||||
out string rhinoPlay,
|
||||
out _);
|
||||
ActivityProse.Format(
|
||||
ActivityKind.TaskStart,
|
||||
"task_unit_play",
|
||||
ActivityContext.ForHarness(
|
||||
"Crob",
|
||||
"",
|
||||
"crab",
|
||||
terrain: ActivityTerrain.Land),
|
||||
"Playing",
|
||||
108,
|
||||
1,
|
||||
out string crabLandPlay,
|
||||
out _);
|
||||
ActivityProse.Format(
|
||||
ActivityKind.TaskStart,
|
||||
"task_unit_play",
|
||||
ActivityContext.ForHarness(
|
||||
"Pip",
|
||||
"",
|
||||
"piranha",
|
||||
terrain: ActivityTerrain.Land),
|
||||
"Playing",
|
||||
109,
|
||||
1,
|
||||
out string fishLandPlay,
|
||||
out _);
|
||||
ActivityProse.Format(
|
||||
ActivityKind.TaskStart,
|
||||
"task_unit_play",
|
||||
ActivityContext.ForHarness(
|
||||
"Pip",
|
||||
"",
|
||||
"piranha",
|
||||
terrain: ActivityTerrain.Liquid),
|
||||
"Playing",
|
||||
109,
|
||||
1,
|
||||
out string fishWaterPlay,
|
||||
out _);
|
||||
bool taxDiverge = !string.IsNullOrEmpty(beetlePlay)
|
||||
&& !string.IsNullOrEmpty(frogPlay)
|
||||
&& !string.IsNullOrEmpty(rhinoPlay)
|
||||
|
|
@ -2543,13 +2582,26 @@ public static class AgentHarness
|
|||
|| frogPlay.IndexOf("splash", System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| frogPlay.IndexOf("damp", System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| frogPlay.IndexOf("jump", System.StringComparison.OrdinalIgnoreCase) >= 0);
|
||||
bool crabLandOk = !string.IsNullOrEmpty(crabLandPlay)
|
||||
&& crabLandPlay.IndexOf("water", System.StringComparison.OrdinalIgnoreCase) < 0
|
||||
&& crabLandPlay.IndexOf("wet", System.StringComparison.OrdinalIgnoreCase) < 0
|
||||
&& (crabLandPlay.IndexOf("scuttl", System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| crabLandPlay.IndexOf("sidestep", System.StringComparison.OrdinalIgnoreCase) >= 0);
|
||||
bool fishTerrainOk = !string.IsNullOrEmpty(fishLandPlay)
|
||||
&& !string.IsNullOrEmpty(fishWaterPlay)
|
||||
&& fishLandPlay.IndexOf("water", System.StringComparison.OrdinalIgnoreCase) < 0
|
||||
&& fishLandPlay.IndexOf("wet", System.StringComparison.OrdinalIgnoreCase) < 0
|
||||
&& fishWaterPlay.IndexOf("water", System.StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
|
||||
pass = farmerOk && minerOk && divergeOk && kingOk && huntPressureOk && taxDiverge;
|
||||
pass = farmerOk && minerOk && divergeOk && kingOk && huntPressureOk && taxDiverge
|
||||
&& crabLandOk && fishTerrainOk;
|
||||
detail =
|
||||
$"farmerOk={farmerOk} minerOk={minerOk} divergeOk={divergeOk} kingOk={kingOk} "
|
||||
+ $"huntPressureOk={huntPressureOk} taxDiverge={taxDiverge} "
|
||||
+ $"crabLandOk={crabLandOk} fishTerrainOk={fishTerrainOk} "
|
||||
+ $"farmer='{farmerLine}' miner='{minerLine}' king='{kingCombatLine}' hunt='{huntCombatLine}' "
|
||||
+ $"beetle='{beetlePlay}' frog='{frogPlay}' rhino='{rhinoPlay}'";
|
||||
+ $"beetle='{beetlePlay}' frog='{frogPlay}' rhino='{rhinoPlay}' "
|
||||
+ $"crabLand='{crabLandPlay}' fishLand='{fishLandPlay}' fishWater='{fishWaterPlay}'";
|
||||
break;
|
||||
}
|
||||
case "activity_prose_library":
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "IdleSpectator",
|
||||
"author": "dazed",
|
||||
"version": "0.12.72",
|
||||
"version": "0.12.73",
|
||||
"description": "AFK Idle Spectator (I) + Lore (L). Detailed living activity prose by default.",
|
||||
"GUID": "com.dazed.idlespectator"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue