serv4 + submodule update (#12740)
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user