197 lines
6.4 KiB
C#
197 lines
6.4 KiB
C#
using UnityEngine;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>Registers relationship lifecycle interest candidates under the ownership contract.</summary>
|
|
public static class RelationshipInterestFeed
|
|
{
|
|
public static void Emit(string eventId, Actor subject, Actor related, string labelOverride = null)
|
|
{
|
|
if (AgentHarness.Busy || subject == null || !subject.isAlive())
|
|
{
|
|
return;
|
|
}
|
|
|
|
DiscreteEventEntry entry = RelationshipEventCatalog.GetOrFallback(eventId);
|
|
if (!entry.CreatesInterest)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Actor relatedAlive = related != null && related.isAlive() ? related : null;
|
|
|
|
// Pack / join labels claim a second party - resolve live related or drop the dishonest claim.
|
|
bool claimsPack = eventId == "family_group_new"
|
|
|| eventId == "family_group_join"
|
|
|| eventId == "family_group_leave"
|
|
|| eventId == "set_lover"
|
|
|| eventId == "add_child";
|
|
if (claimsPack && relatedAlive == null)
|
|
{
|
|
relatedAlive = ActorRelation.ResolvePackRelated(subject);
|
|
}
|
|
|
|
if (claimsPack && relatedAlive == null)
|
|
{
|
|
// Honest Ambient: subject only, no pack/lover claim in the label.
|
|
string soloLabel = SoloLabel(eventId, EventFeedUtil.SafeName(subject));
|
|
string soloKey = "rel:" + entry.Id + ":" + EventFeedUtil.SafeId(subject) + ":solo";
|
|
EventFeedUtil.Register(
|
|
soloKey,
|
|
"relationship",
|
|
entry.Category,
|
|
soloLabel,
|
|
entry.Id,
|
|
Mathf.Min(entry.EventStrength, 40f),
|
|
InterestOwnership.Ambient,
|
|
subject.current_position,
|
|
subject);
|
|
return;
|
|
}
|
|
|
|
string a = EventFeedUtil.SafeName(subject);
|
|
string b = EventFeedUtil.SafeName(relatedAlive);
|
|
string label = string.IsNullOrEmpty(labelOverride) ? entry.MakeLabel(a, b) : labelOverride;
|
|
string key = "rel:" + entry.Id + ":" + EventFeedUtil.SafeId(subject) + ":" + EventFeedUtil.SafeId(relatedAlive);
|
|
EventFeedUtil.Register(
|
|
key,
|
|
"relationship",
|
|
entry.Category,
|
|
label,
|
|
entry.Id,
|
|
entry.EventStrength,
|
|
entry.OwnsCamera,
|
|
subject.current_position,
|
|
subject,
|
|
related: relatedAlive);
|
|
}
|
|
|
|
public static void EmitFamily(string eventId, object family, Actor anchor)
|
|
{
|
|
if (AgentHarness.Busy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DiscreteEventEntry entry = RelationshipEventCatalog.GetOrFallback(eventId);
|
|
Actor follow = anchor != null && anchor.isAlive() ? anchor : null;
|
|
if (follow == null)
|
|
{
|
|
follow = FirstFamilyMember(family);
|
|
}
|
|
|
|
if (follow == null)
|
|
{
|
|
// No owned member - skip rather than invent a stranger.
|
|
return;
|
|
}
|
|
|
|
Actor related = ActorRelation.FirstFamilyPeer(follow);
|
|
string name = "";
|
|
try
|
|
{
|
|
name = family?.GetType().GetMethod("getName")?.Invoke(family, null) as string
|
|
?? family?.GetType().GetProperty("name")?.GetValue(family, null) as string
|
|
?? "";
|
|
}
|
|
catch
|
|
{
|
|
// ignore
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
name = EventFeedUtil.SafeName(follow);
|
|
}
|
|
|
|
string key = "rel:" + entry.Id + ":" + EventFeedUtil.SafeId(follow) + ":" + (name ?? "family");
|
|
EventFeedUtil.Register(
|
|
key,
|
|
"relationship",
|
|
entry.Category,
|
|
entry.MakeLabel(name, EventFeedUtil.SafeName(related)),
|
|
entry.Id,
|
|
entry.EventStrength,
|
|
entry.OwnsCamera,
|
|
follow.current_position,
|
|
follow,
|
|
related: related);
|
|
}
|
|
|
|
private static string SoloLabel(string eventId, string name)
|
|
{
|
|
switch (eventId)
|
|
{
|
|
case "family_group_join":
|
|
return "Gathers with kin: " + name;
|
|
case "family_group_new":
|
|
return "Starts a kin group: " + name;
|
|
case "family_group_leave":
|
|
return "Leaves kin: " + name;
|
|
case "set_lover":
|
|
return "Seeking a bond: " + name;
|
|
case "add_child":
|
|
return "Family grows: " + name;
|
|
default:
|
|
return name;
|
|
}
|
|
}
|
|
|
|
private static Actor FirstFamilyMember(object family)
|
|
{
|
|
if (family == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
foreach (Actor member in ActorRelation.EnumerateFamilyMembers(
|
|
ActorRelation.ResolveActor(
|
|
family.GetType().GetField("founder")?.GetValue(family)
|
|
?? family.GetType().GetProperty("founder")?.GetValue(family, null))
|
|
?? null,
|
|
max: 1))
|
|
{
|
|
return member;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// fall through
|
|
}
|
|
|
|
// Direct units list on the family meta object.
|
|
try
|
|
{
|
|
object list = family.GetType().GetField("units")?.GetValue(family)
|
|
?? family.GetType().GetProperty("units")?.GetValue(family, null)
|
|
?? family.GetType().GetMethod("getUnits")?.Invoke(family, null)
|
|
?? family.GetType().GetMethod("getSimpleList")?.Invoke(family, null);
|
|
if (list is System.Collections.IEnumerable enumerable)
|
|
{
|
|
foreach (object raw in enumerable)
|
|
{
|
|
Actor a = ActorRelation.ResolveActor(raw);
|
|
if (a != null && a.isAlive())
|
|
{
|
|
return a;
|
|
}
|
|
}
|
|
}
|
|
|
|
Actor founder = family.GetType().GetField("founder")?.GetValue(family) as Actor
|
|
?? family.GetType().GetProperty("founder")?.GetValue(family, null) as Actor;
|
|
if (founder != null && founder.isAlive())
|
|
{
|
|
return founder;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// ignore
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|