using Content.Server.NPC.HTN.PrimitiveTasks; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager; using Robust.Shared.Serialization.Markdown; using Robust.Shared.Serialization.Markdown.Mapping; using Robust.Shared.Serialization.Markdown.Sequence; using Robust.Shared.Serialization.Markdown.Validation; using Robust.Shared.Serialization.Markdown.Value; using Robust.Shared.Serialization.TypeSerializers.Interfaces; namespace Content.Server.NPC.HTN; public sealed class HTNTaskListSerializer : ITypeSerializer, SequenceDataNode> { public ValidationNode Validate(ISerializationManager serializationManager, SequenceDataNode node, IDependencyCollection dependencies, ISerializationContext? context = null) { var list = new List(); var protoManager = dependencies.Resolve(); foreach (var data in node.Sequence) { if (data is not MappingDataNode mapping) { list.Add(new ErrorNode(data, $"Found invalid mapping node on {data}")); continue; } var id = ((ValueDataNode) mapping["id"]).Value; var isCompound = protoManager.HasIndex(id); var isPrimitive = protoManager.HasIndex(id); list.Add(isCompound ^ isPrimitive ? new ValidatedValueNode(node) : new ErrorNode(node, $"Found duplicated HTN compound and primitive tasks for {id}")); } return new ValidatedSequenceNode(list); } public List Read(ISerializationManager serializationManager, SequenceDataNode node, IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, List? value = default) { value ??= new List(); foreach (var data in node.Sequence) { var mapping = (MappingDataNode) data; var id = ((ValueDataNode) mapping["id"]).Value; // Can't check prototypes here because we're still loading them so yay! value.Add(id); } return value; } public DataNode Write(ISerializationManager serializationManager, List value, bool alwaysWrite = false, ISerializationContext? context = null) { var sequence = new SequenceDataNode(); foreach (var task in value) { var mapping = new MappingDataNode { ["id"] = new ValueDataNode(task) }; sequence.Add(mapping); } return sequence; } public List Copy(ISerializationManager serializationManager, List source, List target, bool skipHook, ISerializationContext? context = null) { target.Clear(); target.EnsureCapacity(source.Capacity); // Tasks are just prototypes soooo? target.AddRange(source); return target; } }