using Content.Shared.Damage;
using Content.Shared.Database;
using Content.Shared.Interaction;
+using Content.Shared.Inventory;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Projectiles;
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly FixtureSystem _fixture = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly IRobustRandom _random = default!;
+ private EntityQuery<InventoryComponent> _inventoryQuery;
private EntityQuery<PhysicsComponent> _physicsQuery;
// This should probably be moved to the component, requires a rewrite, all fires tick at the same time
{
UpdatesAfter.Add(typeof(AtmosphereSystem));
+ _inventoryQuery = GetEntityQuery<InventoryComponent>();
_physicsQuery = GetEntityQuery<PhysicsComponent>();
SubscribeLocalEvent<FlammableComponent, MapInitEvent>(OnMapInit);
continue;
}
- EnsureComp<IgnitionSourceComponent>(uid);
- _ignitionSourceSystem.SetIgnited(uid);
+ var source = EnsureComp<IgnitionSourceComponent>(uid);
+ _ignitionSourceSystem.SetIgnited((uid, source));
if (TryComp(uid, out TemperatureComponent? temp))
_temperatureSystem.ChangeHeat(uid, 12500 * flammable.FireStacks, false, temp);
- _damageableSystem.TryChangeDamage(uid, flammable.Damage * flammable.FireStacks, interruptsDoAfters: false);
+ var ev = new GetFireProtectionEvent();
+ // let the thing on fire handle it
+ RaiseLocalEvent(uid, ref ev);
+ // and whatever it's wearing
+ if (_inventoryQuery.TryComp(uid, out var inv))
+ _inventory.RelayEvent((uid, inv), ref ev);
+
+ _damageableSystem.TryChangeDamage(uid, flammable.Damage * flammable.FireStacks * ev.Multiplier, interruptsDoAfters: false);
AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable);
}
--- /dev/null
+using Content.Shared.Inventory;
+
+namespace Content.Shared.Atmos;
+
+/// <summary>
+/// Raised on a burning entity to check its fire protection.
+/// Damage taken is multiplied by the final amount, but not temperature.
+/// TemperatureProtection is needed for that.
+/// </summary>
+[ByRefEvent]
+public sealed class GetFireProtectionEvent : EntityEventArgs, IInventoryRelayEvent
+{
+ public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET;
+
+ /// <summary>
+ /// What to multiply the fire damage by.
+ /// If this is 0 then it's ignored
+ /// </summary>
+ public float Multiplier;
+
+ public GetFireProtectionEvent()
+ {
+ Multiplier = 1f;
+ }
+
+ /// <summary>
+ /// Reduce fire damage taken by a percentage.
+ /// </summary>
+ public void Reduce(float by)
+ {
+ Multiplier -= by;
+ }
+}
--- /dev/null
+using Content.Shared.Clothing.EntitySystems;
+
+namespace Content.Shared.Clothing.Components;
+
+/// <summary>
+/// Makes this clothing reduce fire damage when worn.
+/// </summary>
+[RegisterComponent, Access(typeof(FireProtectionSystem))]
+public sealed partial class FireProtectionComponent : Component
+{
+ /// <summary>
+ /// Percentage to reduce fire damage by, subtracted not multiplicative.
+ /// 0.25 means 25% less fire damage.
+ /// </summary>
+ [DataField(required: true)]
+ public float Reduction;
+}
--- /dev/null
+using Content.Shared.Atmos;
+using Content.Shared.Clothing.Components;
+using Content.Shared.Inventory;
+
+namespace Content.Shared.Clothing.EntitySystems;
+
+/// <summary>
+/// Handles reducing fire damage when wearing clothing with <see cref="FireProtectionComponent"/>.
+/// </summary>
+public sealed class FireProtectionSystem : EntitySystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<FireProtectionComponent, InventoryRelayedEvent<GetFireProtectionEvent>>(OnGetProtection);
+ }
+
+ private void OnGetProtection(Entity<FireProtectionComponent> ent, ref InventoryRelayedEvent<GetFireProtectionEvent> args)
+ {
+ args.Args.Reduce(ent.Comp.Reduction);
+ }
+}
lowPressureMultiplier: 1000
- type: TemperatureProtection
coefficient: 0.1
+ - type: FireProtection
+ reduction: 0.2
- type: Armor
modifiers:
coefficients:
lowPressureMultiplier: 1000
- type: TemperatureProtection
coefficient: 0.005
+ - type: FireProtection
+ reduction: 0.2
- type: Armor
modifiers:
coefficients:
- type: IngestionBlocker
- type: TemperatureProtection
coefficient: 0.005
+ - type: FireProtection
+ reduction: 0.15 # not fully sealed so less protection
- type: IdentityBlocker
- type: Tag
tags:
- type: IngestionBlocker
- type: TemperatureProtection
coefficient: 0.005
+ - type: FireProtection
+ reduction: 0.2
- type: PressureProtection
highPressureMultiplier: 0.25
lowPressureMultiplier: 1000
highPressureMultiplier: 0.3
lowPressureMultiplier: 1000
- type: TemperatureProtection
- coefficient: 0.001 # yes it needs to be this low, fires are fucking deadly apparently!!!!
+ coefficient: 0.01
+ - type: FireProtection
+ reduction: 0.75 # almost perfectly sealed, atmos firesuit is better
- type: ClothingSpeedModifier
walkModifier: 0.4
sprintModifier: 0.6
Blunt: 0.9
Slash: 0.9
Piercing: 0.9
- Heat: 0.2
+ Heat: 0.8
Radiation: 0.5
- Caustic: 0.5
- type: ClothingSpeedModifier
walkModifier: 0.7
sprintModifier: 0.7
- type: PressureProtection
highPressureMultiplier: 0.04
lowPressureMultiplier: 1000
- - type: TemperatureProtection
- coefficient: 0.01
- type: ExplosionResistance
damageCoefficient: 0.5
- type: Armor
coefficient: 0.001
- type: ExplosionResistance
damageCoefficient: 0.2
+ - type: FireProtection
+ reduction: 0.8 # perfect protection like atmos firesuit for pyro tf2 ops
- type: Armor
modifiers:
coefficients:
highPressureMultiplier: 0.04
- type: TemperatureProtection
coefficient: 0.005
+ - type: FireProtection
+ reduction: 0.65 # doesnt have a full seal so not as good
- type: Armor
modifiers:
coefficients:
Slash: 0.9
- Heat: 0.3
- Cold: 0.2
+ Heat: 0.8
+ Cold: 0.8
- type: ClothingSpeedModifier
walkModifier: 0.8
sprintModifier: 0.7
lowPressureMultiplier: 1000
- type: TemperatureProtection
coefficient: 0.001
+ - type: FireProtection
+ reduction: 0.8 # atmos firesuit offers best protection, hardsuits are a little vulnerable
- type: Armor
modifiers:
coefficients:
Slash: 0.9
- Heat: 0.3
- Cold: 0.2
+ Heat: 0.8
+ Cold: 0.8
- type: ClothingSpeedModifier
walkModifier: 0.8
sprintModifier: 0.8