diff --git a/EXILED/Exiled.Events/EventArgs/Player/UsedItemEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/UsedItemEventArgs.cs index e25e9fd72..c6aeed7ff 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/UsedItemEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/UsedItemEventArgs.cs @@ -28,10 +28,14 @@ public class UsedItemEventArgs : IPlayerEvent, IUsableEvent /// /// /// - public UsedItemEventArgs(ReferenceHub player, UsableItem item) + /// + /// + /// + public UsedItemEventArgs(ReferenceHub player, UsableItem item, bool causedByHolstering) { Player = Player.Get(player); - Usable = Item.Get(item) is Usable usable ? usable : null; + Usable = Item.Get(item) as Usable; + CausedByHolstering = causedByHolstering; } /// @@ -46,5 +50,11 @@ public UsedItemEventArgs(ReferenceHub player, UsableItem item) /// Gets the player who used the item. /// public Player Player { get; } + + /// + /// Gets a value indicating whether this event was triggered by a player switching items (true) or by waiting after using the item (false). + /// + /// Use this value if you wish to keep the bug where you could switch items quickly to skip this event. + public bool CausedByHolstering { get; } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs index 3da3e94ef..70798015e 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs @@ -42,7 +42,7 @@ namespace Exiled.Events.Handlers.Internal internal static class Round { /// - public static void OnServerOnUsingCompleted(ReferenceHub hub, UsableItem usable) => Handlers.Player.OnUsedItem(new (hub, usable)); + public static void OnServerOnUsingCompleted(ReferenceHub hub, UsableItem usable) => Handlers.Player.OnUsedItem(new (hub, usable, false)); /// public static void OnWaitingForPlayers() diff --git a/EXILED/Exiled.Events/Patches/Events/Player/UsedItemByHolstering.cs b/EXILED/Exiled.Events/Patches/Events/Player/UsedItemByHolstering.cs new file mode 100644 index 000000000..9a499ada9 --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Player/UsedItemByHolstering.cs @@ -0,0 +1,58 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Player +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features; + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Player; + using HarmonyLib; + using InventorySystem.Items.Usables; + + using static HarmonyLib.AccessTools; + + /// + /// Patches . + /// Adds an alternative trigger of the event. + /// + [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.UsedItem))] + [HarmonyPatch(typeof(Consumable), nameof(Consumable.OnHolstered))] + public class UsedItemByHolstering + { + private static IEnumerable Transpiler(IEnumerable instructions) + { + List newInstructions = ListPool.Pool.Get(instructions); + + // after ServerRemoveSelf, which lines up with before the ret + newInstructions.InsertRange(newInstructions.Count - 2, new CodeInstruction[] + { + // this.Owner + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(Consumable), nameof(Consumable.Owner))), + + // this (Consumable inherits UsableItem) + new(OpCodes.Ldarg_0), + + // true + new(OpCodes.Ldc_I4_1), + + // OnUsedItem(new UsedItemEventArgs(ReferenceHub, UsableItem, bool)); + new(OpCodes.Newobj, Constructor(typeof(UsedItemEventArgs), new[] { typeof(ReferenceHub), typeof(UsableItem), typeof(bool) })), + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnUsedItem))), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file