using Content.Shared.Storage;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Sequence;
using Robust.Shared.Serialization.Markdown.Validation;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
namespace Content.Shared.Containers;
///
/// Component for spawning entity prototypes into containers on map init.
///
///
/// Unlike this is deterministic and supports arbitrary containers. While this
/// could maybe be merged with that component, it would require significant changes to , which is also used by several other systems.
///
[RegisterComponent]
public sealed partial class ContainerFillComponent : Component
{
[DataField("containers", customTypeSerializer:typeof(ContainerFillSerializer))]
public Dictionary> Containers = new();
///
/// If true, entities spawned via the construction system will not have entities spawned into containers managed
/// by the construction system.
///
[DataField("ignoreConstructionSpawn")]
public bool IgnoreConstructionSpawn = true;
}
// all of this exists just to validate prototype ids.
// it would be nice if you could specify only a type validator and not have to re-implement everything else.
// or a dictionary serializer that accepts a custom type serializer for the dictionary values
public sealed class ContainerFillSerializer : ITypeValidator>, MappingDataNode>
{
private static PrototypeIdListSerializer ListSerializer => new();
public ValidationNode Validate(
ISerializationManager serializationManager,
MappingDataNode node,
IDependencyCollection dependencies,
ISerializationContext? context = null)
{
var mapping = new Dictionary();
foreach (var (key, val) in node.Children)
{
var keyVal = serializationManager.ValidateNode(key, context);
var listVal = (val is SequenceDataNode seq)
? ListSerializer.Validate(serializationManager, seq, dependencies, context)
: new ErrorNode(val, "ContainerFillComponent prototypes must be a sequence/list");
mapping.Add(keyVal, listVal);
}
return new ValidatedMappingNode(mapping);
}
}