Skip to content
Merged
22 changes: 22 additions & 0 deletions EXILED/Exiled.Events/EventArgs/Interfaces/IMicroHIDEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// -----------------------------------------------------------------------
// <copyright file="IMicroHIDEvent.cs" company="ExMod Team">
// Copyright (c) ExMod Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Interfaces
{
using API.Features.Items;

/// <summary>
/// Event args used for all <see cref="API.Features.Items.MicroHid" /> related events.
/// </summary>
public interface IMicroHIDEvent : IItemEvent
{
/// <summary>
/// Gets the <see cref="API.Features.Items.MicroHid" /> triggering the event.
/// </summary>
public MicroHid MicroHID { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Exiled.Events.EventArgs.Player
/// <summary>
/// Contains all information before MicroHID state is changed.
/// </summary>
public class ChangingMicroHIDStateEventArgs : IDeniableEvent, IItemEvent
public class ChangingMicroHIDStateEventArgs : IDeniableEvent, IMicroHIDEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="ChangingMicroHIDStateEventArgs" /> class.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// -----------------------------------------------------------------------
// <copyright file="ExplodingMicroHIDEventArgs.cs" company="ExMod Team">
// Copyright (c) ExMod Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Player
{
using Exiled.API.Features.Items;
using Exiled.Events.EventArgs.Interfaces;
using InventorySystem.Items.MicroHID;

/// <summary>
/// Contains all information before the micro hid explode.
/// </summary>
public class ExplodingMicroHIDEventArgs : IDeniableEvent, IMicroHIDEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="ExplodingMicroHIDEventArgs" /> class.
/// </summary>
/// <param name="item"><inheritdoc cref="Item"/></param>
/// <param name="isAllowed">Whether the Micro HID can explode the player or not.</param>
public ExplodingMicroHIDEventArgs(MicroHIDItem item, bool isAllowed = true)
{
MicroHID = Item.Get<MicroHid>(item);
Player = MicroHID.Owner;
IsAllowed = isAllowed;
}

/// <summary>
/// Gets the item.
/// </summary>
public Item Item => MicroHID;

/// <summary>
/// Gets the player in owner of the item.
/// </summary>
public Exiled.API.Features.Player Player { get; }

/// <summary>
/// Gets MicroHid item.
/// </summary>
public MicroHid MicroHID { get; }

/// <summary>
/// Gets or sets a value indicating whether the player can explode the micro HID.
/// </summary>
public bool IsAllowed { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Exiled.Events.EventArgs.Player
/// <summary>
/// Contains all information before the micro opens a doors.
/// </summary>
public class MicroHIDOpeningDoorEventArgs : IDeniableEvent, IDoorEvent, IItemEvent
public class MicroHIDOpeningDoorEventArgs : IDeniableEvent, IDoorEvent, IMicroHIDEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="MicroHIDOpeningDoorEventArgs"/> class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Exiled.Events.EventArgs.Player
/// <summary>
/// Contains all information before MicroHID energy is changed.
/// </summary>
public class UsingMicroHIDEnergyEventArgs : IDeniableEvent, IItemEvent
public class UsingMicroHIDEnergyEventArgs : IDeniableEvent, IMicroHIDEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="UsingMicroHIDEnergyEventArgs" /> class.
Expand Down
11 changes: 11 additions & 0 deletions EXILED/Exiled.Events/Handlers/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,11 @@ public class Player
/// </summary>
public static Event<ChangingDisruptorModeEventArgs> ChangingDisruptorMode { get; set; } = new();

/// <summary>
/// Invoked before the player explode with the micro HID.
/// </summary>
public static Event<ExplodingMicroHIDEventArgs> ExplodingMicroHID { get; set; } = new();

/// <summary>
/// Invoked before the micro HID opens a door.
/// </summary>
Expand Down Expand Up @@ -1265,6 +1270,12 @@ public static void OnItemRemoved(ReferenceHub referenceHub, InventorySystem.Item
/// <param name="ev">The <see cref="ChangingDisruptorModeEventArgs"/> instance.</param>
public static void OnChangingDisruptorMode(ChangingDisruptorModeEventArgs ev) => ChangingDisruptorMode.InvokeSafely(ev);

/// <summary>
/// Called before disruptor's mode is changed.
/// </summary>
/// <param name="ev">The <see cref="ExplodingMicroHIDEventArgs"/> instance.</param>
public static void OnExplodingMicroHID(ExplodingMicroHIDEventArgs ev) => ExplodingMicroHID.InvokeSafely(ev);

/// <summary>
/// Called before the micro HID opens a door.
/// </summary>
Expand Down
70 changes: 70 additions & 0 deletions EXILED/Exiled.Events/Patches/Events/Player/ExplodingMicroHID.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// -----------------------------------------------------------------------
// <copyright file="ExplodingMicroHID.cs" company="ExMod Team">
// Copyright (c) ExMod Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Patches.Events.Player
{
using System.Collections.Generic;
using System.Reflection.Emit;

using Exiled.API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;
using HarmonyLib;
using InventorySystem.Items.MicroHID.Modules;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="ChargeFireModeModule.ServerExplode"/>.
/// Adds the <see cref="Handlers.Player.ExplodingMicroHID" /> event.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.ExplodingMicroHID))]
[HarmonyPatch(typeof(ChargeFireModeModule), nameof(ChargeFireModeModule.ServerExplode))]
internal static class ExplodingMicroHID
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

int offset = -2;
int index = newInstructions.FindIndex(x => x.StoresField(Field(typeof(ChargeFireModeModule), nameof(ChargeFireModeModule._alreadyExploded)))) + offset;

Label retLabel = generator.DefineLabel();

newInstructions[newInstructions.Count - 1].labels.Add(retLabel);

newInstructions.InsertRange(
index,
new[]
{
// this.MicroHid;
new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Call, PropertyGetter(typeof(ChargeFireModeModule), nameof(ChargeFireModeModule.MicroHid))),

// true
new(OpCodes.Ldc_I4_1),

// ExplodingMicroHIDEventArgs ev = new(MicroHIDItem, true);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ExplodingMicroHIDEventArgs))[0]),
new(OpCodes.Dup),

// Handlers.Player.OnExplodingMicroHID(ev);
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnExplodingMicroHID))),

// if (!ev.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(ExplodingMicroHIDEventArgs), nameof(ExplodingMicroHIDEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, retLabel),
});

for (int z = 0; z < newInstructions.Count; z++)
yield return newInstructions[z];

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@ namespace Exiled.Events.Patches.Events.Player
using System.Collections.Generic;
using System.Reflection.Emit;

using API.Features;
using API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;
using HarmonyLib;
using InventorySystem.Items.MicroHID;
using InventorySystem.Items.MicroHID.Modules;
using UnityEngine;

using static HarmonyLib.AccessTools;

Expand Down