Files
7d2dXG/XG-Rebirth/Mods/0A-KFCommonUtilityLib/Harmony/RecoilPatch.cs
2025-05-30 00:19:27 +09:30

156 lines
6.1 KiB
C#

using HarmonyLib;
using KFCommonUtilityLib.Scripts.StaticManagers;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;
using CameraShake;
using System;
[HarmonyPatch]
class RecoilPatch
{
[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.Awake))]
[HarmonyPostfix]
private static void Postfix_Awake_EntityPlayerLocal(EntityPlayerLocal __instance)
{
RecoilManager.InitPlayer(__instance);
}
[HarmonyPatch(typeof(vp_FPCamera), nameof(vp_FPCamera.LateUpdate))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_LateUpdate_vp_FPCamera(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
var mtd_update = AccessTools.Method(typeof(vp_FPCamera), nameof(vp_FPCamera.Update3rdPerson));
var prop_trans = AccessTools.PropertyGetter(typeof(vp_Component), nameof(vp_Component.transform));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].Calls(mtd_update))
{
codes.InsertRange(i - 1, new[]
{
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Call, prop_trans),
CodeInstruction.Call(typeof(KFExtensions), nameof(KFExtensions.AddMissingComponent), new Type[]{ typeof(Transform) }, new Type[]{ typeof(CameraShaker) }),
CodeInstruction.Call(typeof(CameraShaker), nameof(CameraShaker.UpdateShake))
});
break;
}
}
return codes;
}
[HarmonyPatch(typeof(GameManager), nameof(GameManager.SaveAndCleanupWorld))]
[HarmonyPostfix]
private static void Postfix_SaveAndCleanupWorld_GameManager()
{
RecoilManager.Cleanup();
}
[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.OnFired))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_OnFired_EntityPlayerLocal(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
FieldInfo fld_isfpv = AccessTools.Field(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.bFirstPersonView));
ConstructorInfo mtd_ctor = AccessTools.Constructor(typeof(Vector2), new[] { typeof(float), typeof(float) });
for (int i = 0; i < codes.Count - 1; i++)
{
if (codes[i].Is(OpCodes.Call, mtd_ctor) && codes[i + 1].opcode == OpCodes.Ldloc_0)
{
for (int j = i + 1; j < codes.Count - 1; j++)
{
if (codes[j].opcode == OpCodes.Pop && codes[j + 1].opcode == OpCodes.Ldarg_0)
{
codes.RemoveRange(i + 1, j - i);
break;
}
}
codes.InsertRange(i + 1, new[]
{
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldloca_S, 0),
new CodeInstruction(OpCodes.Ldloca_S, 1),
CodeInstruction.Call(typeof(RecoilPatch), nameof(RecoilPatch.ModifyRecoil))
});
i += 4;
}
else if (codes[i].LoadsField(fld_isfpv))
{
codes.RemoveRange(i + 2, codes.Count - i - 3);
codes.InsertRange(i + 2, new[]
{
new CodeInstruction(OpCodes.Ldloc_0),
new CodeInstruction(OpCodes.Ldloc_1),
CodeInstruction.Call(typeof(RecoilManager), nameof(RecoilManager.AddRecoil))
});
break;
}
}
return codes;
}
private static void ModifyRecoil(EntityPlayerLocal player, ref Vector2 kickHor, ref Vector2 kickVer)
{
float multiplierHor = Mathf.Max(1 - EffectManager.GetValue(CustomEnums.KickDegreeHorizontalModifier, player.inventory.holdingItemItemValue, 0f, player), 0);
float multiplierVer = Mathf.Max(1 - EffectManager.GetValue(CustomEnums.KickDegreeVerticalModifier, player.inventory.holdingItemItemValue, 0f, player), 0);
kickHor *= multiplierHor;
kickVer *= multiplierVer;
}
[HarmonyPatch(typeof(PlayerMoveController), nameof(PlayerMoveController.Update))]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler_Update_PlayerMoveController(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();
FieldInfo fld_rotation = AccessTools.Field(typeof(MovementInput), nameof(MovementInput.rotation));
FieldInfo fld_rx = AccessTools.Field(typeof(Vector3), nameof(Vector3.x));
FieldInfo fld_ry = AccessTools.Field(typeof(Vector3), nameof(Vector3.y));
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].LoadsField(fld_rotation, true))
{
if (codes[i + 1].LoadsField(fld_rx, true))
{
for (; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Stind_R4)
{
codes.Insert(i, CodeInstruction.Call(typeof(RecoilManager), nameof(RecoilManager.CompensateX)));
break;
}
}
}
else if (codes[i + 1].LoadsField(fld_ry, true))
{
for (; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Stind_R4)
{
codes.Insert(i, CodeInstruction.Call(typeof(RecoilManager), nameof(RecoilManager.CompensateY)));
break;
}
}
}
}
}
return codes;
}
[HarmonyPatch(typeof(EntityPlayerLocal), nameof(EntityPlayerLocal.MoveByInput))]
[HarmonyPrefix]
private static bool Prefix_MoveByInput_EntityPlayerLocal()
{
RecoilManager.ApplyRecoil();
return true;
}
}