From b02a1d9a85798cab9cae8533529cbbbc1399d35a Mon Sep 17 00:00:00 2001
From: Avepy <54192195+Avepy@users.noreply.github.com>
Date: Mon, 16 Dec 2024 13:52:18 +0100
Subject: [PATCH] refactor(server): OnWeaponDamageEvent and
WeaponDamageResponse (#40)
* refactor(server): OnWeaponDamageEvent and WeaponDamageResponse
* refactor(server): OnWeaponDamageEvent and WeaponDamageResponse
* refactor(server): OnWeaponDamageEvent and WeaponDamageResponse
---
api/AltV.Net/Core.Events.cs | 82 ++++++++++++++++-------
api/AltV.Net/Data/WeaponDamageResponse.cs | 23 +++++--
2 files changed, 77 insertions(+), 28 deletions(-)
diff --git a/api/AltV.Net/Core.Events.cs b/api/AltV.Net/Core.Events.cs
index bce46bd84..7aa37724b 100644
--- a/api/AltV.Net/Core.Events.cs
+++ b/api/AltV.Net/Core.Events.cs
@@ -538,21 +538,69 @@ public void OnWeaponDamage(IntPtr eventPointer, IntPtr playerPointer, IntPtr ent
OnWeaponDamageEvent(eventPointer, sourcePlayer, targetEntity, weapon, damage, shotOffset, bodyPart);
}
+ ///
+ /// Handles the weapon damage event triggered in the game.
+ ///
+ ///
+ /// This method iterates through all registered event handlers for weapon damage events,
+ /// determines whether the event should be canceled, and updates the damage value if modified
+ /// by any handler.
+ ///
+ /// If any handler indicates cancellation, the event is marked as canceled.
+ /// If a damage override is provided, it updates the damage value.
+ ///
public virtual void OnWeaponDamageEvent(IntPtr eventPointer, IPlayer sourcePlayer, IEntity targetEntity,
- uint weapon, ushort damage,
- Position shotOffset, BodyPart bodyPart)
+ uint weapon, ushort damage, Position shotOffset, BodyPart bodyPart)
{
+ try
+ {
+ var (shouldCancel, weaponDamage) =
+ ProcessWeaponDamageEvents(sourcePlayer, targetEntity, weapon, damage, shotOffset, bodyPart);
+
+ if (weaponDamage.HasValue)
+ {
+ unsafe
+ {
+ Alt.CoreImpl.Library.Server.Event_WeaponDamageEvent_SetDamageValue(eventPointer,
+ weaponDamage.Value);
+ }
+ }
+
+ if (shouldCancel)
+ {
+ unsafe
+ {
+ Alt.CoreImpl.Library.Shared.Event_Cancel(eventPointer);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Alt.Log($"Unhandled exception in {nameof(OnWeaponDamageEvent)}: {ex}");
+ }
+ }
+
+ ///
+ /// Processes weapon damage events by invoking all registered event handlers and aggregating results.
+ ///
+ ///
+ /// A tuple containing a flag indicating if the event should be canceled and the aggregated weapon damage value.
+ ///
+ private (bool shouldCancel, uint? weaponDamage) ProcessWeaponDamageEvents(IPlayer sourcePlayer,
+ IEntity targetEntity, uint weapon, ushort damage, Position shotOffset, BodyPart bodyPart)
+ {
+ var shouldCancel = false;
uint? weaponDamage = null;
- var cancel = false;
+
foreach (var @delegate in WeaponDamageEventHandler.GetEvents())
{
try
{
var result = @delegate(sourcePlayer, targetEntity, weapon, damage, shotOffset, bodyPart);
- if (!result.notCancel)
+ if (result.Cancel)
{
- cancel = true;
+ shouldCancel = true;
}
if (result.Damage.HasValue)
@@ -560,31 +608,17 @@ public virtual void OnWeaponDamageEvent(IntPtr eventPointer, IPlayer sourcePlaye
weaponDamage ??= result.Damage.Value;
}
}
- catch (TargetInvocationException exception)
+ catch (TargetInvocationException tex)
{
- Alt.Log("exception at event:" + "OnWeaponDamageEvent" + ":" + exception.InnerException);
+ Alt.Log($"TargetInvocationException in {nameof(ProcessWeaponDamageEvents)} handler: {tex.InnerException}");
}
- catch (Exception exception)
+ catch (Exception ex)
{
- Alt.Log("exception at event:" + "OnWeaponDamageEvent" + ":" + exception);
+ Alt.Log($"Exception in {nameof(ProcessWeaponDamageEvents)} handler: {ex}");
}
}
- if (weaponDamage is not null)
- {
- unsafe
- {
- Alt.CoreImpl.Library.Server.Event_WeaponDamageEvent_SetDamageValue(eventPointer, weaponDamage.Value);
- }
- }
-
- if (cancel)
- {
- unsafe
- {
- Alt.CoreImpl.Library.Shared.Event_Cancel(eventPointer);
- }
- }
+ return (shouldCancel, weaponDamage);
}
public void OnPlayerChangeVehicleSeat(IntPtr vehiclePointer, IntPtr playerPointer, byte oldSeat,
diff --git a/api/AltV.Net/Data/WeaponDamageResponse.cs b/api/AltV.Net/Data/WeaponDamageResponse.cs
index 43bf4f694..840661a20 100644
--- a/api/AltV.Net/Data/WeaponDamageResponse.cs
+++ b/api/AltV.Net/Data/WeaponDamageResponse.cs
@@ -1,6 +1,21 @@
namespace AltV.Net.Data;
-public record WeaponDamageResponse(bool notCancel, uint? Damage) {
- public static implicit operator WeaponDamageResponse(bool val) => new WeaponDamageResponse(val, null);
- public static implicit operator WeaponDamageResponse(uint val) => new WeaponDamageResponse(true, val);
-};
\ No newline at end of file
+///
+/// Represents the response to a weapon damage event, indicating whether the damage is processed and the amount of damage.
+///
+public record WeaponDamageResponse(bool Cancel, uint? Damage)
+{
+ ///
+ /// Implicit conversion from a boolean value to .
+ /// Sets to the specified value and to null.
+ ///
+ /// Indicates whether the damage is processed.
+ public static implicit operator WeaponDamageResponse(bool cancel) => new(cancel, null);
+
+ ///
+ /// Implicit conversion from an uint value to .
+ /// Sets to true and to the specified value.
+ ///
+ /// The amount of damage.
+ public static implicit operator WeaponDamageResponse(uint damage) => new(false, damage);
+}