worldbox-observer-mod/IdleSpectator/PlotInterestFeed.cs
2026-07-15 22:16:24 -05:00

178 lines
5.1 KiB
C#

using System.Collections;
using System.Reflection;
using UnityEngine;
namespace IdleSpectator;
/// <summary>Registers plot interest from Harmony hooks and World.plots polling.</summary>
public static class PlotInterestFeed
{
public static void Emit(string plotAssetId, Actor subject, string phase)
{
if (AgentHarness.Busy)
{
return;
}
DiscreteEventEntry entry = PlotInterestCatalog.GetOrFallback(plotAssetId);
if (!entry.CreatesInterest)
{
return;
}
Actor follow = subject;
if (follow == null || !follow.isAlive())
{
// Plot without a living author: skip rather than invent a stranger.
return;
}
string name = EventFeedUtil.SafeName(follow);
string label = entry.MakeLabel(name, phase ?? "");
string key = "plot:" + entry.Id + ":" + (phase ?? "active") + ":" + EventFeedUtil.SafeId(follow);
EventFeedUtil.Register(
key,
"plot",
entry.Category,
label,
entry.Id,
entry.EventStrength,
entry.OwnsCamera,
follow.current_position,
follow);
}
public static void EmitFromPlot(object plot, string phase)
{
if (plot == null)
{
return;
}
string assetId = ReadPlotAssetId(plot);
Actor author = ReadPlotAuthor(plot);
Emit(assetId, author, phase);
}
public static void Tick()
{
if (AgentHarness.Busy)
{
return;
}
IEnumerable plots = ResolvePlotsEnumerable();
if (plots == null)
{
return;
}
int registered = 0;
foreach (object plot in plots)
{
if (plot == null || registered >= 8)
{
break;
}
EmitFromPlot(plot, "active");
registered++;
}
}
private static IEnumerable ResolvePlotsEnumerable()
{
try
{
object world = World.world;
if (world == null)
{
return null;
}
object plots = world.GetType().GetField("plots")?.GetValue(world)
?? world.GetType().GetProperty("plots")?.GetValue(world, null);
if (plots is IEnumerable direct)
{
return direct;
}
object manager = world.GetType().GetField("plots_manager")?.GetValue(world)
?? world.GetType().GetProperty("plots_manager")?.GetValue(world, null)
?? typeof(PlotManager);
if (manager is System.Type)
{
manager = null;
}
object mapBox = MapBox.instance;
if (manager == null && mapBox != null)
{
manager = mapBox.GetType().GetField("plots")?.GetValue(mapBox)
?? mapBox.GetType().GetProperty("plots")?.GetValue(mapBox, null);
}
if (manager == null)
{
return null;
}
MethodInfo getAll = manager.GetType().GetMethod("getSimpleList")
?? manager.GetType().GetMethod("getList")
?? manager.GetType().GetMethod("getPlots");
if (getAll != null)
{
return getAll.Invoke(manager, null) as IEnumerable;
}
return manager as IEnumerable;
}
catch
{
return null;
}
}
private static string ReadPlotAssetId(object plot)
{
try
{
object asset = plot.GetType().GetField("asset")?.GetValue(plot)
?? plot.GetType().GetProperty("asset")?.GetValue(plot, null)
?? plot.GetType().GetMethod("getAsset")?.Invoke(plot, null);
if (asset != null)
{
object id = asset.GetType().GetField("id")?.GetValue(asset)
?? asset.GetType().GetProperty("id")?.GetValue(asset, null);
if (id != null)
{
return id.ToString();
}
}
object typeId = plot.GetType().GetField("type")?.GetValue(plot)
?? plot.GetType().GetProperty("type")?.GetValue(plot, null);
return typeId?.ToString() ?? "unknown";
}
catch
{
return "unknown";
}
}
private static Actor ReadPlotAuthor(object plot)
{
try
{
object author = plot.GetType().GetField("author")?.GetValue(plot)
?? plot.GetType().GetProperty("author")?.GetValue(plot, null)
?? plot.GetType().GetMethod("getAuthor")?.Invoke(plot, null)
?? plot.GetType().GetField("founder")?.GetValue(plot);
return author as Actor;
}
catch
{
return null;
}
}
}