using System.Collections; using System.Reflection; using UnityEngine; namespace IdleSpectator; /// Registers plot interest from Harmony hooks and World.plots polling. 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; } } }