Files
7d2dXG/Mods/0A-KFCommonUtilityLib/Harmony/AnimationRiggingPatches.cs
Nathaniel Cosford f0e287b071 Mods for V1.3
2025-06-03 22:58:58 +09:30

1732 lines
84 KiB
C#

using HarmonyLib;
using KFCommonUtilityLib;
using KFCommonUtilityLib.Scripts.StaticManagers;
using KFCommonUtilityLib.Scripts.Utilities;
using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using System.Xml.Linq;
using UniLinq;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Animations.Rigging;
[HarmonyPatch]
static class AnimationRiggingPatches
{
[HarmonyPatch(typeof(SDCSUtils), nameof(SDCSUtils.setupEquipmentCommon))]
[HarmonyPrefix]
private static bool Prefix_setupEquipmentCommon_SDCSUtils(GameObject _rigObj, out bool __state)
{
__state = false;
if (_rigObj.TryGetComponent<Animator>(out var animator))
{
__state = true;
animator.UnbindAllStreamHandles();
animator.UnbindAllSceneHandles();
}
return true;
}
[HarmonyPatch(typeof(SDCSUtils), nameof(SDCSUtils.setupEquipmentCommon))]
[HarmonyPostfix]
private static void Postfix_setupEquipmentCommon_SDCSUtils(GameObject _rigObj, bool __state)
{
if (__state && _rigObj.TryGetComponent<Animator>(out var animator))
{
animator.Rebind();
}
}
[HarmonyPatch(typeof(SDCSUtils), nameof(SDCSUtils.setupRig))]
[HarmonyPrefix]
private static bool Prefix_setupRig_SDCSUtils(ref RuntimeAnimatorController animController, ref GameObject _rigObj)
{
if (_rigObj && _rigObj.TryGetComponent<AnimationGraphBuilder>(out var builder) && builder.HasWeaponOverride)
{
animController = null;
}
return true;
}
//[HarmonyPatch(typeof(UMACharacterBodyAnimator), nameof(UMACharacterBodyAnimator.assignLayerWeights))]
//[HarmonyPrefix]
//private static bool Prefix_assignLayerWeights_UMACharacterBodyAnimator(UMACharacterBodyAnimator __instance)
//{
// if (__instance.Animator && __instance.Animator.TryGetComponent<AnimationGraphBuilder>(out var builder) && builder.HasWeaponOverride)
// {
// return false;
// }
// return true;
//}
//[HarmonyPatch(typeof(AvatarSDCSController), nameof(AvatarSDCSController.setLayerWeights))]
//[HarmonyPrefix]
//private static bool Prefix_setLayerWeights_AvatarSDCSController(AvatarSDCSController __instance)
//{
// if (__instance.anim && __instance.anim.TryGetComponent<AnimationGraphBuilder>(out var builder) && builder.HasWeaponOverride)
// {
// return false;
// }
// return true;
//}
[HarmonyPatch(typeof(ItemActionRanged), nameof(ItemActionRanged.OnModificationsChanged))]
[HarmonyPostfix]
private static void Postfix_OnModificationChanged_ItemActionRanged(ItemActionData _data)
{
ItemActionRanged.ItemActionDataRanged rangedData = (ItemActionRanged.ItemActionDataRanged)_data;
if (rangedData.IsDoubleBarrel)
{
rangedData.muzzle = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, "Muzzle_L");
rangedData.muzzle2 = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, "Muzzle_R");
}
else
{
rangedData.muzzle = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, "Muzzle");
}
rangedData.Laser = AnimationRiggingManager.GetTransformOverrideByName(rangedData.invData.model, "laser");
ItemActionLauncher.ItemActionDataLauncher launcherData = _data as ItemActionLauncher.ItemActionDataLauncher;
if (launcherData != null)
{
launcherData.projectileJoint = AnimationRiggingManager.GetTransformOverrideByName(launcherData.invData.model, "ProjectileJoint");
}
}
/// <summary>
/// attachment path patch, only apply to MinEventActionSetTransformActive!
/// </summary>
/// <param name="instructions"></param>
/// <returns></returns>
[HarmonyPatch(typeof(MinEventActionSetTransformActive), nameof(MinEventActionSetTransformActive.Execute))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Execute_MinEventActionSetTransformActive(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_find = AccessTools.Method(typeof(GameUtils), nameof(GameUtils.FindDeepChild));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_find))
{
codes.RemoveAt(i);
codes.InsertRange(i, new[]
{
new CodeInstruction(OpCodes.Ldarg_1),
CodeInstruction.LoadField(typeof(MinEventParams), nameof(MinEventParams.Self)),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetAttachmentReferenceOverrideTransform))
});
break;
}
}
return codes;
}
[HarmonyPatch(typeof(MinEventActionSetTransformChildrenActive), nameof(MinEventActionSetTransformChildrenActive.Execute))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Execute_MinEventActionSetTransformChildrenActive(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_find = AccessTools.Method(typeof(GameUtils), nameof(GameUtils.FindDeepChildActive));
var fld_trans = AccessTools.Field(typeof(MinEventActionSetTransformChildrenActive), nameof(MinEventActionSetTransformChildrenActive.transformPath));
for (int i = 1; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_find) && codes[i - 1].LoadsField(fld_trans))
{
codes.RemoveAt(i);
codes.InsertRange(i, new[]
{
new CodeInstruction(OpCodes.Ldarg_1),
CodeInstruction.LoadField(typeof(MinEventParams), nameof(MinEventParams.Self)),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetAttachmentReferenceOverrideTransformActive))
});
break;
}
}
return codes;
}
[HarmonyPatch(typeof(MinEventActionAddPart), nameof(MinEventActionAddPart.Execute))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Execute_MinEventActionAddPart(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_idx = AccessTools.PropertyGetter(typeof(Inventory), nameof(Inventory.holdingItemIdx));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_idx))
{
codes.InsertRange(i + 2, new[]
{
new CodeInstruction(OpCodes.Ldarg_0),
CodeInstruction.LoadField(typeof(MinEventActionAddPart),nameof(MinEventActionAddPart.partName)),
new CodeInstruction(OpCodes.Ldc_I4_1),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetAddPartTransformOverride))
});
break;
}
}
return codes;
}
[HarmonyPatch(typeof(MinEventActionAttachPrefabToHeldItem), nameof(MinEventActionAttachPrefabToHeldItem.Execute))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Execute_MinEventActionAttachPrefabToHeldItem(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var codes = instructions.ToList();
var mtd_find = AccessTools.Method(typeof(GameUtils), nameof(GameUtils.FindDeepChild));
var fld_trans = AccessTools.Field(typeof(MinEventParams), nameof(MinEventParams.Transform));
var mtd_layer = AccessTools.Method(typeof(Utils), nameof(Utils.SetLayerRecursively));
var lbd_targets = generator.DeclareLocal(typeof(AnimationTargetsAbs));
for (int i = 1; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Stloc_0)
{
if (codes[i - 1].Calls(mtd_find))
{
codes.InsertRange(i, new[]
{
new CodeInstruction(OpCodes.Ldc_I4_0),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetAddPartTransformOverride))
});
codes.RemoveAt(i - 1);
i += 1;
}
else if (codes[i - 1].LoadsField(fld_trans))
{
codes.InsertRange(i, new[]
{
new CodeInstruction(OpCodes.Ldarg_0),
CodeInstruction.LoadField(typeof(MinEventActionAttachPrefabToHeldItem), nameof(MinEventActionAttachPrefabToHeldItem.parent_transform)),
new CodeInstruction(OpCodes.Ldc_I4_0),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetAddPartTransformOverride))
});
i += 4;
}
}
else if (codes[i].opcode == OpCodes.Stloc_2)
{
var lbl = generator.DefineLabel();
var lbls = codes[i + 1].ExtractLabels();
codes[i + 1].WithLabels(lbl);
codes.InsertRange(i + 1, new[]
{
new CodeInstruction(OpCodes.Ldarg_1).WithLabels(lbls),
CodeInstruction.LoadField(typeof(MinEventParams), nameof(MinEventParams.Transform)),
new CodeInstruction(OpCodes.Ldnull),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(UnityEngine.Object), "op_Inequality")),
new CodeInstruction(OpCodes.Brfalse_S, lbl),
new CodeInstruction(OpCodes.Ldarg_1),
CodeInstruction.LoadField(typeof(MinEventParams), nameof(MinEventParams.Transform)),
CodeInstruction.Call(typeof(Transform), nameof(Transform.GetComponent), new Type[0], new Type[]{ typeof(AnimationTargetsAbs)}),
new CodeInstruction(OpCodes.Stloc_S, lbd_targets)
});
i += 9;
}
else if (codes[i].opcode == OpCodes.Stloc_S && ((LocalBuilder)codes[i].operand).LocalIndex == 4)
{
codes.RemoveAt(i - 1);
codes.InsertRange(i - 1, new[]
{
new CodeInstruction(OpCodes.Ldloc_S, lbd_targets),
new CodeInstruction(OpCodes.Ldloc_2),
CodeInstruction.Call(typeof(AnimationRiggingPatches), nameof(CreateOrMoveAttachment))
});
i += 2;
}
else if (codes[i].Calls(mtd_layer))
{
codes.InsertRange(i + 1, new[]
{
new CodeInstruction(OpCodes.Ldloc_S, lbd_targets),
new CodeInstruction(OpCodes.Ldloc_S, 4),
CodeInstruction.Call(typeof(AnimationRiggingPatches), nameof(CheckAttachmentRefMerge))
});
i += 3;
}
else if (codes[i].opcode == OpCodes.Stloc_S && ((LocalBuilder)codes[i].operand).LocalIndex == 5)
{
var lbl = generator.DefineLabel();
var lbls = codes[i + 1].ExtractLabels();
codes[i + 1].WithLabels(lbl);
codes.InsertRange(i + 1, new[]
{
new CodeInstruction(OpCodes.Ldloc_3).WithLabels(lbls),
CodeInstruction.Call(typeof(Transform), nameof(Transform.GetComponent), new Type[0], new Type[]{ typeof(IgnoreTint)}),
new CodeInstruction(OpCodes.Ldnull),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(UnityEngine.Object), "op_Inequality")),
new CodeInstruction(OpCodes.Brfalse_S, lbl),
new CodeInstruction(OpCodes.Ret)
});
i += 6;
}
}
codes.InsertRange(0, new[]
{
new CodeInstruction(OpCodes.Ldnull),
new CodeInstruction(OpCodes.Stloc_S, lbd_targets)
});
return codes;
}
private static GameObject CreateOrMoveAttachment(GameObject go, AnimationTargetsAbs targets, string name)
{
GameObject res = null;
if (targets)
{
res = targets.GetPrefab(name);
}
if (!res)
{
res = GameObject.Instantiate(go);
}
return res;
}
private static void CheckAttachmentRefMerge(AnimationTargetsAbs targets, GameObject attachmentReference)
{
if (targets)
{
targets.AttachPrefab(attachmentReference);
}
}
/// <summary>
/// reload logging patch
/// </summary>
/// <param name="stateInfo"></param>
[HarmonyPatch(typeof(AnimatorRangedReloadState), nameof(AnimatorRangedReloadState.OnStateEnter))]
[HarmonyPostfix]
private static void Postfix_OnStateEnter_AnimatorRangedReloadState(AnimatorStateInfo stateInfo)
{
if (ConsoleCmdReloadLog.LogInfo)
{
Log.Out(string.Format("ANIMATION LENGTH: length {0} speed {1} speedMultiplier {2} original length {3}", stateInfo.length, stateInfo.speed, stateInfo.speedMultiplier, stateInfo.length * stateInfo.speedMultiplier));
}
}
[HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.OnHoldingItemChanged))]
[HarmonyPostfix]
private static void Postfix_OnHoldingItemChanged_EntityAlive(EntityAlive __instance)
{
AnimationRiggingManager.OnHoldingItemIndexChanged(__instance as EntityPlayer);
}
[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.OnHoldingItemChanged))]
[HarmonyPostfix]
private static void Postfix_OnHoldingItemChanged_EntityPlayerLocal(EntityPlayerLocal __instance)
{
AnimationRiggingManager.OnHoldingItemIndexChanged(__instance);
}
[HarmonyPatch(typeof(GameManager), nameof(GameManager.SaveAndCleanupWorld))]
[HarmonyPostfix]
private static void Postfix_SaveAndCleanupWorld_GameManager()
{
AnimationRiggingManager.Clear();
}
private static void ParseTakeOverReloadTime(XElement _node)
{
string itemName = _node.GetAttribute("name");
if (string.IsNullOrEmpty(itemName))
{
return;
}
ItemClass item = ItemClass.GetItemClass(itemName);
if (item.Properties.GetBool("TakeOverReloadTime"))
{
AnimationRiggingManager.AddReloadTimeTakeOverItem(item.Name);
//Log.Out($"take over reload time: {item.Name} {item.Id}");
}
}
[HarmonyPatch(typeof(ItemClassesFromXml), nameof(ItemClassesFromXml.parseItem))]
[HarmonyPostfix]
private static void Postfix_parseItem_ItemClassesFromXml(XElement _node)
{
ParseTakeOverReloadTime(_node);
}
//[HarmonyPatch(typeof(ItemClass), nameof(ItemClass.StopHolding))]
//[HarmonyPostfix]
//private static void Postfix_StopHolding_ItemClass(Transform _modelTransform)
//{
// if (_modelTransform != null && _modelTransform.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
// {
// targets.SetEnabled(false);
// }
//}
[HarmonyPatch(typeof(Inventory), nameof(Inventory.createHeldItem))]
[HarmonyPostfix]
private static void Postfix_createHeldItem_Inventory(Inventory __instance, Transform __result)
{
if (__result && __result.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
if (GameManager.IsDedicatedServer || !(__instance.entity is EntityPlayer player))
{
targets.Destroy();
}
else
{
if (player is EntityPlayerLocal localPlayer)
{
targets.Init(localPlayer.emodel.avatarController.GetActiveModelRoot(), localPlayer.bFirstPersonView);
}
else
{
targets.DestroyFpv();
targets.Init(player.emodel.avatarController.GetActiveModelRoot(), false);
}
}
}
}
[HarmonyPatch(typeof(Inventory), nameof(Inventory.ForceHoldingItemUpdate))]
[HarmonyPrefix]
private static bool Prefix_ForceHoldingItemUpdate(Inventory __instance)
{
if (__instance.entity is EntityPlayer)
AnimationRiggingManager.OnClearInventorySlot(__instance, __instance.holdingItemIdx);
return true;
}
[HarmonyPatch(typeof(ItemActionRanged), nameof(ItemActionRanged.ItemActionEffects))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_ItemActionEffects_ItemActionRanged(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var codes = instructions.ToList();
var fld_fpv = AccessTools.Field(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.bFirstPersonView));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].LoadsField(fld_fpv))
{
codes.InsertRange(i + 4, new[]
{
new CodeInstruction(OpCodes.Ldloc_S, codes[i + 3].operand),
new CodeInstruction(OpCodes.Ldarg_2),
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ItemActionAttack), nameof(ItemActionAttack.particlesMuzzleFire))),
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ItemActionAttack), nameof(ItemActionAttack.particlesMuzzleFireFpv))),
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ItemActionAttack), nameof(ItemActionAttack.particlesMuzzleSmoke))),
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ItemActionAttack), nameof(ItemActionAttack.particlesMuzzleSmokeFpv))),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.SpawnFpvParticles))),
new CodeInstruction(OpCodes.Brtrue_S, codes[i - 5].operand)
});
break;
}
}
//FieldInfo fld_muzzle = AccessTools.Field(typeof(ItemActionRanged.ItemActionDataRanged), nameof(ItemActionRanged.ItemActionDataRanged.muzzle));
//FieldInfo fld_muzzle2 = AccessTools.Field(typeof(ItemActionRanged.ItemActionDataRanged), nameof(ItemActionRanged.ItemActionDataRanged.muzzle2));
//MethodInfo mtd_getmuzzle = AccessTools.Method(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetMuzzleOverrideFPV));
//MethodInfo mtd_getmuzzle2 = AccessTools.Method(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetMuzzle2OverrideFPV));
//for (int i = 0; i < codes.Count; i++)
//{
// if (codes[i].LoadsField(fld_muzzle))
// {
// codes.InsertRange(i + 1, new[]
// {
// new CodeInstruction(OpCodes.Ldloc_S, 4),
// new CodeInstruction(OpCodes.Call, mtd_getmuzzle)
// });
// }
// else if (codes[i].LoadsField(fld_muzzle2))
// {
// codes.InsertRange(i + 1, new[]
// {
// new CodeInstruction(OpCodes.Ldloc_S, 4),
// new CodeInstruction(OpCodes.Call, mtd_getmuzzle2)
// });
// }
//}
return codes;
}
[HarmonyPatch(typeof(Inventory), nameof(Inventory.clearSlotByIndex))]
[HarmonyPrefix]
private static bool Prefix_clearSlotByIndex(Inventory __instance, int _idx)
{
if (__instance.entity is EntityPlayer)
AnimationRiggingManager.OnClearInventorySlot(__instance, _idx);
return true;
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.Update))]
[HarmonyPostfix]
private static void Postfix_Update_AvatarMultiBodyController(AvatarMultiBodyController __instance)
{
AnimationRiggingManager.UpdatePlayerAvatar(__instance);
if (__instance is AvatarLocalPlayerController avatarLocalPlayer)
{
//if ((avatarLocalPlayer.entity as EntityPlayerLocal).bFirstPersonView && !avatarLocalPlayer.entity.inventory.GetIsFinishedSwitchingHeldItem())
//{
// avatarLocalPlayer.UpdateInt(AvatarController.weaponHoldTypeHash, -1, false);
// avatarLocalPlayer.UpdateBool("Holstered", false, false);
// avatarLocalPlayer.FPSArms.Animator.Play("idle", 0, 0f);
//}
var mapping = MultiActionManager.GetMappingForEntity(__instance.entity.entityId);
if (mapping != null)
{
avatarLocalPlayer.UpdateInt(MultiActionUtils.ExecutingActionIndexHash, mapping.CurActionIndex, true);
}
if (__instance.entity.inventory?.holdingItemData?.actionData != null)
{
foreach (var actionData in __instance.entity.inventory.holdingItemData.actionData)
{
if (actionData is IModuleContainerFor<ActionModuleFireModeSelector.FireModeData> data)
{
avatarLocalPlayer.UpdateInt(ActionModuleFireModeSelector.FireModeParamHashes[actionData.indexInEntityOfAction], data.Instance.currentFireMode, true);
}
}
}
}
if (__instance.entity.AttachedToEntity)
{
__instance.SetVehicleAnimation(AvatarController.vehiclePoseHash, __instance.entity.vehiclePoseMode);
}
}
[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController.Update))]
[HarmonyPostfix]
private static void Postfix_Update_LegacyAvatarController(LegacyAvatarController __instance)
{
AnimationRiggingManager.UpdatePlayerAvatar(__instance);
if (__instance.entity && __instance.entity.AttachedToEntity)
{
__instance.SetVehicleAnimation(AvatarController.vehiclePoseHash, __instance.entity.vehiclePoseMode);
}
}
//[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController.LateUpdate))]
//[HarmonyPostfix]
//private static void Postfix_LateUpdate_AvatarLocalPlayerController(AvatarLocalPlayerController __instance)
//{
// var targets = AnimationRiggingManager.GetRigTargetsFromPlayer(__instance.entity as EntityPlayer);
// if (targets && !targets.Destroyed)
// {
// targets.UpdateTpvSpineRotation(__instance.entity as EntityPlayer);
// }
//}
//[HarmonyPatch(typeof(AvatarSDCSController), nameof(AvatarSDCSController.LateUpdate))]
//[HarmonyPostfix]
//private static void Postfix_LateUpdate_AvatarSDCSController(AvatarSDCSController __instance)
//{
// var targets = AnimationRiggingManager.GetRigTargetsFromPlayer(__instance.entity as EntityPlayer);
// if (targets && !targets.Destroyed)
// {
// targets.UpdateTpvSpineRotation(__instance.entity as EntityPlayer);
// }
//}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.StartAnimationReloading))]
[HarmonyPrefix]
private static bool Prefix_StartAnimationReloding_AvatarController(AvatarMultiBodyController __instance)
{
__instance.Entity?.FireEvent(CustomEnums.onReloadAboutToStart);
return true;
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.StartAnimationReloading))]
[HarmonyPostfix]
private static void Postfix_StartAnimationReloading_AvatarMultibodyController(AvatarMultiBodyController __instance)
{
if (__instance.HeldItemTransform != null && __instance.HeldItemTransform.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
EntityAlive entity = __instance.Entity;
ItemValue holdingItemItemValue = entity.inventory.holdingItemItemValue;
//#if DEBUG
// float x = 1, y = 1;
// var tags = entity.inventory.holdingItem.ItemTags;
// var tags_prev = tags;
// MultiActionManager.ModifyItemTags(entity.inventory.holdingItemItemValue, entity.MinEventContext.ItemActionData, ref tags);
// entity.Progression.ModifyValue(PassiveEffects.ReloadSpeedMultiplier, ref x, ref y, tags);
// Log.Out($"item {entity.inventory.holdingItem.Name} action index {entity.MinEventContext.ItemActionData.indexInEntityOfAction} progression base {x} perc {y} has tag {tags.Test_AnySet(FastTags.Parse("perkMachineGunner"))} \ntags prev {tags_prev} \ntags after {tags}");
//#endif
float reloadSpeed = EffectManager.GetValue(PassiveEffects.ReloadSpeedMultiplier, holdingItemItemValue, 1f, entity);
float reloadSpeedRatio = EffectManager.GetValue(CustomEnums.ReloadSpeedRatioFPV2TPV, holdingItemItemValue, 1f, entity);
float partialReloadMultiplier = EffectManager.GetValue(CustomEnums.PartialReloadCount, holdingItemItemValue, 0, entity);
float partialReloadRatio = 1f;
if (partialReloadMultiplier <= 0)
{
partialReloadMultiplier = 1;
}
else
{
int magSize = (int)EffectManager.GetValue(PassiveEffects.MagazineSize, holdingItemItemValue, ((ItemActionRanged)entity.inventory.holdingItem.Actions[MultiActionManager.GetActionIndexForEntity(entity)]).BulletsPerMagazine, entity);
//how many partial reload is required to fill an empty mag
partialReloadRatio = Mathf.Ceil(magSize / partialReloadMultiplier);
//how many partial reload is required to finish this reload
partialReloadMultiplier = Mathf.Ceil((magSize - holdingItemItemValue.Meta) / partialReloadMultiplier);
//reload time percentage of this reload
partialReloadRatio = partialReloadMultiplier / partialReloadRatio;
}
float localMultiplier, remoteMultiplier;
bool isFPV = entity as EntityPlayerLocal != null && (entity as EntityPlayerLocal).emodel.IsFPV;
bool takeOverReloadTime = AnimationRiggingManager.IsReloadTimeTakeOverItem(holdingItemItemValue.type);
if (isFPV && !takeOverReloadTime)
{
localMultiplier = reloadSpeed / reloadSpeedRatio;
}
else if (!isFPV && takeOverReloadTime)
{
localMultiplier = reloadSpeed * reloadSpeedRatio / partialReloadMultiplier;
}
else if(isFPV && takeOverReloadTime)
{
localMultiplier = reloadSpeed;
}
else
{
localMultiplier = reloadSpeed * partialReloadRatio;
}
if (takeOverReloadTime)
{
remoteMultiplier = reloadSpeed * reloadSpeedRatio / partialReloadMultiplier;
}
else
{
remoteMultiplier = reloadSpeed * partialReloadRatio;
}
if (ConsoleCmdReloadLog.LogInfo)
Log.Out($"Set reload multiplier: isFPV {isFPV}, reloadSpeed {reloadSpeed}, reloadSpeedRatio {reloadSpeedRatio}, finalMultiplier {localMultiplier}, remoteMultiplier {remoteMultiplier}, partialMultiplier {partialReloadMultiplier}, partialRatio {partialReloadRatio}");
__instance.UpdateFloat(AvatarController.reloadSpeedHash, localMultiplier, false);
SetDataFloat(__instance, (AvatarController.DataTypes)AvatarController.reloadSpeedHash, remoteMultiplier, true);
}
}
/// <summary>
/// sets float only on remote clients but not on local client.
/// </summary>
/// <param name="__instance"></param>
/// <param name="_type"></param>
/// <param name="_value"></param>
/// <param name="_netsync"></param>
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.SetDataFloat))]
[HarmonyReversePatch(HarmonyReversePatchType.Original)]
private static void SetDataFloat(AvatarController __instance, AvatarController.DataTypes _type, float _value, bool _netsync = true)
{
IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
if (instructions == null)
return null;
var codes = instructions.ToList();
codes.RemoveRange(0, 5);
codes[0].labels.Clear();
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].LoadsConstant(AnimParamData.ValueTypes.DataFloat))
{
codes[i].opcode = OpCodes.Ldc_I4;
codes[i].operand = (int)AnimParamData.ValueTypes.Float;
break;
}
}
return codes;
}
_ = Transpiler(null);
}
//[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.StartAnimationAttack))]
//[HarmonyPostfix]
//private static void Postfix_StartAnimationAttack_AvatarMultiBodyController(AvatarMultiBodyController __instance)
//{
// if (__instance is AvatarLocalPlayerController)
// AnimationRiggingManager.FpvWeaponFire();
//}
[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.SetFirstPersonView))]
[HarmonyPrefix]
private static bool Prefix_SetFirstPersonView_EntityPlayerLocal(EntityPlayerLocal __instance, bool _bFirstPersonView)
{
var targets = AnimationRiggingManager.GetRigTargetsFromPlayer(__instance);
if (_bFirstPersonView != __instance.bFirstPersonView && targets && !targets.Destroyed && targets.IsAnimationSet)
{
//targets.SetEnabled(false);
//targets.GraphBuilder.SetCurrentTarget(null);
Log.Out($"Switch view destroy slot {__instance.inventory.holdingItemIdx}");
targets.Destroy();
}
return true;
}
[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController.SwitchModelAndView))]
[HarmonyPostfix]
private static void Postfix_SwitchModelAndView_AvatarLocalPlayerController(AvatarLocalPlayerController __instance, bool _bFPV)
{
if (_bFPV)
{
__instance.hasTurnRate = false;
}
}
[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController.SetInRightHand))]
[HarmonyPostfix]
private static void Postfix_SetInRightHand_AvatarLocalPlayerController(Transform _transform, AvatarLocalPlayerController __instance)
{
if (_transform != null && _transform.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed && targets.ItemCurrent)
{
//targets.SetEnabled(true);
targets.GraphBuilder.SetCurrentTarget(targets);
}
else if (__instance.PrimaryBody?.Animator && __instance.PrimaryBody.Animator.TryGetComponent<AnimationGraphBuilder>(out var builder))
{
builder.SetCurrentTarget(null);
}
}
[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController.SetInRightHand))]
[HarmonyPostfix]
private static void Postfix_SetInRightHand_LegacyAvatarController(Transform _transform, LegacyAvatarController __instance)
{
if (_transform != null && _transform.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed && targets.ItemCurrent)
{
//targets.SetEnabled(true);
targets.GraphBuilder.SetCurrentTarget(targets);
}
else if (__instance.anim && __instance.anim.TryGetComponent<AnimationGraphBuilder>(out var builder))
{
builder.SetCurrentTarget(null);
}
}
//[HarmonyPatch(typeof(Inventory), nameof(Inventory.setHoldingItemTransform))]
//[HarmonyPrefix]
//private static bool Prefix_setHoldingItemTransform_Inventory(Inventory __instance)
//{
// if (__instance.lastdrawnHoldingItemTransform && __instance.lastdrawnHoldingItemTransform.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
// {
// targets.SetEnabled(false);
// }
// return true;
//}
[HarmonyPatch(typeof(vp_FPWeapon), nameof(vp_FPWeapon.Start))]
[HarmonyPostfix]
private static void Postfix_Start_vp_FPWeapon(vp_FPWeapon __instance)
{
var player = __instance.GetComponentInParent<EntityPlayerLocal>();
if (player && player.inventory != null)
{
for (int i = 0; i < player.inventory.models.Length; i++)
{
Transform model = player.inventory.models[i];
if (model != null && model.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
if (i == player.inventory.holdingItemIdx)
{
player.inventory.ForceHoldingItemUpdate();
}
else
{
targets.Init(__instance.transform, true);
}
}
}
}
}
#region temporary fix for arm glitch on switching weapon
[HarmonyPatch(typeof(Inventory), nameof(Inventory.updateHoldingItem))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_updateHoldingItem_Inventory(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_setparent = AccessTools.Method(typeof(Transform), nameof(Transform.SetParent), new[] { typeof(Transform), typeof(bool) });
var mtd_startholding = AccessTools.Method(typeof(ItemClass), nameof(ItemClass.StartHolding));
var mtd_showrighthand = AccessTools.Method(typeof(Inventory), nameof(Inventory.ShowRightHand));
var mtd_holdingchanged = AccessTools.Method(typeof(EntityAlive), nameof(EntityAlive.OnHoldingItemChanged));
var prop_holdingitem = AccessTools.PropertyGetter(typeof(Inventory), nameof(Inventory.holdingItem));
var fld_transform = AccessTools.Field(typeof(MinEventParams), nameof(MinEventParams.Transform));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_setparent))
{
codes[i - 1].opcode = OpCodes.Ldc_I4_1;
}
else if (codes[i].Calls(mtd_startholding))
{
for (int j = i - 1; j >= 0; j--)
{
if (codes[j].Calls(prop_holdingitem))
{
for (int k = i + 1; k < codes.Count; k++)
{
if (codes[k].StoresField(fld_transform))
{
codes.InsertRange(k + 1, new[]
{
new CodeInstruction(OpCodes.Ldloc_0).WithLabels(codes[k + 1].ExtractLabels()),
CodeInstruction.LoadField(typeof(CustomEnums), nameof(CustomEnums.onSelfHoldingItemAssemble)),
new CodeInstruction(OpCodes.Ldarg_0),
CodeInstruction.LoadField(typeof(Inventory), nameof(Inventory.entity)),
CodeInstruction.LoadField(typeof(EntityAlive), nameof(EntityAlive.MinEventContext)),
CodeInstruction.Call(typeof(ItemValue), nameof(ItemValue.FireEvent)),
});
k += 6;
}
else if (codes[k].Calls(mtd_showrighthand))
{
codes.InsertRange(k + 1, codes.GetRange(j - 1, i - j + 2));
codes[i + 1].WithLabels(codes[j - 1].ExtractLabels());
codes.RemoveRange(j - 1, i - j + 2);
break;
}
}
break;
}
}
i += 6;
}
else if (codes[i].Calls(mtd_holdingchanged))
{
codes.InsertRange(i + 1, new[]
{
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(codes[i + 1].ExtractLabels()),
CodeInstruction.Call(typeof(Inventory), nameof(Inventory.syncHeldItem))
});
break;
}
}
return codes;
}
[HarmonyPatch(typeof(Inventory), nameof(Inventory.setHoldingItemTransform))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setHoldingItemTransform_Inventory(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_sync = AccessTools.Method(typeof(Inventory), nameof(Inventory.syncHeldItem));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_sync))
{
codes[i + 1].WithLabels(codes[i - 1].ExtractLabels());
codes.RemoveRange(i - 1, 2);
break;
}
}
return codes;
}
//private static Coroutine delayShowWeaponCo;
//private static IEnumerator DelayShowWeapon(Camera camera)
//{
// Log.Out($"Delay show weapon!");
// camera.cullingMask &= ~(1 << 10);
// yield return new WaitForSeconds(0.5f);
// if (camera)
// {
// camera.cullingMask |= 1 << 10;
// }
// delayShowWeaponCo = null;
// Log.Out($"Show weapon!");
// yield break;
//}
//[HarmonyPatch(typeof(Inventory), nameof(Inventory.setHeldItemByIndex))]
//[HarmonyPrefix]
//private static bool Prefix_setHeldItemByIndex_Inventory(Inventory __instance, out bool __state)
//{
// __state = __instance.holdingItemData?.model && __instance.holdingItemData.model.GetComponent<RigTargets>();
// return true;
//}
//[HarmonyPatch(typeof(Inventory), nameof(Inventory.setHeldItemByIndex))]
//[HarmonyPostfix]
//private static void Postfix_setHeldItemByIndex_Inventory(Inventory __instance, bool __state)
//{
// if (__state && __instance.entity is EntityPlayerLocal player && player.bFirstPersonView && (!__instance.holdingItemData?.model || !__instance.holdingItemData.model.GetComponent<RigTargets>()))
// {
// if (delayShowWeaponCo != null)
// {
// ThreadManager.StopCoroutine(delayShowWeaponCo);
// }
// if (__instance.holdingItemIdx == __instance.DUMMY_SLOT_IDX)
// {
// player.ShowHoldingItem(true);
// }
// else
// {
// delayShowWeaponCo = ThreadManager.StartCoroutine(DelayShowWeapon(player.playerCamera));
// }
// }
//}
//[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.ShowHoldingItem))]
//[HarmonyPrefix]
//private static bool Prefix_ShowHoldingItem_EntityPlayerLocal(bool show)
//{
// if (delayShowWeaponCo != null)
// {
// if (show)
// {
// return false;
// }
// ThreadManager.StopCoroutine(delayShowWeaponCo);
// }
// return true;
//}
/*
[HarmonyPatch(typeof(Inventory), nameof(Inventory.setHoldingItemTransform))]
[HarmonyPostfix]
private static void Postfix_setHoldingItemTransform_Inventory(Transform _t, Inventory __instance)
{
if (_t != null && _t.TryGetComponent<RigTargets>(out var targets) && !targets.Destroyed)
{
targets.SetEnabled(__instance.entity.emodel.IsFPV);
}
}
[HarmonyPatch(typeof(Inventory), nameof(Inventory.SetItem), new[] {typeof(int), typeof(ItemValue), typeof(int), typeof(bool)})]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_SetItem_Inventory(IEnumerable<CodeInstruction> instructions)
{
MethodInfo mtd_update = AccessTools.Method(typeof(Inventory), nameof(Inventory.updateHoldingItem));
foreach (var code in instructions)
{
yield return code;
if (code.Calls(mtd_update))
{
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldc_I4_1);
yield return new CodeInstruction(OpCodes.Ldc_R4, 0f);
yield return CodeInstruction.Call(typeof(Inventory), nameof(Inventory.ShowHeldItem));
}
}
}
[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.ShowWeaponCamera))]
[HarmonyPostfix]
private static void Postfix_ShowWeaponCamera_EntityPlayerLocal(EntityPlayerLocal __instance, bool show)
{
if (__instance.bFirstPersonView)
{
__instance.weaponCamera.cullingMask &= ~(1 << 10);
if (delayShowWeaponCo != null)
{
ThreadManager.StopCoroutine(delayShowWeaponCo);
}
if (show)
{
delayShowWeaponCo = ThreadManager.StartCoroutine(DelayShowWeapon(__instance.weaponCamera));
}
}
}
*/
#endregion
[HarmonyPatch(typeof(World), nameof(World.SpawnEntityInWorld))]
[HarmonyPrefix]
private static bool Prefix_SpawnEntityInWorld_World(Entity _entity)
{
if (_entity is EntityItem _entityItem)
{
var targets = _entityItem.GetComponentInChildren<AnimationTargetsAbs>(true);
if (targets && !targets.Destroyed)
{
targets.Destroy();
}
}
return true;
}
[HarmonyPatch(typeof(World), nameof(World.SpawnEntityInWorld))]
[HarmonyPostfix]
private static void Postfix_SpawnEntityInWorld_World(Entity _entity)
{
if (_entity is EntityPlayer player && !(_entity is EntityPlayerLocal) && player.inventory != null)
{
foreach (var model in player.inventory.models)
{
if (model && model.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
targets.DestroyFpv();
targets.Init(player.emodel.avatarController.GetActiveModelRoot(), false);
}
}
}
}
[HarmonyPatch(typeof(EntityItem), nameof(EntityItem.createMesh))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_createMesh_EntityItem(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
codes[codes.Count - 1].WithLabels(codes[codes.Count - 11].labels);
codes.RemoveRange(codes.Count - 11, 10);
return codes;
}
[HarmonyPatch(typeof(EntityItem), nameof(EntityItem.createMesh))]
[HarmonyPostfix]
private static void Postfix_createMesh_EntityItem(EntityItem __instance)
{
if (__instance.itemTransform)
{
__instance.itemTransform.tag = "Item";
if (__instance.itemTransform.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
targets.Destroy();
}
}
__instance.meshRenderers = __instance.itemTransform.GetComponentsInChildren<Renderer>(true);
__instance.VisiblityCheck(0, false);
}
[HarmonyPatch(typeof(EModelBase), nameof(EModelBase.SwitchModelAndView))]
[HarmonyPostfix]
private static void Postfix_SwitchModelAndView_EModelBase(EModelBase __instance)
{
if (__instance.entity is EntityPlayerLocal player && player.inventory != null)
{
foreach (var model in player.inventory.models)
{
if (model && model.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
targets.Init(player.emodel.avatarController.GetActiveModelRoot(), player.bFirstPersonView);
}
}
}
}
[HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.Detach))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Detach_EntityAlive(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var fld_inv = AccessTools.Field(typeof(EntityAlive), nameof(EntityAlive.inventory));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].StoresField(fld_inv))
{
codes.InsertRange(i + 1, new[]
{
new CodeInstruction(OpCodes.Ldarg_0),
CodeInstruction.Call(typeof(AnimationRiggingPatches), nameof(AnimationRiggingPatches.DetachInitInventory))
});
break;
}
}
return codes;
}
private static void DetachInitInventory(EntityAlive __instance)
{
if (!(__instance is EntityPlayer player))
{
return;
}
if (__instance.inventory != null)
{
foreach (var model in __instance.inventory.models)
{
if (model && model.TryGetComponent<AnimationTargetsAbs>(out var targets) && !targets.Destroyed)
{
targets.Init(__instance.emodel.avatarController.GetActiveModelRoot(), player is EntityPlayerLocal localPlayer ? localPlayer.bFirstPersonView : false);
}
}
}
}
[HarmonyPatch(typeof(SDCSUtils), nameof(SDCSUtils.cleanupEquipment))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_cleanupEquipment_SDCSUtils(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_removeat = AccessTools.Method(typeof(List<RigLayer>), nameof(List<RigLayer>.RemoveAt));
var mtd_destroy = AccessTools.Method(typeof(GameUtils), nameof(GameUtils.DestroyAllChildrenBut), new[] {typeof(Transform), typeof(List<string>)});
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_removeat))
{
codes.InsertRange(i - 2, new[]
{
new CodeInstruction(OpCodes.Ldloc_2),
new CodeInstruction(OpCodes.Ldloc_3),
CodeInstruction.Call(typeof(List<RigLayer>), "get_Item"),
CodeInstruction.Call(typeof(RigLayer), "get_name"),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.ShouldExcludeRig)),
new CodeInstruction(OpCodes.Brtrue_S, codes[i - 3].operand)
});
i += 6;
}
else if (codes[i].Calls(mtd_destroy))
{
codes.InsertRange(i, new[]
{
new CodeInstruction(OpCodes.Dup),
CodeInstruction.Call(typeof(AnimationRiggingManager), nameof(AnimationRiggingManager.GetExcludeRigs)),
CodeInstruction.Call(typeof(List<string>), nameof(List<string>.AddRange)),
});
i += 3;
}
}
return codes;
}
[HarmonyPatch(typeof(ItemActionRanged), nameof(ItemActionRanged.SwapSelectedAmmo))]
[HarmonyPrefix]
private static bool Prefix_SwapSelectedAmmo_ItemActionRanged(ItemActionRanged __instance, EntityAlive _entity, int _ammoIndex)
{
if (_ammoIndex == (int)_entity.inventory.holdingItemItemValue.SelectedAmmoTypeIndex && __instance is IModuleContainerFor<ActionModuleInspectable> inspectable && _entity is EntityPlayerLocal player)
{
ItemActionRanged.ItemActionDataRanged _actionData = _entity.inventory.holdingItemData.actionData[__instance.ActionIndex] as ItemActionRanged.ItemActionDataRanged;
if (!_entity.MovementRunning && !_entity.AimingGun && !player.bLerpCameraFlag && _actionData != null && !_entity.inventory.holdingItem.IsActionRunning(_entity.inventory.holdingItemData) && !__instance.CanReload(_actionData) && (_entity.inventory.holdingItemItemValue.Meta > 0 || inspectable.Instance.allowEmptyInspect))
{
_entity.emodel.avatarController._setTrigger("weaponInspect", true);
return false;
}
}
return true;
}
[HarmonyPatch(typeof(ItemActionRanged), nameof(ItemActionRanged.ExecuteAction))]
[HarmonyPostfix]
private static void Postfix_ExecuteAction_ItemActionRanged(ItemActionRanged __instance, ItemActionData _actionData)
{
if (_actionData is ItemActionRanged.ItemActionDataRanged rangedData)
{
int burstCount = __instance.GetBurstCount(_actionData);
_actionData.invData.holdingEntity.emodel.avatarController._setBool("TriggerPulled", rangedData.bPressed && rangedData.curBurstCount < burstCount, true);
}
}
[HarmonyPatch(typeof(ItemClass), nameof(ItemClass.LateInitAll))]
[HarmonyPostfix]
private static void Postfix_LateInitAll_ItemClass()
{
AnimationRiggingManager.ParseItemIDs();
}
[HarmonyPatch(typeof(Animator), nameof(Animator.Rebind), new Type[0])]
[HarmonyReversePatch(HarmonyReversePatchType.Original)]
public static void RebindNoDefault(this Animator __instance)
{
IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
if (instructions == null)
{
yield break;
}
foreach (var ins in instructions)
{
if (ins.opcode == OpCodes.Ldc_I4_1)
{
yield return new CodeInstruction(OpCodes.Ldc_I4_0);
}
else
{
yield return ins;
}
}
}
_ = Transpiler(null);
}
//[HarmonyPatch(typeof(ItemActionDynamic), nameof(ItemActionDynamic.GetExecuteActionGrazeTarget))]
//[HarmonyPostfix]
//private static void Postfix_Test2(WorldRayHitInfo[] __result)
//{
// Log.Out($"World ray info count: {__result.Length}");
//}
//[HarmonyPatch(typeof(ItemActionDynamic), nameof(ItemActionDynamic.hitTarget))]
//[HarmonyPostfix]
//private static void Postfix_hittest(ItemActionData _actionData, WorldRayHitInfo hitInfo, bool _isGrazingHit = false)
//{
// Log.Out($"HIT TARGET! IsGrazing: {_isGrazingHit}\n{StackTraceUtility.ExtractStackTrace()}");
//}
//[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController._setTrigger))]
//[HarmonyPostfix]
//private static void Postfix_AvatarLocalPlayerController_SetTrigger(int _pid, AvatarLocalPlayerController __instance)
//{
// AnimationRiggingManager.SetTrigger(_pid, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController._resetTrigger))]
//[HarmonyPostfix]
//private static void Postfix_AvatarLocalPlayerController_ResetTrigger(int _pid, AvatarLocalPlayerController __instance)
//{
// AnimationRiggingManager.ResetTrigger(_pid, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController._setFloat))]
//[HarmonyPostfix]
//private static void Postfix_AvatarLocalPlayerController_SetFloat(int _pid, float _value, AvatarLocalPlayerController __instance)
//{
// AnimationRiggingManager.SetFloat(_pid, _value, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController._setBool))]
//[HarmonyPostfix]
//private static void Postfix_AvatarLocalPlayerController_SetBool(int _pid, bool _value, AvatarLocalPlayerController __instance)
//{
// AnimationRiggingManager.SetBool(_pid, _value, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController._setInt))]
//[HarmonyPostfix]
//private static void Postfix_AvatarLocalPlayerController_SetInt(int _pid, int _value, AvatarLocalPlayerController __instance)
//{
// AnimationRiggingManager.SetInt(_pid, _value, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController._setTrigger))]
//[HarmonyPostfix]
//private static void Postfix_LegacyAvatarController_SetTrigger(int _propertyHash, LegacyAvatarController __instance)
//{
// AnimationRiggingManager.SetTrigger(_propertyHash, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController._resetTrigger))]
//[HarmonyPostfix]
//private static void Postfix_LegacyAvatarController_ResetTrigger(int _propertyHash, LegacyAvatarController __instance)
//{
// AnimationRiggingManager.ResetTrigger(_propertyHash, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController._setFloat))]
//[HarmonyPostfix]
//private static void Postfix_LegacyAvatarController_SetFloat(int _propertyHash, float _value, LegacyAvatarController __instance)
//{
// AnimationRiggingManager.SetFloat(_propertyHash, _value, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController._setBool))]
//[HarmonyPostfix]
//private static void Postfix_LegacyAvatarController_SetBool(int _propertyHash, bool _value, LegacyAvatarController __instance)
//{
// AnimationRiggingManager.SetBool(_propertyHash, _value, __instance.entity as EntityPlayer);
//}
//[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController._setInt))]
//[HarmonyPostfix]
//private static void Postfix_LegacyAvatarController_SetInt(int _propertyHash, int _value, LegacyAvatarController __instance)
//{
// AnimationRiggingManager.SetInt(_propertyHash, _value, __instance.entity as EntityPlayer);
//}
[HarmonyPatch(typeof(AvatarLocalPlayerController), nameof(AvatarLocalPlayerController._resetTrigger), typeof(int), typeof(bool))]
[HarmonyReversePatch(HarmonyReversePatchType.Original)]
public static void VanillaResetTrigger(AvatarLocalPlayerController __instance, int _pid, bool _netsync = true)
{
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.TryGetTrigger), new[] { typeof(int), typeof(bool) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetTrigger_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.TryGetBool), new[] { typeof(int), typeof(bool) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetBool_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.TryGetInt), new[] { typeof(int), typeof(int) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetInt_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.TryGetFloat), new[] { typeof(int), typeof(float) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetFloat_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedFloat)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.TryGetTrigger), new[] { typeof(int), typeof(bool) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetTrigger_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.TryGetBool), new[] { typeof(int), typeof(bool) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetBool_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.TryGetInt), new[] { typeof(int), typeof(int) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetInt_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.TryGetFloat), new[] { typeof(int), typeof(float) }, new[] { ArgumentType.Normal, ArgumentType.Out })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_TryGetFloat_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedFloat)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController._setBool), new[] { typeof(int), typeof(bool), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setBool_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetBool), new[] { typeof(int), typeof(bool) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController._setTrigger), new[] { typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setTrigger_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetTrigger), new[] { typeof(int)}),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedTrigger)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController._resetTrigger), new[] { typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_resetTrigger_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.ResetTrigger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.ResetWrappedTrigger)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController._setInt), new[] { typeof(int), typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setInt_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetInteger), new[] { typeof(int), typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedInt)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController._setFloat), new[] { typeof(int), typeof(float), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setFloat_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedFloat)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetFloat), new[] { typeof(int), typeof(float) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedFloat)));
}
[HarmonyPatch(typeof(AvatarCharacterController), nameof(AvatarCharacterController._setBool), new[] { typeof(int), typeof(bool), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setBool_AvatarCharacterController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetBool), new[] { typeof(int), typeof(bool) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarCharacterController), nameof(AvatarCharacterController._setTrigger), new[] { typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setTrigger_AvatarCharacterController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetTrigger), new[] { typeof(int)}),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedTrigger)));
}
[HarmonyPatch(typeof(AvatarCharacterController), nameof(AvatarCharacterController._resetTrigger), new[] { typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_resetTrigger_AvatarCharacterController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.ResetTrigger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.ResetWrappedTrigger)));
}
[HarmonyPatch(typeof(AvatarCharacterController), nameof(AvatarCharacterController._setInt), new[] { typeof(int), typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setInt_AvatarCharacterController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetInteger), new[] { typeof(int), typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedInt)));
}
[HarmonyPatch(typeof(AvatarCharacterController), nameof(AvatarCharacterController._setFloat), new[] { typeof(int), typeof(float), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setFloat_AvatarCharacterController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetFloat), new[] { typeof(int), typeof(float) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedFloat)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController._setBool), new[] { typeof(int), typeof(bool), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setBool_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetBool), new[] { typeof(int), typeof(bool) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedBool)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController._setTrigger), new[] { typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setTrigger_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetTrigger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedTrigger)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController._resetTrigger), new[] { typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_resetTrigger_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.ResetTrigger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.ResetWrappedTrigger)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController._setInt), new[] { typeof(int), typeof(int), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setInt_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetInteger), new[] { typeof(int), typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedInt)));
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController._setFloat), new[] { typeof(int), typeof(float), typeof(bool) })]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setFloat_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedFloat)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetFloat), new[] { typeof(int), typeof(float) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedFloat)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.GetParameterName))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_GetParameterName_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.PropertyGetter(typeof(Animator), nameof(Animator.parameters)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedParameters)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.SyncAnimParameters))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_SyncAnimParameters_AvatarController(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var codes = instructions.MethodReplacer(
AccessTools.PropertyGetter(typeof(Animator), nameof(Animator.parameters)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedParameters)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedFloat)))
.ToList();
//var lbd_wrapper = generator.DeclareLocal(typeof(IAnimatorWrapper));
//var fld_anim = AccessTools.Field(typeof(AvatarController), nameof(AvatarController.anim));
//for (int i = 1; i < codes.Count; i++)
//{
// if (codes[i].opcode == OpCodes.Stloc_0)
// {
// codes.InsertRange(i + 1, new[]
// {
// new CodeInstruction(OpCodes.Ldarg_0),
// CodeInstruction.LoadField(typeof(AvatarController), nameof(AvatarController.anim)),
// CodeInstruction.Call(typeof(KFExtensions), nameof(KFExtensions.GetAnimatorWrapper)),
// new CodeInstruction(OpCodes.Stloc_S, lbd_wrapper)
// });
// i += 4;
// }
// else if (codes[i].opcode == OpCodes.Ldloc_3 && codes[i - 1].LoadsField(fld_anim))
// {
// codes.Insert(i - 2, new CodeInstruction(OpCodes.Ldloc_S, lbd_wrapper).WithLabels(codes[i - 2].ExtractLabels()));
// codes.RemoveRange(i - 1, 2);
// i--;
// }
//}
return codes;
}
[HarmonyPatch(typeof(AvatarSDCSController), nameof(AvatarSDCSController.LateUpdate))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_LateUpdate_AvatarSDCSController(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var mtd_getbool = AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(int) });
var mtd_getint = AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) });
var mtd_getfloat = AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(int) });
var mtd_istransition = AccessTools.Method(typeof(Animator),nameof(Animator.IsInTransition), new[] { typeof(int) });
var mtd_updatespine = AccessTools.Method(typeof(LegacyAvatarController), nameof(LegacyAvatarController.updateSpineRotation));
var fld_reload = AccessTools.Field(typeof(AvatarController), nameof(AvatarController.reloadHash));
var mtd_getvanillabool = AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool));
var mtd_getvanillaint = AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt));
var mtd_getvanillafloat = AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedFloat));
var mtd_isvanillatransition = AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.IsVanillaInTransition));
var codes = instructions.Manipulator(ins => ins.opcode == OpCodes.Ldstr, ins =>
{
switch (ins.operand)
{
case "Reload":
ins.opcode = OpCodes.Ldsfld;
ins.operand = fld_reload;
break;
}
}).MethodReplacer(AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(string) }), mtd_getbool)
.MethodReplacer(AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(string) }), mtd_getint)
.MethodReplacer(AccessTools.Method(typeof(Animator), nameof(Animator.GetFloat), new[] { typeof(string) }), mtd_getfloat)
.MethodReplacer(AccessTools.Method(typeof(Animator), nameof(Animator.SetBool), new[] { typeof(string), typeof(bool) }), AccessTools.Method(typeof(Animator), nameof(Animator.SetBool), new[] { typeof(int), typeof(bool) }))
.MethodReplacer(mtd_getbool, mtd_getvanillabool)
.MethodReplacer(mtd_getint, mtd_getvanillaint)
.MethodReplacer(mtd_getfloat, mtd_getvanillafloat)
.MethodReplacer(mtd_istransition, mtd_isvanillatransition)
.ToList();
//var lbd_wrapper = generator.DeclareLocal(typeof(IAnimatorWrapper));
//for (var i = 0; i < codes.Count; i++)
//{
// if (codes[i].Calls(mtd_updatespine))
// {
// codes.InsertRange(i + 1, new[]
// {
// new CodeInstruction(OpCodes.Ldarg_0),
// CodeInstruction.LoadField(typeof(AvatarController), nameof(AvatarController.anim)),
// CodeInstruction.Call(typeof(KFExtensions), nameof(KFExtensions.GetItemAnimatorWrapper)),
// new CodeInstruction(OpCodes.Stloc_S, lbd_wrapper)
// });
// i += 4;
// }
// else if (codes[i].Calls(mtd_getvanillabool) || codes[i].Calls(mtd_getvanillafloat) || codes[i].Calls(mtd_getvanillaint) || codes[i].Calls(mtd_isvanillatransition))
// {
// codes.Insert(i - 3, new CodeInstruction(OpCodes.Ldloc_S, lbd_wrapper).WithLabels(codes[i - 3].ExtractLabels()));
// codes.RemoveRange(i - 2, 2);
// i--;
// }
//}
//foreach (var code in codes)
//{
// Log.Out(code.ToString());
//}
return codes;
}
[HarmonyPatch(typeof(AvatarSDCSController), nameof(AvatarSDCSController.updateLayerStateInfo))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_updateLayerStateInfo_AvatarSDCSController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetCurrentAnimatorStateInfo)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetCurrentVanillaStateInfo)));
}
[HarmonyPatch(typeof(AvatarUMAController), nameof(AvatarUMAController.updateLayerStateInfo))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_updateLayerStateInfo_AvatarUMAController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetCurrentAnimatorStateInfo)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetCurrentVanillaStateInfo)));
}
[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController.updateLayerStateInfo))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_updateLayerStateInfo_LegacyAvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetCurrentAnimatorStateInfo)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetCurrentVanillaStateInfo)));
}
[HarmonyPatch(typeof(AvatarSDCSController), nameof(AvatarSDCSController.setLayerWeights))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setLayerWeights_AvatarSDCSController(IEnumerable<CodeInstruction> instructions)
{
int id = Animator.StringToHash("MinibikeIdle");
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetLayerWeight)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetVanillaLayerWeight)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.IsInTransition)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.IsVanillaInTransition)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetBool), new[] { typeof(string) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedBool)))
.Manipulator(ins => ins.opcode == OpCodes.Ldstr, ins => { ins.opcode = OpCodes.Ldc_I4; ins.operand = id; });
}
[HarmonyPatch(typeof(LegacyAvatarController), nameof(LegacyAvatarController.setLayerWeights))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setLayerWeights_LegacyAvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetLayerWeight)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetVanillaLayerWeight)));
}
[HarmonyPatch(typeof(AvatarUMAController), nameof(AvatarUMAController.setLayerWeights))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_setLayerWeights_AvatarUMAController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetLayerWeight)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetVanillaLayerWeight)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.IsInTransition)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.IsVanillaInTransition)));
}
[HarmonyPatch(typeof(UMACharacterBodyAnimator), nameof(UMACharacterBodyAnimator.assignLayerWeights))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_assignLayerWeights_UMACharacterBodyAnimator(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetLayerWeight)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetVanillaLayerWeight)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.GetInteger), new[] { typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.GetWrappedInt)))
.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.IsInTransition)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.IsVanillaInTransition)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.Update))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Update_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetLayerWeight)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetVanillaLayerWeight)));
}
[HarmonyPatch(typeof(AvatarController), nameof(AvatarController.InitHitDuration))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_InitHitDuration_AvatarController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetLayerWeight)),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetVanillaLayerWeight)));
}
private static int drunkHash = Animator.StringToHash("drunk");
[HarmonyPatch(typeof(FirstPersonAnimator), nameof(FirstPersonAnimator.SetDrunk))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_SetDrunk_FirstPersonAnimator(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetFloat), new[] { typeof(string), typeof(float) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedFloat)))
.Manipulator(ins => ins.LoadsConstant("drunk"),
ins =>
{
ins.opcode = OpCodes.Ldsfld;
ins.operand = AccessTools.Field(typeof(AnimationRiggingPatches), nameof(AnimationRiggingPatches.drunkHash));
});
}
[HarmonyPatch(typeof(AvatarMultiBodyController), nameof(AvatarMultiBodyController.SetVehicleAnimation))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_SetVehicleAnimation_AvatarMultiBodyController(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(
AccessTools.Method(typeof(Animator), nameof(Animator.SetInteger), new[] { typeof(string), typeof(int) }),
AccessTools.Method(typeof(KFExtensions), nameof(KFExtensions.SetWrappedInt)));
}
//BodyAnimator.LateUpdate
//UMACharacterBodyAnimator.LateUpdate
//BodyAnimator.cacheLayerStateInfo
//UMACharacterBodyAnimator.cacheLayerStateInfo
//not used
}