Skip to content

Commit

Permalink
New Hurt Event (#2176)
Browse files Browse the repository at this point in the history
Co-authored-by: IRacle <79921583+IRacle1@users.noreply.github.com>
  • Loading branch information
louis1706 and IRacle1 authored Nov 12, 2023
1 parent d32e7e9 commit df21098
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 14 deletions.
62 changes: 62 additions & 0 deletions Exiled.Events/EventArgs/Player/HurtEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// -----------------------------------------------------------------------
// <copyright file="HurtEventArgs.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.Player
{
using API.Features;
using API.Features.DamageHandlers;

using Interfaces;

using CustomAttackerHandler = API.Features.DamageHandlers.AttackerDamageHandler;
using DamageHandlerBase = PlayerStatsSystem.DamageHandlerBase;

/// <summary>
/// Contains all information before a player gets damaged.
/// </summary>
public class HurtEventArgs : IAttackerEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="HurtEventArgs" /> class.
/// </summary>
/// <param name="target">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="damageHandler">
/// <inheritdoc cref="DamageHandler" />
/// </param>
/// <param name="handlerOutput">
/// <inheritdoc cref="HandlerOutput" />
/// </param>
public HurtEventArgs(Player target, DamageHandlerBase damageHandler, DamageHandlerBase.HandlerOutput handlerOutput)
{
DamageHandler = new CustomDamageHandler(target, damageHandler);
Attacker = DamageHandler.BaseIs(out CustomAttackerHandler attackerDamageHandler) ? attackerDamageHandler.Attacker : null;
Player = target;
HandlerOutput = handlerOutput;
}

/// <inheritdoc/>
public Player Player { get; }

/// <inheritdoc/>
public Player Attacker { get; }

/// <summary>
/// Gets the amount of inflicted damage.
/// </summary>
public float Amount => DamageHandler.Damage;

/// <summary>
/// Gets or sets the action than will be made on the player.
/// </summary>
public DamageHandlerBase.HandlerOutput HandlerOutput { get; set; }

/// <inheritdoc/>
public CustomDamageHandler DamageHandler { get; set; }
}
}
16 changes: 4 additions & 12 deletions Exiled.Events/EventArgs/Player/HurtingEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,10 @@ public HurtingEventArgs(Player target, DamageHandlerBase damageHandler)
Player = target;
}

/// <summary>
/// Gets the target player, who is going to be hurt.
/// </summary>
/// <inheritdoc/>
public Player Player { get; }

/// <summary>
/// Gets the attacker player.
/// </summary>
/// <inheritdoc/>
public Player Attacker { get; }

/// <summary>
Expand All @@ -56,14 +52,10 @@ public float Amount
set => DamageHandler.Damage = value;
}

/// <summary>
/// Gets or sets the <see cref="CustomDamageHandler" /> for the event.
/// </summary>
/// <inheritdoc/>
public CustomDamageHandler DamageHandler { get; set; }

/// <summary>
/// Gets or sets a value indicating whether or not the player will be dealt damage.
/// </summary>
/// <inheritdoc/>
public bool IsAllowed { get; set; } = true;
}
}
11 changes: 11 additions & 0 deletions Exiled.Events/Handlers/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ public class Player
/// </summary>
public static Event<HurtingEventArgs> Hurting { get; set; } = new();

/// <summary>
/// Invoked after hurting a <see cref="API.Features.Player"/>.
/// </summary>
public static Event<HurtEventArgs> Hurt { get; set; } = new();

/// <summary>
/// Invoked before a <see cref="API.Features.Player"/> dies.
/// </summary>
Expand Down Expand Up @@ -1024,6 +1029,12 @@ public static void OnItemAdded(ReferenceHub referenceHub, InventorySystem.Items.
/// <param name="ev">The <see cref="HurtingEventArgs"/> instance. </param>
public static void OnHurting(HurtingEventArgs ev) => Hurting.InvokeSafely(ev);

/// <summary>
/// Called ater a <see cref="API.Features.Player"/> being hurt.
/// </summary>
/// <param name="ev">The <see cref="HurtingEventArgs"/> instance. </param>
public static void OnHurt(HurtEventArgs ev) => Hurt.InvokeSafely(ev);

/// <summary>
/// Called before a <see cref="API.Features.Player"/> dies.
/// </summary>
Expand Down
26 changes: 24 additions & 2 deletions Exiled.Events/Patches/Events/Player/Hurting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ namespace Exiled.Events.Patches.Events.Player

/// <summary>
/// Patches <see cref="PlayerStats.DealDamage(DamageHandlerBase)" />.
/// Adds the <see cref="Handlers.Player.Hurting" /> event.
/// Adds the <see cref="Handlers.Player.Hurting" /> event and <see cref="Handlers.Player.Hurt" /> event.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Hurting))]
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Hurt))]
[HarmonyPatch(typeof(PlayerStats), nameof(PlayerStats.DealDamage))]
internal static class Hurting
{
Expand All @@ -43,7 +44,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
Label notRecontainment = generator.DefineLabel();
Label ret = generator.DefineLabel();

const int offset = 1;
int offset = 1;
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ret) + offset;

newInstructions.InsertRange(
Expand Down Expand Up @@ -96,6 +97,27 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Brfalse, ret),
});

offset = 2;
index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(DamageHandlerBase), nameof(DamageHandlerBase.ApplyDamage))) + offset;

newInstructions.InsertRange(
index,
new[]
{
// HurtEventArgs ev = new(player, handler, handleroutput)
new CodeInstruction(OpCodes.Ldloc, player.LocalIndex),
new(OpCodes.Ldarg_1),
new(OpCodes.Ldloc_1),
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(HurtEventArgs))[0]),
new(OpCodes.Dup),

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

// handlerOutput = ev.HandlerOutput;
new(OpCodes.Callvirt, PropertyGetter(typeof(HurtEventArgs), nameof(HurtEventArgs.HandlerOutput))),
new(OpCodes.Stloc_1),
});
newInstructions[newInstructions.Count - 1].WithLabels(ret);

for (int z = 0; z < newInstructions.Count; z++)
Expand Down

0 comments on commit df21098

Please sign in to comment.