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);
///
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;
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/EventArgs/Map/ElevatorSequencesUpdatedEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Map/ElevatorSequencesUpdatedEventArgs.cs
new file mode 100644
index 000000000..c2a8fbe9a
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Map/ElevatorSequencesUpdatedEventArgs.cs
@@ -0,0 +1,46 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Map
+{
+ using Exiled.API.Features;
+ using Exiled.Events.EventArgs.Interfaces;
+ using Interactables.Interobjects;
+
+ ///
+ /// Contains all information after an elevator sequence is updated.
+ ///
+ public class ElevatorSequencesUpdatedEventArgs : IExiledEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ public ElevatorSequencesUpdatedEventArgs(ElevatorChamber elevatorChamber, ElevatorChamber.ElevatorSequence sequence)
+ {
+ Elevator = elevatorChamber;
+ Lift = Lift.Get(elevatorChamber);
+ Sequence = sequence;
+ }
+
+ ///
+ /// Gets the elevator chamber that triggered this event.
+ ///
+ public ElevatorChamber Elevator { get; }
+
+ ///
+ /// Gets the lift that triggered this event.
+ ///
+ public Lift Lift { get; }
+
+ ///
+ /// Gets the new sequence of the elevator.
+ ///
+ public ElevatorChamber.ElevatorSequence Sequence { get; }
+ }
+}
\ No newline at end of file
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/Handlers/Map.cs b/EXILED/Exiled.Events/Handlers/Map.cs
index 3036d4ede..00d73e9ba 100644
--- a/EXILED/Exiled.Events/Handlers/Map.cs
+++ b/EXILED/Exiled.Events/Handlers/Map.cs
@@ -55,6 +55,11 @@ public static class Map
///
public static Event Decontaminating { get; set; } = new();
+ ///
+ /// Invoked after an elevator sequence is updated.
+ ///
+ public static Event ElevatorSequencesUpdated { get; set; } = new();
+
///
/// Invoked before a grenade explodes.
///
@@ -91,12 +96,12 @@ public static class Map
public static Event TurningOffLights { get; set; } = new();
///
- /// Invoked after an pickup is spawned.
+ /// Invoked after a pickup is spawned.
///
public static Event PickupAdded { get; set; } = new();
///
- /// Invoked after an pickup is destroyed.
+ /// Invoked after a pickup is destroyed.
///
public static Event PickupDestroyed { get; set; } = new();
@@ -157,6 +162,12 @@ public static class Map
/// The instance.
public static void OnDecontaminating(DecontaminatingEventArgs ev) => Decontaminating.InvokeSafely(ev);
+ ///
+ /// Called after an elevator sequence is updated.
+ ///
+ /// The instance.
+ public static void OnElevatorSequencesUpdated(ElevatorSequencesUpdatedEventArgs ev) => ElevatorSequencesUpdated.InvokeSafely(ev);
+
///
/// Called before a grenade explodes.
///
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:
diff --git a/EXILED/Exiled.Events/Patches/Events/Map/ElevatorSequencesUpdated.cs b/EXILED/Exiled.Events/Patches/Events/Map/ElevatorSequencesUpdated.cs
new file mode 100644
index 000000000..098a5852a
--- /dev/null
+++ b/EXILED/Exiled.Events/Patches/Events/Map/ElevatorSequencesUpdated.cs
@@ -0,0 +1,31 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Patches.Events.Map
+{
+ using Exiled.Events.Attributes;
+ using Exiled.Events.EventArgs.Map;
+ using HarmonyLib;
+ using Interactables.Interobjects;
+
+ ///
+ /// Patches 's setter.
+ /// Adds the event.
+ ///
+ [EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.ElevatorSequencesUpdated))]
+ [HarmonyPatch(typeof(ElevatorChamber), nameof(ElevatorChamber.CurSequence), MethodType.Setter)]
+ internal class ElevatorSequencesUpdated
+ {
+#pragma warning disable SA1313
+ private static void Postfix(ElevatorChamber __instance)
+#pragma warning restore SA1313
+ {
+ ElevatorSequencesUpdatedEventArgs ev = new(__instance, __instance.CurSequence);
+ Handlers.Map.OnElevatorSequencesUpdated(ev);
+ }
+ }
+}
\ No newline at end of file
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