Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// -----------------------------------------------------------------------
// <copyright file="MicroHIDOpeningDoorEventArgs.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.Doors;
using Exiled.API.Features.Items;
using Exiled.Events.EventArgs.Interfaces;

using Interactables.Interobjects.DoorUtils;
using InventorySystem.Items.MicroHID;

/// <summary>
/// Contains all information before the micro opens a doors.
/// </summary>
public class MicroHIDOpeningDoorEventArgs : IDeniableEvent, IDoorEvent, IItemEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="MicroHIDOpeningDoorEventArgs"/> class.
/// </summary>
/// <param name="item"><inheritdoc cref="Item"/></param>
/// <param name="isAllowed">Whether the Micro HID can open the door or not.</param>
/// <param name="door"><inheritdoc cref="Door"/></param>
public MicroHIDOpeningDoorEventArgs(MicroHIDItem item, DoorVariant door, bool isAllowed = true)
{
MicroHID = Item.Get<MicroHid>(item);
Player = MicroHID.Owner;
IsAllowed = isAllowed;
Door = Door.Get(door);
}

/// <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 the <see cref="API.Features.Doors.Door"/> instance.
/// </summary>
public Door Door { get; }

/// <summary>
/// Gets or sets a value indicating whether the player can explode the micro HID.
/// </summary>
public bool IsAllowed { get; set; }
}
}
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 micro HID opens a door.
/// </summary>
public static Event<MicroHIDOpeningDoorEventArgs> MicroHIDOpeningDoor { get; set; } = new();

/// <summary>
/// Invoked before player interacts with coffee cup.
/// </summary>
Expand Down Expand Up @@ -1260,6 +1265,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 the micro HID opens a door.
/// </summary>
/// <param name="ev">The <see cref="ChangingDisruptorModeEventArgs"/> instance.</param>
public static void OnMicroHIDOpeningDoor(MicroHIDOpeningDoorEventArgs ev) => MicroHIDOpeningDoor.InvokeSafely(ev);

/// <summary>
/// Called before player interacts with coffee cup.
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions EXILED/Exiled.Events/Patches/Events/Player/MicroHIDOpeningDoor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// -----------------------------------------------------------------------
// <copyright file="MicroHIDOpeningDoor.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 Attributes;
using Exiled.API.Features.Pools;
using Exiled.Events.EventArgs.Player;

using HarmonyLib;
using InventorySystem.Items.MicroHID.Modules;

using static HarmonyLib.AccessTools;

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

int offset = 0;
int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Brtrue_S) + offset;

LocalBuilder result = generator.DeclareLocal(typeof(bool));

newInstructions.InsertRange(
index,
new CodeInstruction[]
{
// bool result = onStack
new(OpCodes.Stloc_S, result.LocalIndex),

// this.MicroHid
new(OpCodes.Ldarg_0),
new(OpCodes.Call, PropertyGetter(typeof(ChargeFireModeModule), nameof(ChargeFireModeModule.MicroHid))),

// breakableDoor
new(OpCodes.Ldloc_0),

// result
new(OpCodes.Ldloc_S, result.LocalIndex),

// MicroHIDOpeningDoorEventArgs ev = new(MicroHIDItem, DoorVariant, ValueOnStack);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(MicroHIDOpeningDoorEventArgs))[0]),
new(OpCodes.Dup),

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

// ev.IsAllowed (leave on stack)
new(OpCodes.Callvirt, PropertyGetter(typeof(MicroHIDOpeningDoorEventArgs), nameof(MicroHIDOpeningDoorEventArgs.IsAllowed))),
});

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

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}