diff --git a/EXILED/Exiled.API/Enums/LockerType.cs b/EXILED/Exiled.API/Enums/LockerType.cs
index b38b592c0a..af62a06cb3 100644
--- a/EXILED/Exiled.API/Enums/LockerType.cs
+++ b/EXILED/Exiled.API/Enums/LockerType.cs
@@ -46,9 +46,15 @@ public enum LockerType
Adrenaline,
///
- /// Unknow type of locker.
+ /// Unknown type of locker.
///
- Unknow,
+ Unknown,
+
+ ///
+ /// Unknown type of locker.
+ ///
+ [Obsolete("Use LockerType.Unknown", true)]
+ Unknow = Unknown,
///
/// MircoHid pedestal.
diff --git a/EXILED/Exiled.API/Extensions/LockerExtensions.cs b/EXILED/Exiled.API/Extensions/LockerExtensions.cs
index bdf3689bbc..4a6466f636 100644
--- a/EXILED/Exiled.API/Extensions/LockerExtensions.cs
+++ b/EXILED/Exiled.API/Extensions/LockerExtensions.cs
@@ -48,7 +48,7 @@ public static class LockerExtensions
"RegularMedkitStructure" => LockerType.Medkit,
"AdrenalineMedkitStructure" => LockerType.Adrenaline,
"MicroHIDpedestal" => LockerType.MicroHid,
- _ => LockerType.Unknow,
+ _ => LockerType.Unknown,
};
}
}
diff --git a/EXILED/Exiled.API/Features/Lockers/Chamber.cs b/EXILED/Exiled.API/Features/Lockers/Chamber.cs
index 1b499294ae..af4fba905d 100644
--- a/EXILED/Exiled.API/Features/Lockers/Chamber.cs
+++ b/EXILED/Exiled.API/Features/Lockers/Chamber.cs
@@ -16,6 +16,7 @@ namespace Exiled.API.Features.Lockers
using Exiled.API.Extensions;
using Exiled.API.Features.Pickups;
using Exiled.API.Interfaces;
+ using InventorySystem.Items.Pickups;
using MapGeneration.Distributors;
using UnityEngine;
@@ -188,6 +189,56 @@ public bool IsOpen
///
public bool CanInteract => Base.CanInteract;
+ ///
+ /// Adds an item to the current chamber.
+ ///
+ /// The pickup to add.
+ public void AddItem(Pickup item)
+ {
+ Transform parent = UseMultipleSpawnpoints && Spawnpoints.Any()
+ ? Spawnpoints.GetRandomValue()
+ : Spawnpoint;
+
+ if (IsOpen)
+ {
+ item.Transform.SetParent(parent);
+
+ if (!item.IsSpawned)
+ item.Spawn();
+
+ return;
+ }
+
+ // If the item is already spawned on the network, unspawn it before proceeding.
+ if (item.IsSpawned)
+ item.UnSpawn();
+
+ // Set the item's parent transform.
+ item.Transform.SetParent(parent);
+
+ // Lock the item in place.
+ item.IsLocked = true;
+
+ // Notify any pickup distributor triggers.
+ (item.Base as IPickupDistributorTrigger)?.OnDistributed();
+
+ // If the item has a Rigidbody component, make it kinematic and reset its position and rotation.
+ if (item.Rigidbody != null)
+ {
+ item.Rigidbody.isKinematic = true;
+ item.Rigidbody.transform.localPosition = Vector3.zero;
+ item.Rigidbody.transform.localRotation = Quaternion.identity;
+
+ // Add the Rigidbody to the list of bodies to be unfrozen later.
+ SpawnablesDistributorBase.BodiesToUnfreeze.Add(item.Rigidbody);
+ }
+
+ Base.Content.Add(item.Base);
+ item.Spawn();
+ if (Base._wasEverOpened)
+ item.IsLocked = false;
+ }
+
///
/// Spawns a specified item from .
///
diff --git a/EXILED/Exiled.API/Features/Lockers/Locker.cs b/EXILED/Exiled.API/Features/Lockers/Locker.cs
index 653e432d2f..8c7f801d25 100644
--- a/EXILED/Exiled.API/Features/Lockers/Locker.cs
+++ b/EXILED/Exiled.API/Features/Lockers/Locker.cs
@@ -156,11 +156,11 @@ public Vector3 RandomChamberPosition
/// The to filter by. If unspecified, all zones are considered.
/// The to filter by. If unspecified, all locker types are considered.
/// A random object, or if no matching locker is found.
- public static Locker? Random(ZoneType zone = ZoneType.Unspecified, LockerType lockerType = LockerType.Unknow)
+ public static Locker? Random(ZoneType zone = ZoneType.Unspecified, LockerType lockerType = LockerType.Unknown)
{
IEnumerable filteredLockers = List;
- if (lockerType != LockerType.Unknow)
+ if (lockerType != LockerType.Unknown)
filteredLockers = filteredLockers.Where(l => l.Type == lockerType);
if (zone != ZoneType.Unspecified)
@@ -173,58 +173,7 @@ public Vector3 RandomChamberPosition
/// Adds an item to a randomly selected locker chamber.
///
/// The to be added to the locker chamber.
- public void AddItem(Pickup item)
- {
- // Select a random chamber from the available locker chambers.
- Chamber chamber = Chambers.GetRandomValue();
-
- // Determine the parent transform where the item will be placed.
- Transform parentTransform = chamber.UseMultipleSpawnpoints && chamber.Spawnpoints.Any()
- ? chamber.Spawnpoints.GetRandomValue()
- : chamber.Spawnpoint;
-
- // If the chamber is open, immediately set the item's parent and spawn it.
- if (chamber.IsOpen)
- {
- item.Transform.SetParent(parentTransform);
-
- if(!item.IsSpawned)
- item.Spawn();
- }
- else
- {
- // If the item is already spawned on the network, unspawn it before proceeding.
- if (item.IsSpawned)
- item.UnSpawn();
-
- // Set the item's parent transform.
- item.Transform.SetParent(parentTransform);
-
- // Lock the item in place.
- item.IsLocked = true;
-
- // Notify any pickup distributor triggers.
- (item.Base as IPickupDistributorTrigger)?.OnDistributed();
-
- // If the item has a Rigidbody component, make it kinematic and reset its position and rotation.
- if (item.Rigidbody != null)
- {
- item.Rigidbody.isKinematic = true;
- item.Rigidbody.transform.localPosition = Vector3.zero;
- item.Rigidbody.transform.localRotation = Quaternion.identity;
-
- // Add the Rigidbody to the list of bodies to be unfrozen later.
- SpawnablesDistributorBase.BodiesToUnfreeze.Add(item.Rigidbody);
- }
-
- // If the chamber is configured to spawn items on the first opening, add the item to the list of items to be spawned.
- // Otherwise, spawn the item immediately.
- if (chamber.InitiallySpawn)
- chamber.Base._toBeSpawned.Add(item.Base);
- else
- ItemDistributor.SpawnPickup(item.Base);
- }
- }
+ public void AddItem(Pickup item) => Chambers.GetRandomValue().AddItem(item);
///
/// Spawns an item of the specified to the locker by creating a new .
diff --git a/EXILED/Exiled.API/Features/Spawn/LockerSpawnPoint.cs b/EXILED/Exiled.API/Features/Spawn/LockerSpawnPoint.cs
index ad0019ce48..41ff71695e 100644
--- a/EXILED/Exiled.API/Features/Spawn/LockerSpawnPoint.cs
+++ b/EXILED/Exiled.API/Features/Spawn/LockerSpawnPoint.cs
@@ -4,12 +4,13 @@
// Licensed under the CC BY-SA 3.0 license.
//
// -----------------------------------------------------------------------
+
namespace Exiled.API.Features.Spawn
{
using System;
- using System.Linq;
using Exiled.API.Enums;
+ using Exiled.API.Extensions;
using Exiled.API.Features.Lockers;
using UnityEngine;
using YamlDotNet.Serialization;
@@ -38,7 +39,7 @@ public class LockerSpawnPoint : SpawnPoint
///
/// Gets or sets the type of the .
///
- public LockerType Type { get; set; } = LockerType.Unknow;
+ public LockerType Type { get; set; } = LockerType.Unknown;
///
public override float Chance { get; set; }
@@ -57,16 +58,25 @@ public override Vector3 Position
{
get
{
- Locker foundLocker = Locker.Random(Zone, Type) ?? throw new NullReferenceException("No locker found in the specified zone.");
-
- // If UseChamber is true, use a random chamber's position.
- if (UseChamber)
- return foundLocker.RandomChamberPosition;
-
- // Otherwise, use the Offset if provided, or the locker's position.
- return Offset != Vector3.zero ? foundLocker.Transform.TransformPoint(Offset) : foundLocker.Position;
+ GetSpawningInfo(out _, out _, out Vector3 position);
+ return position;
}
set => throw new InvalidOperationException("The position of this type of SpawnPoint cannot be changed.");
}
+
+ ///
+ /// Gets the spawn info.
+ ///
+ /// The locker to spawn in.
+ /// The chamber to spawn in. Null when is false.
+ /// The position to spawn in.
+ /// No locker was found.
+ #nullable enable
+ public void GetSpawningInfo(out Locker locker, out Chamber? chamber, out Vector3 position)
+ {
+ locker = Locker.Random(Zone, Type) ?? throw new NullReferenceException($"No locker found of type {Type} in {Zone}.");
+ chamber = UseChamber ? locker.Chambers.GetRandomValue() : null;
+ position = chamber?.GetRandomSpawnPoint() ?? (Offset == Vector3.zero ? locker.Position : locker.Transform.TransformPoint(Offset));
+ }
}
}
diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs b/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs
index 8aff47f913..356f701c0a 100644
--- a/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs
+++ b/EXILED/Exiled.CustomItems/API/Features/CustomItem.cs
@@ -17,6 +17,7 @@ namespace Exiled.CustomItems.API.Features
using Exiled.API.Extensions;
using Exiled.API.Features;
using Exiled.API.Features.Attributes;
+ using Exiled.API.Features.Lockers;
using Exiled.API.Features.Pickups;
using Exiled.API.Features.Pools;
using Exiled.API.Features.Spawn;
@@ -25,15 +26,10 @@ namespace Exiled.CustomItems.API.Features
using Exiled.Events.EventArgs.Player;
using Exiled.Events.EventArgs.Scp914;
using Exiled.Loader;
-
using InventorySystem.Items.Pickups;
-
using MEC;
-
using PlayerRoles;
-
using UnityEngine;
-
using YamlDotNet.Serialization;
using static CustomItems;
@@ -578,86 +574,35 @@ public virtual uint Spawn(IEnumerable spawnPoints, uint limit)
if (Loader.Random.NextDouble() * 100 >= spawnPoint.Chance || (limit > 0 && spawned >= limit))
continue;
- spawned++;
-
- /*if (spawnPoint is DynamicSpawnPoint dynamicSpawnPoint && dynamicSpawnPoint.Location == SpawnLocationType.InsideLocker)
+ Pickup? pickup;
+ if (spawnPoint is LockerSpawnPoint { UseChamber: true } lockerSpawnPoint)
{
- for (int i = 0; i < 50; i++)
+ try
{
- if (Exiled.API.Features.Lockers.Locker.List is null)
- {
- Log.Debug($"{nameof(Spawn)}: Locker list is null.");
- continue;
- }
-
- Locker locker = Exiled.API.Features.Lockers.Locker.Random();
-
- if (locker is null)
- {
- Log.Debug($"{nameof(Spawn)}: Selected locker is null.");
- continue;
- }
-
- if (locker.Loot is null)
- {
- Log.Debug($"{nameof(Spawn)}: Invalid locker location. Attempting to find a new one..");
- continue;
- }
-
- if (locker.Chambers is null)
- {
- Log.Debug($"{nameof(Spawn)}: Locker chambers is null");
- continue;
- }
-
- LockerChamber chamber = locker.Chambers[Loader.Random.Next(Mathf.Max(0, locker.Chambers.Length - 1))];
-
- if (chamber is null)
- {
- Log.Debug($"{nameof(Spawn)}: chamber is null");
- continue;
- }
-
- Vector3 position = chamber._spawnpoint.transform.position;
-
- Pickup? pickup = Spawn(position, null);
- if (pickup?.Base is BaseFirearmPickup firearmPickup && this is CustomWeapon customWeapon)
- {
- firearmPickup.Status = new FirearmStatus(customWeapon.ClipSize, firearmPickup.Status.Flags, firearmPickup.Status.Attachments);
- firearmPickup.NetworkStatus = firearmPickup.Status;
- }
-
- Log.Debug($"Spawned {Name} at {position} ({spawnPoint.Name})");
- break;
+ lockerSpawnPoint.GetSpawningInfo(out _, out Chamber? chamber, out Vector3 position);
+ pickup = Spawn(position);
+ chamber?.AddItem(pickup);
+ }
+ catch (Exception e)
+ {
+ Log.Error($"CustomItem {Name}({Id} failed to spawn: {e.Message})");
+ continue;
}
}
else
{
- Pickup? pickup = Spawn(spawnPoint.Position, null);
- if (pickup?.Base is BaseFirearmPickup firearmPickup && this is CustomWeapon customWeapon)
- {
- firearmPickup.Status = new FirearmStatus(customWeapon.ClipSize, firearmPickup.Status.Flags, firearmPickup.Status.Attachments);
- firearmPickup.NetworkStatus = firearmPickup.Status;
- }
-
- Log.Debug($"Spawned {Name} at {spawnPoint.Position} ({spawnPoint.Name})");
- }*/
-
- Pickup? pickup = Spawn(spawnPoint.Position);
+ pickup = Spawn(spawnPoint.Position);
+ }
if (pickup == null)
continue;
- if (spawnPoint is LockerSpawnPoint { UseChamber: true } lockerSpawnPoint)
- {
- Exiled.API.Features.Lockers.Locker? foundLocker = Exiled.API.Features.Lockers.Locker.Random(lockerSpawnPoint.Zone, lockerSpawnPoint.Type);
- foundLocker?.AddItem(pickup);
- }
+ spawned++;
- if (pickup.Is(out Exiled.API.Features.Pickups.FirearmPickup firearmPickup) && this is CustomWeapon customWeapon)
+ /*if (pickup.Is(out FirearmPickup firearmPickup) && this is CustomWeapon customWeapon)
{
- // set MaxAmmo if synced TODO
- }
+ // TODO: Set MaxAmmo (if synced)
+ }*/
}
return spawned;