|
| 1 | +using System.Collections.Generic; |
| 2 | +using System.Reflection; |
| 3 | +using System.Reflection.Emit; |
| 4 | +using HarmonyLib; |
| 5 | +using NitroxClient.Communication.Abstract; |
| 6 | +using NitroxModel.DataStructures; |
| 7 | +using NitroxModel.Helper; |
| 8 | +using NitroxModel.Packets; |
| 9 | +using UnityEngine; |
| 10 | + |
| 11 | +namespace NitroxPatcher.Patches.Dynamic; |
| 12 | + |
| 13 | +/// <summary> |
| 14 | +/// Sync destruction of giver object when required. |
| 15 | +/// </summary> |
| 16 | +public sealed partial class PickPrefab_AddToContainerAsync_Patch : NitroxPatch, IDynamicPatch |
| 17 | +{ |
| 18 | + internal static readonly MethodInfo TARGET_METHOD = AccessTools.EnumeratorMoveNext(Reflect.Method((PickPrefab t) => t.AddToContainerAsync(default, default))); |
| 19 | + |
| 20 | + /* |
| 21 | + * 1st injection: |
| 22 | + * if (!component) |
| 23 | + * { |
| 24 | + * UnityEngine.Object.Destroy(gameObject); |
| 25 | + * BroadcastDeletion(this); <------- [INSERTED LINE] |
| 26 | + * |
| 27 | + * 2nd injection: |
| 28 | + * else if (!container.HasRoomFor(component)) |
| 29 | + * { |
| 30 | + * UnityEngine.Object.Destroy(gameObject); |
| 31 | + * BroadcastDeletion(this); <------- [INSERTED LINE] |
| 32 | + */ |
| 33 | + public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) |
| 34 | + { |
| 35 | + // The 2 injections are similar (looking for a destroy instruction and adding our callback after it) |
| 36 | + return new CodeMatcher(instructions).MatchEndForward(new CodeMatch(OpCodes.Call, Reflect.Method(() => Object.Destroy(default)))) |
| 37 | + .Advance(1) |
| 38 | + .InsertAndAdvance([ |
| 39 | + new CodeInstruction(OpCodes.Ldarg_0), |
| 40 | + new CodeInstruction(OpCodes.Call, Reflect.Method(() => BroadcastDeletion(default))) |
| 41 | + ]) |
| 42 | + .MatchEndForward(new CodeMatch(OpCodes.Call, Reflect.Method(() => Object.Destroy(default)))) |
| 43 | + .Advance(1) |
| 44 | + .InsertAndAdvance([ |
| 45 | + new CodeInstruction(OpCodes.Ldarg_0), |
| 46 | + new CodeInstruction(OpCodes.Call, Reflect.Method(() => BroadcastDeletion(default))) |
| 47 | + ]) |
| 48 | + .InstructionEnumeration(); |
| 49 | + } |
| 50 | + |
| 51 | + public static void BroadcastDeletion(PickPrefab pickPrefab) |
| 52 | + { |
| 53 | + if (pickPrefab.TryGetNitroxId(out NitroxId objectId) || |
| 54 | + (pickPrefab.TryGetComponent(out GrownPlant grownPlant) && grownPlant.seed && grownPlant.seed.TryGetNitroxId(out objectId))) |
| 55 | + { |
| 56 | + Resolve<IPacketSender>().Send(new EntityDestroyed(objectId)); |
| 57 | + } |
| 58 | + } |
| 59 | +} |
0 commit comments