worldbox-observer-mod/IdleSpectator/BuildingEventPatches.cs

118 lines
3.8 KiB
C#

using ai.behaviours;
using HarmonyLib;
using UnityEngine;
namespace IdleSpectator;
/// <summary>Building damage/destroy interest patches from mutation discovery.</summary>
[HarmonyPatch]
public static class BuildingEventPatches
{
[HarmonyPatch(typeof(BehDealDamageToTargetBuilding), nameof(BehDealDamageToTargetBuilding.execute))]
[HarmonyPostfix]
public static void PostfixDamageBuilding(Actor pActor, BehResult __result)
{
if (pActor == null || !pActor.isAlive() || __result == BehResult.Stop)
{
return;
}
Emit("building_damage", 70f, InterestOwnership.Signal, pActor, "Damages a building: {a}");
}
[HarmonyPatch(typeof(BehConsumeTargetBuilding), nameof(BehConsumeTargetBuilding.execute))]
[HarmonyPostfix]
public static void PostfixConsumeBuilding(Actor pActor, BehResult __result)
{
if (pActor == null || !pActor.isAlive() || __result == BehResult.Stop)
{
return;
}
Emit("building_consume", 78f, InterestOwnership.Signal, pActor, "Consumes a building: {a}");
}
[HarmonyPatch(typeof(Building), "startDestroyBuilding")]
[HarmonyPostfix]
public static void PostfixStartDestroy(Building __instance)
{
if (__instance == null || AgentHarness.Busy)
{
return;
}
try
{
Vector3 pos = Vector3.zero;
object posObj = __instance.GetType().GetField("current_position")?.GetValue(__instance)
?? __instance.GetType().GetProperty("current_position")?.GetValue(__instance, null);
if (posObj is Vector3 v)
{
pos = v;
}
string buildingName = "";
object asset = __instance.GetType().GetField("asset")?.GetValue(__instance)
?? __instance.GetType().GetProperty("asset")?.GetValue(__instance, null);
if (asset != null)
{
object id = asset.GetType().GetField("id")?.GetValue(asset)
?? asset.GetType().GetProperty("id")?.GetValue(asset, null);
buildingName = id?.ToString() ?? "";
}
Actor near = pos != Vector3.zero
? EventFeedUtil.NearestUnit(pos) ?? EventFeedUtil.AnyAliveUnit()
: EventFeedUtil.AnyAliveUnit();
if (near == null)
{
return;
}
string label = string.IsNullOrEmpty(buildingName)
? "Building destroyed near " + EventFeedUtil.SafeName(near)
: "Building falls: " + buildingName;
string key = "building:destroy:" + buildingName + ":" + EventFeedUtil.SafeId(near);
EventFeedUtil.Register(
key,
"building",
"Spectacle",
label,
string.IsNullOrEmpty(buildingName) ? "building_destroy" : buildingName,
88f,
InterestOwnership.Signal,
near.current_position,
near);
}
catch
{
// ignore API mismatches
}
}
private static void Emit(
string eventId,
float strength,
InterestOwnership owns,
Actor actor,
string labelTemplate)
{
if (AgentHarness.Busy)
{
return;
}
string label = (labelTemplate ?? "{a}").Replace("{a}", EventFeedUtil.SafeName(actor));
string key = "building:" + eventId + ":" + EventFeedUtil.SafeId(actor);
EventFeedUtil.Register(
key,
"building",
"Spectacle",
label,
eventId,
strength,
owns,
actor.current_position,
actor);
}
}