mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
make kill anim patch update resilient
This commit is contained in:
1 parent
88329bef79
commit
cb794c3fc2
3 files changed
+69
-31
No files matched your search
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using Il2CppInterop.Runtime.InteropTypes;
|
||||||
|
using MiraAPI.Events;
|
||||||
|
using MiraAPI.Events.Vanilla.Gameplay;
|
||||||
|
using MiraAPI.Utilities;
|
||||||
|
|
||||||
|
namespace MiraAPI.Patches.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Patch to invoke AfterMurderEvent after a kill animation is performed.
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPatch]
|
||||||
|
public static class KillAnimationMurderEventPatch
|
||||||
|
{
|
||||||
|
public static MethodBase TargetMethod()
|
||||||
|
{
|
||||||
|
return Helpers.GetStateMachineMoveNext<KillAnimation>(nameof(KillAnimation.CoPerformKill))!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Postfix(Il2CppObjectBase __instance)
|
||||||
|
{
|
||||||
|
var wrapper = new StateMachineWrapper<KillAnimation>(__instance);
|
||||||
|
if (wrapper.GetState() != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var source = wrapper.GetParameter<PlayerControl>("source");
|
||||||
|
var target = wrapper.GetParameter<PlayerControl>("target");
|
||||||
|
|
||||||
|
var afterMurderEvent = new AfterMurderEvent(source, target, Helpers.GetBodyById(target.PlayerId));
|
||||||
|
MiraEventManager.InvokeEvent(afterMurderEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using HarmonyLib;
|
|
||||||
using MiraAPI.Events;
|
|
||||||
using MiraAPI.Events.Vanilla.Gameplay;
|
|
||||||
using MiraAPI.Utilities;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// General patches for the KillAnimation class.
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPatch]
|
|
||||||
public static class KillAnimationPatches
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Used to trigger the <see cref="AfterMurderEvent"/>.
|
|
||||||
/// </summary>
|
|
||||||
[HarmonyPostfix]
|
|
||||||
[HarmonyPatch(typeof(KillAnimation._CoPerformKill_d__2), nameof(KillAnimation._CoPerformKill_d__2.MoveNext))]
|
|
||||||
public static void KillAnimPostfix(KillAnimation._CoPerformKill_d__2 __instance)
|
|
||||||
{
|
|
||||||
// Checking if state is -1 to wait for the end of coroutine.
|
|
||||||
if (__instance.__1__state != -1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var afterMurderEvent = new AfterMurderEvent(__instance.source, __instance.target, Helpers.GetBodyById(__instance.target.PlayerId));
|
|
||||||
MiraEventManager.InvokeEvent(afterMurderEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using System.Reflection;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Il2CppInterop.Runtime.InteropTypes;
|
using Il2CppInterop.Runtime.InteropTypes;
|
||||||
|
|
||||||
@@ -11,8 +13,11 @@ namespace MiraAPI.Utilities;
|
|||||||
public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
||||||
{
|
{
|
||||||
private readonly Il2CppObjectBase _stateMachine;
|
private readonly Il2CppObjectBase _stateMachine;
|
||||||
|
|
||||||
|
// normally it is fields, but IL2CPP turns them into properties
|
||||||
private readonly PropertyInfo _thisProperty;
|
private readonly PropertyInfo _thisProperty;
|
||||||
private readonly PropertyInfo _stateProperty;
|
private readonly PropertyInfo _stateProperty;
|
||||||
|
private readonly Dictionary<string, PropertyInfo> _propertyCache;
|
||||||
|
|
||||||
private T? _parentInstance;
|
private T? _parentInstance;
|
||||||
|
|
||||||
@@ -32,6 +37,13 @@ public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
|||||||
var type = _stateMachine.GetType();
|
var type = _stateMachine.GetType();
|
||||||
_thisProperty = AccessTools.Property(type, "__4__this");
|
_thisProperty = AccessTools.Property(type, "__4__this");
|
||||||
_stateProperty = AccessTools.Property(type, "__1__state");
|
_stateProperty = AccessTools.Property(type, "__1__state");
|
||||||
|
|
||||||
|
if (_thisProperty == null || _stateProperty == null)
|
||||||
|
{
|
||||||
|
throw new MissingMemberException($"Could not find required properties in type '{type}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_propertyCache = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -39,4 +51,25 @@ public class StateMachineWrapper<T> where T : Il2CppObjectBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The current state as an integer.</returns>
|
/// <returns>The current state as an integer.</returns>
|
||||||
public int GetState() => (int)_stateProperty.GetValue(_stateMachine)!;
|
public int GetState() => (int)_stateProperty.GetValue(_stateMachine)!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a parameter from the state machine by its name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parameterName">The name of the parameter to retrieve.</param>
|
||||||
|
/// <typeparam name="TField">The type of the parameter to retrieve.</typeparam>
|
||||||
|
/// <returns>>The value of the specified parameter.</returns>
|
||||||
|
/// <exception cref="MissingFieldException">Thrown if the specified parameter does not exist.</exception>
|
||||||
|
public TField GetParameter<TField>(string parameterName)
|
||||||
|
{
|
||||||
|
if (_propertyCache.TryGetValue(parameterName, out var property))
|
||||||
|
{
|
||||||
|
return (TField)property.GetValue(_stateMachine)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
property = AccessTools.Property(_stateMachine.GetType(), parameterName)
|
||||||
|
?? throw new MissingFieldException($"Could not find parameter '{parameterName}' in state machine of type '{_stateMachine.GetType()}'.");
|
||||||
|
|
||||||
|
_propertyCache[parameterName] = property;
|
||||||
|
return (TField)property.GetValue(_stateMachine)!;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user