Skip to content

Commit

Permalink
[Exiled::Events] Adding Map::ElevatorMoving and `Map::ElevatorArr…
Browse files Browse the repository at this point in the history
…ived` events (#2498)

* new elevator events

* some fixes

* final fix

---------

Co-authored-by: Yamato <[email protected]>
  • Loading branch information
VALERA771 and louis1706 authored Apr 6, 2024
1 parent a767096 commit d551c37
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 0 deletions.
41 changes: 41 additions & 0 deletions Exiled.Events/EventArgs/Map/ElevatorArrivedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// -----------------------------------------------------------------------
// <copyright file="ElevatorArrivedEventArgs.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Map
{
using System.Collections.Generic;
using System.Linq;

using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;

/// <summary>
/// Contains all information after an elevator has arrived.
/// </summary>
public class ElevatorArrivedEventArgs : IExiledEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="ElevatorArrivedEventArgs"/> class.
/// </summary>
/// <param name="lift"><inheritdoc cref="Lift"/></param>
public ElevatorArrivedEventArgs(Lift lift)
{
Lift = lift;
Players = Player.Get(x => x.Lift == Lift).ToList();
}

/// <summary>
/// Gets an elevator.
/// </summary>
public Lift Lift { get; }

/// <summary>
/// Gets the players in the elevator.
/// </summary>
public IReadOnlyCollection<Player> Players { get; }
}
}
46 changes: 46 additions & 0 deletions Exiled.Events/EventArgs/Map/ElevatorMovingEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// -----------------------------------------------------------------------
// <copyright file="ElevatorMovingEventArgs.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Map
{
using System.Collections.Generic;
using System.Linq;

using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;

/// <summary>
/// Contains all information before elevator starts moving.
/// </summary>
public class ElevatorMovingEventArgs : IDeniableEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="ElevatorMovingEventArgs"/> class.
/// </summary>
/// <param name="lift"><inheritdoc cref="Lift"/></param>
/// <param name="isAllowed"><inheritdoc cref="IsAllowed"/></param>
public ElevatorMovingEventArgs(Lift lift, bool isAllowed = true)
{
Lift = lift;
Players = Player.Get(x => x.Lift == lift).ToList();
IsAllowed = isAllowed;
}

/// <summary>
/// Gets the current elevator.
/// </summary>
public Lift Lift { get; }

/// <summary>
/// Gets a list of all players in elevator.
/// </summary>
public IReadOnlyCollection<Player> Players { get; }

/// <inheritdoc/>
public bool IsAllowed { get; set; }
}
}
22 changes: 22 additions & 0 deletions Exiled.Events/Handlers/Map.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ public static class Map
/// </summary>
public static Event<PlacingPickupIntoPocketDimensionEventArgs> PlacingPickupIntoPocketDimension { get; set; } = new();

/// <summary>
/// Invoked before elevator starts moving.
/// </summary>
public static Event<ElevatorMovingEventArgs> ElevatorMoving { get; set; } = new();

/// <summary>
/// Invoked after an elevator has arrived.
/// </summary>
public static Event<ElevatorArrivedEventArgs> ElevatorArrived { get; set; } = new();

/// <summary>
/// Called before placing a decal.
/// </summary>
Expand Down Expand Up @@ -216,5 +226,17 @@ public static class Map
/// </summary>
/// <param name="ev">The <see cref="PlacingPickupIntoPocketDimensionEventArgs"/> instnace.</param>
public static void OnPlacingPickupIntoPocketDimension(PlacingPickupIntoPocketDimensionEventArgs ev) => PlacingPickupIntoPocketDimension.InvokeSafely(ev);

/// <summary>
/// Called before elevator starts moving.
/// </summary>
/// <param name="ev">The <see cref="ElevatorMovingEventArgs"/> instance.</param>
public static void OnElevatorMoving(ElevatorMovingEventArgs ev) => ElevatorMoving.InvokeSafely(ev);

/// <summary>
/// Called after an elevator has arrived.
/// </summary>
/// <param name="ev">The <see cref="ElevatorArrivedEventArgs"/> instance.</param>
public static void OnElevatorArrived(ElevatorArrivedEventArgs ev) => ElevatorArrived.InvokeSafely(ev);
}
}
93 changes: 93 additions & 0 deletions Exiled.Events/Patches/Events/Map/ElevatorMovingAndArrived.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// -----------------------------------------------------------------------
// <copyright file="ElevatorMovingAndArrived.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

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

using Exiled.API.Features;
using Exiled.API.Features.Core.Generic.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Map;
using HarmonyLib;
using Interactables.Interobjects;
using Mirror;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="ElevatorChamber.TrySetDestination"/>
/// to add <see cref="Handlers.Map.ElevatorArrived"/> and <see cref="Handlers.Map.ElevatorMoving"/> events.
/// </summary>
[EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.ElevatorArrived))]
[EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.ElevatorMoving))]
[HarmonyPatch(typeof(ElevatorChamber), nameof(ElevatorChamber.TrySetDestination))]
internal class ElevatorMovingAndArrived
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

int index = newInstructions.FindIndex(x => x.Calls(PropertyGetter(typeof(NetworkServer), nameof(NetworkServer.active))));

Label continueLabel = generator.DefineLabel();

newInstructions.InsertRange(
index,
new[]
{
// Lift.Get(this);
new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Call, Method(typeof(Lift), nameof(Lift.Get), new[] { typeof(ElevatorChamber) })),

// true
new(OpCodes.Ldc_I4_1),

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

// Handlers.Map.OnElevatorMoving(ev);
new(OpCodes.Call, Method(typeof(Handlers.Map), nameof(Handlers.Map.OnElevatorMoving))),

// if (!ev.IsAllowed)
// return false;
new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorMovingEventArgs), nameof(ElevatorMovingEventArgs.IsAllowed))),
new(OpCodes.Brtrue_S, continueLabel),

new(OpCodes.Ldc_I4_0),
new(OpCodes.Ret),

new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel),
});

int offset = 1;
index = newInstructions.FindLastIndex(x => x.Calls(Method(typeof(ElevatorChamber), nameof(ElevatorChamber.SetInnerDoor)))) + offset;

newInstructions.InsertRange(
index,
new[]
{
// Lift.Get(this);
new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Call, Method(typeof(Lift), nameof(Lift.Get), new[] { typeof(ElevatorChamber) })),

// ElevatorArrivedEventArgs ev = new(Lift);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ElevatorArrivedEventArgs))[0]),

// Handlers.Map.OnElevatorArrived(ev);
new(OpCodes.Call, Method(typeof(Handlers.Map), nameof(Handlers.Map.OnElevatorArrived))),
});

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

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

0 comments on commit d551c37

Please sign in to comment.