Generalize ResistanceSets into DamageModifierSets (#4619)

* generalize ResistanceSets into DamageModifierSets

* remove unneeded test prototype
This commit is contained in:
mirrorcult
2021-09-15 15:51:13 -07:00
committed by GitHub
parent cd6c2bb373
commit cc52ebb9b5
57 changed files with 131 additions and 112 deletions

View File

@@ -53,14 +53,9 @@ namespace Content.IntegrationTests.Tests.Damageable
- TestDamage3b
- TestDamage3c
- type: resistanceSet
id: testResistances
# this space is intentionally left blank
# This container should not support TestDamage1 or TestDamage2b
- type: damageContainer
id: testDamageContainer
defaultResistanceSet: testResistances
supportedGroups:
- TestGroup3
supportedTypes:

View File

@@ -1,27 +1,22 @@
using System;
using System;
using System.Collections.Generic;
using Robust.Shared.Prototypes;
using Content.Shared.Damage.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
using Robust.Shared.ViewVariables;
namespace Content.Shared.Damage.Prototypes
namespace Content.Shared.Damage
{
/// <summary>
/// Prototype of damage resistance sets. Can be applied to <see cref="DamageSpecifier"/> using <see
/// cref="DamageSpecifier.ApplyResistanceSet(ResistanceSetPrototype)"/>. This can be done several times as the
/// A set of coefficients or flat modifiers to damage types.. Can be applied to <see cref="DamageSpecifier"/> using <see
/// cref="DamageSpecifier.ApplyModifierSet(DamageSpecifier, DamageModifierSet)"/>. This can be done several times as the
/// <see cref="DamageSpecifier"/> is passed to it's final target. By default the receiving <see cref="DamageableComponent"/>, will
/// also apply it's own <see cref="ResistanceSetPrototype"/>.
/// also apply it's own <see cref="DamageModifierSet"/>.
/// </summary>
[Prototype("resistanceSet")]
[DataDefinition]
[Serializable, NetSerializable]
public class ResistanceSetPrototype : IPrototype
public class DamageModifierSet
{
[ViewVariables]
[DataField("id", required: true)]
public string ID { get; } = default!;
[DataField("coefficients", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<float, DamageTypePrototype>))]
public Dictionary<string, float> Coefficients = new();

View File

@@ -141,12 +141,12 @@ namespace Content.Shared.Damage
}
/// <summary>
/// Reduce (or increase) damages by applying a resistance set.
/// Reduce (or increase) damages by applying a damage modifier set.
/// </summary>
/// <remarks>
/// Only applies resistance to a damage type if it is dealing damage, not healing.
/// </remarks>
public static DamageSpecifier ApplyResistanceSet(DamageSpecifier damageSpec, ResistanceSetPrototype resistanceSet)
public static DamageSpecifier ApplyModifierSet(DamageSpecifier damageSpec, DamageModifierSet modifierSet)
{
// Make a copy of the given data. Don't modify the one passed to this function. I did this before, and weapons became
// duller as you hit walls. Neat, but not intended. And confusing, when you realize your fists don't work no
@@ -159,7 +159,7 @@ namespace Content.Shared.Damage
float newValue = entry.Value;
if (resistanceSet.FlatReduction.TryGetValue(entry.Key, out var reduction))
if (modifierSet.FlatReduction.TryGetValue(entry.Key, out var reduction))
{
newValue -= reduction;
if (newValue <= 0)
@@ -170,7 +170,7 @@ namespace Content.Shared.Damage
}
}
if (resistanceSet.Coefficients.TryGetValue(entry.Key, out var coefficient))
if (modifierSet.Coefficients.TryGetValue(entry.Key, out var coefficient))
{
// negative coefficients **can** heal you.
newValue = MathF.Round(newValue*coefficient, MidpointRounding.AwayFromZero);

View File

@@ -19,7 +19,7 @@ namespace Content.Shared.Damage
/// </summary>
/// <remarks>
/// The supported damage types are specified using a <see cref="DamageContainerPrototype"/>s. DamageContainers
/// may also have resistances to certain damage types, defined via a <see cref="ResistanceSetPrototype"/>.
/// may also have resistances to certain damage types, defined via a <see cref="DamageModifierSetPrototype"/>.
/// </remarks>
[RegisterComponent]
[NetworkedComponent()]
@@ -36,12 +36,16 @@ namespace Content.Shared.Damage
public string? DamageContainerID;
/// <summary>
/// This <see cref="ResistanceSetPrototype"/> will be applied to any damage that is dealt to this container,
/// This <see cref="DamageModifierSetPrototype"/> will be applied to any damage that is dealt to this container,
/// unless the damage explicitly ignores resistances.
/// </summary>
/// <remarks>
/// Though DamageModifierSets can be deserialized directly, we only want to use the prototype version here
/// to reduce duplication.
/// </remarks>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("resistanceSet", customTypeSerializer: typeof(PrototypeIdSerializer<ResistanceSetPrototype>))]
public string? ResistanceSetID;
[DataField("damageModifierSet", customTypeSerializer: typeof(PrototypeIdSerializer<DamageModifierSetPrototype>))]
public string? DamageModifierSetId;
/// <summary>
/// All the damage information is stored in this <see cref="DamageSpecifier"/>.
@@ -116,14 +120,14 @@ namespace Content.Shared.Damage
public class DamageableComponentState : ComponentState
{
public readonly Dictionary<string, int> DamageDict;
public readonly string? ResistanceSetID;
public readonly string? ModifierSetId;
public DamageableComponentState(
Dictionary<string, int> damageDict,
string? resistanceSetID)
string? modifierSetId)
{
DamageDict = damageDict;
ResistanceSetID = resistanceSetID;
ModifierSetId = modifierSetId;
}
}
}

View File

@@ -118,11 +118,11 @@ namespace Content.Shared.Damage
}
// Apply resistances
if (!ignoreResistances && damageable.ResistanceSetID != null)
if (!ignoreResistances && damageable.DamageModifierSetId != null)
{
if (_prototypeManager.TryIndex<ResistanceSetPrototype>(damageable.ResistanceSetID, out var resistanceSet))
if (_prototypeManager.TryIndex<DamageModifierSetPrototype>(damageable.DamageModifierSetId, out var modifierSet))
{
damage = DamageSpecifier.ApplyResistanceSet(damage, resistanceSet);
damage = DamageSpecifier.ApplyModifierSet(damage, modifierSet);
}
if (damage.Empty)
@@ -174,7 +174,7 @@ namespace Content.Shared.Damage
private void DamageableGetState(EntityUid uid, DamageableComponent component, ref ComponentGetState args)
{
args.State = new DamageableComponentState(component.Damage.DamageDict, component.ResistanceSetID);
args.State = new DamageableComponentState(component.Damage.DamageDict, component.DamageModifierSetId);
}
private void DamageableHandleState(EntityUid uid, DamageableComponent component, ref ComponentHandleState args)
@@ -184,7 +184,7 @@ namespace Content.Shared.Damage
return;
}
component.ResistanceSetID = state.ResistanceSetID;
component.DamageModifierSetId = state.ModifierSetId;
// Has the damage actually changed?
DamageSpecifier newDamage = new() { DamageDict = state.DamageDict };

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
using Robust.Shared.ViewVariables;
namespace Content.Shared.Damage.Prototypes
{
/// <summary>
/// A version of DamageModifierSet that can be serialized as a prototype, but is functionally identical.
/// </summary>
/// <remarks>
/// Done to avoid removing the 'required' tag on the ID and passing around a 'prototype' when we really
/// just want normal data to be deserialized.
/// </remarks>
[Prototype("damageModifierSet")]
public class DamageModifierSetPrototype : DamageModifierSet, IPrototype
{
[ViewVariables]
[DataField("id", required: true)]
public string ID { get; } = default!;
}
}

View File

@@ -11,7 +11,7 @@ namespace Content.Tests.Shared
// Basic tests of various damage prototypes and classes.
[TestFixture]
[TestOf(typeof(DamageSpecifier))]
[TestOf(typeof(ResistanceSetPrototype))]
[TestOf(typeof(DamageModifierSetPrototype))]
[TestOf(typeof(DamageGroupPrototype))]
public class DamageTest : ContentUnitTest
{
@@ -132,13 +132,13 @@ namespace Content.Tests.Shared
//Check that DamageSpecifier will be properly adjusted by a resistance set
[Test]
public void ResistanceSetTest()
public void ModifierSetTest()
{
// Create a copy of the damage data
DamageSpecifier damageSpec = 10 * new DamageSpecifier(_damageSpec);
// Create a resistance set
ResistanceSetPrototype resistanceSet = new()
// Create a modifier set
DamageModifierSetPrototype modifierSet = new()
{
Coefficients = _resistanceCoefficientDict,
FlatReduction = _resistanceReductionDict
@@ -149,14 +149,14 @@ namespace Content.Tests.Shared
//then multiply by 1 / -2 / 3 / 1.06
// Apply once
damageSpec = DamageSpecifier.ApplyResistanceSet(damageSpec, resistanceSet);
damageSpec = DamageSpecifier.ApplyModifierSet(damageSpec, modifierSet);
Assert.That(damageSpec.DamageDict["Blunt"], Is.EqualTo(25));
Assert.That(damageSpec.DamageDict["Piercing"], Is.EqualTo(-40)); // became healing
Assert.That(damageSpec.DamageDict["Slash"], Is.EqualTo(6));
Assert.That(damageSpec.DamageDict["Radiation"], Is.EqualTo(31)); // would be 32 w/o fraction adjustment
// And again, checking for some other behavior
damageSpec = DamageSpecifier.ApplyResistanceSet(damageSpec, resistanceSet);
damageSpec = DamageSpecifier.ApplyModifierSet(damageSpec, modifierSet);
Assert.That(damageSpec.DamageDict["Blunt"], Is.EqualTo(30));
Assert.That(damageSpec.DamageDict["Piercing"], Is.EqualTo(-40)); // resistances don't apply to healing
Assert.That(!damageSpec.DamageDict.ContainsKey("Slash")); // Reduction reduced to 0, and removed from specifier
@@ -241,7 +241,7 @@ namespace Content.Tests.Shared
damageTypes:
- Cellular
- type: resistanceSet
- type: damageModifierSet
id: Metallic
coefficients:
Blunt: 0.7
@@ -251,7 +251,7 @@ namespace Content.Tests.Shared
flatReductions:
Blunt: 5
- type: resistanceSet
- type: damageModifierSet
id: Inflatable
coefficients:
Blunt: 0.5
@@ -261,7 +261,7 @@ namespace Content.Tests.Shared
flatReductions:
Blunt: 5
- type: resistanceSet
- type: damageModifierSet
id: Glass
coefficients:
Blunt: 0.5

View File

@@ -1,4 +1,4 @@
- type: resistanceSet
- type: damageModifierSet
id: Metallic
coefficients:
Blunt: 0.7
@@ -8,7 +8,7 @@
flatReductions:
Blunt: 5
- type: resistanceSet
- type: damageModifierSet
id: Inflatable
coefficients:
Blunt: 0.5
@@ -18,7 +18,7 @@
flatReductions:
Blunt: 5
- type: resistanceSet
- type: damageModifierSet
id: Glass
coefficients:
Blunt: 0.5

View File

@@ -126,7 +126,7 @@
- type: Airtight
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -31,7 +31,7 @@
isOpen: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Glass
damageModifierSet: Glass
- type: Destructible
thresholds:
- trigger:

View File

@@ -108,7 +108,7 @@
- type: Anchorable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
@@ -141,7 +141,7 @@
- type: Anchorable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -22,7 +22,7 @@
- SmallImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Inflatable
damageModifierSet: Inflatable
- type: Destructible
thresholds:
- trigger:

View File

@@ -30,7 +30,7 @@
- type: DeployableBarrier
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -46,7 +46,7 @@
fillBaseName: beaker
- type: Damageable
damageContainer: Inorganic
resistanceSet: Glass
damageModifierSet: Glass
- type: Destructible
thresholds:
- trigger:

View File

@@ -30,7 +30,7 @@
- type: Pullable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -27,7 +27,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -65,7 +65,7 @@
- type: Occluder
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -7,7 +7,7 @@
- type: InteractionOutline
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -13,7 +13,7 @@
- type: InteractionOutline
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -25,7 +25,7 @@
- type: Rotatable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -39,7 +39,7 @@
- type: ApcPowerReceiver
- type: Damageable
damageContainer: Inorganic
resistanceSet: Glass
damageModifierSet: Glass
- type: Destructible
thresholds:
- trigger:

View File

@@ -7,7 +7,7 @@
components:
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: PlaceableSurface
- type: Sprite
netsync: false

View File

@@ -10,7 +10,7 @@
sprite: Structures/Furniture/Tables/frame.rsi
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
@@ -43,7 +43,7 @@
sprite: Structures/Furniture/Tables/generic.rsi
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -25,7 +25,7 @@
rotation: -90
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -13,7 +13,7 @@
sprite: Structures/Furniture/instruments.rsi
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -25,7 +25,7 @@
- type: Pullable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -29,7 +29,7 @@
state: 0
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -19,7 +19,7 @@
- MobMask
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -33,7 +33,7 @@
- MobImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -32,7 +32,7 @@
node: missingWires
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
@@ -80,7 +80,7 @@
node: machineFrame
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -13,7 +13,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -13,7 +13,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Anchorable
- type: Rotatable
- type: Pullable

View File

@@ -17,7 +17,7 @@
- type: Anchorable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -46,7 +46,7 @@
nodeGroupID: MVPower
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -26,7 +26,7 @@
- SmallImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
@@ -112,7 +112,7 @@
- SmallImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -40,7 +40,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
@@ -81,7 +81,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
@@ -127,7 +127,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -22,7 +22,7 @@
anchored: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -20,7 +20,7 @@
drawdepth: BelowFloor
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -39,7 +39,7 @@
drawRate: 50
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -43,7 +43,7 @@
acts: [ "Destruction" ]
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Physics
bodyType: Dynamic
fixtures:
@@ -364,7 +364,7 @@
acts: [ "Destruction" ]
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: InteractionOutline
- type: Sprite
sprite: Structures/Storage/canister.rsi

View File

@@ -41,7 +41,7 @@
placeCentered: true
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -36,7 +36,7 @@
- type: PlaceableSurface
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -531,7 +531,7 @@
state_closed: livestockcrate_door
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -25,7 +25,7 @@
- SmallImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -27,7 +27,7 @@
- type: Anchorable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -13,7 +13,7 @@
!type:PhysShapeAabb {}
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -36,7 +36,7 @@
type: SignalPortSelectorBoundUserInterface
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -11,7 +11,7 @@
state: 0
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -25,7 +25,7 @@
- ExplosivePassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -19,7 +19,7 @@
state: full
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Physics
bodyType: Static
fixtures:

View File

@@ -29,7 +29,7 @@
- ExplosivePassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -16,7 +16,7 @@
state: metal
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -10,7 +10,7 @@
sprite: Structures/Windows/plasma_window.rsi
- type: Damageable
damageContainer: Inorganic
resistanceSet: Glass
damageModifierSet: Glass
- type: Destructible
thresholds:
- trigger:

View File

@@ -31,7 +31,7 @@
- VaultImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Glass
damageModifierSet: Glass
- type: Repairable
- type: Destructible
thresholds:

View File

@@ -20,7 +20,7 @@
drawdepth: FloorObjects
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -12,7 +12,7 @@
state: spike
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:

View File

@@ -26,7 +26,7 @@
- SmallImpassable
- type: Damageable
damageContainer: Inorganic
resistanceSet: Metallic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger: