using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using HarmonyLib; using NitroxClient.GameLogic; using NitroxModel.Helper; using UnityEngine; namespace NitroxPatcher.Patches.Dynamic; /// /// Replaces local use of by and prevents remote bullets from detecting collisions /// public sealed partial class Bullet_Update_Patch : NitroxPatch, IDynamicPatch { internal static readonly MethodInfo TARGET_METHOD = Reflect.Method((Bullet t) => t.Update()); /* * RaycastHit raycastHit; * REPLACE: * if (Physics.SphereCast(this.tr.position, this.shellRadius, this.tr.forward, out raycastHit, num, this.layerMask.value)) * { * num = raycastHit.distance; * BY: * if (!Bullet_Update_Patch.IsRemoteObject(this) && Physics.SphereCast(this.tr.position, this.shellRadius, this.tr.forward, out raycastHit, num, this.layerMask.value)) * { * num = raycastHit.distance; */ public static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { Label label = generator.DefineLabel(); // Replace the two occurences of Time.deltaTime return new CodeMatcher(instructions).ReplaceDeltaTime() .ReplaceDeltaTime() .MatchStartForward([ new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Call, Reflect.Property((Bullet t) => t.tr).GetGetMethod()), new CodeMatch(OpCodes.Callvirt, Reflect.Property((Transform t) => t.position).GetGetMethod()), new CodeMatch(OpCodes.Ldarg_0), ]) // Skip the Ldarg_0 because it is the previous ifs' jump target .Advance(1) // Insert if (!Bullet_Update_Patch.IsRemoteObject(this)) before the condition .InsertAndAdvance([ new CodeInstruction(OpCodes.Call, Reflect.Method(() => IsRemoteObject(default))), new CodeInstruction(OpCodes.Brtrue_S, label), new CodeInstruction(OpCodes.Ldarg_0), ]) // Find the destination of the position to go to .MatchStartForward([ new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Call, Reflect.Property((Bullet t) => t.tr).GetGetMethod()), new CodeMatch(OpCodes.Dup), new CodeMatch(OpCodes.Callvirt, Reflect.Property((Transform t) => t.position).GetGetMethod()) ]) .AddLabels([label]) .InstructionEnumeration(); } public static bool IsRemoteObject(Bullet bullet) { return bullet.GetComponent(); } }