From f6db99af9cde92930bb5f275a3374641171c6a76 Mon Sep 17 00:00:00 2001 From: Yamato <66829532+louis1706@users.noreply.github.com> Date: Sat, 4 Jan 2025 19:40:56 +0100 Subject: [PATCH 01/15] feat: ``Lift::Get(ElevatorGroup)`` (#372) Lift::Get(ElevatorGroup) --- EXILED/Exiled.API/Features/Lift.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/EXILED/Exiled.API/Features/Lift.cs b/EXILED/Exiled.API/Features/Lift.cs index c38e146a3..ec2a87c84 100644 --- a/EXILED/Exiled.API/Features/Lift.cs +++ b/EXILED/Exiled.API/Features/Lift.cs @@ -223,6 +223,13 @@ public float AnimationTime /// A or if not found. public static Lift Get(ElevatorType type) => Get(lift => lift.Type == type).FirstOrDefault(); + /// + /// Gets the corresponding to the specified , if any. + /// + /// The . + /// A or if not found. + public static Lift Get(ElevatorGroup type) => Get(lift => lift.Group == type).FirstOrDefault(); + /// /// Gets the corresponding to the specified name, if any. /// From be5fb53fd2ec593e419dead4ac7cce4a475a4c25 Mon Sep 17 00:00:00 2001 From: scp252arc <95125564+scp252arc@users.noreply.github.com> Date: Sun, 5 Jan 2025 13:07:23 +0300 Subject: [PATCH 02/15] fix: PlacingBulletHoleEventArgs::Position (#377) Fix --- .../Patches/Events/Map/PlacingBulletHole.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs b/EXILED/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs index 16a1b96e8..ff3a09dfa 100644 --- a/EXILED/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs +++ b/EXILED/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs @@ -9,23 +9,19 @@ namespace Exiled.Events.Patches.Events.Map { using System.Collections.Generic; using System.Linq; - using System.Reflection; using System.Reflection.Emit; using API.Features.Pools; + using Attributes; using Decals; - using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Map; using Handlers; using HarmonyLib; - using InventorySystem.Items; using InventorySystem.Items.Firearms.Modules; using UnityEngine; using static HarmonyLib.AccessTools; - using Player = API.Features.Player; - /// /// Patches . /// Adds the event. @@ -50,10 +46,10 @@ private static IEnumerable Transpiler(IEnumerable x.Name == "Get").First()), + new(OpCodes.Call, typeof(Exiled.API.Features.Items.Item).GetMethods().Where(x => x.Name == "Get").First()), // hit - new(OpCodes.Ldarg_2), + new(OpCodes.Ldarg_1), // PlacingBulletHole ev = new(Item, RaycastHit) new(OpCodes.Newobj, GetDeclaredConstructors(typeof(PlacingBulletHoleEventArgs))[0]), @@ -70,13 +66,13 @@ private static IEnumerable Transpiler(IEnumerable Date: Mon, 6 Jan 2025 13:30:58 +0300 Subject: [PATCH 03/15] fix: DryFiring fired constantly (#378) Fix DryFiring fired constantly --- .../Patches/Events/Player/DryFire.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs b/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs index 59b209e10..9ea721c3b 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/DryFire.cs @@ -12,17 +12,15 @@ namespace Exiled.Events.Patches.Events.Player #pragma warning disable SA1649 using System.Collections.Generic; using System.Linq; - using System.Reflection; using System.Reflection.Emit; - using Exiled.API.Extensions; - using Exiled.API.Features.Pools; + using Attributes; - using Exiled.Events.Attributes; + using Exiled.API.Features.Pools; using Exiled.Events.EventArgs.Player; - using Exiled.Events.Handlers; + using Handlers; using HarmonyLib; @@ -67,7 +65,7 @@ private static IEnumerable Transpiler(IEnumerable x.Calls(PropertyGetter(typeof(AutomaticActionModule), nameof(AutomaticActionModule.Cocked)))) + offset; + int index = newInstructions.FindLastIndex(x => x.Calls(PropertySetter(typeof(AutomaticActionModule), nameof(AutomaticActionModule.Cocked)))) + offset; newInstructions.InsertRange(index, GetInstructions(newInstructions[index], ret)); @@ -78,6 +76,7 @@ private static IEnumerable Transpiler(IEnumerable Commented out, because it is never called (nw moment). Calls 2 PumpActionModule.ShootOneBarrel(bool) instead. /// /// Patches /// to add event for double shots. @@ -102,10 +101,11 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } + */ /// - /// Patches - /// to add event for double shots. + /// Patches + /// to add event for pump shots. /// [EventPatch(typeof(Player), nameof(Player.DryfiringWeapon))] [HarmonyPatch(typeof(PumpActionModule), nameof(PumpActionModule.ShootOneBarrel))] From 5139cfc002eae2f65aa06bbd0c161cbae400b3eb Mon Sep 17 00:00:00 2001 From: X <24619207+Undid-Iridium@users.noreply.github.com> Date: Mon, 6 Jan 2025 05:58:03 -0500 Subject: [PATCH 04/15] feat: Unbanned event addition (#185) * Option A * Style cop happy * Sigh stylecop * For Yamato * Done, not tested * Stylecop --------- Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com> --- .../Patches/Events/Server/Unban.cs | 75 +++++++++++++++++-- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs b/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs index 0700f5419..66310a212 100644 --- a/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs @@ -18,15 +18,19 @@ namespace Exiled.Events.Patches.Events.Server using static HarmonyLib.AccessTools; /// - /// Patches - /// to add and events. + /// Patches + /// to add and events. /// - [HarmonyPatch(typeof(BanHandler), nameof(BanHandler.RemoveBan))] [EventPatch(typeof(Handlers.Server), nameof(Handlers.Server.Unbanning))] [EventPatch(typeof(Handlers.Server), nameof(Handlers.Server.Unbanned))] + [HarmonyPatch] internal class Unban { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + [HarmonyPatch(typeof(BanHandler), nameof(BanHandler.RemoveBan))] + [HarmonyTranspiler] + private static IEnumerable Transpiler( + IEnumerable instructions, + ILGenerator generator) { List newInstructions = ListPool.Pool.Get(instructions); @@ -34,7 +38,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); + } + + [HarmonyPatch(typeof(BanHandler), nameof(BanHandler.ValidateBans), typeof(BanHandler.BanType))] + [HarmonyTranspiler] + private static IEnumerable BanHandlerTranspiler( + IEnumerable instructions, + ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + LocalBuilder ev = generator.DeclareLocal(typeof(UnbanningEventArgs)); + + Label continueLabel = generator.DefineLabel(); + + const int offset = 2; + int index = newInstructions.FindIndex(instruction => + instruction.Calls(Method(typeof(BanHandler), nameof(BanHandler.CheckExpiration)))) + offset; + + CodeInstruction addToUnbannedListInstruction = newInstructions[index]; + newInstructions.InsertRange(index, new[] + { + // id + new CodeInstruction(OpCodes.Ldloc, 4).MoveLabelsFrom(addToUnbannedListInstruction), + + // type + new(OpCodes.Ldarg_0), + + // true + new(OpCodes.Ldc_I4_1), + + // UnbanningEventArgs ev = new(string, BanHandler.BanType, true); + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(UnbanningEventArgs))[0]), + + new(OpCodes.Dup), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, ev.LocalIndex), + + // Handlers.Server.OnUnbanning(ev); + new(OpCodes.Call, Method(typeof(Handlers.Server), nameof(Handlers.Server.OnUnbanning))), + + // if (!ev.IsAllowed) + // return; + new(OpCodes.Callvirt, PropertyGetter(typeof(UnbanningEventArgs), nameof(UnbanningEventArgs.IsAllowed))), + new(OpCodes.Brtrue_S, continueLabel), + + new(OpCodes.Ret), + }); + + // Add label to ldloc.1 + addToUnbannedListInstruction.WithLabels(continueLabel); + + for (var z = 0; z < newInstructions.Count; z++) + { yield return newInstructions[z]; + } ListPool.Pool.Return(newInstructions); } From ef50d954a59dcc41b2e4c7fb3aeaa0b94f4ea157 Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:58:43 +0300 Subject: [PATCH 05/15] feat: Adding CustomKeycard for CustomItems (#98) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * uwu * itemtype check * bruh bruh brrr ☠ * fix * fix * fix no.2 * some events * ExMod Team copyright --------- Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com> Co-authored-by: Yamato --- .../Extensions/BitwiseExtensions.cs | 16 +++ .../API/Features/CustomKeycard.cs | 127 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs diff --git a/EXILED/Exiled.API/Extensions/BitwiseExtensions.cs b/EXILED/Exiled.API/Extensions/BitwiseExtensions.cs index d26328475..38ef020b7 100644 --- a/EXILED/Exiled.API/Extensions/BitwiseExtensions.cs +++ b/EXILED/Exiled.API/Extensions/BitwiseExtensions.cs @@ -59,5 +59,21 @@ public static T ModifyFlags(this T flags, bool value, params T[] changeFlags) return (T)Enum.ToObject(typeof(T), currentValue); } + + /// + /// Checks if flag has specified value. + /// + /// Flag to check. + /// Value to check in flag. + /// The type of the enum. + /// if value is presented in flag. Otherwise, . + public static bool HasFlagFast(this T flag, T value) + where T : Enum + { + long flagValue = Convert.ToInt64(flag); + long valueValue = Convert.ToInt64(value); + + return (flagValue & valueValue) == valueValue; + } } } \ No newline at end of file diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs b/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs new file mode 100644 index 000000000..e28f1ea3d --- /dev/null +++ b/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs @@ -0,0 +1,127 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.CustomItems.API.Features +{ + using System; + + using Exiled.API.Enums; + using Exiled.API.Extensions; + using Exiled.API.Features; + using Exiled.API.Features.Doors; + using Exiled.API.Features.Items; + using Exiled.API.Features.Lockers; + using Exiled.API.Features.Pickups; + using Exiled.Events.EventArgs.Item; + using Exiled.Events.EventArgs.Player; + using UnityEngine; + + /// + /// The Custom keycard base class. + /// + public abstract class CustomKeycard : CustomItem + { + /// + /// Throws if specified is not Keycard. + public override ItemType Type + { + get => base.Type; + set + { + if (!value.IsKeycard()) + throw new ArgumentOutOfRangeException("Type", value, "Invalid keycard type."); + + base.Type = value; + } + } + + /// + /// Gets or sets the permissions for custom keycard. + /// + public virtual KeycardPermissions Permissions { get; set; } + + /// + public override void Give(Player player, Item item, bool displayMessage = true) + { + base.Give(player, item, displayMessage); + + if (item.Is(out Keycard card)) + card.Permissions = Permissions; + } + + /// + public override Pickup? Spawn(Vector3 position, Item item, Player? previousOwner = null) + { + if (item.Is(out Keycard card)) + card.Permissions = Permissions; + + return base.Spawn(position, item, previousOwner); + } + + /// + /// Called when custom keycard interacts with a door. + /// + /// Owner of Custom keycard. + /// Door with which interacting. + protected virtual void OnInteractingDoor(Player player, Door door) + { + } + + /// + /// Called when custom keycard interacts with a locker. + /// + /// Owner of Custom keycard. + /// Chamber with which interacting. + protected virtual void OnInteractingLocker(Player player, Chamber chamber) + { + } + + /// + protected override void SubscribeEvents() + { + base.SubscribeEvents(); + + Exiled.Events.Handlers.Player.InteractingDoor += OnInternalInteractingDoor; + Exiled.Events.Handlers.Player.InteractingLocker += OnInternalInteractingLocker; + Exiled.Events.Handlers.Item.KeycardInteracting += OnInternalKeycardInteracting; + } + + /// + protected override void UnsubscribeEvents() + { + base.UnsubscribeEvents(); + + Exiled.Events.Handlers.Player.InteractingDoor -= OnInternalInteractingDoor; + Exiled.Events.Handlers.Player.InteractingLocker -= OnInternalInteractingLocker; + Exiled.Events.Handlers.Item.KeycardInteracting -= OnInternalKeycardInteracting; + } + + private void OnInternalKeycardInteracting(KeycardInteractingEventArgs ev) + { + if (!Check(ev.Pickup)) + return; + + OnInteractingDoor(ev.Player, ev.Door); + } + + private void OnInternalInteractingDoor(InteractingDoorEventArgs ev) + { + if (!Check(ev.Player.CurrentItem)) + return; + + OnInteractingDoor(ev.Player, ev.Door); + } + + private void OnInternalInteractingLocker(InteractingLockerEventArgs ev) + { + if (!Check(ev.Player.CurrentItem)) + return; + + OnInteractingLocker(ev.Player, ev.InteractingChamber); + } + } +} \ No newline at end of file From 06ff3814e6e39570f71ed4c4d23baa9e433804f3 Mon Sep 17 00:00:00 2001 From: Trevlouw <45270312+Trevlouw@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:03:15 -0500 Subject: [PATCH 06/15] feat: ShadowType (#382) More features for the Light wrapper --- EXILED/Exiled.API/Features/Toys/Light.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/EXILED/Exiled.API/Features/Toys/Light.cs b/EXILED/Exiled.API/Features/Toys/Light.cs index eee626928..9496f6b83 100644 --- a/EXILED/Exiled.API/Features/Toys/Light.cs +++ b/EXILED/Exiled.API/Features/Toys/Light.cs @@ -113,6 +113,15 @@ public LightType LightType set => Base.NetworkLightType = value; } + /// + /// Gets or sets the type of shadows the light casts. + /// + public LightShadows ShadowType + { + get => Base.NetworkShadowType; + set => Base.NetworkShadowType = value; + } + /// /// Creates a new . /// From 49fdfac9f14a1ea0b12eda311aeb84183280217b Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+Misfiy@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:10:02 +0100 Subject: [PATCH 07/15] fix: remove var & fix FF for explosions --- EXILED/Exiled.Events/Patches/Events/Server/Unban.cs | 4 ++-- .../Exiled.Events/Patches/Generic/IndividualFriendlyFire.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs b/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs index 66310a212..7792e7cdd 100644 --- a/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/Unban.cs @@ -86,7 +86,7 @@ private static IEnumerable Transpiler( new(OpCodes.Call, Method(typeof(Handlers.Server), nameof(Handlers.Server.OnUnbanned))), }); - for (var z = 0; z < newInstructions.Count; z++) + for (int z = 0; z < newInstructions.Count; z++) { yield return newInstructions[z]; } @@ -143,7 +143,7 @@ private static IEnumerable BanHandlerTranspiler( // Add label to ldloc.1 addToUnbannedListInstruction.WithLabels(continueLabel); - for (var z = 0; z < newInstructions.Count; z++) + for (int z = 0; z < newInstructions.Count; z++) { yield return newInstructions[z]; } diff --git a/EXILED/Exiled.Events/Patches/Generic/IndividualFriendlyFire.cs b/EXILED/Exiled.Events/Patches/Generic/IndividualFriendlyFire.cs index 17b57d822..bafb4a284 100644 --- a/EXILED/Exiled.Events/Patches/Generic/IndividualFriendlyFire.cs +++ b/EXILED/Exiled.Events/Patches/Generic/IndividualFriendlyFire.cs @@ -99,7 +99,7 @@ public static bool CheckFriendlyFirePlayerRules(Footprint attackerFootprint, Ref // Only check friendlyFire if the FootPrint hasn't changed (Fix for Grenade not dealing damage because it's from a dead player) if (!attackerFootprint.CompareLife(new Footprint(attackerFootprint.Hub))) - return true; + return HitboxIdentity.IsDamageable(attackerFootprint.Role, victimHub.roleManager.CurrentRole.RoleTypeId); // Check if attackerFootprint.Hub or victimHub is null and log debug information if (attackerFootprint.Hub is null || victimHub is null) From 4e7bef578a6e4d3ccc1ddce44cacbb02f5854a84 Mon Sep 17 00:00:00 2001 From: Cosmos Zvezdochkin <66907231+CosmosZvezdo4kin@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:16:53 +0300 Subject: [PATCH 08/15] feat: DroppingAmmo, DroppedAmmo and InteractingDoor (#371) --- .../API/Features/CustomItem.cs | 38 +++++++++++++++++-- .../EventArgs/Player/DroppedAmmoEventArgs.cs | 15 ++++++-- .../EventArgs/Player/DroppingAmmoEventArgs.cs | 17 ++++++--- .../Player/InteractingDoorEventArgs.cs | 20 +++++++++- .../Patches/Events/Player/DroppingAmmo.cs | 11 +++--- .../Patches/Events/Player/InteractingDoor.cs | 3 +- 6 files changed, 83 insertions(+), 21 deletions(-) diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs b/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs index 5eea6969b..40c85b7cf 100644 --- a/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs +++ b/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs @@ -834,7 +834,8 @@ internal bool TryUnregister() protected virtual void SubscribeEvents() { Exiled.Events.Handlers.Player.Dying += OnInternalOwnerDying; - Exiled.Events.Handlers.Player.DroppingItem += OnInternalDropping; + Exiled.Events.Handlers.Player.DroppingItem += OnInternalDroppingItem; + Exiled.Events.Handlers.Player.DroppingAmmo += OnInternalDroppingAmmo; Exiled.Events.Handlers.Player.ChangingItem += OnInternalChanging; Exiled.Events.Handlers.Player.Escaping += OnInternalOwnerEscaping; Exiled.Events.Handlers.Player.PickingUpItem += OnInternalPickingUp; @@ -852,7 +853,8 @@ protected virtual void SubscribeEvents() protected virtual void UnsubscribeEvents() { Exiled.Events.Handlers.Player.Dying -= OnInternalOwnerDying; - Exiled.Events.Handlers.Player.DroppingItem -= OnInternalDropping; + Exiled.Events.Handlers.Player.DroppingItem -= OnInternalDroppingItem; + Exiled.Events.Handlers.Player.DroppingAmmo -= OnInternalDroppingAmmo; Exiled.Events.Handlers.Player.ChangingItem -= OnInternalChanging; Exiled.Events.Handlers.Player.Escaping -= OnInternalOwnerEscaping; Exiled.Events.Handlers.Player.PickingUpItem -= OnInternalPickingUp; @@ -900,10 +902,27 @@ protected virtual void OnOwnerHandcuffing(OwnerHandcuffingEventArgs ev) /// Handles tracking items when they are dropped by a player. /// /// . + protected virtual void OnDroppingItem(DroppingItemEventArgs ev) + { + } + + /// + /// Handles tracking items when they are dropped by a player. + /// + /// . + [Obsolete("Use OnDroppingItem instead.", false)] protected virtual void OnDropping(DroppingItemEventArgs ev) { } + /// + /// Handles tracking when player requests drop of item which equals to the specified by . + /// + /// . + protected virtual void OnDroppingAmmo(DroppingAmmoEventArgs ev) + { + } + /// /// Handles tracking items when they are picked up by a player. /// @@ -1061,12 +1080,25 @@ private void OnInternalOwnerHandcuffing(HandcuffingEventArgs ev) } } - private void OnInternalDropping(DroppingItemEventArgs ev) + private void OnInternalDroppingItem(DroppingItemEventArgs ev) { if (!Check(ev.Item)) return; + OnDroppingItem(ev); + + // TODO: Don't forget to remove this with next update +#pragma warning disable CS0618 OnDropping(ev); +#pragma warning restore CS0618 + } + + private void OnInternalDroppingAmmo(DroppingAmmoEventArgs ev) + { + if (Type != ev.ItemType) + return; + + OnDroppingAmmo(ev); } private void OnInternalPickingUp(PickingUpItemEventArgs ev) diff --git a/EXILED/Exiled.Events/EventArgs/Player/DroppedAmmoEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/DroppedAmmoEventArgs.cs index fe2dacbd9..78d229d08 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/DroppedAmmoEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/DroppedAmmoEventArgs.cs @@ -11,6 +11,7 @@ namespace Exiled.Events.EventArgs.Player using API.Enums; using API.Features; + using Exiled.API.Extensions; using Exiled.API.Features.Pickups; using Interfaces; @@ -27,8 +28,8 @@ public class DroppedAmmoEventArgs : IPlayerEvent /// /// /// - /// - /// + /// + /// /// /// /// @@ -36,14 +37,20 @@ public class DroppedAmmoEventArgs : IPlayerEvent /// /// /// - public DroppedAmmoEventArgs(Player player, AmmoType ammoType, ushort amount, List ammoPickups) + public DroppedAmmoEventArgs(Player player, ItemType itemType, ushort amount, List ammoPickups) { Player = player; - AmmoType = ammoType; + ItemType = itemType; + AmmoType = ItemExtensions.GetAmmoType(itemType); Amount = amount; AmmoPickups = Pickup.Get(ammoPickups); } + /// + /// Gets the type of dropped item instead of . + /// + public ItemType ItemType { get; } + /// /// Gets the type of dropped ammo. /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/DroppingAmmoEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/DroppingAmmoEventArgs.cs index cceb19e75..0b379c903 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/DroppingAmmoEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/DroppingAmmoEventArgs.cs @@ -9,7 +9,7 @@ namespace Exiled.Events.EventArgs.Player { using API.Enums; using API.Features; - + using Exiled.API.Extensions; using Interfaces; using PlayerRoles; @@ -27,8 +27,8 @@ public class DroppingAmmoEventArgs : IPlayerEvent, IDeniableEvent /// /// /// - /// - /// + /// + /// /// /// /// @@ -36,14 +36,21 @@ public class DroppingAmmoEventArgs : IPlayerEvent, IDeniableEvent /// /// /// - public DroppingAmmoEventArgs(Player player, AmmoType ammoType, ushort amount, bool isAllowed = true) + public DroppingAmmoEventArgs(Player player, ItemType itemType, ushort amount, bool isAllowed = true) { Player = player; - AmmoType = ammoType; + ItemType = itemType; + AmmoType = ItemExtensions.GetAmmoType(itemType); Amount = amount; IsAllowed = isAllowed; } + /// + /// Gets the type of item being dropped instead of . + /// For example, if the plugin gives the player one of the items instead of ammo. + /// + public ItemType ItemType { get; } + /// /// Gets the type of ammo being dropped. /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs index 49a5f2049..75eb562f3 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs @@ -9,6 +9,7 @@ namespace Exiled.Events.EventArgs.Player { using API.Features; using Exiled.API.Features.Doors; + using Interactables; using Interactables.Interobjects.DoorUtils; using Interfaces; @@ -26,16 +27,21 @@ public class InteractingDoorEventArgs : IPlayerEvent, IDoorEvent, IDeniableEvent /// /// /// + /// + /// + /// /// /// /// /// /// /// - public InteractingDoorEventArgs(Player player, DoorVariant door, bool isAllowed = true, bool canInteract = true) + public InteractingDoorEventArgs(Player player, DoorVariant door, byte colliderId, bool isAllowed = true, bool canInteract = true) { Player = player; Door = Door.Get(door); + ColliderId = colliderId; + Collider = InteractableCollider.TryGetCollider(door, colliderId, out InteractableCollider interactableCollider) ? interactableCollider : null; IsAllowed = isAllowed; CanInteract = canInteract; } @@ -51,10 +57,20 @@ public InteractingDoorEventArgs(Player player, DoorVariant door, bool isAllowed public bool IsAllowed { get; set; } /// - /// Gets or sets the instance. + /// Gets or sets the instance. /// public Door Door { get; set; } + /// + /// Gets the instance that the player interacted with. + /// + public InteractableCollider Collider { get; } + + /// + /// Gets the ColliderId of that the player interacted with. + /// + public byte ColliderId { get; } + /// /// Gets the player who's interacting with the door. /// diff --git a/EXILED/Exiled.Events/Patches/Events/Player/DroppingAmmo.cs b/EXILED/Exiled.Events/Patches/Events/Player/DroppingAmmo.cs index 63b5e620f..180a0bd11 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/DroppingAmmo.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/DroppingAmmo.cs @@ -50,9 +50,8 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Date: Wed, 8 Jan 2025 12:07:38 +0100 Subject: [PATCH 09/15] fix: DoorType and RoomType for Checkpoint (#379) Fix DoorType and RoomType for Checkpoint --- EXILED/Exiled.API/Features/Doors/Door.cs | 8 +++++++- EXILED/Exiled.API/Features/Room.cs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/EXILED/Exiled.API/Features/Doors/Door.cs b/EXILED/Exiled.API/Features/Doors/Door.cs index 63b4f62ce..c5ba62fac 100644 --- a/EXILED/Exiled.API/Features/Doors/Door.cs +++ b/EXILED/Exiled.API/Features/Doors/Door.cs @@ -627,7 +627,13 @@ private DoorType GetDoorType() // Doors contains the DoorNameTagExtension component "CHECKPOINT_LCZ_A" => DoorType.CheckpointLczA, "CHECKPOINT_LCZ_B" => DoorType.CheckpointLczB, - "CHECKPOINT_EZ_HCZ_A" => DoorType.CheckpointEzHczA, + + // TODO: Remove when it's fix https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/782 + "CHECKPOINT_EZ_HCZ_A" => Room?.Type switch + { + RoomType.HczEzCheckpointA => DoorType.CheckpointEzHczA, + _ => DoorType.CheckpointEzHczB, + }, "CHECKPOINT_EZ_HCZ_B" => DoorType.CheckpointEzHczB, "106_PRIMARY" => DoorType.Scp106Primary, "106_SECONDARY" => DoorType.Scp106Secondary, diff --git a/EXILED/Exiled.API/Features/Room.cs b/EXILED/Exiled.API/Features/Room.cs index 098340fa7..dc880fe69 100644 --- a/EXILED/Exiled.API/Features/Room.cs +++ b/EXILED/Exiled.API/Features/Room.cs @@ -508,12 +508,12 @@ private static RoomType FindType(GameObject gameObject) "EZ_Shelter" => RoomType.EzShelter, "EZ_HCZ_Checkpoint Part" => gameObject.transform.position.z switch { - > 80 => RoomType.EzCheckpointHallwayA, + > 95 => RoomType.EzCheckpointHallwayA, _ => RoomType.EzCheckpointHallwayB, }, "HCZ_EZ_Checkpoint Part" => gameObject.transform.position.z switch { - > 80 => RoomType.HczEzCheckpointA, + > 95 => RoomType.HczEzCheckpointA, _ => RoomType.HczEzCheckpointB }, _ => RoomType.Unknown, From 659a6a86406e3a1d4468a5b9ad237665c22becfc Mon Sep 17 00:00:00 2001 From: Nameless <85962933+Misfiy@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:12:38 +0100 Subject: [PATCH 10/15] feat: CustomStats (#363) * CustomStats * replace Mathf.Clamp01 by Mathf.Clamp * Remove CustomStaminaStat.cs --------- Co-authored-by: Yamato --- .../Exiled.API/Features/CustomHealthStat.cs | 1 + .../CustomStats/CustomHumeShieldStat.cs | 79 +++++++++++++++++++ EXILED/Exiled.API/Features/Player.cs | 24 +++++- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs diff --git a/EXILED/Exiled.API/Features/CustomHealthStat.cs b/EXILED/Exiled.API/Features/CustomHealthStat.cs index af351bf7a..57f6d31c2 100644 --- a/EXILED/Exiled.API/Features/CustomHealthStat.cs +++ b/EXILED/Exiled.API/Features/CustomHealthStat.cs @@ -11,6 +11,7 @@ namespace Exiled.API.Features /// /// A custom version of which allows the player's max amount of health to be changed. + /// TODO: Move to Features.CustomStats. /// public class CustomHealthStat : HealthStat { diff --git a/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs b/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs new file mode 100644 index 000000000..78c4cd807 --- /dev/null +++ b/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs @@ -0,0 +1,79 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features.CustomStats +{ + using Mirror; + using PlayerRoles.PlayableScps.HumeShield; + using PlayerStatsSystem; + using UnityEngine; + using Utils.Networking; + + /// + /// A custom version of which allows the player's max amount of HumeShield to be changed. + /// + public class CustomHumeShieldStat : HumeShieldStat + { + /// + public override float MaxValue => CustomMaxValue == -1 ? base.MaxValue : CustomMaxValue; + + /// + /// Gets or sets the multiplier for gaining HumeShield. + /// + public float ShieldRegenerationMultiplier { get; set; } = 1; + + /// + /// Gets or sets the maximum amount of HumeShield the player can have. + /// + public float CustomMaxValue { get; set; } = -1; + + private float ShieldRegeneration => TryGetHsModule(out HumeShieldModuleBase controller) ? controller.HsRegeneration * ShieldRegenerationMultiplier : 0; + + /// + public override void Update() + { + if (MaxValue == -1 && ShieldRegenerationMultiplier is 1) + { + base.Update(); + return; + } + + if (!NetworkServer.active) + return; + + if (_valueDirty) + { + new SyncedStatMessages.StatMessage() + { + Stat = this, + SyncedValue = CurValue, + }.SendToHubsConditionally(CanReceive); + _lastSent = CurValue; + _valueDirty = false; + } + + if (ShieldRegeneration == 0) + return; + + float delta = ShieldRegeneration * Time.deltaTime; + + if (delta > 0) + { + if (CurValue >= MaxValue) + return; + + CurValue = Mathf.MoveTowards(CurValue, MaxValue, delta); + return; + } + + if (CurValue <= 0) + return; + + CurValue += delta; + } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index 1c1e7fb54..c0bc8f40b 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -19,6 +19,7 @@ namespace Exiled.API.Features using DamageHandlers; using Enums; using Exiled.API.Features.Core.Interfaces; + using Exiled.API.Features.CustomStats; using Exiled.API.Features.Doors; using Exiled.API.Features.Hazards; using Exiled.API.Features.Items; @@ -96,6 +97,7 @@ public class Player : TypeCastObject, IEntity, IWorldSpace private ReferenceHub referenceHub; private CustomHealthStat healthStat; + private CustomHumeShieldStat humeShieldStat; private Role role; /// @@ -177,6 +179,7 @@ private set CameraTransform = value.PlayerCameraReference; value.playerStats._dictionarizedTypes[typeof(HealthStat)] = value.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = healthStat = new CustomHealthStat { Hub = value }; + value.playerStats._dictionarizedTypes[typeof(HumeShieldStat)] = value.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HumeShieldStat))] = humeShieldStat = new CustomHumeShieldStat { Hub = value }; } } @@ -930,6 +933,24 @@ public float HumeShield set => HumeShieldStat.CurValue = value; } + /// + /// Gets or sets the players maximum Hume Shield. + /// + public float MaxHumeShield + { + get => humeShieldStat.MaxValue; + set => humeShieldStat.CustomMaxValue = value; + } + + /// + /// Gets or sets the players multiplier for gaining HumeShield. + /// + public float HumeShieldRegenerationMultiplier + { + get => humeShieldStat.ShieldRegenerationMultiplier; + set => humeShieldStat.ShieldRegenerationMultiplier = value; + } + /// /// Gets a of all active Artificial Health processes on the player. /// @@ -937,8 +958,9 @@ public float HumeShield /// /// Gets the player's . + /// TODO: Change to . /// - public HumeShieldStat HumeShieldStat => ReferenceHub.playerStats.GetModule(); + public HumeShieldStat HumeShieldStat => humeShieldStat; /// /// Gets or sets the item in the player's hand. Value will be if the player is not holding anything. From 1792bc7e4b1281e72cd611a0e80cf87e64cf91bb Mon Sep 17 00:00:00 2001 From: Rysik5318 <72207886+Rysik5318@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:31:45 +0400 Subject: [PATCH 11/15] fix: NPC Spawn using wrong SpawnType (#375) Update Npc.cs --- EXILED/Exiled.API/Features/Npc.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.API/Features/Npc.cs b/EXILED/Exiled.API/Features/Npc.cs index 4055dfa6a..e058efd07 100644 --- a/EXILED/Exiled.API/Features/Npc.cs +++ b/EXILED/Exiled.API/Features/Npc.cs @@ -276,7 +276,7 @@ public static Npc Spawn(string name, RoleTypeId role = RoleTypeId.None, bool ign Timing.CallDelayed(0.5f, () => { - npc.Role.Set(role, SpawnReason.RoundStart, position is null ? RoleSpawnFlags.All : RoleSpawnFlags.AssignInventory); + npc.Role.Set(role, SpawnReason.ForceClass, position is null ? RoleSpawnFlags.All : RoleSpawnFlags.AssignInventory); if (position is not null) npc.Position = position.Value; From 6ae3594fc4da800e5f07ae12674dab47544697a4 Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Tue, 7 Jan 2025 06:15:00 +0300 Subject: [PATCH 12/15] fix: Fix FF for explosions (#383) * fix: nre fix * fix: respawningteam event fix * fix: fix explosion ff From b33f211bf0f20e8a082f3c0e014470742a9feb1d Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Fri, 10 Jan 2025 23:40:58 +0300 Subject: [PATCH 13/15] feat: LockerType extension (#384) * feat: LockerType extension * fix: fix of fix * fix: init fix for play gun sound * Revert "fix: init fix for play gun sound" This reverts commit f4d55418d2f782d46465c9dc7f8153f5fa0c2145. --- EXILED/Exiled.API/Enums/LockerType.cs | 63 +++++++++++++++++++ .../Exiled.API/Extensions/LockerExtensions.cs | 15 ++++- EXILED/Exiled.API/Features/Lockers/Locker.cs | 11 +++- 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/EXILED/Exiled.API/Enums/LockerType.cs b/EXILED/Exiled.API/Enums/LockerType.cs index ca176fb21..b38b592c0 100644 --- a/EXILED/Exiled.API/Enums/LockerType.cs +++ b/EXILED/Exiled.API/Enums/LockerType.cs @@ -7,6 +7,8 @@ namespace Exiled.API.Enums { + using System; + /// /// Unique identifier for different types of s. /// @@ -15,6 +17,7 @@ public enum LockerType /// /// The pedestal used by SCP items. /// + [Obsolete("This value is not used.")] Pedestal, /// @@ -46,5 +49,65 @@ public enum LockerType /// Unknow type of locker. /// Unknow, + + /// + /// MircoHid pedestal. + /// + MicroHid, + + /// + /// Experimental weapon locker. + /// + ExperimentalWeapon, + + /// + /// SCP-500 pedestal. + /// + Scp500Pedestal, + + /// + /// SCP-207? (Anti SCP-207) pedestal. + /// + AntiScp207Pedestal, + + /// + /// SCP-207 pedestal. + /// + Scp207Pedestal, + + /// + /// SCP-268 pedestal. + /// + Scp268Pedestal, + + /// + /// SCP-1344 pedestal. + /// + Scp1344Pedestal, + + /// + /// SCP-018 pedestal. + /// + Scp018Pedestal, + + /// + /// SCP-1576 pedestal. + /// + Scp1576Pedestal, + + /// + /// SCP-244 pedestal. + /// + Scp244Pedestal, + + /// + /// SCP-2176 pedestal. + /// + Scp2176Pedestal, + + /// + /// SCP-1853 pedestal. + /// + Scp1853Pedestal, } } diff --git a/EXILED/Exiled.API/Extensions/LockerExtensions.cs b/EXILED/Exiled.API/Extensions/LockerExtensions.cs index c7c1a78ab..bdf3689bb 100644 --- a/EXILED/Exiled.API/Extensions/LockerExtensions.cs +++ b/EXILED/Exiled.API/Extensions/LockerExtensions.cs @@ -29,14 +29,25 @@ public static class LockerExtensions /// /// The name to check. /// The corresponding . - public static LockerType GetLockerTypeByName(this string name) => name.Replace("(Clone)", string.Empty) switch + public static LockerType GetLockerTypeByName(this string name) => name.Split('(')[0].Trim() switch { - "Scp500PedestalStructure Variant" => LockerType.Pedestal, + "Scp500PedestalStructure Variant" => LockerType.Scp500Pedestal, + "AntiScp207PedestalStructure Variant" => LockerType.AntiScp207Pedestal, + "Scp207PedestalStructure Variant" => LockerType.Scp207Pedestal, + "Experimental Weapon Locker" => LockerType.ExperimentalWeapon, + "Scp1344PedestalStructure Variant" => LockerType.Scp1344Pedestal, + "Scp1576PedestalStructure Variant" => LockerType.Scp1576Pedestal, + "Scp2176PedestalStructure Variant" => LockerType.Scp2176Pedestal, + "Scp1853PedestalStructure Variant" => LockerType.Scp1853Pedestal, + "Scp268PedestalStructure Variant" => LockerType.Scp268Pedestal, + "Scp244PedestalStructure Variant" => LockerType.Scp244Pedestal, + "Scp018PedestalStructure Variant" => LockerType.Scp018Pedestal, "LargeGunLockerStructure" => LockerType.LargeGun, "RifleRackStructure" => LockerType.RifleRack, "MiscLocker" => LockerType.Misc, "RegularMedkitStructure" => LockerType.Medkit, "AdrenalineMedkitStructure" => LockerType.Adrenaline, + "MicroHIDpedestal" => LockerType.MicroHid, _ => LockerType.Unknow, }; } diff --git a/EXILED/Exiled.API/Features/Lockers/Locker.cs b/EXILED/Exiled.API/Features/Lockers/Locker.cs index 739015590..3b5dfe7c1 100644 --- a/EXILED/Exiled.API/Features/Lockers/Locker.cs +++ b/EXILED/Exiled.API/Features/Lockers/Locker.cs @@ -110,7 +110,7 @@ public Vector3 RandomChamberPosition Chamber randomChamber = Chambers.GetRandomValue(); // Determine if the chamber uses multiple spawn points and has at least one available spawn point. - if (randomChamber.UseMultipleSpawnpoints && randomChamber.Spawnpoints.Count() > 0) + if (randomChamber.UseMultipleSpawnpoints && randomChamber.Spawnpoints.Any()) { // Return the position of a random spawn point within the chamber. return randomChamber.Spawnpoints.GetRandomValue().position; @@ -136,11 +136,18 @@ public Vector3 RandomChamberPosition /// The with the given or if not found. public static IEnumerable Get(ZoneType zoneType) => Get(room => room.Zone.HasFlag(zoneType)); + /// + /// Gets an of given the specified . + /// + /// The to search for. + /// An of which contains elements that satisfy the condition. + public static IEnumerable Get(LockerType lockerType) => Get(x => x.Type == lockerType); + /// /// Gets a of filtered based on a predicate. /// /// The condition to satify. - /// A of which contains elements that satify the condition. + /// A of which contains elements that satisfy the condition. public static IEnumerable Get(Func predicate) => List.Where(predicate); /// From 48720bd3b1390ae0bc45b0465e1c7a19d8fb8f27 Mon Sep 17 00:00:00 2001 From: Yamato <66829532+louis1706@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:41:29 +0100 Subject: [PATCH 14/15] feat: Fix OnInternalSpawning & Added ChargingJailbird setter (by BlackSerperior6) (#368) BlackSerperior6 Co-authored-by: BlackSerperior6 <109168410+blackserperior6@users.noreply.github.com> --- EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs | 2 +- .../EventArgs/Item/ChargingJailbirdEventArgs.cs | 6 ++---- EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs | 7 ++++++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs b/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs index b8217fb41..7de3e2eef 100644 --- a/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs +++ b/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs @@ -920,7 +920,7 @@ private void OnInternalChangingNickname(ChangingNicknameEventArgs ev) private void OnInternalSpawning(SpawningEventArgs ev) { - if (!IgnoreSpawnSystem && SpawnChance > 0 && !Check(ev.Player) && ev.Player.Role.Type == Role && Loader.Random.NextDouble() * 100 <= SpawnChance) + if (!IgnoreSpawnSystem && SpawnChance > 0 && !Check(ev.Player) && ev.NewRole == Role && Loader.Random.NextDouble() * 100 <= SpawnChance) AddRole(ev.Player); } diff --git a/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs index 342d4b311..6bb6c9ad6 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs @@ -26,9 +26,7 @@ public ChargingJailbirdEventArgs(ReferenceHub player, InventorySystem.Items.Item { Player = Player.Get(player); Jailbird = (Jailbird)Item.Get(swingItem); -#pragma warning disable CS0618 IsAllowed = isAllowed; -#pragma warning restore CS0618 } /// @@ -47,8 +45,8 @@ public ChargingJailbirdEventArgs(ReferenceHub player, InventorySystem.Items.Item public Item Item => Jailbird; /// - /// Gets a value indicating whether the Jailbird can be charged. + /// Gets or sets a value indicating whether the Jailbird can be charged. /// - public bool IsAllowed { get; } + public bool IsAllowed { get; set; } } } diff --git a/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs b/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs index af13bdffc..8ffa6e06e 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs @@ -88,7 +88,12 @@ private static bool HandleJailbird(JailbirdItem instance, JailbirdMessageType me ChargingJailbirdEventArgs ev = new(instance.Owner, instance); Item.OnChargingJailbird(ev); - return true; + if (ev.IsAllowed) + return true; + + ev.Player.RemoveHeldItem(destroy: false); + ev.Player.AddItem(ev.Item); + return false; } default: From 0ddb6071177fb116fde399a3dec8abce8d6cab37 Mon Sep 17 00:00:00 2001 From: Yamato <66829532+louis1706@users.noreply.github.com> Date: Fri, 10 Jan 2025 23:12:16 +0100 Subject: [PATCH 15/15] feat: `ExplodingGrenadeEventArgs::ExplosionType` (#385) * ExplosionType * ExplodingGrenadeEventArgs::ExplosionType --- .../EventArgs/Map/ExplodingGrenadeEventArgs.cs | 17 ++++++++++++++++- .../Patches/Events/Map/ExplodingFragGrenade.cs | 7 +++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/EXILED/Exiled.Events/EventArgs/Map/ExplodingGrenadeEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Map/ExplodingGrenadeEventArgs.cs index 27b0bc165..7cb2613ce 100644 --- a/EXILED/Exiled.Events/EventArgs/Map/ExplodingGrenadeEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Map/ExplodingGrenadeEventArgs.cs @@ -27,6 +27,8 @@ namespace Exiled.Events.EventArgs.Map /// public class ExplodingGrenadeEventArgs : IPlayerEvent, IDeniableEvent { + private ExplosionType explosionType; + /// /// Initializes a new instance of the class. /// @@ -34,12 +36,14 @@ public class ExplodingGrenadeEventArgs : IPlayerEvent, IDeniableEvent /// /// /// - public ExplodingGrenadeEventArgs(Footprint thrower, Vector3 position, ExplosionGrenade grenade, Collider[] targets) + /// + public ExplodingGrenadeEventArgs(Footprint thrower, Vector3 position, ExplosionGrenade grenade, Collider[] targets, ExplosionType explosionType) { Player = Player.Get(thrower.Hub); Projectile = Pickup.Get(grenade); Position = position; TargetsToAffect = HashSetPool.Pool.Get(); + ExplosionType = explosionType; if (Projectile.Base is not ExplosionGrenade) return; @@ -97,6 +101,7 @@ public ExplodingGrenadeEventArgs(Player thrower, EffectGrenade grenade, HashSet< Player = thrower ?? Server.Host; Projectile = Pickup.Get(grenade); Position = Projectile.Position; + ExplosionType = ExplosionType.Custom; TargetsToAffect = HashSetPool.Pool.Get(targetsToAffect ?? new HashSet()); IsAllowed = isAllowed; } @@ -114,6 +119,16 @@ public ExplodingGrenadeEventArgs(Player thrower, EffectGrenade grenade, HashSet< /// public Vector3 Position { get; } + /// + /// Gets or sets the Explosion type. + /// + /// Explosion that are not from will return and can't be modified. + public ExplosionType ExplosionType + { + get => explosionType; + set => explosionType = Projectile is ExplosionGrenadeProjectile ? value : ExplosionType.Custom; + } + /// /// Gets the players who could be affected by the grenade, if any, and the damage that be dealt. /// diff --git a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs index 37a8bef64..e29c8c621 100644 --- a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs +++ b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs @@ -84,8 +84,11 @@ private static IEnumerable Transpiler(IEnumerable