serv4 + submodule update (#12740)
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
@@ -16,7 +16,7 @@ public sealed class BodyComponent : Component, IDraggable
|
||||
public readonly string? Prototype;
|
||||
|
||||
[DataField("root")]
|
||||
public BodyPartSlot Root = default!;
|
||||
public BodyPartSlot? Root;
|
||||
|
||||
[DataField("gibSound")]
|
||||
public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib");
|
||||
|
||||
@@ -7,10 +7,10 @@ namespace Content.Shared.Body.Components;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BodyComponentState : ComponentState
|
||||
{
|
||||
public readonly BodyPartSlot Root;
|
||||
public readonly BodyPartSlot? Root;
|
||||
public readonly SoundSpecifier GibSound;
|
||||
|
||||
public BodyComponentState(BodyPartSlot root, SoundSpecifier gibSound)
|
||||
public BodyComponentState(BodyPartSlot? root, SoundSpecifier gibSound)
|
||||
{
|
||||
Root = root;
|
||||
GibSound = gibSound;
|
||||
|
||||
@@ -125,8 +125,10 @@ public sealed class BodyPrototypeSerializer : ITypeReader<BodyPrototype, Mapping
|
||||
return new ValidatedSequenceNode(nodes);
|
||||
}
|
||||
|
||||
public BodyPrototype Read(ISerializationManager serializationManager, MappingDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, BodyPrototype? value = default)
|
||||
public BodyPrototype Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<BodyPrototype>? instanceProvider = null)
|
||||
{
|
||||
var id = node.Get<ValueDataNode>("id").Value;
|
||||
var name = node.Get<ValueDataNode>("name").Value;
|
||||
|
||||
@@ -125,7 +125,7 @@ public partial class SharedBodySystem
|
||||
{
|
||||
if (id == null ||
|
||||
!Resolve(id.Value, ref body, false) ||
|
||||
!TryComp(body.Root.Child, out BodyPartComponent? part))
|
||||
!TryComp(body.Root?.Child, out BodyPartComponent? part))
|
||||
yield break;
|
||||
|
||||
yield return (body.Root.Child.Value, part);
|
||||
@@ -155,7 +155,7 @@ public partial class SharedBodySystem
|
||||
if (bodyId == null || !Resolve(bodyId.Value, ref body, false))
|
||||
yield break;
|
||||
|
||||
foreach (var slot in GetPartAllSlots(body.Root.Child))
|
||||
foreach (var slot in GetPartAllSlots(body.Root?.Child))
|
||||
{
|
||||
yield return slot;
|
||||
}
|
||||
|
||||
@@ -37,5 +37,5 @@ public sealed class ReactiveReagentEffectEntry
|
||||
|
||||
[DataField("groups", readOnly: true, serverOnly: true,
|
||||
customTypeSerializer:typeof(PrototypeIdDictionarySerializer<HashSet<ReactionMethod>, ReactiveGroupPrototype>))]
|
||||
public Dictionary<string, HashSet<ReactionMethod>> ReactiveGroups { get; } = default!;
|
||||
public Dictionary<string, HashSet<ReactionMethod>>? ReactiveGroups { get; }
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ namespace Content.Shared.Construction.Steps
|
||||
MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null, ConstructionGraphStep? _ = null)
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<ConstructionGraphStep>? instanceProvider = null)
|
||||
{
|
||||
var type = GetType(node) ??
|
||||
throw new ArgumentException(
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Content.Shared.Damage
|
||||
/// <remarks>
|
||||
/// If this data-field is specified, this allows damageable components to be initialized with non-zero damage.
|
||||
/// </remarks>
|
||||
[DataField("damage")]
|
||||
[DataField("damage", readOnly: true)] //todo remove this readonly when implementing writing to damagespecifier
|
||||
public DamageSpecifier Damage = new();
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Damage
|
||||
{
|
||||
@@ -18,31 +16,13 @@ namespace Content.Shared.Damage
|
||||
[DataDefinition]
|
||||
public sealed class DamageSpecifier : IEquatable<DamageSpecifier>
|
||||
{
|
||||
[JsonPropertyName("types")]
|
||||
[DataField("types", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<FixedPoint2, DamageTypePrototype>))]
|
||||
private readonly Dictionary<string,FixedPoint2>? _damageTypeDictionary;
|
||||
|
||||
[JsonPropertyName("groups")]
|
||||
[DataField("groups", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<FixedPoint2, DamageGroupPrototype>))]
|
||||
private readonly Dictionary<string, FixedPoint2>? _damageGroupDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Main DamageSpecifier dictionary. Most DamageSpecifier functions exist to somehow modifying this.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Dictionary<string, FixedPoint2> DamageDict
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_damageDict == null)
|
||||
DeserializeDamage();
|
||||
return _damageDict!;
|
||||
}
|
||||
set => _damageDict = value;
|
||||
}
|
||||
[JsonIgnore]
|
||||
private Dictionary<string, FixedPoint2>? _damageDict;
|
||||
[IncludeDataField(customTypeSerializer: typeof(DamageSpecifierDictionarySerializer), readOnly: true)]
|
||||
public Dictionary<string, FixedPoint2> DamageDict { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Sum of the damage values.
|
||||
@@ -88,57 +68,20 @@ namespace Content.Shared.Damage
|
||||
/// </summary>
|
||||
public DamageSpecifier(DamageGroupPrototype group, FixedPoint2 value)
|
||||
{
|
||||
_damageGroupDictionary = new() { { group.ID, value } };
|
||||
// Simply distribute evenly (except for rounding).
|
||||
// We do this by reducing remaining the # of types and damage every loop.
|
||||
var remainingTypes = group.DamageTypes.Count;
|
||||
var remainingDamage = value;
|
||||
foreach (var damageType in group.DamageTypes)
|
||||
{
|
||||
var damage = remainingDamage / FixedPoint2.New(remainingTypes);
|
||||
DamageDict.Add(damageType, damage);
|
||||
remainingDamage -= damage;
|
||||
remainingTypes -= 1;
|
||||
}
|
||||
}
|
||||
#endregion constructors
|
||||
|
||||
/// <summary>
|
||||
/// Combines the damage group and type datafield dictionaries FixedPoint2o a single damage dictionary.
|
||||
/// </summary>
|
||||
public void DeserializeDamage()
|
||||
{
|
||||
// Add all the damage types by just copying the type dictionary (if it is not null).
|
||||
if (_damageTypeDictionary != null)
|
||||
{
|
||||
_damageDict = new(_damageTypeDictionary);
|
||||
}
|
||||
else
|
||||
{
|
||||
_damageDict = new();
|
||||
}
|
||||
|
||||
if (_damageGroupDictionary == null)
|
||||
return;
|
||||
|
||||
// Then resolve damage groups and add them
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
foreach (var entry in _damageGroupDictionary)
|
||||
{
|
||||
if (!prototypeManager.TryIndex<DamageGroupPrototype>(entry.Key, out var group))
|
||||
{
|
||||
// This can happen if deserialized before prototypes are loaded.
|
||||
Logger.Error($"Unknown damage group given to DamageSpecifier: {entry.Key}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Simply distribute evenly (except for rounding).
|
||||
// We do this by reducing remaining the # of types and damage every loop.
|
||||
var remainingTypes = group.DamageTypes.Count;
|
||||
var remainingDamage = entry.Value;
|
||||
foreach (var damageType in group.DamageTypes)
|
||||
{
|
||||
var damage = remainingDamage / FixedPoint2.New(remainingTypes);
|
||||
if (!_damageDict.TryAdd(damageType, damage))
|
||||
{
|
||||
// Key already exists, add values
|
||||
_damageDict[damageType] += damage;
|
||||
}
|
||||
remainingDamage -= damage;
|
||||
remainingTypes -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reduce (or increase) damages by applying a damage modifier set.
|
||||
/// </summary>
|
||||
|
||||
80
Content.Shared/Damage/DamageSpecifierDictionarySerializer.cs
Normal file
80
Content.Shared/Damage/DamageSpecifierDictionarySerializer.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
|
||||
namespace Content.Shared.Damage;
|
||||
|
||||
//todo writing
|
||||
public sealed class DamageSpecifierDictionarySerializer : ITypeReader<Dictionary<string, FixedPoint2>, MappingDataNode>
|
||||
{
|
||||
private ITypeValidator<Dictionary<string, FixedPoint2>, MappingDataNode> _damageTypeSerializer = new PrototypeIdDictionarySerializer<FixedPoint2, DamageTypePrototype>();
|
||||
private ITypeValidator<Dictionary<string, FixedPoint2>, MappingDataNode> _damageGroupSerializer = new PrototypeIdDictionarySerializer<FixedPoint2, DamageGroupPrototype>();
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, ISerializationContext? context = null)
|
||||
{
|
||||
var vals = new Dictionary<ValidationNode, ValidationNode>();
|
||||
if (node.TryGet<MappingDataNode>("types", out var typesNode))
|
||||
{
|
||||
vals.Add(new ValidatedValueNode(new ValueDataNode("types")), _damageTypeSerializer.Validate(serializationManager, typesNode, dependencies, context));
|
||||
}
|
||||
|
||||
if (node.TryGet<MappingDataNode>("groups", out var groupsNode))
|
||||
{
|
||||
vals.Add(new ValidatedValueNode(new ValueDataNode("groups")), _damageGroupSerializer.Validate(serializationManager, groupsNode, dependencies, context));
|
||||
}
|
||||
|
||||
return new ValidatedMappingNode(vals);
|
||||
}
|
||||
|
||||
public Dictionary<string, FixedPoint2> Read(ISerializationManager serializationManager, MappingDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<Dictionary<string, FixedPoint2>>? instanceProvider = null)
|
||||
{
|
||||
var dict = instanceProvider != null ? instanceProvider() : new();
|
||||
// Add all the damage types by just copying the type dictionary (if it is not null).
|
||||
if (node.TryGet("types", out var typesNode))
|
||||
{
|
||||
serializationManager.Read(typesNode, instanceProvider: () => dict);
|
||||
}
|
||||
|
||||
if (!node.TryGet("groups", out var groupsNode))
|
||||
return dict;
|
||||
|
||||
// Then resolve damage groups and add them
|
||||
var prototypeManager = dependencies.Resolve<IPrototypeManager>();
|
||||
foreach (var entry in serializationManager.Read<Dictionary<string, FixedPoint2>>(groupsNode))
|
||||
{
|
||||
if (!prototypeManager.TryIndex<DamageGroupPrototype>(entry.Key, out var group))
|
||||
{
|
||||
// This can happen if deserialized before prototypes are loaded.
|
||||
// i made this a warning bc it was failing tests -paul
|
||||
dependencies.Resolve<ILogManager>().RootSawmill.Error($"Unknown damage group given to DamageSpecifier: {entry.Key}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Simply distribute evenly (except for rounding).
|
||||
// We do this by reducing remaining the # of types and damage every loop.
|
||||
var remainingTypes = group.DamageTypes.Count;
|
||||
var remainingDamage = entry.Value;
|
||||
foreach (var damageType in group.DamageTypes)
|
||||
{
|
||||
var damage = remainingDamage / FixedPoint2.New(remainingTypes);
|
||||
if (!dict.TryAdd(damageType, damage))
|
||||
{
|
||||
// Key already exists, add values
|
||||
dict[damageType] += damage;
|
||||
}
|
||||
remainingDamage -= damage;
|
||||
remainingTypes -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Content.Shared.Damage.Prototypes
|
||||
/// These groups can be used to specify supported damage types of a <see cref="DamageContainerPrototype"/>, or
|
||||
/// to change/get/set damage in a <see cref="DamageableComponent"/>.
|
||||
/// </remarks>
|
||||
[Prototype("damageGroup")]
|
||||
[Prototype("damageGroup", 2)]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DamageGroupPrototype : IPrototype
|
||||
{
|
||||
|
||||
@@ -15,10 +15,12 @@ namespace Content.Shared.Decals
|
||||
return serializationManager.ValidateNode<Dictionary<Vector2i, Dictionary<uint, Decal>>>(node, context);
|
||||
}
|
||||
|
||||
public DecalGridComponent.DecalGridChunkCollection Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, DecalGridComponent.DecalGridChunkCollection? _ = null)
|
||||
public DecalGridComponent.DecalGridChunkCollection Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<DecalGridComponent.DecalGridChunkCollection>? _ = default)
|
||||
{
|
||||
var dictionary = serializationManager.Read<Dictionary<Vector2i, Dictionary<uint, Decal>>>(node, context, skipHook: skipHook);
|
||||
var dictionary = serializationManager.Read<Dictionary<Vector2i, Dictionary<uint, Decal>>>(node, context, skipHook);
|
||||
|
||||
var uids = new SortedSet<uint>();
|
||||
var uidChunkMap = new Dictionary<uint, Vector2i>();
|
||||
@@ -57,13 +59,5 @@ namespace Content.Shared.Decals
|
||||
{
|
||||
return serializationManager.WriteValue(value.ChunkCollection, alwaysWrite, context);
|
||||
}
|
||||
|
||||
public DecalGridComponent.DecalGridChunkCollection Copy(ISerializationManager serializationManager, DecalGridComponent.DecalGridChunkCollection source,
|
||||
DecalGridComponent.DecalGridChunkCollection target, bool skipHook, ISerializationContext? context = null)
|
||||
{
|
||||
var dict = target.ChunkCollection;
|
||||
serializationManager.Copy(source.ChunkCollection, ref dict, context, skipHook);
|
||||
return new DecalGridComponent.DecalGridChunkCollection(dict) {NextUid = source.NextUid};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Content.Shared.Decals
|
||||
[DataField("chunkCollection", serverOnly: true)]
|
||||
public DecalGridChunkCollection ChunkCollection = new(new ());
|
||||
|
||||
[DataRecord]
|
||||
public record DecalGridChunkCollection(Dictionary<Vector2i, Dictionary<uint, Decal>> ChunkCollection)
|
||||
{
|
||||
public uint NextUid;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Content.Shared.FixedPoint
|
||||
/// Represents a quantity of something, to a precision of 0.01.
|
||||
/// To enforce this level of precision, floats are shifted by 2 decimal points, rounded, and converted to an int.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[Serializable, CopyByRef]
|
||||
public struct FixedPoint2 : ISelfSerialize, IComparable<FixedPoint2>, IEquatable<FixedPoint2>, IFormattable
|
||||
{
|
||||
private int _value;
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Preferences;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
@@ -15,13 +11,13 @@ public abstract class SharedHumanoidComponent : Component
|
||||
/// base humanoid to spawn, etc.
|
||||
/// </summary>
|
||||
[DataField("species", customTypeSerializer: typeof(PrototypeIdSerializer<SpeciesPrototype>))]
|
||||
public string Species { get; set; } = default!;
|
||||
public string Species { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The initial profile and base layers to apply to this humanoid.
|
||||
/// </summary>
|
||||
[DataField("initial", customTypeSerializer: typeof(PrototypeIdSerializer<HumanoidProfilePrototype>))]
|
||||
public string Initial { get; } = default!;
|
||||
public string? Initial { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Skin color of this humanoid.
|
||||
|
||||
Reference in New Issue
Block a user