diff --git a/Exiled.Events/EventArgs/Map/Scp244SpawningEventArgs.cs b/Exiled.Events/EventArgs/Map/Scp244SpawningEventArgs.cs index e4f93f9b04..61b6d288b6 100644 --- a/Exiled.Events/EventArgs/Map/Scp244SpawningEventArgs.cs +++ b/Exiled.Events/EventArgs/Map/Scp244SpawningEventArgs.cs @@ -12,27 +12,23 @@ namespace Exiled.Events.EventArgs.Map using Interfaces; /// - /// Contains all information up to spawning Scp244. + /// Contains all information up to spawning Scp244. /// - public class Scp244SpawningEventArgs : IRoomEvent, IPickupEvent, IDeniableEvent + public class Scp244SpawningEventArgs : IRoomEvent, IDeniableEvent { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// - /// + /// /// /// - /// + /// /// - /// - /// - /// - public Scp244SpawningEventArgs(Room room, Scp244Pickup scp244Pickup, bool isAllowed = true) + public Scp244SpawningEventArgs(Room room, Pickup scp244Pickup) { Room = room; - Pickup = scp244Pickup; - IsAllowed = isAllowed; + Pickup = scp244Pickup.As(); } /// @@ -43,11 +39,11 @@ public Scp244SpawningEventArgs(Room room, Scp244Pickup scp244Pickup, bool isAllo /// /// Gets a value indicating the pickup being spawning. /// - public Pickup Pickup { get; } + public Scp244Pickup Pickup { get; } /// /// Gets or sets a value indicating whether or not the item can be spawning. /// - public bool IsAllowed { get; set; } + public bool IsAllowed { get; set; } = true; } } \ No newline at end of file diff --git a/Exiled.Events/Patches/Events/Map/Scp244Spawning.cs b/Exiled.Events/Patches/Events/Map/Scp244Spawning.cs index d931c863e0..0c9bcd2665 100644 --- a/Exiled.Events/Patches/Events/Map/Scp244Spawning.cs +++ b/Exiled.Events/Patches/Events/Map/Scp244Spawning.cs @@ -7,57 +7,84 @@ namespace Exiled.Events.Patches.Events.Map { - using Exiled.API.Features; + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Core.Generic.Pools; using Exiled.API.Features.Pickups; using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Map; + using MapGeneration; + using UnityEngine; + #pragma warning disable SA1313 // Parameter names should begin with lower-case letter using HarmonyLib; - using InventorySystem.Items; using InventorySystem.Items.Pickups; using InventorySystem.Items.Usables.Scp244; - using MapGeneration; using Mirror; - using UnityEngine; + + using static HarmonyLib.AccessTools; /// - /// Patches . - /// Adds the event. + /// Patches . + /// Adds the event. /// [EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.Scp244Spawning))] [HarmonyPatch(typeof(Scp244Spawner), nameof(Scp244Spawner.SpawnScp244))] internal static class Scp244Spawning { - private static bool Prefix(ItemBase ib) + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { - if (Scp244Spawner.CompatibleRooms.Count == 0 && Random.value > 0.35f) - return false; + List newInstructions = ListPool.Pool.Get(instructions); + + Label continueLabel = generator.DefineLabel(); + + LocalBuilder pickup = generator.DeclareLocal(typeof(ItemPickupBase)); + + int index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Dup); - int index = Random.Range(0, Scp244Spawner.CompatibleRooms.Count); - Vector3 position = Scp244Spawner.CompatibleRooms[index].transform.TransformPoint(Scp244Spawner.NameToPos[Scp244Spawner.CompatibleRooms[index].Name]); - ItemPickupBase itemPickupBase = Object.Instantiate(ib.PickupDropModel, position, Quaternion.identity); - itemPickupBase.NetworkInfo = new PickupSyncInfo + newInstructions.RemoveRange(index, 1); + + int offset = 1; + index = newInstructions.FindIndex(i => i.opcode == OpCodes.Dup) + offset; + newInstructions.InsertRange(index, new CodeInstruction[] { - ItemId = ib.ItemTypeId, - WeightKg = ib.Weight, - Serial = ItemSerialGenerator.GenerateNext(), - }; - Scp244DeployablePickup scp244DeployablePickup = itemPickupBase as Scp244DeployablePickup; - if (scp244DeployablePickup != null) - scp244DeployablePickup.State = Scp244State.Active; - - Scp244SpawningEventArgs ev = new(Room.Get(Scp244Spawner.CompatibleRooms[index]), Pickup.Get(itemPickupBase).As()); - Handlers.Map.OnScp244Spawning(ev); - - if (!ev.IsAllowed) + new(OpCodes.Dup), + new(OpCodes.Stloc_S, pickup.LocalIndex), + }); + + offset = -2; + index = newInstructions.FindIndex(i => i.Calls(Method(typeof(NetworkServer), nameof(NetworkServer.Spawn), new[] { typeof(GameObject), typeof(NetworkConnection) }))) + offset; + + newInstructions.InsertRange(index, new[] { - NetworkServer.Destroy(itemPickupBase.gameObject); - return false; - } + new CodeInstruction(OpCodes.Ldsfld, Field(typeof(Scp244Spawner), nameof(Scp244Spawner.CompatibleRooms))).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Ldloc_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(List), "Item")), + + new(OpCodes.Ldloc_S, pickup.LocalIndex), + new(OpCodes.Call, Method(typeof(Pickup), nameof(Pickup.Get), new[] { typeof(ItemPickupBase) })), + + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(Scp244SpawningEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Call, Method(typeof(Handlers.Map), nameof(Handlers.Map.OnScp244Spawning))), + + new(OpCodes.Call, PropertyGetter(typeof(Scp244SpawningEventArgs), nameof(Scp244SpawningEventArgs.IsAllowed))), + new(OpCodes.Brtrue_S, continueLabel), + + new(OpCodes.Ldloc_S, pickup.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(ItemPickupBase), nameof(ItemPickupBase.gameObject))), + new(OpCodes.Call, Method(typeof(NetworkServer), nameof(NetworkServer.Destroy))), + new(OpCodes.Ret), + + new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel), + new(OpCodes.Ldloc_S, pickup.LocalIndex), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; - NetworkServer.Spawn(itemPickupBase.gameObject); - Scp244Spawner.CompatibleRooms.RemoveAt(index); - return false; + ListPool.Pool.Return(newInstructions); } } } \ No newline at end of file