diff --git a/NwPluginAPI/Core/Items/ItemPickup.cs b/NwPluginAPI/Core/Items/ItemPickup.cs index 2da60da..85f8eff 100644 --- a/NwPluginAPI/Core/Items/ItemPickup.cs +++ b/NwPluginAPI/Core/Items/ItemPickup.cs @@ -7,11 +7,17 @@ namespace PluginAPI.Core.Items using Core; using System.Collections.Generic; using UnityEngine; + using PluginAPI.Core.Zones; + using MapGeneration; public class ItemPickup { private static readonly Dictionary CachedItems = new Dictionary(); - private PickupStandardPhysics _pickupStandardPhysics; + private PickupStandardPhysics? _pickupStandardPhysics; + + // This values are from ItemPickupBase + private const float MinimalPickupTime = 0.245f; + private const float WeightToTime = 0.175f; /// /// The base-game object. @@ -26,7 +32,7 @@ public class ItemPickup /// /// Gets the pickup's previous owner. /// - public Player LastOwner => OriginalObject.PreviousOwner.Hub != null ? Player.Get(OriginalObject.PreviousOwner.Hub) : null; + public Player? LastOwner => OriginalObject.PreviousOwner.Hub != null ? Player.Get(OriginalObject.PreviousOwner.Hub) : null; /// /// Gets the pickup's serial. @@ -51,15 +57,24 @@ public bool IsLocked set => OriginalObject.Info.Locked = value; } + /// + /// Gets or sets whether the item pickup is currently in use. + /// + /// True if the item pickup is in use; otherwise, false. + public bool InUse + { + get => OriginalObject.Info.InUse; + set => OriginalObject.Info.InUse = value; + } + /// /// Gets the pickup's . /// - public PickupStandardPhysics PickupStandardPhysics + public PickupStandardPhysics? PickupStandardPhysics { get { - if (_pickupStandardPhysics == null) - _pickupStandardPhysics = OriginalObject.PhysicsModule as PickupStandardPhysics; + _pickupStandardPhysics ??= (PickupStandardPhysics)OriginalObject.PhysicsModule; return _pickupStandardPhysics; } } @@ -67,7 +82,7 @@ public PickupStandardPhysics PickupStandardPhysics /// /// Gets the pickup's . /// - public Rigidbody Rigidbody => PickupStandardPhysics.Rb; + public Rigidbody? Rigidbody => PickupStandardPhysics?.Rb; /// /// Gets the pickup's . @@ -80,15 +95,83 @@ public PickupStandardPhysics PickupStandardPhysics public GameObject GameObject => OriginalObject.gameObject; /// - /// Gets the pickup's position. + /// Gets or sets the pickup's position. + /// + public Vector3 Position + { + get => OriginalObject.Position; + set => OriginalObject.Position = value; + } + + /// + /// Gets or sets the rotation of the pickup. /// - public Vector3 Position => Transform.position; + /// The rotation of the item pickup as a . + public Quaternion Rotation + { + get => OriginalObject.Rotation; + set => OriginalObject.Rotation = value; + } /// - /// Gets the pickup's rotation. + /// Gets or sets the scale of the pickup. /// - public Quaternion Rotation => Transform.rotation; + /// The scale of the pickup as a . + public Vector3 Scale + { + get => OriginalObject.transform.localScale; + set + { + // If the provided scale matches the current scale, no action is taken. + if (value == OriginalObject.transform.localScale) + return; + + // If the object has not been spawned on the network, set the scale directly. + if (!NetworkServer.spawned.ContainsKey(OriginalObject.netId)) + { + OriginalObject.transform.localScale = value; + } + else + { + // Unspawn the item pickup, set the scale, and then spawn it again. + UnSpawn(); + OriginalObject.transform.localScale = value; + Spawn(); + } + } + } + /// + /// Gets or sets the time it takes to pick up this pickup based on its weight. + /// + /// The pickup time in seconds. + public float PickupTime + { + get => MinimalPickupTime + (WeightToTime * Weight); + set => Weight = MinimalPickupTime - (WeightToTime / value); + } + + /// + /// Gets the time it takes to pick up this item for a specific . + /// + /// The attempting to pick up the item. + /// The pickup time in seconds for the specified player. + public float PickupTimeForPlayer(Player player) + { + return OriginalObject.SearchTimeForPlayer(player.ReferenceHub); + } + + /// + /// Gets the room in which this item pickup is located. + /// + /// The representing the room or null if not found. + public RoomIdentifier? Room => RoomIdUtils.RoomAtPositionRaycasts(Position); + + /// + /// Gets an existing associated with the given or adds a new one if not found. + /// + /// The to look up or add. + /// The existing or newly created associated with the input item. private static ItemPickup GetOrAdd(ItemPickupBase item) { if (CachedItems.TryGetValue(item.Info.Serial, out ItemPickup it)) @@ -99,9 +182,15 @@ private static ItemPickup GetOrAdd(ItemPickupBase item) return newItem; } + /// + /// Removes an existing associated with the given . + /// + /// The to remove from the cache. + /// True if an associated was found and removed; otherwise, false. public static bool Remove(ItemPickupBase item) { - if (!CachedItems.TryGetValue(item.Info.Serial, out ItemPickup it)) return false; + if (!CachedItems.TryGetValue(item.Info.Serial, out _)) + return false; return CachedItems.Remove(item.Info.Serial); } @@ -113,12 +202,12 @@ public static bool Remove(ItemPickupBase item) /// The position. /// The rotation. /// The created . - public static ItemPickup Create(ItemType item, Vector3 position, Quaternion rotation) + public static ItemPickup? Create(ItemType item, Vector3 position, Quaternion rotation = default) { if (item == ItemType.None || !InventoryItemLoader.AvailableItems.TryGetValue(item, out ItemBase ib)) return null; - PickupSyncInfo syncInfo = new PickupSyncInfo() + PickupSyncInfo syncInfo = new() { ItemId = item, Serial = ItemSerialGenerator.GenerateNext(), @@ -126,10 +215,60 @@ public static ItemPickup Create(ItemType item, Vector3 position, Quaternion rota }; ItemPickupBase newPickup = InventoryExtensions.ServerCreatePickup(ib, syncInfo, position, rotation, false); + return GetOrAdd(newPickup); + } + + /// + /// Creates a new and spawns it. + /// + /// The of the item. + /// The position where the pickup should be created. + /// The rotation of the pickup (optional). + /// The created and spawned if successful, otherwise null. + public static ItemPickup? CreateAndSpawn(ItemType type, Vector3 position, Quaternion rotation = default) + { + var pickup = Create(type, position, rotation); + pickup?.Spawn(); + return pickup; + } + + /// + /// Creates a new . + /// + /// The of the item. + /// The position where the pickup should be created. + /// Additional pickup information. + /// The rotation of the pickup (optional). + /// The created if successful, otherwise null. + public static ItemPickup? Create(ItemType type, Vector3 position, PickupSyncInfo pickupInfo) + { + if (type == ItemType.None || !InventoryItemLoader.AvailableItems.TryGetValue(type, out ItemBase ib)) + return null; + + if(pickupInfo.Serial == 0 || pickupInfo.ItemId == ItemType.None) + return null; + + ItemPickupBase newPickup = InventoryExtensions.ServerCreatePickup(ib, pickupInfo, position, false); return GetOrAdd(newPickup); } + /// + /// Creates a clone of the current with a new serial. + /// + /// The cloned . + public ItemPickup? Clone() + { + PickupSyncInfo newInfo = new() + { + ItemId = Type, + Serial = ItemSerialGenerator.GenerateNext(), + WeightKg = Weight + }; + + return Create(Type, Position, newInfo); + } + /// /// Spawns the pickup. /// @@ -138,6 +277,14 @@ public void Spawn() NetworkServer.Spawn(GameObject); } + /// + /// Unspawn the pickup. + /// + public void UnSpawn() + { + NetworkServer.UnSpawn(GameObject); + } + /// /// Destroys the pickup. /// @@ -146,9 +293,19 @@ public void Destroy() OriginalObject.DestroySelf(); } + /// + /// Initializes a new instance of the class based on an existing . + /// + /// The original to associate with this . public ItemPickup(ItemPickupBase item) { OriginalObject = item; } + + /// + /// Returns a string representation of the item pickup, including important related data. + /// + /// A string containing information about the item pickup. + public override string ToString() => $"{Type} - {Serial} | {Weight} - *{Scale}* | {Position} | {IsLocked} - {InUse}"; } } \ No newline at end of file diff --git a/NwPluginAPI/Core/Map.cs b/NwPluginAPI/Core/Map.cs index 2ea0f5a..89ee5c5 100644 --- a/NwPluginAPI/Core/Map.cs +++ b/NwPluginAPI/Core/Map.cs @@ -112,7 +112,7 @@ public static DecontaminationController.DecontaminationStatus DecontaminationSta #region Facility rooms tools - #region GetRandomRoom + #region Get random room /// /// Get a random room from the specified zone. @@ -129,7 +129,7 @@ public static RoomIdentifier GetRandomRoom(FacilityZone zone) #endregion - #region Light Flicker + #region Light flicker /// /// Turns off the lights in the specified zone, for a period of time. @@ -173,7 +173,7 @@ public static void FlickerAllLights(float duration) #endregion - #region Turn On Lights + #region Turn on lights /// /// Turn on all the lights on the map @@ -223,7 +223,10 @@ public static void ChangeColorOfAllLights(Color color) { foreach (var controller in RoomLightController.Instances) { + // this is only for save the default color. controller.Room.ApiRoom.Lights.LightColor = color; + + controller.NetworkOverrideColor = color; } } @@ -236,8 +239,10 @@ public static void ChangeColorOfLights(Color color, FacilityZone zone) { if (controller.Room.Zone != zone) continue; - + // this is only for save the default color. controller.Room.ApiRoom.Lights.LightColor = color; + + controller.NetworkOverrideColor = color; } } @@ -264,7 +269,7 @@ public static void ResetColorOfAllLights() foreach (var controller in RoomLightController.Instances) { if (controller.Room.ApiRoom.Lights.LightColor != controller.Room.ApiRoom.Lights.DefaultColor) - controller.Room.ApiRoom.Lights.LightColor = controller.Room.ApiRoom.Lights.DefaultColor; + controller.NetworkOverrideColor = controller.Room.ApiRoom.Lights.DefaultColor; } } @@ -279,7 +284,7 @@ public static void ResetColorOfLights(FacilityZone zone) if (controller.Room.Zone != zone) continue; if (controller.Room.ApiRoom.Lights.LightColor != controller.Room.ApiRoom.Lights.DefaultColor) - controller.Room.ApiRoom.Lights.LightColor = controller.Room.ApiRoom.Lights.DefaultColor; + controller.NetworkOverrideColor = controller.Room.ApiRoom.Lights.DefaultColor; } } diff --git a/NwPluginAPI/NwPluginAPI.csproj b/NwPluginAPI/NwPluginAPI.csproj index 8e97608..0528bc9 100644 --- a/NwPluginAPI/NwPluginAPI.csproj +++ b/NwPluginAPI/NwPluginAPI.csproj @@ -4,6 +4,7 @@ net48 x64 Library + Enable PluginAPI PluginAPI