diff --git a/Content.Server/Chemistry/Components/VaporComponent.cs b/Content.Server/Chemistry/Components/VaporComponent.cs index f9b9197066..7eda0be87f 100644 --- a/Content.Server/Chemistry/Components/VaporComponent.cs +++ b/Content.Server/Chemistry/Components/VaporComponent.cs @@ -1,131 +1,24 @@ -using System.Linq; -using Content.Shared.Chemistry.Reagent; -using Content.Shared.Chemistry.Solution; -using Content.Shared.Physics; +using Content.Shared.Chemistry.Reagent; using Content.Shared.Vapor; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics.Collision; -using Robust.Shared.Physics.Dynamics; -using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; namespace Content.Server.Chemistry.Components { [RegisterComponent] - class VaporComponent : SharedVaporComponent, IStartCollide + internal sealed class VaporComponent : SharedVaporComponent { - public const float ReactTime = 0.125f; - - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [ViewVariables] [DataField("transferAmount")] - private ReagentUnit _transferAmount = ReagentUnit.New(0.5); + internal ReagentUnit TransferAmount = ReagentUnit.New(0.5); - private bool _reached; - private float _reactTimer; - private float _timer; - private EntityCoordinates _target; - private bool _running; - private float _aliveTime; - - protected override void Initialize() - { - base.Initialize(); - - Owner.EnsureComponentWarn(out SolutionContainerComponent _); - } - - public void Start(Vector2 dir, float speed, EntityCoordinates target, float aliveTime) - { - _running = true; - _target = target; - _aliveTime = aliveTime; - // Set Move - if (Owner.TryGetComponent(out PhysicsComponent? physics)) - { - physics.BodyStatus = BodyStatus.InAir; - physics.ApplyLinearImpulse(dir * speed); - } - } - - public void Update(float frameTime) - { - if (!Owner.TryGetComponent(out SolutionContainerComponent? contents)) - return; - - if (!_running) - return; - - _timer += frameTime; - _reactTimer += frameTime; - - if (_reactTimer >= ReactTime && Owner.Transform.GridID.IsValid()) - { - _reactTimer = 0; - var mapGrid = _mapManager.GetGrid(Owner.Transform.GridID); - - var tile = mapGrid.GetTileRef(Owner.Transform.Coordinates.ToVector2i(Owner.EntityManager, _mapManager)); - foreach (var reagentQuantity in contents.ReagentList.ToArray()) - { - if (reagentQuantity.Quantity == ReagentUnit.Zero) continue; - var reagent = _prototypeManager.Index(reagentQuantity.ReagentId); - contents.TryRemoveReagent(reagentQuantity.ReagentId, reagent.ReactionTile(tile, (reagentQuantity.Quantity / _transferAmount) * 0.25f)); - } - } - - // Check if we've reached our target. - if(!_reached && _target.TryDistance(Owner.EntityManager, Owner.Transform.Coordinates, out var distance) && distance <= 0.5f) - { - _reached = true; - } - - if (contents.CurrentVolume == 0 || _timer > _aliveTime) - { - // Delete this - Owner.Delete(); - } - } - - internal bool TryAddSolution(Solution solution) - { - if (solution.TotalVolume == 0) - { - return false; - } - - if (!Owner.TryGetComponent(out SolutionContainerComponent? contents)) - { - return false; - } - - var result = contents.TryAddSolution(solution); - - if (!result) - { - return false; - } - - return true; - } - - void IStartCollide.CollideWith(Fixture ourFixture, Fixture otherFixture, in Manifold manifold) - { - if (!Owner.TryGetComponent(out SolutionContainerComponent? contents)) - return; - - contents.Solution.DoEntityReaction(otherFixture.Body.Owner, ReactionMethod.Touch); - - // Check for collision with a impassable object (e.g. wall) and stop - if ((otherFixture.CollisionLayer & (int) CollisionGroup.Impassable) != 0 && otherFixture.Hard) - { - Owner.QueueDelete(); - } - } + internal bool Reached; + internal float ReactTimer; + internal float Timer; + internal EntityCoordinates Target; + internal bool Active; + internal float AliveTime; } } diff --git a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs index 14203c5dbb..f5e21c4adc 100644 --- a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs @@ -1,17 +1,122 @@ -using Content.Server.Chemistry.Components; +using System.Linq; +using Content.Server.Chemistry.Components; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Chemistry.Solution; +using Content.Shared.Physics; using JetBrains.Annotations; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Physics.Dynamics; +using Robust.Shared.Prototypes; namespace Content.Server.Chemistry.EntitySystems { [UsedImplicitly] - public class VaporSystem : EntitySystem + internal sealed class VaporSystem : EntitySystem { + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + + private const float ReactTime = 0.125f; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(HandleCollide); + } + + private void HandleCollide(EntityUid uid, VaporComponent component, StartCollideEvent args) + { + if (!ComponentManager.TryGetComponent(uid, out SolutionContainerComponent? contents)) return; + + contents.Solution.DoEntityReaction(args.OtherFixture.Body.Owner, ReactionMethod.Touch); + + // Check for collision with a impassable object (e.g. wall) and stop + if ((args.OtherFixture.CollisionLayer & (int) CollisionGroup.Impassable) != 0 && args.OtherFixture.Hard) + { + EntityManager.QueueDeleteEntity(uid); + } + } + + public void Start(VaporComponent vapor, Vector2 dir, float speed, EntityCoordinates target, float aliveTime) + { + vapor.Active = true; + vapor.Target = target; + vapor.AliveTime = aliveTime; + // Set Move + if (vapor.Owner.TryGetComponent(out PhysicsComponent? physics)) + { + physics.BodyStatus = BodyStatus.InAir; + physics.ApplyLinearImpulse(dir * speed); + } + } + + internal bool TryAddSolution(VaporComponent vapor, Solution solution) + { + if (solution.TotalVolume == 0) + { + return false; + } + + if (!vapor.Owner.TryGetComponent(out SolutionContainerComponent? contents)) + { + return false; + } + + var result = contents.TryAddSolution(solution); + + if (!result) + { + return false; + } + + return true; + } + public override void Update(float frameTime) { - foreach (var vaporComp in ComponentManager.EntityQuery(true)) + foreach (var (vaporComp, solution) in ComponentManager.EntityQuery(true)) { - vaporComp.Update(frameTime); + Update(frameTime, vaporComp, solution); + } + } + + private void Update(float frameTime, VaporComponent vapor, SolutionContainerComponent contents) + { + if (!vapor.Active) + return; + + var entity = vapor.Owner; + + vapor.Timer += frameTime; + vapor.ReactTimer += frameTime; + + if (vapor.ReactTimer >= ReactTime && vapor.Owner.Transform.GridID.IsValid()) + { + vapor.ReactTimer = 0; + var mapGrid = _mapManager.GetGrid(entity.Transform.GridID); + + var tile = mapGrid.GetTileRef(entity.Transform.Coordinates.ToVector2i(EntityManager, _mapManager)); + foreach (var reagentQuantity in contents.ReagentList.ToArray()) + { + if (reagentQuantity.Quantity == ReagentUnit.Zero) continue; + var reagent = _protoManager.Index(reagentQuantity.ReagentId); + contents.TryRemoveReagent(reagentQuantity.ReagentId, reagent.ReactionTile(tile, (reagentQuantity.Quantity / vapor.TransferAmount) * 0.25f)); + } + } + + // Check if we've reached our target. + if(!vapor.Reached && vapor.Target.TryDistance(EntityManager, entity.Transform.Coordinates, out var distance) && distance <= 0.5f) + { + vapor.Reached = true; + } + + if (contents.CurrentVolume == 0 || vapor.Timer > vapor.AliveTime) + { + // Delete this + entity.QueueDelete(); } } } diff --git a/Content.Server/Fluids/Components/SprayComponent.cs b/Content.Server/Fluids/Components/SprayComponent.cs index 6b316e746e..e753ca818f 100644 --- a/Content.Server/Fluids/Components/SprayComponent.cs +++ b/Content.Server/Fluids/Components/SprayComponent.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Content.Server.Chemistry.Components; +using Content.Server.Chemistry.EntitySystems; using Content.Shared.ActionBlocker; using Content.Shared.Audio; using Content.Shared.Chemistry.Reagent; @@ -8,7 +9,6 @@ using Content.Shared.Cooldown; using Content.Shared.DragDrop; using Content.Shared.Fluids; using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; using Content.Shared.Notification.Managers; using Content.Shared.Vapor; using Robust.Server.GameObjects; @@ -26,12 +26,11 @@ using Robust.Shared.ViewVariables; namespace Content.Server.Fluids.Components { [RegisterComponent] - class SprayComponent : SharedSprayComponent, IAfterInteract, IUse, IActivate, IDropped + internal sealed class SprayComponent : SharedSprayComponent, IAfterInteract, IUse, IActivate, IDropped { public const float SprayDistance = 3f; [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IServerEntityManager _serverEntityManager = default!; [DataField("transferAmount")] private ReagentUnit _transferAmount = ReagentUnit.New(10); @@ -117,7 +116,9 @@ namespace Content.Server.Fluids.Components return true; var playerPos = eventArgs.User.Transform.Coordinates; - if (eventArgs.ClickLocation.GetGridId(_serverEntityManager) != playerPos.GetGridId(_serverEntityManager)) + var entManager = Owner.EntityManager; + + if (eventArgs.ClickLocation.GetGridId(entManager) != playerPos.GetGridId(entManager)) return true; if (!Owner.TryGetComponent(out SolutionContainerComponent? contents)) @@ -149,7 +150,7 @@ namespace Content.Server.Fluids.Components if (solution.TotalVolume <= ReagentUnit.Zero) break; - var vapor = _serverEntityManager.SpawnEntity(_vaporPrototype, playerPos.Offset(distance < 1 ? quarter : threeQuarters)); + var vapor = entManager.SpawnEntity(_vaporPrototype, playerPos.Offset(distance < 1 ? quarter : threeQuarters)); vapor.Transform.LocalRotation = rotation; if (vapor.TryGetComponent(out AppearanceComponent? appearance)) // Vapor sprite should face down. @@ -161,9 +162,10 @@ namespace Content.Server.Fluids.Components // Add the solution to the vapor and actually send the thing var vaporComponent = vapor.GetComponent(); - vaporComponent.TryAddSolution(solution); + var vaporSystem = EntitySystem.Get(); + vaporSystem.TryAddSolution(vaporComponent, solution); - vaporComponent.Start(rotation.ToVec(), _sprayVelocity, target, _sprayAliveTime); + vaporSystem.Start(vaporComponent, rotation.ToVec(), _sprayVelocity, target, _sprayAliveTime); if (_impulse > 0f && eventArgs.User.TryGetComponent(out IPhysBody? body)) {