Skip to content

Commit

Permalink
DeadmanSwitchEventAndAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
louis1706 committed Jan 13, 2025
1 parent 5dc7ad5 commit 2ef7fe9
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 1 deletion.
7 changes: 6 additions & 1 deletion EXILED/Exiled.API/Features/Warhead.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,18 @@ public static class Warhead
/// <summary>
/// Gets the cached <see cref="AlphaWarheadOutsitePanel"/> component.
/// </summary>
public static AlphaWarheadOutsitePanel OutsitePanel => alphaWarheadOutsitePanel != null ? alphaWarheadOutsitePanel : (alphaWarheadOutsitePanel = Object.FindObjectOfType<AlphaWarheadOutsitePanel>());
public static AlphaWarheadOutsitePanel OutsitePanel => alphaWarheadOutsitePanel != null ? alphaWarheadOutsitePanel : (alphaWarheadOutsitePanel = UnityEngine.Object.FindObjectOfType<AlphaWarheadOutsitePanel>());

/// <summary>
/// Gets the <see cref="GameObject"/> of the warhead lever.
/// </summary>
public static GameObject Lever => SitePanel.lever.gameObject;

/// <summary>
/// Gets or sets a value indicating whether DeadmanSwitch detonation is enabled.
/// </summary>
public static bool DisableDeadmanSwitch { get; set; }

/// <summary>
/// Gets or sets a value indicating whether automatic detonation is enabled.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// -----------------------------------------------------------------------
// <copyright file="DeadmanSwitchInitiatingEventArgs.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.Warhead
{
using Exiled.Events.EventArgs.Interfaces;

/// <summary>
/// Contains all information before detonating the warhead.
/// </summary>
public class DeadmanSwitchInitiatingEventArgs : IDeniableEvent
{
/// <inheritdoc/>
public bool IsAllowed { get; set; } = true;
}
}
10 changes: 10 additions & 0 deletions EXILED/Exiled.Events/Handlers/Warhead.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public class Warhead
/// </summary>
public static Event Detonated { get; set; } = new();

/// <summary>
/// Invoked before the DeadmanSwitch is Initiated.
/// </summary>
public static Event DeadmanSwitchInitiating { get; set; } = new();

/// <summary>
/// Invoked before detonating the warhead.
/// </summary>
Expand Down Expand Up @@ -65,6 +70,11 @@ public class Warhead
/// </summary>
public static void OnDetonated() => Detonated.InvokeSafely();

/// <summary>
/// Called after the warhead has been detonated.
/// </summary>
public static void OnDeadmanSwitchInitiating() => DeadmanSwitchInitiating.InvokeSafely();

/// <summary>
/// Called before detonating the warhead.
/// </summary>
Expand Down
64 changes: 64 additions & 0 deletions EXILED/Exiled.Events/Patches/Events/Warhead/DeadmanSwitchStart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// -----------------------------------------------------------------------
// <copyright file="DeadmanSwitchStart.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.Warhead
{
using System.Collections.Generic;
using System.Reflection.Emit;

using API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Warhead;
using Handlers;
using HarmonyLib;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="AlphaWarheadController.Detonate" />
/// to add <see cref="Exiled.API.Features.Warhead.DisableDeadmanSwitch"/> and <see cref="Warhead.DeadmanSwitchInitiating"/> events.
/// </summary>
[EventPatch(typeof(Warhead), nameof(Warhead.DeadmanSwitchInitiating))]
[HarmonyPatch(typeof(DeadmanSwitch), nameof(DeadmanSwitch.InitiateProtocol))]
internal static class DeadmanSwitchStart
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label retLabel = generator.DefineLabel();
LocalBuilder ev = generator.DeclareLocal(typeof(DetonatingEventArgs));

newInstructions.InsertRange(0, new CodeInstruction[]
{
// if (Exiled.API.Features.Warhead.DisableDeadmanSwitch)
// return;
new(OpCodes.Call, PropertyGetter(typeof(Exiled.API.Features.Warhead), nameof(Exiled.API.Features.Warhead.DisableDeadmanSwitch))),
new(OpCodes.Brtrue_S, retLabel),

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

// Handlers.Warhead.OnDeadmanSwitchInitiating(ev);
new(OpCodes.Call, Method(typeof(Warhead), nameof(Warhead.OnDeadmanSwitchInitiating))),

// if (ev.IsAllowed)
// goto retLabel;
new(OpCodes.Callvirt, PropertyGetter(typeof(DeadmanSwitchInitiatingEventArgs), nameof(DeadmanSwitchInitiatingEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, retLabel),
});

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

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

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

0 comments on commit 2ef7fe9

Please sign in to comment.