251 lines
5.6 KiB
C#
251 lines
5.6 KiB
C#
using System;
|
|
using HarmonyLib;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Feeds Activity status gain/loss lines from authoritative WorldBox status transitions.
|
|
/// Gain = new dict entry (<see cref="BaseSimObject.addNewStatusEffect"/>).
|
|
/// Loss = <see cref="Status.finish"/> (remove, expire, clear) while the actor is still alive.
|
|
/// </summary>
|
|
[HarmonyPatch]
|
|
public static class ActorStatusPatches
|
|
{
|
|
[HarmonyPatch(typeof(BaseSimObject), "addNewStatusEffect")]
|
|
[HarmonyPostfix]
|
|
public static void PostfixAddNewStatusEffect(
|
|
BaseSimObject __instance,
|
|
StatusAsset pStatusAsset,
|
|
float pOverrideTimer,
|
|
bool pColorEffect,
|
|
bool pIsActor,
|
|
bool pHasAnyStatus)
|
|
{
|
|
_ = pOverrideTimer;
|
|
_ = pColorEffect;
|
|
_ = pHasAnyStatus;
|
|
if (__instance == null || pStatusAsset == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Actor actor = ResolveLivingActor(__instance, pIsActor);
|
|
if (actor == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ActivityLog.NoteStatusChange(actor, pStatusAsset.id, gained: true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count timer-refresh reapplications for harness asserts (no Activity line).
|
|
/// </summary>
|
|
[HarmonyPatch(
|
|
typeof(BaseSimObject),
|
|
"addStatusEffect",
|
|
new Type[] { typeof(StatusAsset), typeof(float), typeof(bool) })]
|
|
[HarmonyPrefix]
|
|
public static void PrefixAddStatusEffect(
|
|
BaseSimObject __instance,
|
|
StatusAsset pStatusAsset,
|
|
out bool __state)
|
|
{
|
|
__state = false;
|
|
if (__instance == null || pStatusAsset == null || string.IsNullOrEmpty(pStatusAsset.id))
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (!__instance.isActor())
|
|
{
|
|
return;
|
|
}
|
|
|
|
__state = ActorAlreadyHasStatus(__instance, pStatusAsset.id);
|
|
}
|
|
catch
|
|
{
|
|
__state = false;
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(
|
|
typeof(BaseSimObject),
|
|
"addStatusEffect",
|
|
new Type[] { typeof(StatusAsset), typeof(float), typeof(bool) })]
|
|
[HarmonyPostfix]
|
|
public static void PostfixAddStatusEffect(
|
|
BaseSimObject __instance,
|
|
StatusAsset pStatusAsset,
|
|
bool __result,
|
|
bool __state)
|
|
{
|
|
if (!__state || !__result || __instance == null || pStatusAsset == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (!__instance.isActor())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Actor actor = __instance.a;
|
|
long actorId = 0;
|
|
try
|
|
{
|
|
if (actor != null)
|
|
{
|
|
actorId = actor.getID();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
actorId = 0;
|
|
}
|
|
|
|
ActivityLog.NoteStatusRefresh(pStatusAsset.id, actorId);
|
|
}
|
|
catch
|
|
{
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(Status), nameof(Status.finish))]
|
|
[HarmonyPrefix]
|
|
public static void PrefixFinish(Status __instance, out bool __state)
|
|
{
|
|
__state = false;
|
|
try
|
|
{
|
|
__state = __instance != null && !__instance.is_finished;
|
|
}
|
|
catch
|
|
{
|
|
__state = false;
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(Status), nameof(Status.finish))]
|
|
[HarmonyPostfix]
|
|
public static void PostfixFinish(Status __instance, bool __state)
|
|
{
|
|
if (!__state || __instance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BaseSimObject sim;
|
|
StatusAsset asset;
|
|
try
|
|
{
|
|
sim = __instance.sim_object;
|
|
asset = __instance.asset;
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (sim == null || asset == null || string.IsNullOrEmpty(asset.id))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Actor actor;
|
|
try
|
|
{
|
|
if (!sim.isActor())
|
|
{
|
|
return;
|
|
}
|
|
|
|
actor = sim.a;
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (actor == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Skip death/dispose cleanup bursts - death milestone covers that moment.
|
|
try
|
|
{
|
|
if (!actor.isAlive())
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
|
|
ActivityLog.NoteStatusChange(actor, asset.id, gained: false);
|
|
}
|
|
|
|
private static Actor ResolveLivingActor(BaseSimObject sim, bool hintedActor)
|
|
{
|
|
if (sim == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (!hintedActor && !sim.isActor())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Actor actor = sim.a;
|
|
if (actor == null || !actor.isAlive())
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return actor;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static bool ActorAlreadyHasStatus(BaseSimObject sim, string statusId)
|
|
{
|
|
try
|
|
{
|
|
var ids = sim.getStatusesIds();
|
|
if (ids == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
foreach (string id in ids)
|
|
{
|
|
if (!string.IsNullOrEmpty(id)
|
|
&& id.Equals(statusId, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// fall through
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|