Audit all
This commit is contained in:
parent
2d1d915156
commit
04731c2c06
16 changed files with 1258 additions and 271 deletions
|
|
@ -745,19 +745,9 @@ public static class ActivityLog
|
|||
amount != 0 ? amount : HappinessGameApi.ResolveAmount(effectId),
|
||||
HappinessSourceHook.Harness,
|
||||
related: null,
|
||||
role: HappinessRelationRole.None,
|
||||
forceRing: true);
|
||||
if (published != null && !string.IsNullOrEmpty(relatedName))
|
||||
{
|
||||
published.RelatedName = relatedName;
|
||||
HappinessCatalogEntry entry = EventCatalog.Happiness.GetOrFallback(effectId);
|
||||
string clause = ActivityHappinessProse.Clause(entry, relatedName, out bool usedRelated, out _);
|
||||
published.PlainClause = clause;
|
||||
published.RichClause = usedRelated
|
||||
? clause.Replace(relatedName, ActivityProse.ColorName(relatedName))
|
||||
: clause;
|
||||
}
|
||||
|
||||
role: HappinessContextBag.RoleForDeathEffect(effectId.Trim()),
|
||||
forceRing: true,
|
||||
relatedNameOverride: relatedName);
|
||||
if (published != null)
|
||||
{
|
||||
InterestFeeds.IngestForHarness(published);
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ public static class ActivityStatusProse
|
|||
new Dictionary<string, (string, string)>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
["afterglow"] = ("Basks in an afterglow", "Lets the afterglow fade"),
|
||||
["angry"] = ("Flies into a rage", "Cools off"),
|
||||
["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", "Finishes budding"),
|
||||
["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"),
|
||||
|
|
@ -45,10 +45,10 @@ public static class ActivityStatusProse
|
|||
["on_guard"] = ("Goes on guard", "Drops guard"),
|
||||
["poisoned"] = ("Is poisoned", "Purges the poison"),
|
||||
["possessed"] = ("Is possessed", "Breaks free of possession"),
|
||||
["possessed_follower"] = ("Falls under a possessed follower's sway", "Escapes the follower's sway"),
|
||||
["possessed_follower"] = ("Is converted into a possessed follower", "Breaks free of follower possession"),
|
||||
["powerup"] = ("Powers up", "Loses the power-up"),
|
||||
["pregnant"] = ("Becomes pregnant", "Is no longer pregnant"),
|
||||
["pregnant_parthenogenesis"] = ("Becomes pregnant by parthenogenesis", "Ends the parthenogenic pregnancy"),
|
||||
["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"),
|
||||
|
|
@ -66,9 +66,9 @@ public static class ActivityStatusProse
|
|||
["stunned"] = ("Is stunned", "Shakes off the stun"),
|
||||
["surprised"] = ("Is surprised", "Recovers from surprise"),
|
||||
["swearing"] = ("Starts swearing", "Stops swearing"),
|
||||
["taking_roots"] = ("Starts taking root", "Pulls free of the roots"),
|
||||
["taking_roots"] = ("Starts taking root", "Finishes rooting and sprouts offspring"),
|
||||
["tantrum"] = ("Throws a tantrum", "Calms down from the tantrum"),
|
||||
["uprooting"] = ("Starts uprooting", "Finishes uprooting"),
|
||||
["uprooting"] = ("Emerges as a young plant", "Settles after emerging"),
|
||||
["voices_in_my_head"] = ("Hears voices", "The voices fall quiet"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public static class AgentHarness
|
|||
private static Actor _lastSpawned;
|
||||
private static string _lastSpawnedAssetId = "";
|
||||
private static Actor _happinessPartner;
|
||||
private static long _activitySubjectId;
|
||||
private static bool _directorRunActive;
|
||||
private static string _rememberedFocusKey = "";
|
||||
private static string LastScreenshotPath = "";
|
||||
|
|
@ -56,6 +57,12 @@ public static class AgentHarness
|
|||
|
||||
public static bool Busy => Queue.Count > 0 || _waitUntil > 0f;
|
||||
|
||||
/// <summary>
|
||||
/// When true, relationship interest feeds still Emit while <see cref="Busy"/>
|
||||
/// (harness verification of live Harmony patches).
|
||||
/// </summary>
|
||||
public static bool ForceRelationshipFeeds;
|
||||
|
||||
/// <summary>
|
||||
/// When true, InterestDirector / SpeciesDiscovery stay frozen during harness commands.
|
||||
/// <c>director_run</c> temporarily clears this so dwell/interrupt/discovery can execute.
|
||||
|
|
@ -828,18 +835,24 @@ public static class AgentHarness
|
|||
|
||||
case "happiness_force_note":
|
||||
{
|
||||
long id = WatchCaption.CurrentUnitId;
|
||||
Actor focus = MoveCamera.hasFocusUnit() ? MoveCamera._focus_unit : null;
|
||||
if (id == 0 && focus != null)
|
||||
long id = 0;
|
||||
try
|
||||
{
|
||||
try
|
||||
if (focus != null)
|
||||
{
|
||||
id = focus.getID();
|
||||
}
|
||||
catch
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
|
||||
// Prefer live focus over a stale dossier CurrentUnitId.
|
||||
if (id == 0)
|
||||
{
|
||||
id = WatchCaption.CurrentUnitId;
|
||||
}
|
||||
|
||||
string effectId = !string.IsNullOrEmpty(cmd.value) ? cmd.value.Trim() : "just_ate";
|
||||
|
|
@ -1031,6 +1044,50 @@ public static class AgentHarness
|
|||
break;
|
||||
}
|
||||
|
||||
case "relationship_set_parent":
|
||||
{
|
||||
Actor child = MoveCamera.hasFocusUnit() ? MoveCamera._focus_unit : _lastSpawned;
|
||||
Actor parent = _happinessPartner;
|
||||
bool ok = false;
|
||||
string detail;
|
||||
ForceRelationshipFeeds = true;
|
||||
try
|
||||
{
|
||||
if (child != null && parent != null && child.isAlive() && parent.isAlive()
|
||||
&& child != parent)
|
||||
{
|
||||
child.setParent1(parent);
|
||||
ok = true;
|
||||
detail = $"parent={SafeName(parent)} child={SafeName(child)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
detail = "need focus child + remembered parent";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
detail = "exception: " + ex.Message;
|
||||
ok = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ForceRelationshipFeeds = false;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
_cmdOk++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cmdFail++;
|
||||
}
|
||||
|
||||
Emit(cmd, ok, detail: detail);
|
||||
break;
|
||||
}
|
||||
|
||||
case "happiness_bond_friends":
|
||||
{
|
||||
Actor a = MoveCamera.hasFocusUnit() ? MoveCamera._focus_unit : null;
|
||||
|
|
@ -1070,21 +1127,45 @@ public static class AgentHarness
|
|||
|
||||
case "happiness_kill_partner":
|
||||
{
|
||||
Actor focus = MoveCamera.hasFocusUnit() ? MoveCamera._focus_unit : null;
|
||||
Actor partner = _happinessPartner;
|
||||
bool ok = false;
|
||||
string err = "";
|
||||
try
|
||||
{
|
||||
if (partner != null && partner.isAlive())
|
||||
{
|
||||
partner.die(true, AttackType.Divine);
|
||||
ok = !partner.isAlive();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
err = ex.Message ?? "die_exception";
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
try
|
||||
{
|
||||
ok = partner != null && !partner.isAlive();
|
||||
}
|
||||
catch
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// Keep the surviving focus so grief asserts resolve the right subject.
|
||||
try
|
||||
{
|
||||
if (focus != null && focus.isAlive())
|
||||
{
|
||||
CameraDirector.FocusUnit(focus);
|
||||
_activitySubjectId = focus.getID();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
_cmdOk++;
|
||||
|
|
@ -1095,7 +1176,11 @@ public static class AgentHarness
|
|||
}
|
||||
|
||||
WatchCaption.ForceRefreshHistory();
|
||||
Emit(cmd, ok, detail: $"killed={SafeName(partner)} ok={ok}");
|
||||
Emit(
|
||||
cmd,
|
||||
ok,
|
||||
detail: $"killed={SafeName(partner)} ok={ok}"
|
||||
+ (string.IsNullOrEmpty(err) ? "" : " err=" + err));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2381,6 +2466,15 @@ public static class AgentHarness
|
|||
}
|
||||
|
||||
CameraDirector.FocusUnit(unit);
|
||||
try
|
||||
{
|
||||
_activitySubjectId = unit.getID();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_activitySubjectId = 0;
|
||||
}
|
||||
|
||||
_cmdOk++;
|
||||
Emit(cmd, ok: true, detail: $"unit={SafeName(unit)} asset={(unit.asset != null ? unit.asset.id : "?")}");
|
||||
}
|
||||
|
|
@ -2681,7 +2775,7 @@ public static class AgentHarness
|
|||
|
||||
entry = EventCatalog.Plot.GetOrFallback(id);
|
||||
key = "plot:" + entry.Id + ":new:" + EventFeedUtil.SafeId(unit);
|
||||
label = entry.MakeLabel(EventFeedUtil.SafeName(unit), "new");
|
||||
label = EventReason.Plot(unit, entry.LabelTemplate, "new", entry.Id);
|
||||
strength = entry.EventStrength;
|
||||
category = entry.Category;
|
||||
source = "plot";
|
||||
|
|
@ -2744,7 +2838,7 @@ public static class AgentHarness
|
|||
|
||||
entry = EventCatalog.Trait.GetOrFallback(id);
|
||||
key = "trait:" + entry.Id + ":gains:" + EventFeedUtil.SafeId(unit);
|
||||
label = EventFeedUtil.SafeName(unit) + " gains " + entry.Id;
|
||||
label = EventReason.Trait(unit, entry.Id, gained: true);
|
||||
strength = entry.EventStrength;
|
||||
category = entry.Category;
|
||||
source = "trait";
|
||||
|
|
@ -2756,7 +2850,7 @@ public static class AgentHarness
|
|||
}
|
||||
|
||||
key = "meta:" + id + ":" + EventFeedUtil.SafeId(unit);
|
||||
label = "Meta: " + id + " (" + EventFeedUtil.SafeName(unit) + ")";
|
||||
label = EventReason.MetaNew(unit, id);
|
||||
strength = 74f;
|
||||
category = "Politics";
|
||||
source = "meta";
|
||||
|
|
@ -2764,7 +2858,7 @@ public static class AgentHarness
|
|||
case "boat":
|
||||
id = "boat_unload";
|
||||
key = "boat:boat_unload:" + EventFeedUtil.SafeId(unit);
|
||||
label = "Boat unloads: " + EventFeedUtil.SafeName(unit);
|
||||
label = EventReason.Boat(unit, "unload");
|
||||
strength = 72f;
|
||||
category = "Travel";
|
||||
source = "boat";
|
||||
|
|
@ -3590,6 +3684,41 @@ public static class AgentHarness
|
|||
detail = $"want='{want}' found='{found}' pending={InterestRegistry.PendingCount}";
|
||||
break;
|
||||
}
|
||||
case "interest_label_contains":
|
||||
{
|
||||
string want = (cmd.value ?? cmd.expect ?? "").Trim();
|
||||
bool have = false;
|
||||
string found = "";
|
||||
if (!string.IsNullOrEmpty(want))
|
||||
{
|
||||
string currentLabel = InterestDirector.CurrentLabel ?? "";
|
||||
if (currentLabel.IndexOf(want, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
have = true;
|
||||
found = currentLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var pending = new System.Collections.Generic.List<InterestCandidate>(64);
|
||||
InterestRegistry.CopyPending(pending);
|
||||
for (int i = 0; i < pending.Count; i++)
|
||||
{
|
||||
InterestCandidate c = pending[i];
|
||||
string label = c?.Label ?? "";
|
||||
if (label.IndexOf(want, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
have = true;
|
||||
found = label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pass = have;
|
||||
detail = $"want='{want}' found='{found}' pending={InterestRegistry.PendingCount}";
|
||||
break;
|
||||
}
|
||||
case "interest_no_key":
|
||||
{
|
||||
string want = (cmd.value ?? cmd.expect ?? "").Trim();
|
||||
|
|
@ -6154,6 +6283,7 @@ public static class AgentHarness
|
|||
long focusId = MoveCamera._focus_unit.getID();
|
||||
if (focusId != 0)
|
||||
{
|
||||
_activitySubjectId = focusId;
|
||||
return focusId;
|
||||
}
|
||||
}
|
||||
|
|
@ -6163,6 +6293,11 @@ public static class AgentHarness
|
|||
// ignore
|
||||
}
|
||||
|
||||
if (_activitySubjectId != 0)
|
||||
{
|
||||
return _activitySubjectId;
|
||||
}
|
||||
|
||||
return WatchCaption.CurrentUnitId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,6 +215,173 @@ public static class EventReason
|
|||
return gained ? an + " gains " + id : an + " loses " + id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plot labels are phase-aware: start templates stay progressive; finish verbs fire on complete.
|
||||
/// </summary>
|
||||
public static string Plot(Actor a, string template, string phase, string plotId = "")
|
||||
{
|
||||
string filled = Apply(
|
||||
string.IsNullOrEmpty(template) ? "{a} is plotting" : template,
|
||||
a,
|
||||
id: plotId);
|
||||
string p = (phase ?? "active").Trim().ToLowerInvariant();
|
||||
switch (p)
|
||||
{
|
||||
case "complete":
|
||||
case "finished":
|
||||
case "finish":
|
||||
return RewritePlotProgressive(filled, "finishes ");
|
||||
case "cancel":
|
||||
case "cancelled":
|
||||
case "canceled":
|
||||
return RewritePlotAbandon(filled);
|
||||
case "leave":
|
||||
return NameOrSomeone(a) + " leaves a plot";
|
||||
case "join":
|
||||
return filled;
|
||||
case "new":
|
||||
case "active":
|
||||
default:
|
||||
return RewritePlotStart(filled);
|
||||
}
|
||||
}
|
||||
|
||||
private static string RewritePlotStart(string label)
|
||||
{
|
||||
if (string.IsNullOrEmpty(label))
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
// Finish-style verbs on start → "plots to …"
|
||||
string[] finishVerbs =
|
||||
{
|
||||
"summons ", "casts ", "splits ", "causes ", "performs ",
|
||||
};
|
||||
foreach (string verb in finishVerbs)
|
||||
{
|
||||
int idx = IndexOfWordPhrase(label, verb);
|
||||
if (idx < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string infinitive = InfinitiveFromFinishVerb(verb.TrimEnd());
|
||||
return label.Substring(0, idx) + "plots to " + infinitive + label.Substring(idx + verb.Length);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
private static string RewritePlotProgressive(string label, string replacementPrefix)
|
||||
{
|
||||
if (string.IsNullOrEmpty(label))
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
string[] progressives =
|
||||
{
|
||||
"is plotting ", "is joining ", "is breaking ", "is ending ",
|
||||
"is writing ", "is forging ", "is founding ", "is ascending ",
|
||||
};
|
||||
foreach (string progressive in progressives)
|
||||
{
|
||||
int idx = IndexOfWordPhrase(label, progressive);
|
||||
if (idx >= 0)
|
||||
{
|
||||
// "is plotting " → "plotting " after dropping "is "
|
||||
return label.Substring(0, idx)
|
||||
+ replacementPrefix
|
||||
+ progressive.Substring(3)
|
||||
+ label.Substring(idx + progressive.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// Already a finish verb ("summons", "casts", …) - correct for complete.
|
||||
return label;
|
||||
}
|
||||
|
||||
private static string RewritePlotAbandon(string label)
|
||||
{
|
||||
if (string.IsNullOrEmpty(label))
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
string progressive = RewritePlotProgressive(label, "abandons ");
|
||||
if (progressive != label)
|
||||
{
|
||||
return progressive;
|
||||
}
|
||||
|
||||
string[] finishVerbs =
|
||||
{
|
||||
"summons ", "casts ", "splits ", "causes ", "performs ",
|
||||
};
|
||||
foreach (string verb in finishVerbs)
|
||||
{
|
||||
int idx = IndexOfWordPhrase(label, verb);
|
||||
if (idx < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string gerund = GerundFromFinishVerb(verb.TrimEnd());
|
||||
return label.Substring(0, idx) + "abandons " + gerund + label.Substring(idx + verb.Length);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
private static string InfinitiveFromFinishVerb(string verb)
|
||||
{
|
||||
switch (verb)
|
||||
{
|
||||
case "summons":
|
||||
return "summon ";
|
||||
case "casts":
|
||||
return "cast ";
|
||||
case "splits":
|
||||
return "split ";
|
||||
case "causes":
|
||||
return "cause ";
|
||||
case "performs":
|
||||
return "perform ";
|
||||
default:
|
||||
return verb + " ";
|
||||
}
|
||||
}
|
||||
|
||||
private static string GerundFromFinishVerb(string verb)
|
||||
{
|
||||
switch (verb)
|
||||
{
|
||||
case "summons":
|
||||
return "summoning ";
|
||||
case "casts":
|
||||
return "casting ";
|
||||
case "splits":
|
||||
return "splitting ";
|
||||
case "causes":
|
||||
return "causing ";
|
||||
case "performs":
|
||||
return "performing ";
|
||||
default:
|
||||
return verb + " ";
|
||||
}
|
||||
}
|
||||
|
||||
private static int IndexOfWordPhrase(string haystack, string phrase)
|
||||
{
|
||||
if (string.IsNullOrEmpty(haystack) || string.IsNullOrEmpty(phrase))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return haystack.IndexOf(phrase, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static string Boat(Actor a, string phase)
|
||||
{
|
||||
string an = NameOrSomeone(a);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public static class PlotInterestFeed
|
|||
return;
|
||||
}
|
||||
|
||||
string label = EventReason.Apply(entry.LabelTemplate, follow, id: entry.Id);
|
||||
string label = EventReason.Plot(follow, entry.LabelTemplate, phase, entry.Id);
|
||||
string key = "plot:" + entry.Id + ":" + (phase ?? "active") + ":" + EventFeedUtil.SafeId(follow);
|
||||
EventFeedUtil.Register(
|
||||
key,
|
||||
|
|
|
|||
|
|
@ -5,9 +5,15 @@ namespace IdleSpectator;
|
|||
/// <summary>Registers relationship lifecycle interest candidates under the ownership contract.</summary>
|
||||
public static class RelationshipInterestFeed
|
||||
{
|
||||
private const float FoundingMergeSeconds = 0.35f;
|
||||
private static float _foundingAt = -999f;
|
||||
private static long _foundingActorId;
|
||||
|
||||
public static void Emit(string eventId, Actor subject, Actor related, string labelOverride = null)
|
||||
{
|
||||
if (AgentHarness.Busy || subject == null || !subject.isAlive())
|
||||
if ((AgentHarness.Busy && !AgentHarness.ForceRelationshipFeeds)
|
||||
|| subject == null
|
||||
|| !subject.isAlive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -35,6 +41,29 @@ public static class RelationshipInterestFeed
|
|||
? labelOverride
|
||||
: TypedLabel(eventId, subject, relatedAlive);
|
||||
|
||||
// BehFamilyGroupNew always calls newFamily first - keep family_group_new on but
|
||||
// share the founding interest key so one orange reason wins for that beat.
|
||||
if (eventId == "family_group_new" && IsRecentFounding(subject))
|
||||
{
|
||||
string foundingKey = FoundingKey(subject);
|
||||
if (InterestRegistry.TryGet(foundingKey, out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EventFeedUtil.Register(
|
||||
foundingKey,
|
||||
"relationship",
|
||||
entry.Category,
|
||||
label,
|
||||
entry.Id,
|
||||
entry.EventStrength,
|
||||
subject.current_position,
|
||||
subject,
|
||||
related: relatedAlive);
|
||||
return;
|
||||
}
|
||||
|
||||
if (claimsPeer && relatedAlive == null)
|
||||
{
|
||||
string soloKey = "rel:" + entry.Id + ":" + EventFeedUtil.SafeId(subject) + ":solo";
|
||||
|
|
@ -65,7 +94,7 @@ public static class RelationshipInterestFeed
|
|||
|
||||
public static void EmitFamily(string eventId, object family, Actor anchor)
|
||||
{
|
||||
if (AgentHarness.Busy)
|
||||
if (AgentHarness.Busy && !AgentHarness.ForceRelationshipFeeds)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -85,6 +114,12 @@ public static class RelationshipInterestFeed
|
|||
Actor related = ActorRelation.FirstFamilyPeer(follow);
|
||||
string label = TypedLabel(eventId, follow, related);
|
||||
string key = "rel:" + entry.Id + ":" + EventFeedUtil.SafeId(follow);
|
||||
if (eventId == "new_family")
|
||||
{
|
||||
NoteFounding(follow);
|
||||
key = FoundingKey(follow);
|
||||
}
|
||||
|
||||
EventFeedUtil.Register(
|
||||
key,
|
||||
"relationship",
|
||||
|
|
@ -97,6 +132,31 @@ public static class RelationshipInterestFeed
|
|||
related: related);
|
||||
}
|
||||
|
||||
private static void NoteFounding(Actor anchor)
|
||||
{
|
||||
_foundingAt = Time.unscaledTime;
|
||||
_foundingActorId = EventFeedUtil.SafeId(anchor);
|
||||
}
|
||||
|
||||
private static bool IsRecentFounding(Actor subject)
|
||||
{
|
||||
if (subject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
long id = EventFeedUtil.SafeId(subject);
|
||||
if (id == 0 || id != _foundingActorId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Time.unscaledTime - _foundingAt <= FoundingMergeSeconds;
|
||||
}
|
||||
|
||||
private static string FoundingKey(Actor anchor) =>
|
||||
"rel:new_family:" + EventFeedUtil.SafeId(anchor);
|
||||
|
||||
private static string TypedLabel(string eventId, Actor subject, Actor related)
|
||||
{
|
||||
switch (eventId)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
using ai.behaviours;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace IdleSpectator;
|
||||
|
||||
/// <summary>
|
||||
/// Authoritative happiness hooks. Universal changeHappiness covers every effect id;
|
||||
/// death/birth patches supply related-unit context the history struct lacks.
|
||||
/// apply-site prefixes supply related-unit context the history struct lacks.
|
||||
/// </summary>
|
||||
[HarmonyPatch]
|
||||
internal static class ActorHappinessPatches
|
||||
|
|
@ -85,30 +86,49 @@ internal static class ActorHappinessPatches
|
|||
[HarmonyPrefix]
|
||||
public static void PrefixLovers(Actor __instance, Actor pTarget)
|
||||
{
|
||||
// Context for status fell_in_love → changeHappiness("fallen_in_love") during the body.
|
||||
// Do not NoteCanonicalMilestone here - that would merge the ring before it writes.
|
||||
HappinessContextBag.SetPair(__instance, pTarget, HappinessRelationRole.Lover, "fallen_in_love");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Live path: status fell_in_love action_on_receive → changeHappiness("fallen_in_love").
|
||||
/// Bridge still publishes for units that suppress changeHappiness (no emotions / egg),
|
||||
/// and ensures related names when the status path is skipped. Self-merge within 0.35s
|
||||
/// collapses the double for emotion units.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.becomeLoversWith))]
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPriority(Priority.First)]
|
||||
public static void PostfixLovers(Actor __instance, Actor pTarget)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (__instance != null)
|
||||
{
|
||||
HappinessEventRouter.NoteCanonicalMilestone(__instance.getID(), "milestone_lover");
|
||||
}
|
||||
|
||||
if (pTarget != null)
|
||||
{
|
||||
HappinessEventRouter.NoteCanonicalMilestone(pTarget.getID(), "milestone_lover");
|
||||
}
|
||||
BridgeFallenInLove(__instance, pTarget);
|
||||
BridgeFallenInLove(pTarget, __instance);
|
||||
}
|
||||
catch
|
||||
finally
|
||||
{
|
||||
// ignore
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.becomeLoversWith))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixLovers()
|
||||
private static void BridgeFallenInLove(Actor subject, Actor related)
|
||||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
if (subject == null || !subject.isAlive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Actor relatedAlive = related != null && related.isAlive() ? related : null;
|
||||
int amount = HappinessGameApi.ResolveAmount("fallen_in_love", 0);
|
||||
HappinessEventRouter.PublishApplied(
|
||||
subject,
|
||||
"fallen_in_love",
|
||||
amount,
|
||||
HappinessSourceHook.ChangeHappiness,
|
||||
relatedAlive,
|
||||
HappinessRelationRole.Lover);
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.setBestFriend))]
|
||||
|
|
@ -140,4 +160,88 @@ internal static class ActorHappinessPatches
|
|||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.newKillAction))]
|
||||
[HarmonyPrefix]
|
||||
public static void PrefixKillAction(Actor __instance, Actor pDeadUnit)
|
||||
{
|
||||
HappinessContextBag.SetRelated(pDeadUnit, HappinessRelationRole.Victim, "just_killed");
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.newKillAction))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixKillAction()
|
||||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.stealActionFrom))]
|
||||
[HarmonyPrefix]
|
||||
public static void PrefixSteal(Actor __instance, Actor pTarget)
|
||||
{
|
||||
// Victim gets got_robbed; related = thief.
|
||||
HappinessContextBag.SetRelated(__instance, HappinessRelationRole.Robber, "got_robbed");
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.stealActionFrom))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixSteal()
|
||||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(BehCheckForBabiesFromSexualReproduction), nameof(BehCheckForBabiesFromSexualReproduction.execute))]
|
||||
[HarmonyPrefix]
|
||||
public static void PrefixKissed(Actor pActor)
|
||||
{
|
||||
Actor lover = null;
|
||||
try
|
||||
{
|
||||
if (pActor != null && pActor.hasLover())
|
||||
{
|
||||
lover = pActor.lover;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
lover = null;
|
||||
}
|
||||
|
||||
HappinessContextBag.SetPair(pActor, lover, HappinessRelationRole.Lover, "just_kissed");
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(BehCheckForBabiesFromSexualReproduction), nameof(BehCheckForBabiesFromSexualReproduction.execute))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixKissed()
|
||||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(BehFinishTalk), "finishTalk")]
|
||||
[HarmonyPrefix]
|
||||
public static void PrefixFinishTalk(Actor pActor, Actor pTarget)
|
||||
{
|
||||
HappinessContextBag.SetPair(pActor, pTarget, HappinessRelationRole.ConversationPartner, "just_talked");
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(BehFinishTalk), "finishTalk")]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixFinishTalk()
|
||||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(BehFinishTalk), "makeGift")]
|
||||
[HarmonyPrefix]
|
||||
public static void PrefixMakeGift(Actor pActor, Actor pTarget)
|
||||
{
|
||||
HappinessContextBag.SetPair(pActor, pTarget, HappinessRelationRole.GiftPartner, "just_gave_gift");
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(BehFinishTalk), "makeGift")]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixMakeGift()
|
||||
{
|
||||
HappinessContextBag.ClearRelated();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,87 +26,96 @@ public static class RelationshipEventPatches
|
|||
RelationshipInterestFeed.Emit("set_lover", __instance, pActor);
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.addChild))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixAddChild(Actor __instance, object pObject)
|
||||
/// <summary>
|
||||
/// Surviving partners clear dead lovers by field assignment in
|
||||
/// <see cref="MapBox.checkEventUnitsDestroy"/>, which bypasses <see cref="Actor.setLover"/>.
|
||||
/// Emit clear_lover for the living partner before those fields are nulled.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(MapBox), "checkEventUnitsDestroy")]
|
||||
[HarmonyPrefix]
|
||||
public static void PrefixDeadLoverCleanup(MapBox __instance)
|
||||
{
|
||||
Actor child = ResolveRelatedActor(pObject);
|
||||
if (__instance == null || child == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RelationshipInterestFeed.Emit("add_child", __instance, child);
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), "addChildSimple")]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixAddChildSimple(Actor __instance, object pObject)
|
||||
{
|
||||
Actor child = ResolveRelatedActor(pObject);
|
||||
if (__instance == null || child == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RelationshipInterestFeed.Emit("add_child", __instance, child);
|
||||
}
|
||||
|
||||
private static Actor ResolveRelatedActor(object raw)
|
||||
{
|
||||
if (raw == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (raw is Actor actor)
|
||||
{
|
||||
return actor;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (raw is BaseSimObject sim && sim.isActor())
|
||||
if (__instance == null || __instance.units == null || !__instance.units.event_destroy)
|
||||
{
|
||||
return sim.a;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Actor unit in __instance.units)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (unit == null || !unit.isAlive() || !unit.hasLover())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Actor lover = unit.lover;
|
||||
if (lover == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool loverAlive = false;
|
||||
try
|
||||
{
|
||||
loverAlive = lover.isAlive();
|
||||
}
|
||||
catch
|
||||
{
|
||||
loverAlive = false;
|
||||
}
|
||||
|
||||
if (loverAlive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RelationshipInterestFeed.Emit("clear_lover", unit, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// never break vanilla destroy cleanup
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// fall through
|
||||
// never break vanilla destroy cleanup
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
/// <summary>
|
||||
/// Real parent/child link. Vanilla <c>addChild</c> attaches avatar components (Dragon, Boat), not kids.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.setParent1))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixSetParent1(Actor __instance, Actor pParentActor, bool pIncreaseChildren)
|
||||
{
|
||||
EmitAddChild(pParentActor, __instance, pIncreaseChildren);
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Actor), nameof(Actor.setParent2))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixSetParent2(Actor __instance, Actor pActor, bool pIncreaseChildren)
|
||||
{
|
||||
EmitAddChild(pActor, __instance, pIncreaseChildren);
|
||||
}
|
||||
|
||||
private static void EmitAddChild(Actor parent, Actor child, bool increaseChildren)
|
||||
{
|
||||
if (!increaseChildren || parent == null || child == null)
|
||||
{
|
||||
var type = raw.GetType();
|
||||
foreach (string name in new[] { "actor", "Actor", "a", "parent" })
|
||||
{
|
||||
var prop = type.GetProperty(name);
|
||||
if (prop != null && typeof(Actor).IsAssignableFrom(prop.PropertyType))
|
||||
{
|
||||
return prop.GetValue(raw, null) as Actor;
|
||||
}
|
||||
|
||||
var field = type.GetField(name);
|
||||
if (field != null && typeof(Actor).IsAssignableFrom(field.FieldType))
|
||||
{
|
||||
return field.GetValue(raw) as Actor;
|
||||
}
|
||||
}
|
||||
|
||||
var getActor = type.GetMethod("getActor", Type.EmptyTypes)
|
||||
?? type.GetMethod("GetActor", Type.EmptyTypes);
|
||||
if (getActor != null && typeof(Actor).IsAssignableFrom(getActor.ReturnType))
|
||||
{
|
||||
return getActor.Invoke(raw, null) as Actor;
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch
|
||||
|
||||
if (!parent.isAlive() || !child.isAlive())
|
||||
{
|
||||
// ignore
|
||||
return;
|
||||
}
|
||||
|
||||
return null;
|
||||
RelationshipInterestFeed.Emit("add_child", parent, child);
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(FamilyManager), nameof(FamilyManager.newFamily))]
|
||||
|
|
@ -136,6 +145,10 @@ public static class RelationshipEventPatches
|
|||
RelationshipInterestFeed.Emit("baby_created", __result, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Seeking only: BehFindLover returns Continue both when still searching and after
|
||||
/// <see cref="Actor.becomeLoversWith"/>. Success is covered by set_lover / love status.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(BehFindLover), nameof(BehFindLover.execute))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostfixFindLover(Actor pActor, BehResult __result)
|
||||
|
|
@ -145,6 +158,11 @@ public static class RelationshipEventPatches
|
|||
return;
|
||||
}
|
||||
|
||||
if (pActor.hasLover())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RelationshipInterestFeed.Emit("find_lover", pActor, null);
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +175,7 @@ public static class RelationshipEventPatches
|
|||
return;
|
||||
}
|
||||
|
||||
// BehFamilyGroupNew always calls FamilyManager.newFamily first - share that founding key.
|
||||
RelationshipInterestFeed.Emit("family_group_new", pActor, ActorRelation.ResolvePackRelated(pActor));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,8 @@ public static class HappinessEventRouter
|
|||
HappinessSourceHook hook,
|
||||
Actor related = null,
|
||||
HappinessRelationRole role = HappinessRelationRole.None,
|
||||
bool forceRing = false)
|
||||
bool forceRing = false,
|
||||
string relatedNameOverride = null)
|
||||
{
|
||||
return PublishCore(
|
||||
subject,
|
||||
|
|
@ -172,7 +173,8 @@ public static class HappinessEventRouter
|
|||
role,
|
||||
applied: true,
|
||||
suppressedByPsychopath: false,
|
||||
forceRing);
|
||||
forceRing,
|
||||
relatedNameOverride);
|
||||
}
|
||||
|
||||
/// <summary>Record that the game refused to apply happiness (psychopath/egg/no emotions).</summary>
|
||||
|
|
@ -206,7 +208,8 @@ public static class HappinessEventRouter
|
|||
HappinessRelationRole role,
|
||||
bool applied,
|
||||
bool suppressedByPsychopath,
|
||||
bool forceRing)
|
||||
bool forceRing,
|
||||
string relatedNameOverride = null)
|
||||
{
|
||||
if (subject == null || string.IsNullOrEmpty(effectId) || !applied)
|
||||
{
|
||||
|
|
@ -239,7 +242,15 @@ public static class HappinessEventRouter
|
|||
}
|
||||
|
||||
HappinessOccurrence occ = BuildOccurrence(
|
||||
subject, effectId, amount, hook, related, role, applied, suppressedByPsychopath);
|
||||
subject,
|
||||
effectId,
|
||||
amount,
|
||||
hook,
|
||||
related,
|
||||
role,
|
||||
applied,
|
||||
suppressedByPsychopath,
|
||||
relatedNameOverride);
|
||||
FillProse(occ, entry);
|
||||
|
||||
if (ShouldMerge(occ, entry))
|
||||
|
|
@ -449,7 +460,8 @@ public static class HappinessEventRouter
|
|||
Actor related,
|
||||
HappinessRelationRole role,
|
||||
bool applied,
|
||||
bool suppressedByPsychopath)
|
||||
bool suppressedByPsychopath,
|
||||
string relatedNameOverride = null)
|
||||
{
|
||||
HappinessCatalogEntry entry = EventCatalog.Happiness.GetOrFallback(effectId);
|
||||
long subjectId = 0;
|
||||
|
|
@ -495,6 +507,11 @@ public static class HappinessEventRouter
|
|||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(relatedName) && !string.IsNullOrEmpty(relatedNameOverride))
|
||||
{
|
||||
relatedName = relatedNameOverride.Trim();
|
||||
}
|
||||
|
||||
StampWorldDate(out double worldTime, out string dateLabel);
|
||||
string corr = subjectId + "|" + effectId + "|" + relatedId + "|" + Math.Floor(worldTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ internal static class HarnessScenarios
|
|||
return DomainEventAudit();
|
||||
case "event_tracking":
|
||||
return EventTracking();
|
||||
case "family_trigger_smoke":
|
||||
return FamilyTriggerSmoke();
|
||||
case "mutation_discovery":
|
||||
return MutationDiscovery();
|
||||
case "chronicle":
|
||||
|
|
@ -172,6 +174,37 @@ internal static class HarnessScenarios
|
|||
};
|
||||
}
|
||||
|
||||
private static List<HarnessCommand> FamilyTriggerSmoke()
|
||||
{
|
||||
return new List<HarnessCommand>
|
||||
{
|
||||
Step("ft0", "wait_world"),
|
||||
Step("ft1", "dismiss_windows"),
|
||||
Step("ft2", "spectator", value: "off"),
|
||||
|
||||
// Bridge: becomeLoversWith publishes happiness fallen_in_love
|
||||
Step("ft10", "spawn", asset: "human"),
|
||||
Step("ft11", "happiness_remember_partner"),
|
||||
Step("ft12", "spawn", asset: "human"),
|
||||
Step("ft13", "focus", asset: "auto"),
|
||||
Step("ft14", "activity_clear"),
|
||||
Step("ft15", "happiness_reset"),
|
||||
Step("ft16", "happiness_bond_lovers"),
|
||||
Step("ft17", "assert", expect: "activity_happiness_count", value: "2", label: "min"),
|
||||
Step("ft18", "assert", expect: "activity_log_contains", value: "love"),
|
||||
|
||||
// Retarget: setParent1 emits rel:add_child
|
||||
Step("ft20", "spawn", asset: "human"),
|
||||
Step("ft21", "happiness_remember_partner"),
|
||||
Step("ft22", "spawn", asset: "human"),
|
||||
Step("ft23", "focus", asset: "auto"),
|
||||
Step("ft24", "relationship_set_parent"),
|
||||
Step("ft25", "assert", expect: "interest_has_key", value: "rel:add_child"),
|
||||
|
||||
Step("ft99", "snapshot"),
|
||||
};
|
||||
}
|
||||
|
||||
private static List<HarnessCommand> ActivityHappinessAudit()
|
||||
{
|
||||
return new List<HarnessCommand>
|
||||
|
|
@ -202,7 +235,7 @@ internal static class HarnessScenarios
|
|||
Step("hp11", "assert", expect: "activity_happiness_task_id", value: "happiness:become_king"),
|
||||
Step("hp12", "assert", expect: "activity_happiness_ring_count", value: "1", label: "exact"),
|
||||
Step("hp13", "assert", expect: "activity_happiness_life_count", value: "1", label: "min"),
|
||||
Step("hp14", "assert", expect: "activity_log_contains", value: "throne"),
|
||||
Step("hp14", "assert", expect: "activity_log_contains", value: "ruler"),
|
||||
|
||||
// Ambient cooldown: second meal within window should not add another ring write
|
||||
Step("hp20", "happiness_reset"),
|
||||
|
|
@ -226,6 +259,8 @@ internal static class HarnessScenarios
|
|||
Step("hp44", "activity_clear"),
|
||||
Step("hp45", "happiness_reset"),
|
||||
Step("hp46", "happiness_bond_lovers"),
|
||||
Step("hp46b", "assert", expect: "activity_happiness_count", value: "2", label: "min"),
|
||||
Step("hp46c", "assert", expect: "activity_log_contains", value: "love"),
|
||||
Step("hp47", "wait", value: "0.5"),
|
||||
Step("hp48", "happiness_kill_partner"),
|
||||
Step("hp49", "wait", value: "0.5"),
|
||||
|
|
@ -1205,6 +1240,7 @@ internal static class HarnessScenarios
|
|||
Step("et21d", "assert", expect: "dossier_contains", value: "family alpha"),
|
||||
Step("et22", "domain_feed", asset: "plot", value: "summon_meteor_rain"),
|
||||
Step("et23", "assert", expect: "interest_has_key", value: "plot:summon_meteor_rain"),
|
||||
Step("et23b", "assert", expect: "interest_label_contains", value: "plots to summon"),
|
||||
Step("et24", "domain_feed", asset: "era", value: "age_chaos"),
|
||||
Step("et25", "assert", expect: "interest_has_key", value: "era:age_chaos"),
|
||||
Step("et26", "domain_feed", asset: "meta", value: "new_city"),
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public sealed class UnitDossier
|
|||
d.Headline = string.IsNullOrEmpty(d.SpeciesId)
|
||||
? d.Name
|
||||
: $"{d.Name} ({d.SpeciesId})";
|
||||
d.ReasonLine = BuildStoryBeat(d, watchLabel, actor);
|
||||
d.ReasonLine = ComposeReasonWithJob(BuildStoryBeat(d, watchLabel, actor), d.JobLabel);
|
||||
d.DetailLine = BuildDetailLine(d);
|
||||
d.CaptionText = JoinCaption(d.Headline, d.ReasonLine, d.DetailLine);
|
||||
return d;
|
||||
|
|
@ -136,6 +136,32 @@ public sealed class UnitDossier
|
|||
return ActivityProse.HumanizeJobPublic(jobId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Job sits on the orange reason row: alone when there is no watch beat, otherwise
|
||||
/// <c>{reason} · {job}</c>.
|
||||
/// </summary>
|
||||
public static string ComposeReasonWithJob(string reason, string job)
|
||||
{
|
||||
string r = (reason ?? "").Trim();
|
||||
string j = (job ?? "").Trim();
|
||||
if (string.IsNullOrEmpty(j))
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(r))
|
||||
{
|
||||
return j;
|
||||
}
|
||||
|
||||
if (r.IndexOf(j, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
return r + " · " + j;
|
||||
}
|
||||
|
||||
public bool ContainsIgnoreCase(string needle)
|
||||
{
|
||||
if (string.IsNullOrEmpty(needle))
|
||||
|
|
@ -147,6 +173,7 @@ public sealed class UnitDossier
|
|||
|| (Headline ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| (ReasonLine ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| (DetailLine ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| (JobLabel ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| (Name ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| (SpeciesId ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0
|
||||
|| (TaskText ?? "").IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
|
|
|
|||
|
|
@ -647,7 +647,9 @@ public static class WatchCaption
|
|||
return;
|
||||
}
|
||||
|
||||
string next = UnitDossier.OwnedEventReason(actor, _current);
|
||||
string next = UnitDossier.ComposeReasonWithJob(
|
||||
UnitDossier.OwnedEventReason(actor, _current),
|
||||
_current.JobLabel);
|
||||
string prev = _current.ReasonLine ?? "";
|
||||
if (next == prev)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "IdleSpectator",
|
||||
"author": "dazed",
|
||||
"version": "0.25.1",
|
||||
"description": "AFK Idle Spectator (I) + Lore (L). Event strengths/prose in event-catalog.json.",
|
||||
"version": "0.25.11",
|
||||
"description": "AFK Idle Spectator (I) + Lore (L). Event trigger audit Phases 4-8 + job reason row.",
|
||||
"GUID": "com.dazed.idlespectator"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ Scope: Happiness (all authored), Relationship (all), Status/WorldLog/Plot/etc. s
|
|||
|
||||
## Still clean (sample)
|
||||
|
||||
Grief deaths, `fallen_in_love`, gifts, house find/lose, `just_got_out_of_egg`, `just_became_adult`, WorldLog `king_new` template roles, Status `egg` / `pregnant` / `drowning` prose.
|
||||
Grief deaths, `fallen_in_love`, gifts, house find/lose, `just_got_out_of_egg`, `just_became_adult`, WorldLog `king_new` template roles, Status `egg` / `drowning` prose.
|
||||
|
||||
## A/B camera policy (2026-07-16)
|
||||
|
||||
|
|
@ -67,4 +67,53 @@ Sources: `EventReason.*`, happiness catalog `PlainClause`, or discrete catalog t
|
|||
Character fill / ambient may show empty reason.
|
||||
Not every Activity line is a camera event (Ambient happiness, status gains with `CreatesInterest=false`, status losses except egg).
|
||||
|
||||
## Happiness trigger pass (2026-07-16)
|
||||
|
||||
Full 67-id call-site audit vs decompile + BehaviourTask / StatusLibrary / City civic force.
|
||||
|
||||
| Id | Finding | Keep-on fix |
|
||||
|----|---------|-------------|
|
||||
| `just_laughed` / `just_swore` | Fire at **end** of emotion tasks | Prose → finishes laughing / swearing |
|
||||
| `just_ate` | Fires on `consumeFoodResource` | Prose → eats / enjoys a meal |
|
||||
| `just_felt_the_divine` | Divine light clears bad traits | Prose → cleansed by divine light |
|
||||
| `just_played` | Child play task end | Prose → finishes playing around |
|
||||
| `got_caught` | Library asset, **no caller** | Stay Ambient; honest prose |
|
||||
| `got_robbed` / gifts / kiss / talk / kill | Related optional but bag missing | Context bags on steal/gift/kiss/talk/kill |
|
||||
| `fallen_in_love` | Status `fell_in_love` receive + bridge | Keep bridge for no-emotions |
|
||||
| Civic aggregates / BehAddHappiness | Live via forceUnits / Beh* | Marked accurate |
|
||||
|
||||
Worksheet: `docs/event-trigger-audit.tsv` (happiness domain done).
|
||||
|
||||
## Status trigger pass (2026-07-16)
|
||||
|
||||
Full 58-id audit vs `StatusLibrary` + apply sites. Universal Activity hook:
|
||||
`ActorStatusPatches` → `addNewStatusEffect` / `Status.finish` (egg loss also `InterestFeeds.EmitHatch`).
|
||||
|
||||
| Id | Finding | Keep-on fix |
|
||||
|----|---------|-------------|
|
||||
| `angry` | `addAggro`, not the `rage` combat buff | Prose → flies into a fury |
|
||||
| `possessed_follower` | Possession talk converts **target** | Prose → converted into possessed follower |
|
||||
| `pregnant` / `pregnant_parthenogenesis` | Finish → `BabyMaker` birth | Loss prose → gives birth (/ alone) |
|
||||
| `taking_roots` | Finish → vegetative offspring | Loss prose → sprouts offspring |
|
||||
| `budding` | Finish → bud offspring | Loss prose → splits off a bud offspring |
|
||||
| `uprooting` | Plant babies emerging | Prose → emerges as a young plant |
|
||||
| Dreams / `inspired` / combat FX | Sleep pot, finish→happiness, CombatActionLibrary | Already accurate |
|
||||
|
||||
Worksheet: `docs/event-trigger-audit.tsv` (status domain done).
|
||||
|
||||
## WorldLog / plot / trait pass (2026-07-16)
|
||||
|
||||
Phases 4–7 worksheet complete (all audit rows `done`).
|
||||
|
||||
| Area | Finding | Keep-on fix |
|
||||
|------|---------|-------------|
|
||||
| WorldLog `{a}`/`{b}` | `special1`/`special2` match game replacers (kingdom/king, war kingdoms) | Accurate |
|
||||
| Disasters | Policy rows; camera via paired `disaster_*` WorldLog | Accurate (no DisasterManager patch) |
|
||||
| Wars / eras | `WarManager` + `WarInterestFeed`; `WorldAgeManager.startNextAge` | Accurate |
|
||||
| Plots | Same label for new/complete/cancel | `EventReason.Plot` phase rewrite |
|
||||
| Traits | JSON said `Trait: {id} ({a})`; live was `gains`/`loses` | Catalog labels → `{a} gains {id}` |
|
||||
| Boat/meta harness | Crumb strings ≠ `EventReason` | Harness uses `EventReason.Boat` / `MetaNew` |
|
||||
| Building / combat | Already `EventReason.BuildingEat` / `Fight` | Accurate |
|
||||
|
||||
Worksheet: `docs/event-trigger-audit.tsv` (all domains done).
|
||||
|
||||
|
|
|
|||
381
docs/event-trigger-audit.tsv
Normal file
381
docs/event-trigger-audit.tsv
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
domain id strength camera game_call_site verdict fix_action done
|
||||
decisions find_lover 62 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions try_to_steal_money 68 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions banish_unruly_clan_members 76 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions kill_unruly_clan_members 82 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions try_new_plot 78 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions king_change_kingdom_culture 84 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions king_change_kingdom_language 82 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions king_change_kingdom_religion 84 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions leader_change_city_culture 74 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions leader_change_city_language 72 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions leader_change_city_religion 74 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions warrior_army_follow_leader 58 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions warrior_train_with_dummy 42 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
decisions warrior_try_join_army_group 64 Actor.setDecisionCooldown → DeferredInterestFeed.EmitDecision accurate Camera via IsInterestingDecision predicate; action=infinitive done
|
||||
happiness death_family_member 78 Signal Actor accurate done
|
||||
happiness death_lover 90 Signal Actor accurate done
|
||||
happiness death_child 96 Signal Actor accurate done
|
||||
happiness death_best_friend 80 Signal Actor accurate done
|
||||
happiness got_robbed 56 Signal Actor bridge Context bag / bridge for related names done
|
||||
happiness got_poked 30 Ambient Actor accurate done
|
||||
happiness lost_fight 58 Signal Actor accurate done
|
||||
happiness got_caught 20 Ambient HappinessLibrary asset only - no live caller (Ambient stub) prose_fix Updated catalog prose to match call timing/action done
|
||||
happiness paid_tax 30 Ambient Actor accurate done
|
||||
happiness just_ate 30 Ambient Actor prose_fix Updated catalog prose to match call timing/action done
|
||||
happiness just_received_gift 52 Signal BehFinishTalk bridge Context bag / bridge for related names done
|
||||
happiness just_gave_gift 52 Signal BehFinishTalk bridge Context bag / bridge for related names done
|
||||
happiness just_pooped 30 Ambient Actor accurate done
|
||||
happiness just_slept 30 Signal StatusLibrary accurate done
|
||||
happiness had_bad_dream 40 Signal StatusLibrary accurate done
|
||||
happiness had_good_dream 38 Signal StatusLibrary accurate done
|
||||
happiness had_nightmare 44 Signal StatusLibrary accurate done
|
||||
happiness slept_outside 34 Signal BehTrySleep accurate done
|
||||
happiness just_kissed 62 Signal BehCheckForBabiesFromSexualReproduction bridge Context bag / bridge for related names done
|
||||
happiness just_killed 70 Signal Actor bridge Context bag / bridge for related names done
|
||||
happiness become_king 80 Signal Kingdom accurate done
|
||||
happiness become_leader 72 Signal City accurate done
|
||||
happiness just_won_war 52 Aggregate Actor accurate done
|
||||
happiness just_made_peace 50 Aggregate Actor accurate done
|
||||
happiness just_lost_war 55 Aggregate Actor accurate done
|
||||
happiness was_conquered 58 Aggregate City.joinAnotherKingdom → forceUnits changeHappiness accurate done
|
||||
happiness kingdom_fell_apart 60 Aggregate City.makeOwnKingdom(pFellApart) → forceUnits accurate done
|
||||
happiness just_started_war 78 Aggregate WarManager accurate done
|
||||
happiness just_rebelled 58 Aggregate City.makeOwnKingdom/joinAnotherKingdom → forceUnits accurate done
|
||||
happiness fallen_in_love 74 Signal StatusLibrary fell_in_love action_on_receive (+ becomeLoversWith bridge) bridge Status receive + no-emotions PublishApplied bridge done
|
||||
happiness just_had_child 76 Signal Actor accurate done
|
||||
happiness just_read_book 34 Signal BehFinishReading accurate done
|
||||
happiness just_played 32 Signal BehActorChangeHappiness(child play tasks) prose_fix Updated catalog prose to match call timing/action done
|
||||
happiness just_talked 34 Signal BehFinishTalk bridge Context bag / bridge for related names done
|
||||
happiness just_laughed 34 Signal BehAddHappiness(happy_laughing end) prose_fix Updated catalog prose to match call timing/action done
|
||||
happiness just_sang 34 Signal BehAddHappiness(singing end) accurate done
|
||||
happiness just_swore 32 Signal BehAddHappiness(swearing end) prose_fix Updated catalog prose to match call timing/action done
|
||||
happiness just_cried 42 Signal BehAddHappiness(crying end) accurate done
|
||||
happiness just_talked_gossip 32 Signal BehFinishTalk bridge Context bag / bridge for related names done
|
||||
happiness just_surprised 36 Signal StatusLibrary accurate done
|
||||
happiness just_born 68 Signal Actor accurate done
|
||||
happiness just_magnetised 48 Signal StatusLibrary accurate done
|
||||
happiness just_forced_power 58 Signal MapBox accurate done
|
||||
happiness just_possessed 62 Signal StatusLibrary accurate done
|
||||
happiness strange_urge 46 Signal StatusLibrary accurate done
|
||||
happiness just_had_tantrum 50 Signal StatusLibrary accurate done
|
||||
happiness just_felt_the_divine 56 Signal PowerLibrary prose_fix Updated catalog prose to match call timing/action done
|
||||
happiness just_enchanted 54 Signal StatusLibrary accurate done
|
||||
happiness just_inspired 52 Signal StatusLibrary accurate done
|
||||
happiness wrote_book 62 Signal BookManager accurate done
|
||||
happiness just_became_adult 70 Signal Actor accurate done
|
||||
happiness just_got_out_of_egg 72 Signal Actor accurate done
|
||||
happiness just_finished_plot 70 Signal Plot accurate done
|
||||
happiness just_found_house 58 Signal BehFindHouse accurate done
|
||||
happiness just_lost_house 68 Signal Actor accurate done
|
||||
happiness just_made_friend 58 Signal Actor accurate done
|
||||
happiness just_injured 60 Signal Actor accurate done
|
||||
happiness just_cursed 60 Signal StatusLibrary accurate done
|
||||
happiness starving 50 Signal StatusLibrary accurate done
|
||||
happiness conquered_city 70 Aggregate Kingdom accurate done
|
||||
happiness destroyed_city 62 Aggregate Kingdom accurate done
|
||||
happiness lost_crown 72 Signal Kingdom accurate done
|
||||
happiness razed_capital 68 Aggregate Kingdom accurate done
|
||||
happiness lost_capital 64 Aggregate Kingdom accurate done
|
||||
happiness razed_city 60 Aggregate Kingdom accurate done
|
||||
happiness lost_city 66 Aggregate Kingdom accurate done
|
||||
happiness become_alpha 74 Signal Family accurate done
|
||||
status afterglow 20 False BehCheckForBabiesFromSexualReproduction accurate done
|
||||
status cough 20 False StatusLibrary / addNewStatusEffect accurate done
|
||||
status dash 20 False CombatActionLibrary accurate done
|
||||
status dodge 20 False CombatActionLibrary accurate done
|
||||
status flicked 20 False God power / finger flick accurate done
|
||||
status just_ate 20 False Actor consume / StatusLibrary accurate done
|
||||
status on_guard 20 False StatusLibrary / addNewStatusEffect accurate done
|
||||
status recovery_combat_action 20 False CombatActionLibrary cooldown accurate done
|
||||
status recovery_plot 20 False Plot cooldown accurate done
|
||||
status recovery_social 20 False Social cooldown accurate done
|
||||
status recovery_spell 20 False Spell cooldown accurate done
|
||||
status shield 20 False Combat / spell shield accurate done
|
||||
status slowness 20 False StatusLibrary / addNewStatusEffect accurate done
|
||||
status spell_boost 20 False Spell cast accurate done
|
||||
status spell_silence 20 False Spell cast accurate done
|
||||
status burning 72 True Fire / tile / combat accurate done
|
||||
status possessed 74 True Possession convert / god power accurate done
|
||||
status possessed_follower 60 True ControllableUnit.checkTalk convert target prose_fix Target becomes follower; not under sway done
|
||||
status frozen 65 True Cold / freeze powers accurate done
|
||||
status poisoned 58 True Poison attacks / tiles accurate done
|
||||
status drowning 50 True Water drowning check accurate done
|
||||
status stunned 50 True Combat stun / makeStunned accurate done
|
||||
status rage 62 True Combat rage buff accurate done
|
||||
status angry 48 True Actor.addAggro prose_fix Aggro anger; do not conflate with rage done
|
||||
status cursed 60 True Curse powers / traits accurate done
|
||||
status soul_harvested 78 True Soul harvest action accurate done
|
||||
status voices_in_my_head 55 True StatusLibrary / addNewStatusEffect accurate done
|
||||
status tantrum 52 True StatusLibrary; finish→just_had_tantrum accurate done
|
||||
status magnetized 55 True Magnet powers accurate done
|
||||
status invincible 50 True Invincibility powers accurate done
|
||||
status powerup 54 True Powerup effects accurate done
|
||||
status enchanted 52 True Enchant powers accurate done
|
||||
status ash_fever 50 True Ash fever effect accurate done
|
||||
status starving 56 True Hunger / nutrition accurate done
|
||||
status surprised 42 True getSurprised / tryToGetSurprised accurate done
|
||||
status confused 40 True StatusLibrary / addNewStatusEffect accurate done
|
||||
status strange_urge 45 True StatusLibrary / addNewStatusEffect accurate done
|
||||
status inspired 42 True StatusLibrary; finish→just_inspired accurate done
|
||||
status motivated 40 True StatusLibrary / addNewStatusEffect accurate done
|
||||
status fell_in_love 74 True becomeLoversWith / StatusLibrary receive accurate done
|
||||
status pregnant 72 True Sexual reproduction; finish→makeBabyFromPregnancy prose_fix Loss = gives birth done
|
||||
status pregnant_parthenogenesis 72 True BehCheckParthenogenesisReproduction; finish→baby prose_fix Loss = gives birth alone done
|
||||
status crying 58 True Emotion tasks / StatusLibrary accurate done
|
||||
status festive_spirit 36 True Festival / StatusLibrary accurate done
|
||||
status laughing 34 True Emotion tasks / StatusLibrary accurate done
|
||||
status singing 34 True Emotion tasks / StatusLibrary accurate done
|
||||
status sleeping 32 True Sleep tasks; finish→dream pot accurate done
|
||||
status handsome_migrant 44 True Migration status accurate done
|
||||
status being_suspicious 40 True Steal / suspicious tasks accurate done
|
||||
status budding 56 True BehCheckBuddingReproduction; finish→makeBabyViaBudding prose_fix Loss = bud offspring done
|
||||
status caffeinated 36 True Consume caffeine accurate done
|
||||
status had_bad_dream 40 True Sleep action_finish dream pot accurate done
|
||||
status had_good_dream 38 True Sleep action_finish dream pot accurate done
|
||||
status had_nightmare 48 True Sleep action_finish dream pot accurate done
|
||||
status swearing 34 True Emotion tasks / possession swear accurate done
|
||||
status taking_roots 54 True BehCheckVegetativeReproduction; finish→vegetative baby prose_fix Loss = sprouts offspring, not pull free done
|
||||
status uprooting 54 True BabyMaker plant birth prose_fix Plant emerging/maturing, not generic uproot done
|
||||
status egg 40 False Egg form; loss→InterestFeeds.EmitHatch accurate done
|
||||
worldLog king_new 80 True WorldLogMessage.add; special1=kingdom special2=king accurate {b}=king {a}=kingdom matches kingReplacer done
|
||||
worldLog king_left 72 True WorldLogMessage.add; special1=kingdom special2=king accurate {b}=king {a}=kingdom matches kingReplacer done
|
||||
worldLog king_fled_capital 70 True WorldLogMessage.add; special1=kingdom special2=king accurate {b}=king {a}=kingdom matches kingReplacer done
|
||||
worldLog king_fled_city 68 True WorldLogMessage.add; special1=kingdom special2=king accurate {b}=king {a}=kingdom matches kingReplacer done
|
||||
worldLog king_dead 84 True WorldLogMessage.add; special1=kingdom special2=king accurate {b}=king {a}=kingdom matches kingReplacer done
|
||||
worldLog king_killed 88 True WorldLogMessage.add; special1=kingdom special2=king accurate {b}=king {a}=kingdom matches kingReplacer done
|
||||
worldLog favorite_dead 82 True WorldLogMessage.add accurate done
|
||||
worldLog favorite_killed 85 True WorldLogMessage.add accurate done
|
||||
worldLog city_new 72 True WorldLogMessage.add accurate done
|
||||
worldLog log_city_revolted 90 True WorldLogMessage.add accurate done
|
||||
worldLog city_destroyed 92 True WorldLogMessage.add accurate done
|
||||
worldLog diplomacy_war_ended 72 True WorldLogMessage.add accurate done
|
||||
worldLog diplomacy_war_started 100 True WorldLogMessage.add; special1/2=kingdoms accurate Also WarManager.newWar feed (dual path, distinct keys) done
|
||||
worldLog total_war_started 100 True WorldLogMessage.add accurate done
|
||||
worldLog alliance_new 70 True WorldLogMessage.add accurate done
|
||||
worldLog alliance_dissolved 68 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_new 75 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_destroyed 100 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_shattered 98 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_fractured 95 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_royal_clan_new 74 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_royal_clan_changed 72 True WorldLogMessage.add accurate done
|
||||
worldLog kingdom_royal_clan_dead 76 True WorldLogMessage.add accurate done
|
||||
worldLog disaster_tornado 95 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_meteorite 95 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_hellspawn 96 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_earthquake 95 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_greg_abominations 96 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_ice_ones 95 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_sudden_snowman 90 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_garden_surprise 90 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_dragon_from_farlands 98 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_bandits 92 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_alien_invasion 97 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_biomass 96 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_tumor 96 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_heatwave 88 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_evil_mage 94 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_underground_necromancer 95 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog disaster_mad_thoughts 90 True WorldLogMessage.add (disaster→world_log) accurate done
|
||||
worldLog auto_tester 10 False WorldLogMessage.add accurate CreatesInterest=false harness-only done
|
||||
plots rebellion 92 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots new_war 94 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots alliance_create 80 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots alliance_join 68 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots alliance_destroy 86 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots attacker_stop_war 78 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots new_book 52 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots new_language 60 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots new_religion 70 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots new_culture 68 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots clan_ascension 82 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots culture_divide 75 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots religion_schism 84 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots language_divergence 58 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_meteor_rain 96 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_earthquake 95 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_thunderstorm 93 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_stormfront 93 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_hellstorm 97 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_demons 96 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_angles 96 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_skeletons 92 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots summon_living_plants 90 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots big_cast_coffee 48 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots big_cast_bubble_shield 64 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots big_cast_madness 80 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots big_cast_slowness 70 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
plots cause_rebellion 90 True PlotManager/Actor.setPlot/finishPlot → PlotInterestFeed prose_fix Phase-aware EventReason.Plot (new/complete/cancel/leave) done
|
||||
relationship set_lover 78 True Actor.setLover accurate done
|
||||
relationship clear_lover 60 True setLover(null)+MapBox dead-lover cleanup hook_retarget done
|
||||
relationship add_child 74 True Actor.setParent1/setParent2 hook_retarget done
|
||||
relationship new_family 72 True FamilyManager.newFamily accurate done
|
||||
relationship family_removed 58 True FamilyManager.removeObject accurate Confirmed patch + EventReason prose done
|
||||
relationship find_lover 52 True BehFindLover Continue && !hasLover gate done
|
||||
relationship become_alpha 74 True Family.setAlpha accurate done
|
||||
relationship family_group_new 58 True BehFamilyGroupNew; shares new_family key merge done
|
||||
relationship family_group_join 36 True BehFamilyGroupJoin accurate Confirmed patch + EventReason prose done
|
||||
relationship family_group_leave 36 True BehFamilyGroupLeave accurate Confirmed patch + EventReason prose done
|
||||
relationship baby_created 72 True ActorManager.createBabyActorFromData accurate done
|
||||
traits zombie 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits wise 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits whirlwind 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits weightless 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits weak 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits veteran 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits venomous 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits unlucky 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits ugly 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits tumor_infection 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits tough 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits titan_lungs 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits tiny 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits thorns 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits thief 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits super_health 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits sunblessed 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits stupid 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits strong_minded 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits strong 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits soft_skin 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits slow 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits skin_burns 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits short_sighted 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits shiny 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits scar_of_divinity 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits savage 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits regeneration 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits pyromaniac 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits psychopath 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits poisonous 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits poison_immune 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits plague 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits peaceful 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits paranoid 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits pacifist 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits nightchild 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits mute 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits mush_spores 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits moonchild 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits miracle_born 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits miracle_bearer 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits miner 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits metamorphed 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits mega_heartbeat 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits mageslayer 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits madness 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits lustful 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits lucky 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits long_liver 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits light_lamp 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits kingslayer 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits infertile 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits infected 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits immune 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits immortal 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits hotheaded 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits honest 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits heliophobia 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits heart_of_wizard 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits healing_aura 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits hard_skin 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits greedy 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits golden_tooth 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits gluttonous 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits giant 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits genius 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits freeze_proof 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits fragile_health 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits flower_prints 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits flesh_eater 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits fire_proof 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits fire_blood 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits fertile 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits fat 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits fast 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits eyepatch 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits evil 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits energized 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits eagle_eyed 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits dragonslayer 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits dodge 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits desire_harp 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits desire_golden_egg 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits desire_computer 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits desire_alien_mold 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits deflect_projectile 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits deceitful 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits death_nuke 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits death_mark 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits death_bomb 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits dash 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits crippled 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits content 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits contagious 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits cold_aura 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits clumsy 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits clone 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits chosen_one 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits burning_feet 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits bubble_defense 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits boosted_vitality 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits bomberman 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits boat 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits bloodlust 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits block 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits blessed 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits battle_reflexes 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits backstep 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits attractive 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits arcane_reflexes 58 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits ambitious 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits agile 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits acid_touch 72 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits acid_proof 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
traits acid_blood 38 True Actor.addTrait/removeTrait → EventReason.Trait prose_fix Catalog label aligned to gains/loses; spawn-window gate done
|
||||
books family_story 52 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books love_story 56 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books friendship_story 50 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books bad_story_about_king 64 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books fable 48 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books warfare_manual 58 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books economy_manual 48 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books stewardship_manual 48 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books diplomacy_manual 55 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books mathbook 45 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books biology_book 45 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
books history_book 55 True BookManager.newBook/generateNewBook/burnBook accurate burn forces burns-a-book prose done
|
||||
eras age_hope 78 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_sun 80 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_dark 88 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_tears 86 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_moon 82 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_chaos 92 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_wonders 84 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_ice 87 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_ash 90 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_despair 91 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
eras age_unknown 70 True WorldAgeManager.startNextAge → MetaInterestFeed.EmitEra accurate done
|
||||
disasters tornado 95 True Policy→WorldLog disaster_tornado; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters heatwave 88 True Policy→WorldLog disaster_heatwave; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters small_meteorite 95 True Policy→WorldLog disaster_meteorite; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters small_earthquake 95 True Policy→WorldLog disaster_earthquake; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters hellspawn 96 True Policy→WorldLog disaster_hellspawn; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters ice_ones_awoken 95 True Policy→WorldLog disaster_ice_ones; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters sudden_snowman 90 True Policy→WorldLog disaster_sudden_snowman; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters garden_surprise 90 True Policy→WorldLog disaster_garden_surprise; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters dragon_from_farlands 98 True Policy→WorldLog disaster_dragon_from_farlands; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters ash_bandits 92 True Policy→WorldLog disaster_bandits; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters alien_invasion 97 True Policy→WorldLog disaster_alien_invasion; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters biomass 96 True Policy→WorldLog disaster_biomass; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters tumor 96 True Policy→WorldLog disaster_tumor; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters wild_mage 94 True Policy→WorldLog disaster_evil_mage; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters underground_necromancer 95 True Policy→WorldLog disaster_underground_necromancer; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters mad_thoughts 90 True Policy→WorldLog disaster_mad_thoughts; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
disasters greg_abominations 96 True Policy→WorldLog disaster_greg_abominations; no DisasterManager patch accurate Camera via paired worldLog row done
|
||||
warTypes normal 90 True WarManager.newWar/endWar + WarInterestFeed.Tick accurate Live label often Attacker vs Defender done
|
||||
warTypes spite 88 True WarManager.newWar/endWar + WarInterestFeed.Tick accurate Live label often Attacker vs Defender done
|
||||
warTypes inspire 86 True WarManager.newWar/endWar + WarInterestFeed.Tick accurate Live label often Attacker vs Defender done
|
||||
warTypes rebellion 92 True WarManager.newWar/endWar + WarInterestFeed.Tick accurate Live label often Attacker vs Defender done
|
||||
warTypes whisper_of_war 84 True WarManager.newWar/endWar + WarInterestFeed.Tick accurate Live label often Attacker vs Defender done
|
||||
|
Loading…
Reference in a new issue