Skip to content

Commit

Permalink
Add ChangedAttachmentsEvent (#2310)
Browse files Browse the repository at this point in the history
* NewFix

* Squash a lot of useless commit

This reverts commit 50e6123.

Squashed commit of the following:

commit d6f910c
Merge: 71e1870 981476e
Author: louis1706 <[email protected]>
Date:   Thu Nov 30 11:15:32 2023 +0100

    Merge branch 'Fix-ChangingAmmoEvent' of https://github.com/louis1706/EXILED into Fix-ChangingAmmoEvent

commit 981476e
Merge: 263eaaa f010ec9
Author: Yamato <[email protected]>
Date:   Thu Nov 30 01:19:00 2023 +0100

    Merge branch 'dev' into Fix-ChangingAmmoEvent

commit 263eaaa
Author: Yamato <[email protected]>
Date:   Thu Nov 30 01:18:12 2023 +0100

    Update ChangingAmmo.cs

commit 71e1870
Author: louis1706 <[email protected]>
Date:   Thu Nov 30 00:00:25 2023 +0100

    Fix

commit df2b58a
Merge: 782c481 96eb33b
Author: Yamato <[email protected]>
Date:   Wed Nov 29 23:55:51 2023 +0100

    Merge branch 'dev' into Fix-ChangingAmmoEvent

commit 782c481
Merge: 670c692 0953d7c
Author: Misaka-ZeroTwo <[email protected]>
Date:   Wed Nov 29 17:44:59 2023 -0500

    Merge branch 'dev' into Fix-ChangingAmmoEvent

commit 670c692
Author: Yamato <[email protected]>
Date:   Wed Nov 29 23:36:40 2023 +0100

    Update ChangingAmmo.cs

commit 9ced0ee
Author: louis1706 <[email protected]>
Date:   Wed Nov 29 00:36:17 2023 +0100

    Event Should not be fired when Ammo it's not changed

commit 3f97d68
Author: louis1706 <[email protected]>
Date:   Wed Nov 29 00:10:13 2023 +0100

    FixChangingAmmoEventAndUpgradeIt

Add ChangedAttachments Event

Reorder Using

.

Fix Dup

Revert "Fix Dup"

This reverts commit bee995b.

Revert "Reorder Using"

This reverts commit f85fe5e.

Revert

This reverts partially commit 581a878.

New place

* Fix

* Delete Exiled.CustomItems/API/Features/CustomWeapon.cs

* Fix `ChangingAttachments` `ChangedAttachments`

* useless .ToList()

---------

Co-authored-by: Nao <[email protected]>
Co-authored-by: VALERA771 <[email protected]>
Co-authored-by: Ika <[email protected]>
Co-authored-by: Nameless <[email protected]>
  • Loading branch information
5 people authored Jul 4, 2024
1 parent 3324292 commit 5ff18df
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 114 deletions.
77 changes: 77 additions & 0 deletions Exiled.Events/EventArgs/Item/ChangedAttachmentsEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// -----------------------------------------------------------------------
// <copyright file="ChangedAttachmentsEventArgs.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.Item
{
using System.Collections.Generic;
using System.Linq;

using API.Features;
using API.Features.Items;
using API.Structs;

using Exiled.API.Extensions;

using Interfaces;
using InventorySystem.Items.Firearms.Attachments;

using Firearm = API.Features.Items.Firearm;

/// <summary>
/// Contains all information after changing item attachments.
/// </summary>
public class ChangedAttachmentsEventArgs : IPlayerEvent, IFirearmEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="ChangedAttachmentsEventArgs" /> class.
/// </summary>
/// <param name="firearm"><inheritdoc cref="Firearm"/></param>
/// <param name="code"><inheritdoc cref="OldAttachmentsCode"/></param>
public ChangedAttachmentsEventArgs(Firearm firearm, uint code)
{
Firearm = firearm;
Player = Firearm.Owner;
OldAttachmentIdentifiers = Firearm.AttachmentIdentifiers;
NewAttachmentIdentifiers = Firearm.FirearmType.GetAttachmentIdentifiers(code);
OldAttachmentsCode = code;
NewAttachmentsCode = firearm.Base.GetCurrentAttachmentsCode();
}

/// <summary>
/// Gets the old <see cref="AttachmentIdentifier" /> list.
/// </summary>
public IEnumerable<AttachmentIdentifier> OldAttachmentIdentifiers { get; }

/// <summary>
/// Gets or sets the new <see cref="AttachmentIdentifier" /> list.
/// </summary>
public IEnumerable<AttachmentIdentifier> NewAttachmentIdentifiers { get; set; }

/// <summary>
/// Gets the <see cref="OldAttachmentIdentifiers" /> code.
/// </summary>
public uint OldAttachmentsCode { get; }

/// <summary>
/// Gets the <see cref="NewAttachmentIdentifiers" /> code.
/// </summary>
public uint NewAttachmentsCode { get; }

/// <summary>
/// Gets the <see cref="API.Features.Items.Firearm" /> which has been modified.
/// </summary>
public Firearm Firearm { get; }

/// <inheritdoc/>
public Item Item => Firearm;

/// <summary>
/// Gets the <see cref="API.Features.Player" /> who's changed attachments.
/// </summary>
public Player Player { get; }
}
}
43 changes: 28 additions & 15 deletions Exiled.Events/EventArgs/Item/ChangingAmmoEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ namespace Exiled.Events.EventArgs.Item
using Exiled.API.Features;
using Exiled.API.Features.Items;
using Exiled.Events.EventArgs.Interfaces;
using InventorySystem.Items.Firearms;

using BaseFirearm = InventorySystem.Items.Firearms.Firearm;
using Firearm = API.Features.Items.Firearm;

/// <summary>
/// Contains all information before changing firearm ammo.
Expand All @@ -19,21 +23,16 @@ public class ChangingAmmoEventArgs : IPlayerEvent, IFirearmEvent, IDeniableEvent
/// <summary>
/// Initializes a new instance of the <see cref="ChangingAmmoEventArgs"/> class.
/// </summary>
/// <param name="firearm"><inheritdoc cref="Firearm"/></param>
/// <param name="oldAmmo"><inheritdoc cref="OldAmmo"/></param>
/// <param name="newAmmo"><inheritdoc cref="NewAmmo"/></param>
/// <param name="basefirearm"><inheritdoc cref="Firearm"/></param>
/// <param name="oldStatus"><inheritdoc cref="OldAmmo"/></param>
/// <param name="newStatus"><inheritdoc cref="NewAmmo"/></param>
/// <param name="isAllowed"><inheritdoc cref="IsAllowed"/></param>
public ChangingAmmoEventArgs(InventorySystem.Items.ItemBase firearm, byte oldAmmo, byte newAmmo, bool isAllowed = true)
public ChangingAmmoEventArgs(BaseFirearm basefirearm, FirearmStatus oldStatus, FirearmStatus newStatus, bool isAllowed = true)
{
Item item = Item.Get(firearm);

if (item is not Firearm firearmItem)
return;

Player = firearmItem.Owner;
Firearm = firearmItem;
OldAmmo = oldAmmo;
NewAmmo = newAmmo;
Firearm = Item.Get(basefirearm).As<Firearm>();
Player = Firearm.Owner;
OldStatus = oldStatus;
NewStatus = newStatus;
IsAllowed = isAllowed;
}

Expand All @@ -50,15 +49,29 @@ public ChangingAmmoEventArgs(InventorySystem.Items.ItemBase firearm, byte oldAmm
/// <inheritdoc/>
public Item Item => Firearm;

/// <summary>
/// Gets the old status.
/// </summary>
public FirearmStatus OldStatus { get; }

/// <summary>
/// Gets the old ammo.
/// </summary>
public byte OldAmmo { get; }
public byte OldAmmo => OldStatus.Ammo;

/// <summary>
/// Gets or sets the new status to be used by the firearm.
/// </summary>
public FirearmStatus NewStatus { get; set; }

/// <summary>
/// Gets or sets the new ammo to be used by the firearm.
/// </summary>
public byte NewAmmo { get; set; }
public byte NewAmmo
{
get => NewStatus.Ammo;
set => NewStatus = new(value, NewStatus.Flags, NewStatus.Attachments);
}

/// <summary>
/// Gets or sets a value indicating whether or not the ammo can be changed.
Expand Down
36 changes: 16 additions & 20 deletions Exiled.Events/EventArgs/Item/ChangingAttachmentsEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,50 +28,46 @@ public class ChangingAttachmentsEventArgs : IPlayerEvent, IDeniableEvent, IFirea
/// <summary>
/// Initializes a new instance of the <see cref="ChangingAttachmentsEventArgs" /> class.
/// </summary>
/// <param name="player">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="firearm">
/// <inheritdoc cref="Firearm" />
/// </param>
/// <param name="code">The attachments code.</param>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public ChangingAttachmentsEventArgs(
Player player,
Firearm firearm,
uint code,
bool isAllowed = true)
public ChangingAttachmentsEventArgs(Firearm firearm, uint code, bool isAllowed = true)
{
Player = player;
Firearm = firearm;
CurrentAttachmentIdentifiers = firearm.AttachmentIdentifiers;
NewAttachmentIdentifiers = firearm.FirearmType.GetAttachmentIdentifiers(code).ToList();
CurrentCode = firearm.Base.GetCurrentAttachmentsCode();
NewCode = code;
Player = Firearm.Owner;
IsAllowed = isAllowed;
OldAttachmentIdentifiers = firearm.AttachmentIdentifiers;
OldAttachmentsCode = firearm.Base.GetCurrentAttachmentsCode();
NewAttachmentsCode = code;
}

/// <summary>
/// Gets the old <see cref="AttachmentIdentifier" />.
/// Gets the old <see cref="AttachmentIdentifier" /> list.
/// </summary>
public IEnumerable<AttachmentIdentifier> CurrentAttachmentIdentifiers { get; }
public IEnumerable<AttachmentIdentifier> OldAttachmentIdentifiers { get; }

/// <summary>
/// Gets or sets the new <see cref="AttachmentIdentifier" />.
/// Gets or sets the new <see cref="AttachmentIdentifier" /> list.
/// </summary>
public List<AttachmentIdentifier> NewAttachmentIdentifiers { get; set; }

/// <summary>
/// Gets the <see cref="CurrentAttachmentIdentifiers" /> code.
/// Gets the <see cref="OldAttachmentIdentifiers" /> code.
/// </summary>
public uint CurrentCode { get; }
public uint OldAttachmentsCode { get; }

/// <summary>
/// Gets the <see cref="NewAttachmentIdentifiers" /> code.
/// Gets or sets the <see cref="NewAttachmentIdentifiers" /> code.
/// </summary>
public uint NewCode { get; }
public uint NewAttachmentsCode
{
get => NewAttachmentIdentifiers.GetAttachmentsCode();
set => NewAttachmentIdentifiers = Firearm.FirearmType.GetAttachmentIdentifiers(value).ToList();
}

/// <summary>
/// Gets or sets a value indicating whether or not the attachments can be changed.
Expand Down
11 changes: 11 additions & 0 deletions Exiled.Events/Handlers/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public static class Item
/// </summary>
public static Event<ChangingAttachmentsEventArgs> ChangingAttachments { get; set; } = new();

/// <summary>
/// Invoked after item attachments are changed.
/// </summary>
public static Event<ChangedAttachmentsEventArgs> ChangedAttachments { get; set; } = new();

/// <summary>
/// Invoked before receiving a preference.
/// </summary>
Expand Down Expand Up @@ -70,6 +75,12 @@ public static class Item
/// <param name="ev">The <see cref="ChangingAttachmentsEventArgs" /> instance.</param>
public static void OnChangingAttachments(ChangingAttachmentsEventArgs ev) => ChangingAttachments.InvokeSafely(ev);

/// <summary>
/// Called after item attachments are changed.
/// </summary>
/// <param name="ev">The <see cref="ChangingAttachmentsEventArgs" /> instance.</param>
public static void OnChangedAttachments(ChangedAttachmentsEventArgs ev) => ChangedAttachments.InvokeSafely(ev);

/// <summary>
/// Called before receiving a preference.
/// </summary>
Expand Down
74 changes: 20 additions & 54 deletions Exiled.Events/Patches/Events/Item/ChangingAmmo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,20 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

const int offset = 3;
const int offset = 2;
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Brfalse_S) + offset;

LocalBuilder ev = generator.DeclareLocal(typeof(ChangingAmmoEventArgs));
LocalBuilder ammo = generator.DeclareLocal(typeof(byte));

Label cdc = generator.DefineLabel();
Label jmp = generator.DefineLabel();
Label jcc = generator.DefineLabel();

newInstructions[index].labels.Add(cdc);
Label ret = generator.DefineLabel();
Label jump = generator.DefineLabel();

newInstructions.InsertRange(
index,
new[]
{
// value.Ammo
new(OpCodes.Ldarg_1),
new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Ldfld, Field(typeof(FirearmStatus), nameof(FirearmStatus.Ammo))),

// this._status.Ammo
Expand All @@ -60,82 +56,52 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Ldfld, Field(typeof(FirearmStatus), nameof(FirearmStatus.Ammo))),

// if (value.Ammo == this._status.Ammo)
// goto cdc;
// goto jump;
new(OpCodes.Ceq),
new(OpCodes.Brtrue_S, cdc),
new(OpCodes.Brtrue_S, jump),

// this
new(OpCodes.Ldarg_0),
new(OpCodes.Dup),

// this._status
// this._status (oldStatus)
new(OpCodes.Ldfld, Field(typeof(Firearm), nameof(Firearm._status))),

// this.Ammo
new(OpCodes.Ldfld, Field(typeof(FirearmStatus), nameof(FirearmStatus.Ammo))),

// value.Ammo
// value (newStatus)
new(OpCodes.Ldarg_1),
new(OpCodes.Ldfld, Field(typeof(FirearmStatus), nameof(FirearmStatus.Ammo))),

// true
new(OpCodes.Ldc_I4_1),

// ChangingDurabilityEventArgs ev = new(ItemBase, byte, byte, bool)
// ChangingAmmoEventArgs ev = new(BaseFirearm, FirearmStatus, FirearmStatus, bool)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ChangingAmmoEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, ev.LocalIndex),

// Item.ChangingAmmoEventArgs(ev)
// Item.OnChangingAmmo(ev)
new(OpCodes.Call, Method(typeof(Item), nameof(Item.OnChangingAmmo))),

// if (ev.Firearm == null)
// goto cdc;
new(OpCodes.Callvirt, PropertyGetter(typeof(ChangingAmmoEventArgs), nameof(ChangingAmmoEventArgs.Firearm))),
new(OpCodes.Brfalse_S, cdc),
new(OpCodes.Ldloc_S, ev.LocalIndex),

// if (!ev.IsAllowed)
// goto jmp;
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(ChangingAmmoEventArgs), nameof(ChangingAmmoEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, jmp),
new(OpCodes.Brfalse_S, ret),

// ev.NewDurability
// goto jcc;
// value = ev.NewStatus;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(ChangingAmmoEventArgs), nameof(ChangingAmmoEventArgs.NewAmmo))),
new(OpCodes.Stloc_S, ammo.LocalIndex),
new(OpCodes.Br_S, jcc),

// ev.OldAmmo
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).WithLabels(jmp),
new(OpCodes.Callvirt, PropertyGetter(typeof(ChangingAmmoEventArgs), nameof(ChangingAmmoEventArgs.OldAmmo))),
new(OpCodes.Stloc_S, ammo.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(ChangingAmmoEventArgs), nameof(ChangingAmmoEventArgs.NewStatus))),
new(OpCodes.Starg_S, 1),

// this
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(jcc),

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

// value.Flags
new(OpCodes.Ldarg_1),
new(OpCodes.Ldfld, Field(typeof(FirearmStatus), nameof(FirearmStatus.Flags))),

// value.Attachments
new(OpCodes.Ldarg_1),
new(OpCodes.Ldfld, Field(typeof(FirearmStatus), nameof(FirearmStatus.Attachments))),

// this.value = new(byte, FirearmStatusFlags, uint)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(FirearmStatus))[0]),
new(OpCodes.Stfld, Field(typeof(Firearm), nameof(Firearm._status))),
// jump:
new CodeInstruction(OpCodes.Nop).WithLabels(jump),
});

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

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

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

0 comments on commit 5ff18df

Please sign in to comment.