storage and inventory toolshed commands (#39046)
* First commit * CommandImplementation on singletons is die, a la moony * Fix duplicated thingy because yes * Prototypes, bugfixes, refactoring oh my * Remember to actually stage your ftl changes next time, leaf
This commit is contained in:
198
Content.Server/Inventory/InventoryCommand.cs
Normal file
198
Content.Server/Inventory/InventoryCommand.cs
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Server.Administration;
|
||||||
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Toolshed;
|
||||||
|
|
||||||
|
namespace Content.Server.Inventory;
|
||||||
|
|
||||||
|
[ToolshedCommand, AdminCommand(AdminFlags.Debug)]
|
||||||
|
public sealed class InventoryCommand : ToolshedCommand
|
||||||
|
{
|
||||||
|
private InventorySystem? _inventorySystem;
|
||||||
|
|
||||||
|
[CommandImplementation("getflags")]
|
||||||
|
public IEnumerable<EntityUid> InventoryGetFlags([PipedArgument] IEnumerable<EntityUid> ents, SlotFlags slotFlag)
|
||||||
|
{
|
||||||
|
var items = Enumerable.Empty<EntityUid>();
|
||||||
|
foreach (var ent in ents)
|
||||||
|
{
|
||||||
|
items = items.Concat(InventoryGetFlags(ent, slotFlag));
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EntityUid> InventoryGetFlags(EntityUid ent, SlotFlags slotFlag)
|
||||||
|
{
|
||||||
|
_inventorySystem ??= GetSys<InventorySystem>();
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent<InventoryComponent>(ent, out var inventory))
|
||||||
|
return [];
|
||||||
|
|
||||||
|
List<EntityUid> items = new();
|
||||||
|
|
||||||
|
foreach (var slot in inventory.Slots)
|
||||||
|
{
|
||||||
|
if ((slot.SlotFlags & slotFlag) == 0) // Does this seem somewhat illegal? yes. Does C# provide an alternative function for checking if an enum has ANY of a set of bit flags? no.
|
||||||
|
continue;
|
||||||
|
if (_inventorySystem.TryGetSlotEntity(ent, slot.Name, out var item, inventory))
|
||||||
|
items.Add(item.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[CommandImplementation("getnamed")]
|
||||||
|
public IEnumerable<EntityUid> InventoryGetNamed([PipedArgument] IEnumerable<EntityUid> ents, string slotName)
|
||||||
|
{
|
||||||
|
var items = Enumerable.Empty<EntityUid>();
|
||||||
|
foreach (var ent in ents)
|
||||||
|
{
|
||||||
|
items = items.Concat(InventoryGetNamed(ent, slotName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EntityUid> InventoryGetNamed(EntityUid ent, string slotName)
|
||||||
|
{
|
||||||
|
_inventorySystem ??= GetSys<InventorySystem>();
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent<InventoryComponent>(ent, out var inventory))
|
||||||
|
return [];
|
||||||
|
|
||||||
|
List<EntityUid> items = new();
|
||||||
|
|
||||||
|
foreach (var slot in inventory.Slots)
|
||||||
|
{
|
||||||
|
if (slot.Name != slotName)
|
||||||
|
continue;
|
||||||
|
if (_inventorySystem.TryGetSlotEntity(ent, slot.Name, out var item, inventory))
|
||||||
|
items.Add(item.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandImplementation("forceput")]
|
||||||
|
public EntityUid? InventoryForcePut([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntityUid itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventoryPutEnumerableBase(ents, itemEnt, slotFlag, PutType.ForcePut);
|
||||||
|
[CommandImplementation("forcespawn")]
|
||||||
|
public EntityUid? InventoryForceSpawn([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntProtoId itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventorySpawnEnumerableBase(ents, itemEnt, slotFlag, PutType.ForcePut);
|
||||||
|
|
||||||
|
[CommandImplementation("put")]
|
||||||
|
public EntityUid? InventoryPut([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntityUid itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventoryPutEnumerableBase(ents, itemEnt, slotFlag, PutType.Put);
|
||||||
|
[CommandImplementation("spawn")]
|
||||||
|
public EntityUid? InventorySpawn([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntProtoId itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventorySpawnEnumerableBase(ents, itemEnt, slotFlag, PutType.Put);
|
||||||
|
|
||||||
|
[CommandImplementation("tryput")]
|
||||||
|
public EntityUid? InventoryTryPut([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntityUid itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventoryPutEnumerableBase(ents, itemEnt, slotFlag, PutType.Put);
|
||||||
|
[CommandImplementation("tryspawn")]
|
||||||
|
public EntityUid? InventoryTrySpawn([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntProtoId itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventorySpawnEnumerableBase(ents, itemEnt, slotFlag, PutType.Put);
|
||||||
|
|
||||||
|
[CommandImplementation("ensure")]
|
||||||
|
public EntityUid? InventoryEnsure([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntityUid itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventoryPutEnumerableBase(ents, itemEnt, slotFlag, PutType.Ensure);
|
||||||
|
[CommandImplementation("ensurespawn")]
|
||||||
|
public EntityUid? InventoryEnsureSpawn([PipedArgument] IEnumerable<EntityUid> ents,
|
||||||
|
EntProtoId itemEnt,
|
||||||
|
SlotFlags slotFlag) => InventorySpawnEnumerableBase(ents, itemEnt, slotFlag, PutType.Ensure);
|
||||||
|
|
||||||
|
|
||||||
|
private EntityUid? InventorySpawnEnumerableBase(IEnumerable<EntityUid> targetEnts,
|
||||||
|
EntProtoId itemToInsert,
|
||||||
|
SlotFlags slotFlags,
|
||||||
|
PutType putType)
|
||||||
|
{
|
||||||
|
var entityUids = targetEnts as EntityUid[] ?? targetEnts.ToArray();
|
||||||
|
if (!entityUids.Any())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var spawnedItem = Spawn(itemToInsert, Transform(entityUids.First()).Coordinates);
|
||||||
|
|
||||||
|
foreach (var entity in entityUids)
|
||||||
|
{
|
||||||
|
var result = InventoryPutBase(entity, spawnedItem, slotFlags, putType);
|
||||||
|
if (result == null)
|
||||||
|
continue;
|
||||||
|
if (!result.Value.Equals(spawnedItem)) Del(spawnedItem);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Del(spawnedItem);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private EntityUid? InventoryPutEnumerableBase(IEnumerable<EntityUid> targetEnts,
|
||||||
|
EntityUid itemToInsert,
|
||||||
|
SlotFlags slotFlags,
|
||||||
|
PutType putType)
|
||||||
|
{
|
||||||
|
foreach (var entity in targetEnts)
|
||||||
|
{
|
||||||
|
var result = InventoryPutBase(entity, itemToInsert, slotFlags, putType);
|
||||||
|
if (result != null)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityUid? InventoryPutBase(EntityUid targetEnt,
|
||||||
|
EntityUid itemToInsert,
|
||||||
|
SlotFlags slotFlag,
|
||||||
|
PutType putType)
|
||||||
|
{
|
||||||
|
_inventorySystem ??= GetSys<InventorySystem>();
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent<InventoryComponent>(targetEnt, out var inventory))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var slot in inventory.Slots)
|
||||||
|
{
|
||||||
|
if ((slot.SlotFlags & slotFlag) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
if (_inventorySystem.TryGetSlotEntity(targetEnt, slot.Name, out var originalItem, inventory))
|
||||||
|
{
|
||||||
|
if (putType == PutType.ForcePut)
|
||||||
|
EntityManager.DeleteEntity(originalItem);
|
||||||
|
if (putType == PutType.Put)
|
||||||
|
{
|
||||||
|
if (!_inventorySystem.TryUnequip(targetEnt, slot.Name, force: true, inventory: inventory))
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_inventorySystem.TryEquip(targetEnt, itemToInsert, slot.Name, force: true, inventory: inventory))
|
||||||
|
return itemToInsert;
|
||||||
|
else
|
||||||
|
return putType == PutType.Ensure ? originalItem : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum PutType
|
||||||
|
{
|
||||||
|
ForcePut, // Put item in slot, delete old item
|
||||||
|
Put, // Put item in slot, put old item on floor
|
||||||
|
TryPut, // Put item in slot, fail if there is already an item
|
||||||
|
Ensure // Try put item in slot. If there is one, return the item already there
|
||||||
|
}
|
||||||
|
}
|
||||||
58
Content.Server/Storage/StorageCommand.cs
Normal file
58
Content.Server/Storage/StorageCommand.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Server.Administration;
|
||||||
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.Item;
|
||||||
|
using Content.Shared.Storage;
|
||||||
|
using Content.Shared.Storage.EntitySystems;
|
||||||
|
using Robust.Shared.Containers;
|
||||||
|
using Robust.Shared.Toolshed;
|
||||||
|
|
||||||
|
namespace Content.Server.Storage;
|
||||||
|
|
||||||
|
[ToolshedCommand, AdminCommand(AdminFlags.Debug)]
|
||||||
|
public sealed class StorageCommand : ToolshedCommand
|
||||||
|
{
|
||||||
|
private SharedStorageSystem? _storage;
|
||||||
|
private SharedContainerSystem? _container;
|
||||||
|
|
||||||
|
|
||||||
|
[CommandImplementation("insert")]
|
||||||
|
public IEnumerable<EntityUid> StorageInsert([PipedArgument] IEnumerable<EntityUid> entsToInsert,
|
||||||
|
EntityUid targetEnt) => entsToInsert.Where(x => StorageInsert(x, targetEnt) != null);
|
||||||
|
|
||||||
|
public EntityUid? StorageInsert(EntityUid entToInsert, EntityUid targetEnt)
|
||||||
|
{
|
||||||
|
_storage ??= GetSys<SharedStorageSystem>();
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent<StorageComponent>(targetEnt, out var storage))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return _storage.Insert(targetEnt, entToInsert, out var stackedEntity, null, storage, false)
|
||||||
|
? entToInsert
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[CommandImplementation("fasttake")]
|
||||||
|
public IEnumerable<EntityUid> StorageFastTake([PipedArgument] IEnumerable<EntityUid> storageEnts) =>
|
||||||
|
storageEnts.Select(StorageFastTake).OfType<EntityUid>();
|
||||||
|
|
||||||
|
public EntityUid? StorageFastTake(EntityUid storageEnt)
|
||||||
|
{
|
||||||
|
_storage ??= GetSys<SharedStorageSystem>();
|
||||||
|
_container ??= GetSys<SharedContainerSystem>();
|
||||||
|
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent<StorageComponent>(storageEnt, out var storage))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var removing = storage.Container.ContainedEntities[^1];
|
||||||
|
if (_container.RemoveEntity(storageEnt, removing))
|
||||||
|
return removing;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -106,6 +106,30 @@ command-description-scale-multiplyvector =
|
|||||||
Multiply an entity's sprite size with a certain 2d vector (without changing its fixture).
|
Multiply an entity's sprite size with a certain 2d vector (without changing its fixture).
|
||||||
command-description-scale-multiplywithfixture =
|
command-description-scale-multiplywithfixture =
|
||||||
Multiply an entity's sprite size with a certain factor (including its fixture).
|
Multiply an entity's sprite size with a certain factor (including its fixture).
|
||||||
|
command-description-storage-fasttake =
|
||||||
|
Takes the most recently placed item from the piped storage entity.
|
||||||
|
command-description-storage-insert =
|
||||||
|
Inserts the piped entity into the given storage entity.
|
||||||
|
command-description-inventory-getflags =
|
||||||
|
Gets all entities in slots on the piped inventory entity matching a certain slot flag.
|
||||||
|
command-description-inventory-getnamed =
|
||||||
|
Gets all entities in slots on the piped inventory entity matching a certain slot name.
|
||||||
|
command-description-inventory-forceput =
|
||||||
|
Puts a given entity on the first piped entity that has a slot matching the given flag, deleting any item previously in that slot.
|
||||||
|
command-description-inventory-forcespawn =
|
||||||
|
Spawns a given prototype on the first piped entity that has a slot matching the given flag, deleting any item previously in that slot.
|
||||||
|
command-description-inventory-put =
|
||||||
|
Puts a given entity on the first piped entity that has a slot matching the given flag, unequiping any item previously in that slot.
|
||||||
|
command-description-inventory-spawn =
|
||||||
|
Spawns a given prototype on the first piped entity that has a slot matching the given flag, unequiping any item previously in that slot.
|
||||||
|
command-description-inventory-tryput =
|
||||||
|
Tries to put a given entity on the first piped entity that has a slot matching the given flag, failing if any item is in currently in that slot.
|
||||||
|
command-description-inventory-tryspawn =
|
||||||
|
Tries to spawn a given prototype on the first piped entity that has a slot matching the given flag, failing if any item is in currently in that slot.
|
||||||
|
command-description-inventory-ensure =
|
||||||
|
Puts a given entity on the first piped entity that has a slot matching the given flag if none exists, passing through the UID of whatever is in the slot by the end.
|
||||||
|
command-description-inventory-ensurespawn =
|
||||||
|
Spawns a given prototype on the first piped entity that has a slot matching the given flag if none exists, passing through the UID of whatever is in the slot by the end.
|
||||||
command-description-dynamicrule-list =
|
command-description-dynamicrule-list =
|
||||||
Lists all currently active dynamic rules, usually this is just one.
|
Lists all currently active dynamic rules, usually this is just one.
|
||||||
command-description-dynamicrule-get =
|
command-description-dynamicrule-get =
|
||||||
|
|||||||
Reference in New Issue
Block a user