Revert "Refactor Damage to use Protoypes (#4262)"
This reverts commit 20bf5739a9.
This commit is contained in:
@@ -18,242 +18,67 @@ namespace Content.Shared.Damage.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Component that allows attached entities to take damage.
|
||||
/// This basic version never dies (thus can take an indefinite amount of damage).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The supported damage types are specified using a <see cref="DamageContainerPrototype"/>s. DamageContainers
|
||||
/// are effectively a dictionary of damage types and damage numbers, along with functions to modify them. Damage
|
||||
/// groups are collections of damage types. A damage group is 'applicable' to a damageable component if it
|
||||
/// supports at least one damage type in that group. A subset of these groups may be 'fully supported' when every
|
||||
/// member of the group is supported by the container. This basic version never dies (thus can take an
|
||||
/// indefinite amount of damage).
|
||||
/// </remarks>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IDamageableComponent))]
|
||||
[NetworkedComponent()]
|
||||
public class DamageableComponent : Component, IDamageableComponent, IRadiationAct, ISerializationHooks
|
||||
{
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
=======
|
||||
|
||||
=======
|
||||
>>>>>>> fix a few bugs
|
||||
public override string Name => "Damageable";
|
||||
public override uint? NetID => ContentNetIDs.DAMAGEABLE;
|
||||
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
<<<<<<< HEAD
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
>>>>>>> update damagecomponent across shared and server
|
||||
=======
|
||||
>>>>>>> Fix Merge issues
|
||||
// TODO define these in yaml?
|
||||
public const string DefaultResistanceSet = "defaultResistances";
|
||||
public const string DefaultDamageContainer = "metallicDamageContainer";
|
||||
=======
|
||||
/// <summary>
|
||||
/// The main damage dictionary. All the damage information is stored in this dictionary with <see cref="DamageTypePrototype"/> keys.
|
||||
/// </summary>
|
||||
private Dictionary<DamageTypePrototype, int> _damageDict = new();
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
private readonly Dictionary<DamageType, int> _damageList = DamageTypeExtensions.ToNewDictionary();
|
||||
|
||||
[DataField("resistances")] public string ResistanceSetId = DefaultResistanceSet;
|
||||
=======
|
||||
[DataField("resistances")]
|
||||
public string ResistanceSetId { get; set; } = "defaultResistances";
|
||||
|
||||
[ViewVariables] public ResistanceSet Resistances { get; set; } = new();
|
||||
>>>>>>> Merge fixes
|
||||
|
||||
// TODO DAMAGE Use as default values, specify overrides in a separate property through yaml for better (de)serialization
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
[ViewVariables] [DataField("damageContainer")] public string DamageContainerId { get; set; } = DefaultDamageContainer;
|
||||
=======
|
||||
|
||||
/// <summary>
|
||||
/// The main damage dictionary. All the damage information is stored in this dictionary with <see cref="DamageTypePrototype"/> keys.
|
||||
/// </summary>
|
||||
private Dictionary<DamageTypePrototype, int> _damageDict = new();
|
||||
|
||||
[DataField("resistances")]
|
||||
public string ResistanceSetId { get; set; } = "defaultResistances";
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
|
||||
[ViewVariables] public ResistanceSet Resistances { get; set; } = new();
|
||||
=======
|
||||
[ViewVariables]
|
||||
[DataField("damageContainer")]
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public string DamageContainerId { get; set; } = DefaultDamageContainer;
|
||||
>>>>>>> fix a few bugs
|
||||
|
||||
// TODO DAMAGE Use as default values, specify overrides in a separate property through yaml for better (de)serialization
|
||||
[ViewVariables]
|
||||
[DataField("damageContainer")]
|
||||
public string DamageContainerId { get; set; } = "metallicDamageContainer";
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageClass, int> DamageClasses => _damageList.ToClassDictionary();
|
||||
=======
|
||||
// TODO DAMAGE Cache this
|
||||
// When moving logic from damageableComponent --> Damage System, make damageSystem update these on damage change.
|
||||
[ViewVariables] public int TotalDamage => _damageDict.Values.Sum();
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageTypePrototype, int> GetDamagePerType => _damageDict;
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageGroupPrototype, int> GetDamagePerApplicableGroup => DamageTypeDictToDamageGroupDict(_damageDict, ApplicableDamageGroups);
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageGroupPrototype, int> GetDamagePerFullySupportedGroup => DamageTypeDictToDamageGroupDict(_damageDict, FullySupportedDamageGroups);
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
[ViewVariables] public int TotalDamage => _damageList.Values.Sum();
|
||||
|
||||
// Whenever sending over network, also need a <string, int> dictionary
|
||||
// TODO DAMAGE MAYBE Cache this?
|
||||
public IReadOnlyDictionary<string, int> GetDamagePerApplicableGroupIDs => ConvertDictKeysToIDs(GetDamagePerApplicableGroup);
|
||||
public IReadOnlyDictionary<string, int> GetDamagePerFullySupportedGroupIDs => ConvertDictKeysToIDs(GetDamagePerFullySupportedGroup);
|
||||
public IReadOnlyDictionary<string, int> GetDamagePerTypeIDs => ConvertDictKeysToIDs(_damageDict);
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageClass, int> DamageClasses => _damageList.ToClassDictionary();
|
||||
|
||||
// TODO PROTOTYPE Replace these datafield variables with prototype references, once they are supported.
|
||||
// Also requires appropriate changes in OnExplosion() and RadiationAct()
|
||||
[ViewVariables]
|
||||
[DataField("radiationDamageTypes")]
|
||||
public List<string> RadiationDamageTypeIDs { get; set; } = new() {"Radiation"};
|
||||
[ViewVariables]
|
||||
[DataField("explosionDamageTypes")]
|
||||
public List<string> ExplosionDamageTypeIDs { get; set; } = new() { "Piercing", "Heat" };
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageType, int> DamageTypes => _damageList;
|
||||
|
||||
public HashSet<DamageGroupPrototype> ApplicableDamageGroups { get; } = new();
|
||||
[ViewVariables] public HashSet<DamageType> SupportedTypes { get; } = new();
|
||||
|
||||
[ViewVariables] public HashSet<DamageClass> SupportedClasses { get; } = new();
|
||||
|
||||
<<<<<<< HEAD
|
||||
public bool SupportsDamageClass(DamageClass @class)
|
||||
{
|
||||
return SupportedClasses.Contains(@class);
|
||||
=======
|
||||
public HashSet<DamageGroupPrototype> SupportedGroups { get; } = new();
|
||||
=======
|
||||
public string DamageContainerId { get; set; } = "metallicDamageContainer";
|
||||
|
||||
// TODO DAMAGE Cache this
|
||||
// When moving logic from damageableComponent --> Damage System, make damageSystem update these on damage change.
|
||||
[ViewVariables] public int TotalDamage => _damageDict.Values.Sum();
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageTypePrototype, int> GetDamagePerType => _damageDict;
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageGroupPrototype, int> GetDamagePerApplicableGroup => DamageTypeDictToDamageGroupDict(_damageDict, ApplicableDamageGroups);
|
||||
[ViewVariables] public IReadOnlyDictionary<DamageGroupPrototype, int> GetDamagePerFullySupportedGroup => DamageTypeDictToDamageGroupDict(_damageDict, FullySupportedDamageGroups);
|
||||
|
||||
// Whenever sending over network, also need a <string, int> dictionary
|
||||
// TODO DAMAGE MAYBE Cache this?
|
||||
public IReadOnlyDictionary<string, int> GetDamagePerApplicableGroupIDs => ConvertDictKeysToIDs(GetDamagePerApplicableGroup);
|
||||
public IReadOnlyDictionary<string, int> GetDamagePerFullySupportedGroupIDs => ConvertDictKeysToIDs(GetDamagePerFullySupportedGroup);
|
||||
public IReadOnlyDictionary<string, int> GetDamagePerTypeIDs => ConvertDictKeysToIDs(_damageDict);
|
||||
|
||||
// TODO PROTOTYPE Replace these datafield variables with prototype references, once they are supported.
|
||||
// Also requires appropriate changes in OnExplosion() and RadiationAct()
|
||||
[ViewVariables]
|
||||
[DataField("radiationDamageTypes")]
|
||||
public List<string> RadiationDamageTypeIDs { get; set; } = new() {"Radiation"};
|
||||
[ViewVariables]
|
||||
[DataField("explosionDamageTypes")]
|
||||
public List<string> ExplosionDamageTypeIDs { get; set; } = new() { "Piercing", "Heat" };
|
||||
|
||||
public HashSet<DamageGroupPrototype> ApplicableDamageGroups { get; } = new();
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
|
||||
public HashSet<DamageGroupPrototype> FullySupportedDamageGroups { get; } = new();
|
||||
|
||||
public HashSet<DamageTypePrototype> SupportedDamageTypes { get; } = new();
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public bool SupportsDamageClass(DamageGroupPrototype damageGroup)
|
||||
{
|
||||
return SupportedGroups.Contains(damageGroup);
|
||||
>>>>>>> Merge fixes
|
||||
}
|
||||
=======
|
||||
public HashSet<DamageGroupPrototype> FullySupportedDamageGroups { get; } = new();
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
|
||||
public HashSet<DamageTypePrototype> SupportedDamageTypes { get; } = new();
|
||||
public bool SupportsDamageType(DamageType type)
|
||||
{
|
||||
return SupportedTypes.Contains(type);
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> update damagecomponent across shared and server
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
=======
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
// TODO DAMAGE Serialize damage done and resistance changes
|
||||
var damageContainerPrototype = _prototypeManager.Index<DamageContainerPrototype>(DamageContainerId);
|
||||
var damagePrototype = prototypeManager.Index<DamageContainerPrototype>(DamageContainerId);
|
||||
|
||||
ApplicableDamageGroups.Clear();
|
||||
FullySupportedDamageGroups.Clear();
|
||||
SupportedDamageTypes.Clear();
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
SupportedClasses.Clear();
|
||||
SupportedTypes.Clear();
|
||||
=======
|
||||
=======
|
||||
>>>>>>> fix a few bugs
|
||||
_prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
=======
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
|
||||
// TODO DAMAGE Serialize damage done and resistance changes
|
||||
var damageContainerPrototype = _prototypeManager.Index<DamageContainerPrototype>(DamageContainerId);
|
||||
>>>>>>> update damagecomponent across shared and server
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
DamageContainerId = damagePrototype.ID;
|
||||
SupportedClasses.UnionWith(damagePrototype.SupportedClasses);
|
||||
SupportedTypes.UnionWith(damagePrototype.SupportedTypes);
|
||||
=======
|
||||
SupportedGroups.Clear();
|
||||
SupportedTypes.Clear();
|
||||
=======
|
||||
ApplicableDamageGroups.Clear();
|
||||
FullySupportedDamageGroups.Clear();
|
||||
SupportedDamageTypes.Clear();
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
|
||||
//Get Damage groups/types from the DamageContainerPrototype.
|
||||
DamageContainerId = damageContainerPrototype.ID;
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
SupportedGroups.UnionWith(damageContainerPrototype.SupportedDamageGroups);
|
||||
SupportedTypes.UnionWith(damageContainerPrototype.SupportedDamageTypes);
|
||||
>>>>>>> Merge fixes
|
||||
=======
|
||||
ApplicableDamageGroups.UnionWith(damageContainerPrototype.ApplicableDamageGroups);
|
||||
FullySupportedDamageGroups.UnionWith(damageContainerPrototype.FullySupportedDamageGroups);
|
||||
SupportedDamageTypes.UnionWith(damageContainerPrototype.SupportedDamageTypes);
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
|
||||
=======
|
||||
//Get Damage groups/types from the DamageContainerPrototype.
|
||||
DamageContainerId = damageContainerPrototype.ID;
|
||||
ApplicableDamageGroups.UnionWith(damageContainerPrototype.ApplicableDamageGroups);
|
||||
FullySupportedDamageGroups.UnionWith(damageContainerPrototype.FullySupportedDamageGroups);
|
||||
SupportedDamageTypes.UnionWith(damageContainerPrototype.SupportedDamageTypes);
|
||||
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
//initialize damage dictionary 0 damage
|
||||
_damageDict = new(SupportedDamageTypes.Count);
|
||||
foreach (var type in SupportedDamageTypes)
|
||||
{
|
||||
_damageDict.Add(type, 0);
|
||||
}
|
||||
|
||||
Resistances = new ResistanceSet(_prototypeManager.Index<ResistanceSetPrototype>(ResistanceSetId));
|
||||
var resistancePrototype = prototypeManager.Index<ResistanceSetPrototype>(ResistanceSetId);
|
||||
Resistances = new ResistanceSet(resistancePrototype);
|
||||
}
|
||||
|
||||
protected override void Startup()
|
||||
@@ -263,25 +88,9 @@ namespace Content.Shared.Damage.Components
|
||||
ForceHealthChangedEvent();
|
||||
}
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
=======
|
||||
public DamageTypePrototype GetDamageType(string ID)
|
||||
{
|
||||
return _prototypeManager.Index<DamageTypePrototype>(ID);
|
||||
}
|
||||
|
||||
public DamageGroupPrototype GetDamageGroup(string ID)
|
||||
{
|
||||
return _prototypeManager.Index<DamageGroupPrototype>(ID);
|
||||
}
|
||||
|
||||
>>>>>>> update damagecomponent across shared and server
|
||||
=======
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
public override ComponentState GetComponentState(ICommonSession player)
|
||||
{
|
||||
return new DamageableComponentState(GetDamagePerTypeIDs);
|
||||
return new DamageableComponentState(_damageList);
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
@@ -293,104 +102,49 @@ namespace Content.Shared.Damage.Components
|
||||
return;
|
||||
}
|
||||
|
||||
_damageDict.Clear();
|
||||
_damageList.Clear();
|
||||
|
||||
foreach (var (type, damage) in state.DamageDict)
|
||||
foreach (var (type, damage) in state.DamageList)
|
||||
{
|
||||
_damageDict[_prototypeManager.Index<DamageTypePrototype>(type)] = damage;
|
||||
_damageList[type] = damage;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetDamage(DamageTypePrototype type)
|
||||
public int GetDamage(DamageType type)
|
||||
{
|
||||
return GetDamagePerType.GetValueOrDefault(type);
|
||||
return _damageList.GetValueOrDefault(type);
|
||||
}
|
||||
|
||||
public bool TryGetDamage(DamageTypePrototype type, out int damage)
|
||||
public bool TryGetDamage(DamageType type, out int damage)
|
||||
{
|
||||
return GetDamagePerType.TryGetValue(type, out damage);
|
||||
return _damageList.TryGetValue(type, out damage);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public int GetDamage(DamageClass @class)
|
||||
{
|
||||
if (!SupportsDamageClass(@class))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
=======
|
||||
public int GetDamage(DamageGroupPrototype group)
|
||||
{
|
||||
return GetDamagePerApplicableGroup.GetValueOrDefault(group);
|
||||
}
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
public int GetDamage(DamageGroupPrototype group)
|
||||
{
|
||||
return GetDamagePerApplicableGroup.GetValueOrDefault(group);
|
||||
}
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
|
||||
public bool TryGetDamage(DamageGroupPrototype group, out int damage)
|
||||
{
|
||||
return GetDamagePerApplicableGroup.TryGetValue(group, out damage);
|
||||
}
|
||||
var damage = 0;
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
foreach (var type in @class.ToTypes())
|
||||
{
|
||||
damage += GetDamage(type);
|
||||
}
|
||||
=======
|
||||
=======
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
public bool IsApplicableDamageGroup(DamageGroupPrototype group)
|
||||
{
|
||||
return ApplicableDamageGroups.Contains(group);
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
public bool IsFullySupportedDamageGroup(DamageGroupPrototype group)
|
||||
{
|
||||
return FullySupportedDamageGroups.Contains(group);
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
}
|
||||
|
||||
public bool IsSupportedDamageType(DamageTypePrototype type)
|
||||
{
|
||||
return SupportedDamageTypes.Contains(type);
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
}
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
|
||||
<<<<<<< HEAD
|
||||
public bool IsSupportedDamageType(DamageTypePrototype type)
|
||||
{
|
||||
return SupportedDamageTypes.Contains(type);
|
||||
}
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public bool TryGetDamage(DamageClass @class, out int damage)
|
||||
{
|
||||
if (!SupportsDamageClass(@class))
|
||||
=======
|
||||
public bool TrySetDamage(DamageGroupPrototype group, int newValue)
|
||||
{
|
||||
if (!ApplicableDamageGroups.Contains(group))
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
public bool TrySetDamage(DamageGroupPrototype group, int newValue)
|
||||
{
|
||||
if (!ApplicableDamageGroups.Contains(group))
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
{
|
||||
damage = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
damage = GetDamage(@class);
|
||||
return true;
|
||||
}
|
||||
@@ -402,90 +156,44 @@ namespace Content.Shared.Damage.Components
|
||||
/// True if successful, false if this container does not support that type.
|
||||
/// </returns>
|
||||
public bool TrySetDamage(DamageType type, int newValue)
|
||||
=======
|
||||
if (newValue < 0)
|
||||
{
|
||||
// invalid value
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var type in group.DamageTypes)
|
||||
{
|
||||
TrySetDamage(type, newValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySetAllDamage(int newValue)
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
if (newValue < 0)
|
||||
{
|
||||
// invalid value
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var type in group.DamageTypes)
|
||||
{
|
||||
TrySetDamage(type, newValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySetAllDamage(int newValue)
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
{
|
||||
if (newValue < 0)
|
||||
{
|
||||
// invalid value
|
||||
return false;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
var damageClass = type.ToClass();
|
||||
|
||||
if (SupportedClasses.Contains(damageClass))
|
||||
=======
|
||||
if (SupportedTypes.Contains(type))
|
||||
>>>>>>> Merge fixes
|
||||
=======
|
||||
foreach (var type in SupportedDamageTypes)
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
foreach (var type in SupportedDamageTypes)
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
{
|
||||
TrySetDamage(type, newValue);
|
||||
var old = _damageList[type] = newValue;
|
||||
_damageList[type] = newValue;
|
||||
|
||||
var delta = newValue - old;
|
||||
var datum = new DamageChangeData(type, newValue, delta);
|
||||
var data = new List<DamageChangeData> {datum};
|
||||
|
||||
OnHealthChanged(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Heal(DamageType type)
|
||||
{
|
||||
SetDamage(type, 0);
|
||||
=======
|
||||
return true;
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
return true;
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
}
|
||||
|
||||
public bool TryChangeDamage(DamageTypePrototype type, int amount, bool ignoreDamageResistances = false)
|
||||
public void Heal()
|
||||
{
|
||||
// Check if damage type is supported, and get the current value if it is.
|
||||
if (!GetDamagePerType.TryGetValue(type, out var current))
|
||||
foreach (var type in SupportedTypes)
|
||||
{
|
||||
return false;
|
||||
Heal(type);
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public bool ChangeDamage(
|
||||
DamageType type,
|
||||
int amount,
|
||||
@@ -494,19 +202,13 @@ namespace Content.Shared.Damage.Components
|
||||
DamageChangeParams? extraParams = null)
|
||||
{
|
||||
if (!SupportsDamageType(type))
|
||||
=======
|
||||
if (amount == 0)
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
if (amount == 0)
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply resistances (does nothing if amount<0)
|
||||
var finalDamage = amount;
|
||||
if (!ignoreDamageResistances)
|
||||
|
||||
if (!ignoreResistances)
|
||||
{
|
||||
finalDamage = Resistances.CalculateDamage(type, amount);
|
||||
}
|
||||
@@ -514,23 +216,24 @@ namespace Content.Shared.Damage.Components
|
||||
if (finalDamage == 0)
|
||||
return false;
|
||||
|
||||
// Are we healing below zero?
|
||||
if (!_damageList.TryGetValue(type, out var current))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (current + finalDamage < 0)
|
||||
{
|
||||
if (current == 0)
|
||||
// Damage type is supported, but there is nothing to do
|
||||
return false;
|
||||
|
||||
// Cap healing down to zero
|
||||
_damageDict[type] = 0;
|
||||
_damageList[type] = 0;
|
||||
finalDamage = -current;
|
||||
}
|
||||
else
|
||||
{
|
||||
_damageDict[type] = current + finalDamage;
|
||||
_damageList[type] = current + finalDamage;
|
||||
}
|
||||
|
||||
current = _damageDict[type];
|
||||
current = _damageList[type];
|
||||
|
||||
var datum = new DamageChangeData(type, current, finalDamage);
|
||||
var data = new List<DamageChangeData> {datum};
|
||||
@@ -540,8 +243,6 @@ namespace Content.Shared.Damage.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public bool ChangeDamage(DamageClass @class, int amount, bool ignoreResistances,
|
||||
IEntity? source = null,
|
||||
DamageChangeParams? extraParams = null)
|
||||
@@ -551,149 +252,98 @@ namespace Content.Shared.Damage.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
var types = @class.ToTypes();
|
||||
=======
|
||||
var types = damageGroup.DamageTypes.ToArray();
|
||||
>>>>>>> Merge fixes
|
||||
=======
|
||||
public bool TryChangeDamage(DamageGroupPrototype group, int amount, bool ignoreDamageResistances = false)
|
||||
{
|
||||
var types = group.DamageTypes.ToArray();
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
public bool TryChangeDamage(DamageGroupPrototype group, int amount, bool ignoreDamageResistances = false)
|
||||
{
|
||||
var types = group.DamageTypes.ToArray();
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
|
||||
if (amount < 0)
|
||||
{
|
||||
// We are Healing. Keep track of how much we can hand out (with a better var name for readability).
|
||||
var availableHealing = -amount;
|
||||
// Changing multiple types is a bit more complicated. Might be a better way (formula?) to do this,
|
||||
// but essentially just loops between each damage category until all healing is used up.
|
||||
var healingLeft = -amount;
|
||||
var healThisCycle = 1;
|
||||
|
||||
// Get total group damage.
|
||||
var damageToHeal = GetDamagePerApplicableGroup[group];
|
||||
<<<<<<< HEAD
|
||||
|
||||
// Is there any damage to even heal?
|
||||
if (damageToHeal == 0)
|
||||
return false;
|
||||
|
||||
=======
|
||||
|
||||
// Is there any damage to even heal?
|
||||
if (damageToHeal == 0)
|
||||
return false;
|
||||
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
// If total healing is more than there is damage, just set to 0 and return.
|
||||
if (damageToHeal <= availableHealing)
|
||||
// While we have healing left...
|
||||
while (healingLeft > 0 && healThisCycle != 0)
|
||||
{
|
||||
TrySetDamage(group, 0);
|
||||
return true;
|
||||
}
|
||||
// Infinite loop fallback, if no healing was done in a cycle
|
||||
// then exit
|
||||
healThisCycle = 0;
|
||||
|
||||
// Partially heal each damage group
|
||||
int healing, damage;
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (!_damageDict.TryGetValue(type, out damage))
|
||||
int healPerType;
|
||||
if (healingLeft < types.Count)
|
||||
{
|
||||
// Damage Type is not supported. Continue without reducing availableHealing
|
||||
continue;
|
||||
// Say we were to distribute 2 healing between 3
|
||||
// this will distribute 1 to each (and stop after 2 are given)
|
||||
healPerType = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Say we were to distribute 62 healing between 3
|
||||
// this will distribute 20 to each, leaving 2 for next loop
|
||||
healPerType = healingLeft / types.Count;
|
||||
}
|
||||
|
||||
// Apply healing to the damage type. The healing amount may be zero if either damage==0, or if
|
||||
// integer rounding made it zero (i.e., damage is small)
|
||||
healing = (availableHealing * damage) / damageToHeal;
|
||||
TryChangeDamage(type, -healing, ignoreDamageResistances);
|
||||
|
||||
// remove this damage type from the damage we consider for future loops, regardless of how much we
|
||||
// actually healed this type.
|
||||
damageToHeal -= damage;
|
||||
availableHealing -= healing;
|
||||
|
||||
// If we now healed all the damage, exit. otherwise 1/0 and universe explodes.
|
||||
if (damageToHeal == 0)
|
||||
foreach (var type in types)
|
||||
{
|
||||
break;
|
||||
var damage = GetDamage(type);
|
||||
var healAmount = Math.Min(healingLeft, damage);
|
||||
healAmount = Math.Min(healAmount, healPerType);
|
||||
|
||||
ChangeDamage(type, -healAmount, true);
|
||||
healThisCycle += healAmount;
|
||||
healingLeft -= healAmount;
|
||||
}
|
||||
}
|
||||
|
||||
// Damage type is supported, there was damage to heal, and resistances were ignored
|
||||
// --> Damage must have changed
|
||||
return true;
|
||||
}
|
||||
else if (amount > 0)
|
||||
|
||||
var damageLeft = amount;
|
||||
|
||||
while (damageLeft > 0)
|
||||
{
|
||||
// Resistances may result in no actual damage change. We need to keep track if any damage got through.
|
||||
var damageChanged = false;
|
||||
int damagePerType;
|
||||
|
||||
// We are adding damage. Keep track of how much we can dish out (with a better var name for readability).
|
||||
var availableDamage = amount;
|
||||
if (damageLeft < types.Count)
|
||||
{
|
||||
damagePerType = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
damagePerType = damageLeft / types.Count;
|
||||
}
|
||||
|
||||
// How many damage types do we have to distribute over?.
|
||||
var numberDamageTypes = types.Length;
|
||||
|
||||
// Apply damage to each damage group
|
||||
int damage;
|
||||
foreach (var type in types)
|
||||
{
|
||||
// Distribute the remaining damage over the remaining damage types.
|
||||
damage = availableDamage / numberDamageTypes;
|
||||
|
||||
// Try apply the damage type. If damage type is not supported, this has no effect.
|
||||
// We also use the return value to check whether any damage has changed
|
||||
damageChanged = TryChangeDamage(type, damage, ignoreDamageResistances) || damageChanged;
|
||||
|
||||
// regardless of whether we dealt damage, reduce the amount to distribute.
|
||||
availableDamage -= damage;
|
||||
numberDamageTypes -= 1;
|
||||
|
||||
var damageAmount = Math.Min(damagePerType, damageLeft);
|
||||
ChangeDamage(type, damageAmount, true);
|
||||
damageLeft -= damageAmount;
|
||||
}
|
||||
return damageChanged;
|
||||
}
|
||||
|
||||
// amount==0 no damage change.
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public bool SetDamage(DamageType type, int newValue, IEntity? source = null, DamageChangeParams? extraParams = null)
|
||||
=======
|
||||
public bool SetDamage(DamageTypePrototype type, int newValue, IEntity? source = null, DamageChangeParams? extraParams = null)
|
||||
>>>>>>> Fix Merge issues
|
||||
=======
|
||||
public bool TrySetDamage(DamageTypePrototype type, int newValue)
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
public bool TrySetDamage(DamageTypePrototype type, int newValue)
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
{
|
||||
if (!_damageDict.TryGetValue(type, out var oldValue))
|
||||
if (newValue >= TotalDamage)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newValue < 0)
|
||||
{
|
||||
// invalid value
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldValue == newValue)
|
||||
if (!_damageList.ContainsKey(type))
|
||||
{
|
||||
// No health change.
|
||||
// But we are trying to set, not trying to change.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_damageDict[type] = newValue;
|
||||
var old = _damageList[type];
|
||||
_damageList[type] = newValue;
|
||||
|
||||
var delta = newValue - oldValue;
|
||||
var delta = newValue - old;
|
||||
var datum = new DamageChangeData(type, 0, delta);
|
||||
var data = new List<DamageChangeData> {datum};
|
||||
|
||||
@@ -706,7 +356,7 @@ namespace Content.Shared.Damage.Components
|
||||
{
|
||||
var data = new List<DamageChangeData>();
|
||||
|
||||
foreach (var type in SupportedDamageTypes)
|
||||
foreach (var type in SupportedTypes)
|
||||
{
|
||||
var damage = GetDamage(type);
|
||||
var datum = new DamageChangeData(type, damage, 0);
|
||||
@@ -722,32 +372,6 @@ namespace Content.Shared.Damage.Components
|
||||
OnHealthChanged(args);
|
||||
}
|
||||
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
=======
|
||||
private IReadOnlyDictionary<DamageGroupPrototype, int> damageListToDamageGroup(IReadOnlyDictionary<DamageTypePrototype, int> damagelist)
|
||||
{
|
||||
var damageGroupDict = new Dictionary<DamageGroupPrototype, int>();
|
||||
int damageGroupSumDamage = 0;
|
||||
int damageTypeDamage = 0;
|
||||
foreach (var damageGroup in SupportedGroups)
|
||||
{
|
||||
damageGroupSumDamage = 0;
|
||||
foreach (var damageType in SupportedTypes)
|
||||
{
|
||||
damageTypeDamage = 0;
|
||||
damagelist.TryGetValue(damageType, out damageTypeDamage);
|
||||
damageGroupSumDamage += damageTypeDamage;
|
||||
}
|
||||
damageGroupDict.Add(damageGroup, damageGroupSumDamage);
|
||||
}
|
||||
|
||||
return damageGroupDict;
|
||||
}
|
||||
|
||||
>>>>>>> Merge fixes
|
||||
=======
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
protected virtual void OnHealthChanged(DamageChangedEventArgs e)
|
||||
{
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, e);
|
||||
@@ -758,25 +382,11 @@ namespace Content.Shared.Damage.Components
|
||||
Dirty();
|
||||
}
|
||||
|
||||
public void RadiationAct(float frameTime, SharedRadiationPulseComponent radiation)
|
||||
void IRadiationAct.RadiationAct(float frameTime, SharedRadiationPulseComponent radiation)
|
||||
{
|
||||
var totalDamage = Math.Max((int)(frameTime * radiation.RadsPerSecond), 1);
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
ChangeDamage(DamageType.Radiation, totalDamage, false, radiation.Owner);
|
||||
=======
|
||||
=======
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
foreach (var typeID in RadiationDamageTypeIDs)
|
||||
{
|
||||
TryChangeDamage(_prototypeManager.Index<DamageTypePrototype>(typeID), totalDamage);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
}
|
||||
|
||||
public void OnExplosion(ExplosionEventArgs eventArgs)
|
||||
@@ -789,99 +399,19 @@ namespace Content.Shared.Damage.Components
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
ChangeDamage(DamageType.Piercing, damage, false);
|
||||
ChangeDamage(DamageType.Heat, damage, false);
|
||||
=======
|
||||
=======
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
foreach (var typeID in ExplosionDamageTypeIDs)
|
||||
{
|
||||
TryChangeDamage(_prototypeManager.Index<DamageTypePrototype>(typeID), damage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Take a dictionary with <see cref="IPrototype"/> keys and return a dictionary using <see cref="IPrototype.ID"/> as keys
|
||||
/// instead.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Useful when sending damage type and group prototypes dictionaries over the network.
|
||||
/// </remarks>
|
||||
public static IReadOnlyDictionary<string, int>
|
||||
ConvertDictKeysToIDs<TPrototype>(IReadOnlyDictionary<TPrototype, int> prototypeDict)
|
||||
where TPrototype : IPrototype
|
||||
{
|
||||
Dictionary<string, int> idDict = new(prototypeDict.Count);
|
||||
foreach (var entry in prototypeDict)
|
||||
{
|
||||
idDict.Add(entry.Key.ID, entry.Value);
|
||||
}
|
||||
return idDict;
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a dictionary with damage type keys to a dictionary of damage groups keys.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Takes a dictionary with damage types as keys and integers as values, and an iterable list of damage
|
||||
/// groups. Returns a dictionary with damage group keys, with values calculated by adding up the values for
|
||||
/// each damage type in that group. If a damage type is associated with more than one supported damage
|
||||
/// group, it will contribute to the total of each group. Conversely, some damage types may not contribute
|
||||
/// to the new dictionary if their associated group(s) are not in given list of groups.
|
||||
/// </remarks>
|
||||
public static IReadOnlyDictionary<DamageGroupPrototype, int>
|
||||
DamageTypeDictToDamageGroupDict(IReadOnlyDictionary<DamageTypePrototype, int> damageTypeDict, IEnumerable<DamageGroupPrototype> groupKeys)
|
||||
{
|
||||
var damageGroupDict = new Dictionary<DamageGroupPrototype, int>();
|
||||
int damageGroupSumDamage, damageTypeDamage;
|
||||
// iterate over the list of group keys for our new dictionary
|
||||
foreach (var group in groupKeys)
|
||||
{
|
||||
// For each damage type in this group, add up the damage present in the given dictionary
|
||||
damageGroupSumDamage = 0;
|
||||
foreach (var type in group.DamageTypes)
|
||||
{
|
||||
// if the damage type is in the dictionary, add it's damage to the group total.
|
||||
if (damageTypeDict.TryGetValue(type, out damageTypeDamage))
|
||||
{
|
||||
damageGroupSumDamage += damageTypeDamage;
|
||||
}
|
||||
}
|
||||
damageGroupDict.Add(group, damageGroupSumDamage);
|
||||
}
|
||||
return damageGroupDict;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class DamageableComponentState : ComponentState
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< refs/remotes/origin/master
|
||||
public readonly Dictionary<DamageType, int> DamageList;
|
||||
|
||||
public DamageableComponentState(Dictionary<DamageType, int> damageList)
|
||||
=======
|
||||
public readonly IReadOnlyDictionary<string, int> DamageDict;
|
||||
|
||||
public DamageableComponentState(IReadOnlyDictionary<string, int> damageDict)
|
||||
|
||||
>>>>>>> Refactor damageablecomponent update (#4406)
|
||||
=======
|
||||
public readonly IReadOnlyDictionary<string, int> DamageDict;
|
||||
|
||||
public DamageableComponentState(IReadOnlyDictionary<string, int> damageDict)
|
||||
|
||||
>>>>>>> refactor-damageablecomponent
|
||||
{
|
||||
DamageDict = damageDict;
|
||||
DamageList = damageList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user