Storage Standardization [Take 2] (#21270)

This commit is contained in:
Nemanja
2023-10-30 23:55:55 -04:00
committed by GitHub
parent 2c5ea97d9a
commit 0c329ed661
240 changed files with 1365 additions and 1275 deletions

View File

@@ -1,10 +1,11 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.ActionBlocker;
using Content.Shared.CombatMode;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Destructible;
using Content.Shared.DoAfter;
using Content.Shared.Hands;
using Content.Shared.FixedPoint;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Implants.Components;
@@ -46,6 +47,8 @@ public abstract class SharedStorageSystem : EntitySystem
private EntityQuery<StackComponent> _stackQuery;
private EntityQuery<TransformComponent> _xformQuery;
public const ItemSize DefaultStorageMaxItemSize = ItemSize.Normal;
/// <inheritdoc />
public override void Initialize()
{
@@ -89,6 +92,7 @@ public abstract class SharedStorageSystem : EntitySystem
{
// TODO: I had this.
// We can get states being applied before the container is ready.
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (component.Container == default)
return;
@@ -229,7 +233,7 @@ public abstract class SharedStorageSystem : EntitySystem
return;
}
if (TryComp<TransformComponent>(uid, out var transformOwner) && TryComp<TransformComponent>(target, out var transformEnt))
if (_xformQuery.TryGetComponent(uid, out var transformOwner) && TryComp<TransformComponent>(target, out var transformEnt))
{
var parent = transformOwner.ParentUid;
@@ -239,7 +243,7 @@ public abstract class SharedStorageSystem : EntitySystem
_transform
);
if (PlayerInsertEntityInWorld(uid, args.User, target, storageComp))
if (PlayerInsertEntityInWorld((uid, storageComp), args.User, target))
{
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(GetNetEntity(uid),
new List<NetEntity> { GetNetEntity(target) },
@@ -285,7 +289,7 @@ public abstract class SharedStorageSystem : EntitySystem
var angle = targetXform.LocalRotation;
if (PlayerInsertEntityInWorld(uid, args.Args.User, entity, component))
if (PlayerInsertEntityInWorld((uid, component), args.Args.User, entity))
{
successfullyInserted.Add(entity);
successfullyInsertedPositions.Add(position);
@@ -322,7 +326,7 @@ public abstract class SharedStorageSystem : EntitySystem
/// </summary>
private void OnInteractWithItem(EntityUid uid, StorageComponent storageComp, StorageInteractWithItemEvent args)
{
if (args.Session.AttachedEntity is not EntityUid player)
if (args.Session.AttachedEntity is not { } player)
return;
var entity = GetEntity(args.InteractedItemUID);
@@ -396,27 +400,16 @@ public abstract class SharedStorageSystem : EntitySystem
public void RecalculateStorageUsed(EntityUid uid, StorageComponent storageComp)
{
storageComp.StorageUsed = 0;
foreach (var entity in storageComp.Container.ContainedEntities)
if (storageComp.MaxSlots == null)
{
if (!_itemQuery.TryGetComponent(entity, out var itemComp))
continue;
var size = itemComp.Size;
storageComp.StorageUsed += size;
_appearance.SetData(uid, StorageVisuals.StorageUsed, GetCumulativeItemSizes(uid, storageComp));
_appearance.SetData(uid, StorageVisuals.Capacity, storageComp.MaxTotalWeight);
}
else
{
_appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.Container.ContainedEntities.Count);
_appearance.SetData(uid, StorageVisuals.Capacity, storageComp.MaxSlots.Value);
}
_appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.StorageUsed);
_appearance.SetData(uid, StorageVisuals.Capacity, storageComp.StorageCapacityMax);
}
public int GetAvailableSpace(EntityUid uid, StorageComponent? component = null)
{
if (!Resolve(uid, ref component))
return 0;
return component.StorageCapacityMax - component.StorageUsed;
}
/// <summary>
@@ -449,17 +442,20 @@ public abstract class SharedStorageSystem : EntitySystem
/// Verifies if an entity can be stored and if it fits
/// </summary>
/// <param name="uid">The entity to check</param>
/// <param name="insertEnt"></param>
/// <param name="reason">If returning false, the reason displayed to the player</param>
/// <param name="storageComp"></param>
/// <param name="item"></param>
/// <returns>true if it can be inserted, false otherwise</returns>
public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null)
public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null, ItemComponent? item = null)
{
if (!Resolve(uid, ref storageComp))
if (!Resolve(uid, ref storageComp) || !Resolve(insertEnt, ref item))
{
reason = null;
return false;
}
if (TryComp(insertEnt, out TransformComponent? transformComp) && transformComp.Anchored)
if (Transform(insertEnt).Anchored)
{
reason = "comp-storage-anchored-failure";
return false;
@@ -477,15 +473,28 @@ public abstract class SharedStorageSystem : EntitySystem
return false;
}
if (TryComp(insertEnt, out StorageComponent? storage) &&
storage.StorageCapacityMax >= storageComp.StorageCapacityMax)
if (item.Size > GetMaxItemSize((uid, storageComp)))
{
reason = "comp-storage-insufficient-capacity";
reason = "comp-storage-too-big";
return false;
}
if (TryComp(insertEnt, out ItemComponent? itemComp) &&
itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed)
if (TryComp<StorageComponent>(insertEnt, out var insertStorage)
&& GetMaxItemSize((insertEnt, insertStorage)) >= GetMaxItemSize((uid, storageComp)))
{
reason = "comp-storage-too-big";
return false;
}
if (storageComp.MaxSlots != null)
{
if (storageComp.Container.ContainedEntities.Count >= storageComp.MaxSlots)
{
reason = "comp-storage-insufficient-capacity";
return false;
}
}
else if (SharedItemSystem.GetItemSizeWeight(item.Size) + GetCumulativeItemSizes(uid, storageComp) > storageComp.MaxTotalWeight)
{
reason = "comp-storage-insufficient-capacity";
return false;
@@ -499,11 +508,34 @@ public abstract class SharedStorageSystem : EntitySystem
/// Inserts into the storage container
/// </summary>
/// <returns>true if the entity was inserted, false otherwise</returns>
public bool Insert(EntityUid uid, EntityUid insertEnt, out EntityUid? stackedEntity, EntityUid? user = null, StorageComponent? storageComp = null, bool playSound = true)
public bool Insert(
EntityUid uid,
EntityUid insertEnt,
out EntityUid? stackedEntity,
EntityUid? user = null,
StorageComponent? storageComp = null,
bool playSound = true)
{
return Insert(uid, insertEnt, out stackedEntity, out _, user: user, storageComp: storageComp, playSound: playSound);
}
/// <summary>
/// Inserts into the storage container
/// </summary>
/// <returns>true if the entity was inserted, false otherwise</returns>
public bool Insert(
EntityUid uid,
EntityUid insertEnt,
out EntityUid? stackedEntity,
out string? reason,
EntityUid? user = null,
StorageComponent? storageComp = null,
bool playSound = true)
{
stackedEntity = null;
reason = null;
if (!Resolve(uid, ref storageComp) || !CanInsert(uid, insertEnt, out _, storageComp))
if (!Resolve(uid, ref storageComp) || !CanInsert(uid, insertEnt, out reason, storageComp))
return false;
/*
@@ -542,8 +574,7 @@ public abstract class SharedStorageSystem : EntitySystem
if (insertStack.Count > 0)
{
// Try to insert it as a new stack.
if (TryComp(insertEnt, out ItemComponent? itemComp) &&
itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed ||
if (!CanInsert(uid, insertEnt, out _, storageComp) ||
!storageComp.Container.Insert(insertEnt))
{
// If we also didn't do any stack fills above then just end
@@ -568,7 +599,9 @@ public abstract class SharedStorageSystem : EntitySystem
/// <summary>
/// Inserts an entity into storage from the player's active hand
/// </summary>
/// <param name="uid"></param>
/// <param name="player">The player to insert an entity from</param>
/// <param name="storageComp"></param>
/// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertHeldEntity(EntityUid uid, EntityUid player, StorageComponent? storageComp = null)
{
@@ -589,21 +622,23 @@ public abstract class SharedStorageSystem : EntitySystem
return false;
}
return PlayerInsertEntityInWorld(uid, player, toInsert.Value, storageComp);
return PlayerInsertEntityInWorld((uid, storageComp), player, toInsert.Value);
}
/// <summary>
/// Inserts an Entity (<paramref name="toInsert"/>) in the world into storage, informing <paramref name="player"/> if it fails.
/// <paramref name="toInsert"/> is *NOT* held, see <see cref="PlayerInsertHeldEntity(Robust.Shared.GameObjects.EntityUid)"/>.
/// <paramref name="toInsert"/> is *NOT* held, see <see cref="PlayerInsertHeldEntity(EntityUid,EntityUid,StorageComponent)"/>.
/// </summary>
/// <param name="uid"></param>
/// <param name="player">The player to insert an entity with</param>
/// <param name="toInsert"></param>
/// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertEntityInWorld(EntityUid uid, EntityUid player, EntityUid toInsert, StorageComponent? storageComp = null)
public bool PlayerInsertEntityInWorld(Entity<StorageComponent?> uid, EntityUid player, EntityUid toInsert)
{
if (!Resolve(uid, ref storageComp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid))
if (!Resolve(uid, ref uid.Comp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid))
return false;
if (!Insert(uid, toInsert, out _, user: player, storageComp))
if (!Insert(uid, toInsert, out _, user: player, uid.Comp))
{
_popupSystem.PopupClient(Loc.GetString("comp-storage-cant-insert"), uid, player);
return false;
@@ -611,6 +646,71 @@ public abstract class SharedStorageSystem : EntitySystem
return true;
}
/// <summary>
/// Returns true if there is enough space to theoretically fit another item.
/// </summary>
public bool HasSpace(Entity<StorageComponent?> uid)
{
if (!Resolve(uid, ref uid.Comp))
return false;
//todo maybe this shouldn't be authoritative over weight? idk.
if (uid.Comp.MaxSlots != null)
{
return uid.Comp.Container.ContainedEntities.Count < uid.Comp.MaxSlots;
}
return GetCumulativeItemSizes(uid, uid.Comp) < uid.Comp.MaxTotalWeight;
}
/// <summary>
/// Returns the sum of all the ItemSizes of the items inside of a storage.
/// </summary>
public int GetCumulativeItemSizes(EntityUid uid, StorageComponent? component = null)
{
if (!Resolve(uid, ref component))
return 0;
var sum = 0;
foreach (var item in component.Container.ContainedEntities)
{
if (!_itemQuery.TryGetComponent(item, out var itemComp))
continue;
sum += SharedItemSystem.GetItemSizeWeight(itemComp.Size);
}
return sum;
}
public ItemSize GetMaxItemSize(Entity<StorageComponent?> uid)
{
if (!Resolve(uid, ref uid.Comp))
return DefaultStorageMaxItemSize;
// If we specify a max item size, use that
if (uid.Comp.MaxItemSize != null)
return uid.Comp.MaxItemSize.Value;
if (!_itemQuery.TryGetComponent(uid, out var item))
return DefaultStorageMaxItemSize;
// if there is no max item size specified, the value used
// is one below the item size of the storage entity, clamped at ItemSize.Tiny
return (ItemSize) Math.Max((int) item.Size - 1, 1);
}
public FixedPoint2 GetStorageFillPercentage(Entity<StorageComponent?> uid)
{
if (!Resolve(uid, ref uid.Comp))
return 0;
var slotPercent = FixedPoint2.New(uid.Comp.Container.ContainedEntities.Count) / uid.Comp.MaxSlots ?? FixedPoint2.Zero;
var weightPercent = FixedPoint2.New(GetCumulativeItemSizes(uid)) / uid.Comp.MaxTotalWeight;
return FixedPoint2.Max(slotPercent, weightPercent);
}
/// <summary>
/// Plays a clientside pickup animation for the specified uid.
/// </summary>