From 6cea9cb9732e970d6fc9243531b877355c99e890 Mon Sep 17 00:00:00 2001 From: Vera Aguilera Puerto <6766154+Zumorica@users.noreply.github.com> Date: Wed, 22 Sep 2021 11:05:33 +0200 Subject: [PATCH] Refactor Flammable to be ECS. (#4671) - Refactor IHotItem into IsHotEvent. - Refactor IFireAct into TileFireEvent. --- .../Atmos/Visualizers/FireVisualizer.cs | 3 +- Content.Server/Alert/Click/ResistFire.cs | 4 +- .../Atmos/Components/AtmosExposedComponent.cs | 9 +- .../Atmos/Components/FlammableComponent.cs | 157 +----------- .../EntitySystems/AtmosphereSystem.Hotspot.cs | 15 +- .../Atmos/EntitySystems/FlammableSystem.cs | 229 ++++++++++++++++-- Content.Server/Atmos/FireEvent.cs | 7 - Content.Server/Atmos/TileFireEvent.cs | 19 ++ .../ExtinguishReaction.cs | 6 +- .../FlammableReaction.cs | 3 +- Content.Server/Damage/RejuvenateVerb.cs | 3 +- .../Light/Components/MatchstickComponent.cs | 8 +- .../Light/EntitySystems/MatchstickSystem.cs | 25 +- .../Nutrition/Components/SmokingComponent.cs | 32 ++- .../Nutrition/EntitySystems/SmokingSystem.cs | 20 ++ .../Tools/Components/WelderComponent.cs | 8 +- Content.Server/Tools/WelderSystem.cs | 7 + .../Components/SharedFlammableComponent.cs | 18 -- Content.Shared/Atmos/FireVisuals.cs | 12 + Content.Shared/Temperature/IHotItem.cs | 17 -- Content.Shared/Temperature/IsHotEvent.cs | 14 ++ 21 files changed, 348 insertions(+), 268 deletions(-) delete mode 100644 Content.Server/Atmos/FireEvent.cs create mode 100644 Content.Server/Atmos/TileFireEvent.cs create mode 100644 Content.Server/Nutrition/EntitySystems/SmokingSystem.cs delete mode 100644 Content.Shared/Atmos/Components/SharedFlammableComponent.cs create mode 100644 Content.Shared/Atmos/FireVisuals.cs delete mode 100644 Content.Shared/Temperature/IHotItem.cs create mode 100644 Content.Shared/Temperature/IsHotEvent.cs diff --git a/Content.Client/Atmos/Visualizers/FireVisualizer.cs b/Content.Client/Atmos/Visualizers/FireVisualizer.cs index ca0905f046..db7d36e1a2 100644 --- a/Content.Client/Atmos/Visualizers/FireVisualizer.cs +++ b/Content.Client/Atmos/Visualizers/FireVisualizer.cs @@ -1,4 +1,5 @@ -using Content.Shared.Atmos.Components; +using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Shared.GameObjects; diff --git a/Content.Server/Alert/Click/ResistFire.cs b/Content.Server/Alert/Click/ResistFire.cs index d8d157fac8..94d0e594dc 100644 --- a/Content.Server/Alert/Click/ResistFire.cs +++ b/Content.Server/Alert/Click/ResistFire.cs @@ -1,6 +1,8 @@ using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; using Content.Shared.Alert; using JetBrains.Annotations; +using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; namespace Content.Server.Alert.Click @@ -16,7 +18,7 @@ namespace Content.Server.Alert.Click { if (args.Player.TryGetComponent(out FlammableComponent? flammable)) { - flammable.Resist(); + EntitySystem.Get().Resist(args.Player.Uid, flammable); } } } diff --git a/Content.Server/Atmos/Components/AtmosExposedComponent.cs b/Content.Server/Atmos/Components/AtmosExposedComponent.cs index 9be43d8067..0566252776 100644 --- a/Content.Server/Atmos/Components/AtmosExposedComponent.cs +++ b/Content.Server/Atmos/Components/AtmosExposedComponent.cs @@ -5,12 +5,12 @@ using Robust.Shared.ViewVariables; namespace Content.Server.Atmos.Components { + // TODO: Kill this. With fire. /// /// Represents that entity can be exposed to Atmos /// [RegisterComponent] - public class AtmosExposedComponent - : Component + public class AtmosExposedComponent : Component { public override string Name => "AtmosExposed"; @@ -20,9 +20,6 @@ namespace Content.Server.Atmos.Components [ViewVariables] [ComponentDependency] private readonly BarotraumaComponent? _barotraumaComponent = null; - [ViewVariables] - [ComponentDependency] private readonly FlammableComponent? _flammableComponent = null; - public void Update(GasMixture air, float frameDelta, AtmosphereSystem atmosphereSystem) { if (_temperatureComponent != null) @@ -35,8 +32,6 @@ namespace Content.Server.Atmos.Components } _barotraumaComponent?.Update(air.Pressure); - - _flammableComponent?.Update(air); } } } diff --git a/Content.Server/Atmos/Components/FlammableComponent.cs b/Content.Server/Atmos/Components/FlammableComponent.cs index 53b608d0d7..88be46c850 100644 --- a/Content.Server/Atmos/Components/FlammableComponent.cs +++ b/Content.Server/Atmos/Components/FlammableComponent.cs @@ -1,32 +1,22 @@ -using System; using System.Collections.Generic; -using System.Threading.Tasks; -using Content.Server.Alert; using Content.Server.Atmos.EntitySystems; -using Content.Server.Stunnable.Components; -using Content.Server.Temperature.Components; -using Content.Shared.ActionBlocker; -using Content.Shared.Alert; -using Content.Shared.Atmos; -using Content.Shared.Atmos.Components; using Content.Shared.Damage; -using Content.Shared.Interaction; -using Content.Shared.Notification.Managers; -using Content.Shared.Temperature; -using Robust.Server.GameObjects; using Robust.Shared.GameObjects; -using Robust.Shared.Localization; -using Robust.Shared.Physics; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; namespace Content.Server.Atmos.Components { [RegisterComponent] - public class FlammableComponent : SharedFlammableComponent, IFireAct, IInteractUsing + public class FlammableComponent : Component { - private bool _resisting = false; - private readonly List _collided = new(); + public override string Name => "Flammable"; + + [ViewVariables] + public bool Resisting = false; + + [ViewVariables] + public readonly List Collided = new(); [ViewVariables(VVAccess.ReadWrite)] public bool OnFire { get; set; } @@ -45,136 +35,5 @@ namespace Content.Server.Atmos.Components [DataField("damage", required: true)] [ViewVariables(VVAccess.ReadWrite)] public DamageSpecifier Damage = default!; - - public void Extinguish() - { - if (!OnFire) return; - OnFire = false; - FireStacks = 0; - - _collided.Clear(); - - UpdateAppearance(); - } - - public void AdjustFireStacks(float relativeFireStacks) - { - FireStacks = MathF.Min(MathF.Max(-10f, FireStacks + relativeFireStacks), 20f); - if (OnFire && FireStacks <= 0) - Extinguish(); - - UpdateAppearance(); - } - - public void Update(GasMixture air) - { - // Slowly dry ourselves off if wet. - if (FireStacks < 0) - { - FireStacks = MathF.Min(0, FireStacks + 1); - } - - Owner.TryGetComponent(out ServerAlertsComponent? status); - - if (!OnFire) - { - status?.ClearAlert(AlertType.Fire); - return; - } - - status?.ShowAlert(AlertType.Fire); - - if (FireStacks > 0) - { - if (Owner.TryGetComponent(out TemperatureComponent? temp)) - { - temp.ReceiveHeat(200 * FireStacks); - } - - // TODO ATMOS Fire resistance from armor - var damageScale = Math.Min((int) (FireStacks * 2.5f), 10); - EntitySystem.Get().TryChangeDamage(Owner.Uid, Damage * damageScale); - - AdjustFireStacks(-0.1f * (_resisting ? 10f : 1f)); - } - else - { - Extinguish(); - return; - } - - // If we're in an oxygenless environment, put the fire out. - if (air.GetMoles(Gas.Oxygen) < 1f) - { - Extinguish(); - return; - } - - EntitySystem.Get().HotspotExpose(Owner.Transform.Coordinates, 700f, 50f, true); - - var physics = Owner.GetComponent(); - - foreach (var uid in _collided.ToArray()) - { - if (!uid.IsValid() || !Owner.EntityManager.EntityExists(uid)) - { - _collided.Remove(uid); - continue; - } - - var entity = Owner.EntityManager.GetEntity(uid); - var otherPhysics = entity.GetComponent(); - - if (!physics.GetWorldAABB().Intersects(otherPhysics.GetWorldAABB())) - { - _collided.Remove(uid); - } - } - } - - public void UpdateAppearance() - { - if (Owner.Deleted || !Owner.TryGetComponent(out AppearanceComponent? appearanceComponent)) return; - appearanceComponent.SetData(FireVisuals.OnFire, OnFire); - appearanceComponent.SetData(FireVisuals.FireStacks, FireStacks); - } - - public void FireAct(float temperature, float volume) - { - AdjustFireStacks(3); - EntitySystem.Get().Ignite(this); - } - - // This needs some improvements... - public void Resist() - { - if (!OnFire || !EntitySystem.Get().CanInteract(Owner) || _resisting || !Owner.TryGetComponent(out StunnableComponent? stunnable)) return; - - _resisting = true; - - Owner.PopupMessage(Loc.GetString("flammable-component-resist-message")); - stunnable.Paralyze(2f); - - Owner.SpawnTimer(2000, () => - { - _resisting = false; - FireStacks -= 3f; - UpdateAppearance(); - }); - } - - public async Task InteractUsing(InteractUsingEventArgs eventArgs) - { - foreach (var hotItem in eventArgs.Using.GetAllComponents()) - { - if (hotItem.IsCurrentlyHot()) - { - EntitySystem.Get().Ignite(this); - return true; - } - } - - return false; - } } } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Hotspot.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Hotspot.cs index 445984d021..ae213ddc45 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Hotspot.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Hotspot.cs @@ -1,13 +1,15 @@ using Content.Server.Atmos.Components; using Content.Server.Atmos.Reactions; -using Content.Server.Coordinates.Helpers; using Content.Shared.Atmos; -using Content.Shared.Maps; +using Robust.Server.GameObjects; +using Robust.Shared.IoC; namespace Content.Server.Atmos.EntitySystems { public partial class AtmosphereSystem { + [Dependency] private readonly GridTileLookupSystem _gridtileLookupSystem = default!; + private void ProcessHotspot(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile) { if (!tile.Hotspot.Valid) @@ -137,14 +139,11 @@ namespace Content.Server.Atmos.EntitySystems Merge(tile.Air, affected); } - var tileRef = tile.GridIndices.GetTileRef(tile.GridIndex, _mapManager); + var fireEvent = new TileFireEvent(tile.Hotspot.Temperature, tile.Hotspot.Volume); - foreach (var entity in tileRef.GetEntitiesInTileFast()) + foreach (var entity in _gridtileLookupSystem.GetEntitiesIntersecting(tile.GridIndex, tile.GridIndices)) { - foreach (var fireAct in entity.GetAllComponents()) - { - fireAct.FireAct(tile.Hotspot.Temperature, tile.Hotspot.Volume); - } + RaiseLocalEvent(entity.Uid, fireEvent, false); } } } diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index 3a253f64e9..ea1c278f7e 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -1,56 +1,251 @@ +using System; +using Content.Server.Alert; using Content.Server.Atmos.Components; +using Content.Server.Stunnable.Components; +using Content.Server.Temperature.Components; +using Content.Shared.ActionBlocker; +using Content.Shared.Alert; +using Content.Shared.Atmos; +using Content.Shared.Damage; +using Content.Shared.Interaction; +using Content.Shared.Notification.Managers; +using Content.Shared.Temperature; +using Robust.Server.GameObjects; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Physics; using Robust.Shared.Physics.Dynamics; namespace Content.Server.Atmos.EntitySystems { internal sealed class FlammableSystem : EntitySystem { + [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; + + private const float MinimumFireStacks = -10f; + private const float MaximumFireStacks = 20f; + private const float UpdateTime = 1f; + + private float _timer = 0f; + // TODO: Port the rest of Flammable. public override void Initialize() { - base.Initialize(); - SubscribeLocalEvent(HandleCollide); + SubscribeLocalEvent(OnInteractUsingEvent); + SubscribeLocalEvent(OnCollideEvent); + SubscribeLocalEvent(OnIsHotEvent); + SubscribeLocalEvent(OnTileFireEvent); } - private void HandleCollide(EntityUid uid, FlammableComponent component, StartCollideEvent args) + private void OnInteractUsingEvent(EntityUid uid, FlammableComponent flammable, InteractUsingEvent args) { - if (!args.OtherFixture.Body.Owner.TryGetComponent(out FlammableComponent? otherFlammable)) + if (args.Handled) return; - if (!component.FireSpread || !otherFlammable.FireSpread) + var isHotEvent = new IsHotEvent(); + RaiseLocalEvent(args.Used.Uid, isHotEvent, false); + + if (!isHotEvent.IsHot) return; - if (component.OnFire) + Ignite(uid, flammable); + args.Handled = true; + } + + private void OnCollideEvent(EntityUid uid, FlammableComponent flammable, StartCollideEvent args) + { + var otherUid = args.OtherFixture.Body.Owner.Uid; + if (!ComponentManager.TryGetComponent(otherUid, out FlammableComponent? otherFlammable)) + return; + + if (!flammable.FireSpread || !otherFlammable.FireSpread) + return; + + if (flammable.OnFire) { if (otherFlammable.OnFire) { - var fireSplit = (component.FireStacks + otherFlammable.FireStacks) / 2; - component.FireStacks = fireSplit; + var fireSplit = (flammable.FireStacks + otherFlammable.FireStacks) / 2; + flammable.FireStacks = fireSplit; otherFlammable.FireStacks = fireSplit; } else { - component.FireStacks /= 2; - otherFlammable.FireStacks += component.FireStacks; - Ignite(otherFlammable); + flammable.FireStacks /= 2; + otherFlammable.FireStacks += flammable.FireStacks; + Ignite(otherUid, otherFlammable); } } else if (otherFlammable.OnFire) { otherFlammable.FireStacks /= 2; - component.FireStacks += otherFlammable.FireStacks; - Ignite(component); + flammable.FireStacks += otherFlammable.FireStacks; + Ignite(uid, flammable); } } - internal void Ignite(FlammableComponent component) + private void OnIsHotEvent(EntityUid uid, FlammableComponent flammable, IsHotEvent args) { - if (component.FireStacks > 0 && !component.OnFire) + args.IsHot = flammable.OnFire; + } + + private void OnTileFireEvent(EntityUid uid, FlammableComponent flammable, TileFireEvent args) + { + AdjustFireStacks(uid, 3, flammable); + Ignite(uid, flammable); + } + + public void UpdateAppearance(EntityUid uid, FlammableComponent? flammable = null, AppearanceComponent? appearance = null) + { + if (!Resolve(uid, ref flammable, ref appearance)) + return; + + appearance.SetData(FireVisuals.OnFire, flammable.OnFire); + appearance.SetData(FireVisuals.FireStacks, flammable.FireStacks); + } + + public void AdjustFireStacks(EntityUid uid, float relativeFireStacks, FlammableComponent? flammable = null) + { + if (!Resolve(uid, ref flammable)) + return; + + flammable.FireStacks = MathF.Min(MathF.Max(MinimumFireStacks, flammable.FireStacks + relativeFireStacks), MaximumFireStacks); + + if (flammable.OnFire && flammable.FireStacks <= 0) + Extinguish(uid, flammable); + + UpdateAppearance(uid, flammable); + } + + public void Extinguish(EntityUid uid, FlammableComponent? flammable = null) + { + if (!Resolve(uid, ref flammable)) + return; + + if (!flammable.OnFire) + return; + + flammable.OnFire = false; + flammable.FireStacks = 0; + + flammable.Collided.Clear(); + + UpdateAppearance(uid, flammable); + } + + public void Ignite(EntityUid uid, FlammableComponent? flammable = null) + { + if (!Resolve(uid, ref flammable)) + return; + + if (flammable.FireStacks > 0 && !flammable.OnFire) { - component.OnFire = true; + flammable.OnFire = true; } - component.UpdateAppearance(); + UpdateAppearance(uid, flammable); + } + + public void Resist(EntityUid uid, FlammableComponent? flammable = null, StunnableComponent? stunnable = null) + { + if (!Resolve(uid, ref flammable, ref stunnable)) + return; + + if (!flammable.OnFire || !_actionBlockerSystem.CanInteract(flammable.Owner) || flammable.Resisting) + return; + + flammable.Resisting = true; + + flammable.Owner.PopupMessage(Loc.GetString("flammable-component-resist-message")); + stunnable.Paralyze(2f); + + flammable.Owner.SpawnTimer(2000, () => + { + flammable.Resisting = false; + flammable.FireStacks -= 3f; + UpdateAppearance(uid, flammable); + }); + } + + public override void Update(float frameTime) + { + _timer += frameTime; + + if (_timer < UpdateTime) + return; + + _timer -= UpdateTime; + + // TODO: This needs cleanup to take off the crust from TemperatureComponent and shit. + foreach (var (flammable, physics, transform) in ComponentManager.EntityQuery()) + { + var uid = flammable.Owner.Uid; + + // Slowly dry ourselves off if wet. + if (flammable.FireStacks < 0) + { + flammable.FireStacks = MathF.Min(0, flammable.FireStacks + 1); + } + + flammable.Owner.TryGetComponent(out ServerAlertsComponent? status); + + if (!flammable.OnFire) + { + status?.ClearAlert(AlertType.Fire); + return; + } + + status?.ShowAlert(AlertType.Fire); + + if (flammable.FireStacks > 0) + { + if (flammable.Owner.TryGetComponent(out TemperatureComponent? temp)) + { + temp.ReceiveHeat(200 * flammable.FireStacks); + } + + // TODO ATMOS Fire resistance from armor + var damageScale = Math.Min((int) (flammable.FireStacks * 2.5f), 10); + _damageableSystem.TryChangeDamage(flammable.Owner.Uid, flammable.Damage * damageScale); + + AdjustFireStacks(uid, -0.1f * (flammable.Resisting ? 10f : 1f), flammable); + } + else + { + Extinguish(uid, flammable); + return; + } + + var air = _atmosphereSystem.GetTileMixture(transform.Coordinates); + + // If we're in an oxygenless environment, put the fire out. + if (air == null || air.GetMoles(Gas.Oxygen) < 1f) + { + Extinguish(uid, flammable); + return; + } + + _atmosphereSystem.HotspotExpose(transform.Coordinates, 700f, 50f, true); + + foreach (var otherUid in flammable.Collided.ToArray()) + { + if (!otherUid.IsValid() || !EntityManager.EntityExists(otherUid)) + { + flammable.Collided.Remove(otherUid); + continue; + } + + var otherPhysics = ComponentManager.GetComponent(uid); + + // TODO: Sloth, please save our souls! + if (!physics.GetWorldAABB().Intersects(otherPhysics.GetWorldAABB())) + { + flammable.Collided.Remove(otherUid); + } + } + } } } } diff --git a/Content.Server/Atmos/FireEvent.cs b/Content.Server/Atmos/FireEvent.cs deleted file mode 100644 index 2007f61aec..0000000000 --- a/Content.Server/Atmos/FireEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Server.Atmos -{ - public interface IFireAct - { - void FireAct(float temperature, float volume); - } -} diff --git a/Content.Server/Atmos/TileFireEvent.cs b/Content.Server/Atmos/TileFireEvent.cs new file mode 100644 index 0000000000..6bcdd2fc5d --- /dev/null +++ b/Content.Server/Atmos/TileFireEvent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.GameObjects; + +namespace Content.Server.Atmos +{ + /// + /// Event raised directed to an entity when it is standing on a tile that's on fire. + /// + public class TileFireEvent : EntityEventArgs + { + public float Temperature { get; } + public float Volume { get; } + + public TileFireEvent(float temperature, float volume) + { + Temperature = temperature; + Volume = volume; + } + } +} diff --git a/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs b/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs index d24504db76..b306bed33d 100644 --- a/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs +++ b/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using JetBrains.Annotations; @@ -20,8 +21,9 @@ namespace Content.Server.Chemistry.ReagentEntityReactions { if (!entity.TryGetComponent(out FlammableComponent? flammable) || !_reagents.Contains(reagent.ID)) return; - flammable.Extinguish(); - flammable.AdjustFireStacks(-1.5f); + var flammableSystem = EntitySystem.Get(); + flammableSystem.Extinguish(entity.Uid, flammable); + flammableSystem.AdjustFireStacks(entity.Uid, -1.5f, flammable); } } } diff --git a/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs b/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs index a920a38e75..25673c96f9 100644 --- a/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs +++ b/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using JetBrains.Annotations; @@ -20,7 +21,7 @@ namespace Content.Server.Chemistry.ReagentEntityReactions { if (!entity.TryGetComponent(out FlammableComponent? flammable) || !_reagents.Contains(reagent.ID)) return; - flammable.AdjustFireStacks(volume.Float() / 10f); + EntitySystem.Get().AdjustFireStacks(entity.Uid, volume.Float() / 10f, flammable); source?.RemoveReagent(reagent.ID, volume); } } diff --git a/Content.Server/Damage/RejuvenateVerb.cs b/Content.Server/Damage/RejuvenateVerb.cs index d58973a68d..0462f1af28 100644 --- a/Content.Server/Damage/RejuvenateVerb.cs +++ b/Content.Server/Damage/RejuvenateVerb.cs @@ -1,4 +1,5 @@ using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; using Content.Server.Nutrition.Components; using Content.Server.Nutrition.EntitySystems; using Content.Server.Stunnable.Components; @@ -81,7 +82,7 @@ namespace Content.Server.Damage if (target.TryGetComponent(out FlammableComponent? flammable)) { - flammable.Extinguish(); + EntitySystem.Get().Extinguish(target.Uid, flammable); } if (target.TryGetComponent(out CreamPiedComponent? creamPied)) diff --git a/Content.Server/Light/Components/MatchstickComponent.cs b/Content.Server/Light/Components/MatchstickComponent.cs index 525c982d8d..4ec5d83589 100644 --- a/Content.Server/Light/Components/MatchstickComponent.cs +++ b/Content.Server/Light/Components/MatchstickComponent.cs @@ -12,9 +12,8 @@ using Robust.Shared.ViewVariables; namespace Content.Server.Light.Components { [RegisterComponent] - [ComponentReference(typeof(IHotItem))] [Friend(typeof(MatchstickSystem))] - public class MatchstickComponent : Component, IHotItem + public class MatchstickComponent : Component { public override string Name => "Matchstick"; @@ -41,10 +40,5 @@ namespace Content.Server.Light.Components /// [ComponentDependency] public readonly PointLightComponent? PointLightComponent = default!; - - bool IHotItem.IsCurrentlyHot() - { - return CurrentState == SharedBurningStates.Lit; - } } } diff --git a/Content.Server/Light/EntitySystems/MatchstickSystem.cs b/Content.Server/Light/EntitySystems/MatchstickSystem.cs index 611d8f68c2..d0e50234f3 100644 --- a/Content.Server/Light/EntitySystems/MatchstickSystem.cs +++ b/Content.Server/Light/EntitySystems/MatchstickSystem.cs @@ -24,6 +24,7 @@ namespace Content.Server.Light.EntitySystems { base.Initialize(); SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnIsHotEvent); } public override void Update(float frameTime) @@ -40,14 +41,22 @@ namespace Content.Server.Light.EntitySystems private void OnInteractUsing(EntityUid uid, MatchstickComponent component, InteractUsingEvent args) { - if (!args.Handled - && args.Used.TryGetComponent(out var hotItem) - && hotItem.IsCurrentlyHot() - && component.CurrentState == SharedBurningStates.Unlit) - { - Ignite(component, args.User); - args.Handled = true; - } + if (args.Handled || component.CurrentState != SharedBurningStates.Unlit) + return; + + var isHotEvent = new IsHotEvent(); + RaiseLocalEvent(args.Used.Uid, isHotEvent, false); + + if (!isHotEvent.IsHot) + return; + + Ignite(component, args.User); + args.Handled = true; + } + + private void OnIsHotEvent(EntityUid uid, MatchstickComponent component, IsHotEvent args) + { + args.IsHot = component.CurrentState == SharedBurningStates.Lit; } public void Ignite(MatchstickComponent component, IEntity user) diff --git a/Content.Server/Nutrition/Components/SmokingComponent.cs b/Content.Server/Nutrition/Components/SmokingComponent.cs index ee75bc91a9..143495ba9d 100644 --- a/Content.Server/Nutrition/Components/SmokingComponent.cs +++ b/Content.Server/Nutrition/Components/SmokingComponent.cs @@ -23,7 +23,7 @@ namespace Content.Server.Nutrition.Components /// TODO: Allow suicide via excessive Smoking /// [RegisterComponent] - public class SmokingComponent : Component, IInteractUsing, IHotItem + public class SmokingComponent : Component, IInteractUsing { public override string Name => "Smoking"; @@ -50,7 +50,7 @@ namespace Content.Server.Nutrition.Components //private float _temperature = 673.15f; [ViewVariables] - private SharedBurningStates CurrentState + public SharedBurningStates CurrentState { get => _currentState; set @@ -76,25 +76,23 @@ namespace Content.Server.Nutrition.Components } } + // TODO: ECS this method and component. async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) { - if (eventArgs.Using.TryGetComponent(out IHotItem? lighter) - && lighter.IsCurrentlyHot() - && CurrentState == SharedBurningStates.Unlit - ) - { - CurrentState = SharedBurningStates.Lit; - // TODO More complex handling of cigar consumption - Owner.SpawnTimer(_duration * 1000, () => CurrentState = SharedBurningStates.Burnt); - return true; - } + if (CurrentState != SharedBurningStates.Unlit) + return false; - return false; - } + var isHotEvent = new IsHotEvent(); + Owner.EntityManager.EventBus.RaiseLocalEvent(eventArgs.Using.Uid, isHotEvent, false); + + if (!isHotEvent.IsHot) + return false; + + CurrentState = SharedBurningStates.Lit; + // TODO More complex handling of cigar consumption + Owner.SpawnTimer(_duration * 1000, () => CurrentState = SharedBurningStates.Burnt); + return true; - bool IHotItem.IsCurrentlyHot() - { - return _currentState == SharedBurningStates.Lit; } } } diff --git a/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs b/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs new file mode 100644 index 0000000000..237c51c9d3 --- /dev/null +++ b/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs @@ -0,0 +1,20 @@ +using Content.Server.Nutrition.Components; +using Content.Shared.Smoking; +using Content.Shared.Temperature; +using Robust.Shared.GameObjects; + +namespace Content.Server.Nutrition.EntitySystems +{ + public class SmokingSystem : EntitySystem + { + public override void Initialize() + { + SubscribeLocalEvent(OnIsHotEvent); + } + + private void OnIsHotEvent(EntityUid uid, SmokingComponent component, IsHotEvent args) + { + args.IsHot = component.CurrentState == SharedBurningStates.Lit; + } + } +} diff --git a/Content.Server/Tools/Components/WelderComponent.cs b/Content.Server/Tools/Components/WelderComponent.cs index 27672a7adb..367c0eaf4a 100644 --- a/Content.Server/Tools/Components/WelderComponent.cs +++ b/Content.Server/Tools/Components/WelderComponent.cs @@ -33,9 +33,8 @@ namespace Content.Server.Tools.Components [RegisterComponent] [ComponentReference(typeof(ToolComponent))] [ComponentReference(typeof(IToolComponent))] - [ComponentReference(typeof(IHotItem))] [NetworkedComponent()] - public class WelderComponent : ToolComponent, IUse, ISuicideAct, IHotItem, IAfterInteract + public class WelderComponent : ToolComponent, IUse, ISuicideAct, IAfterInteract { [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; @@ -98,11 +97,6 @@ namespace Content.Server.Tools.Components } } - bool IHotItem.IsCurrentlyHot() - { - return WelderLit; - } - protected override void Initialize() { base.Initialize(); diff --git a/Content.Server/Tools/WelderSystem.cs b/Content.Server/Tools/WelderSystem.cs index bf3fb9a604..2a8451dfb6 100644 --- a/Content.Server/Tools/WelderSystem.cs +++ b/Content.Server/Tools/WelderSystem.cs @@ -4,6 +4,7 @@ using System.Linq; using Content.Server.Tools.Components; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Examine; +using Content.Shared.Temperature; using Robust.Shared.GameObjects; using Robust.Shared.Localization; @@ -21,9 +22,15 @@ namespace Content.Server.Tools base.Initialize(); SubscribeLocalEvent(OnSolutionChange); + SubscribeLocalEvent(OnIsHotEvent); SubscribeLocalEvent(OnExamine); } + private void OnIsHotEvent(EntityUid uid, WelderComponent component, IsHotEvent args) + { + args.IsHot = component.WelderLit; + } + private void OnExamine(EntityUid uid, WelderComponent component, ExaminedEvent args) { if (component.WelderLit) diff --git a/Content.Shared/Atmos/Components/SharedFlammableComponent.cs b/Content.Shared/Atmos/Components/SharedFlammableComponent.cs deleted file mode 100644 index 3012c9e6d0..0000000000 --- a/Content.Shared/Atmos/Components/SharedFlammableComponent.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using Robust.Shared.GameObjects; -using Robust.Shared.Serialization; - -namespace Content.Shared.Atmos.Components -{ - public class SharedFlammableComponent : Component - { - public override string Name => "Flammable"; - } - - [Serializable, NetSerializable] - public enum FireVisuals - { - OnFire, - FireStacks, - } -} diff --git a/Content.Shared/Atmos/FireVisuals.cs b/Content.Shared/Atmos/FireVisuals.cs new file mode 100644 index 0000000000..7fb8e5ed57 --- /dev/null +++ b/Content.Shared/Atmos/FireVisuals.cs @@ -0,0 +1,12 @@ +using System; +using Robust.Shared.Serialization; + +namespace Content.Shared.Atmos +{ + [Serializable, NetSerializable] + public enum FireVisuals + { + OnFire, + FireStacks, + } +} diff --git a/Content.Shared/Temperature/IHotItem.cs b/Content.Shared/Temperature/IHotItem.cs deleted file mode 100644 index 8cac8aa13d..0000000000 --- a/Content.Shared/Temperature/IHotItem.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Robust.Shared.Analyzers; - -namespace Content.Shared.Temperature -{ - /// - /// This interface gives components hot quality when they are used. - /// E.g if you hold a lit match or a welder then it will be hot, - /// presuming match is lit or the welder is on respectively. - /// However say you hold an item that is always hot like lava rock, - /// it will be permanently hot. - /// - [RequiresExplicitImplementation] - public interface IHotItem - { - bool IsCurrentlyHot(); - } -} diff --git a/Content.Shared/Temperature/IsHotEvent.cs b/Content.Shared/Temperature/IsHotEvent.cs new file mode 100644 index 0000000000..a70965a159 --- /dev/null +++ b/Content.Shared/Temperature/IsHotEvent.cs @@ -0,0 +1,14 @@ +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; + +namespace Content.Shared.Temperature +{ + /// + /// Directed event raised on entities to query whether they're "hot" or not. + /// For example, a lit welder or matchstick would be hot, etc. + /// + public class IsHotEvent : EntityEventArgs + { + public bool IsHot { get; set; } = false; + } +}