|
| 1 | +using FrooxEngine; |
| 2 | +using HarmonyLib; |
| 3 | +using System; |
| 4 | +using System.Collections.Generic; |
| 5 | +using System.Diagnostics; |
| 6 | +using System.Linq; |
| 7 | +using System.Reflection; |
| 8 | +using System.Reflection.Emit; |
| 9 | +using System.Text; |
| 10 | + |
| 11 | +namespace CommunityBugFixCollection |
| 12 | +{ |
| 13 | + [HarmonyPatchCategory(nameof(DontRaycastDeveloper))] |
| 14 | + [HarmonyPatch(typeof(FrooxEngine.RaycastDriver), nameof(FrooxEngine.RaycastDriver.OnCommonUpdate))] |
| 15 | + internal sealed class DontRaycastDeveloper : ResoniteBugFixMonkey<DontRaycastDeveloper> |
| 16 | + { |
| 17 | + |
| 18 | + public override IEnumerable<string> Authors { get; } = [.. Contributors.Onan]; |
| 19 | + |
| 20 | + public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) |
| 21 | + { |
| 22 | + //Debugger.Launch(); |
| 23 | + List<CodeInstruction> instructionList = [.. instructions]; |
| 24 | + |
| 25 | + |
| 26 | + int index = 0; |
| 27 | + int start = 0; |
| 28 | + int stop = 0; |
| 29 | + CodeInstruction Filter = new CodeInstruction(OpCodes.Nop); |
| 30 | + foreach (CodeInstruction inst in instructionList) |
| 31 | + { |
| 32 | + |
| 33 | + if (inst.operand?.ToString()?.Contains("IgnoreHierarchy") == true) |
| 34 | + { |
| 35 | + if(start == 0) |
| 36 | + { |
| 37 | + start = index; |
| 38 | + } |
| 39 | + |
| 40 | + } |
| 41 | + if (inst.operand?.ToString()?.ToLower()?.Contains("icollider") == true && inst.operand?.ToString()?.ToLower()?.Contains("bool") == true && inst.operand?.ToString()?.ToLower()?.Contains("invoke") == true) |
| 42 | + { |
| 43 | + if (stop == 0) |
| 44 | + { |
| 45 | + stop = index; |
| 46 | + } |
| 47 | + } |
| 48 | + if (inst.opcode == OpCodes.Ldfld && inst.operand?.ToString()?.Contains("Filter") == true) |
| 49 | + { |
| 50 | + Filter = inst; |
| 51 | + } |
| 52 | + index++; |
| 53 | + } |
| 54 | + |
| 55 | + |
| 56 | + //note to self, loading "this" before trying to load a "this" variable on the stack is important - @989onan |
| 57 | + List<CodeInstruction> newinstructions = |
| 58 | + [ |
| 59 | + new CodeInstruction(OpCodes.Ldarg_0), |
| 60 | + instructionList[start], |
| 61 | + new CodeInstruction(OpCodes.Ldloc_S,8), |
| 62 | + new CodeInstruction(OpCodes.Ldarg_0), |
| 63 | + Filter, |
| 64 | + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(DontRaycastDeveloper), "DontRaycastDeveloperFilter")), |
| 65 | + ]; |
| 66 | + instructionList.RemoveRange(start-1, (stop+2) - start); |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | + instructionList.InsertRange(start - 1/*this is needed since start lands on "ignore hiearchy" which is at the beginning*/, newinstructions); |
| 71 | + |
| 72 | + |
| 73 | + return instructionList; |
| 74 | + |
| 75 | + } |
| 76 | + |
| 77 | + |
| 78 | + //recreates the if statement, allowing for full control over this check on raycasts and doing whatever we want. |
| 79 | + public static bool DontRaycastDeveloperFilter(SyncRef<Slot> IgnoreHierarchy, RaycastHit hit, SyncDelegate<Func<ICollider, bool>> Filter) { |
| 80 | + if (!Enabled) |
| 81 | + { |
| 82 | + return (IgnoreHierarchy.Target == null || !hit.Collider.Slot.IsChildOf(IgnoreHierarchy.Target, true)) && (Filter.Target == null || Filter.Target(hit.Collider)); //this is where we use the default behavior. |
| 83 | + } |
| 84 | + return (IgnoreHierarchy.Target == null || !hit.Collider.Slot.IsChildOf(IgnoreHierarchy.Target, true)) && (Filter.Target == null || Filter.Target(hit.Collider)) && hit.Collider.Slot.FindParent(o=>o.Name == "Gizmo")?.GetComponent<SlotGizmo>() == null; //this is where we can specify "STOP RAYCASTING DEVELOPER!!!" |
| 85 | + } |
| 86 | + } |
| 87 | +} |
0 commit comments