diff --git a/Content.Server/Chemistry/Components/VaporComponent.cs b/Content.Server/Chemistry/Components/VaporComponent.cs index adedfca4a9..5f8db633b1 100644 --- a/Content.Server/Chemistry/Components/VaporComponent.cs +++ b/Content.Server/Chemistry/Components/VaporComponent.cs @@ -5,17 +5,15 @@ using Robust.Shared.Map; namespace Content.Server.Chemistry.Components { [RegisterComponent] - internal sealed class VaporComponent : SharedVaporComponent + public sealed class VaporComponent : Component { + public const string SolutionName = "vapor"; + [ViewVariables] [DataField("transferAmount")] - internal FixedPoint2 TransferAmount = FixedPoint2.New(0.5); + public FixedPoint2 TransferAmount = FixedPoint2.New(0.5); - internal bool Reached; - internal float ReactTimer; - internal float Timer; - internal MapCoordinates Target; - internal bool Active; - internal float AliveTime; + public float ReactTimer; + public bool Active; } } diff --git a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs index 3f13b93fc4..89f0d54058 100644 --- a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs @@ -4,6 +4,8 @@ using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using Content.Shared.Physics; +using Content.Shared.Spawners.Components; +using Content.Shared.Throwing; using Content.Shared.Vapor; using JetBrains.Annotations; using Robust.Shared.Map; @@ -18,6 +20,7 @@ namespace Content.Server.Chemistry.EntitySystems [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; private const float ReactTime = 0.125f; @@ -43,16 +46,23 @@ namespace Content.Server.Chemistry.EntitySystems } } - public void Start(VaporComponent vapor, Vector2 dir, float speed, MapCoordinates target, float aliveTime) + public void Start(VaporComponent vapor, TransformComponent vaporXform, Vector2 dir, float speed, MapCoordinates target, float aliveTime, EntityUid? user = null) { vapor.Active = true; - vapor.Target = target; - vapor.AliveTime = aliveTime; + var despawn = EnsureComp(vapor.Owner); + despawn.Lifetime = aliveTime; + // Set Move if (EntityManager.TryGetComponent(vapor.Owner, out PhysicsComponent? physics)) { - physics.BodyStatus = BodyStatus.InAir; - physics.ApplyLinearImpulse(dir * speed); + physics.LinearDamping = 0f; + physics.AngularDamping = 0f; + + _throwing.TryThrow(vapor.Owner, dir * speed, user: user, pushbackRatio: 50f); + + var distance = (target.Position - vaporXform.WorldPosition).Length; + var time = (distance / physics.LinearVelocity.Length); + despawn.Lifetime = MathF.Min(aliveTime, time); } } @@ -63,7 +73,7 @@ namespace Content.Server.Chemistry.EntitySystems return false; } - if (!_solutionContainerSystem.TryGetSolution(vapor.Owner, SharedVaporComponent.SolutionName, + if (!_solutionContainerSystem.TryGetSolution(vapor.Owner, VaporComponent.SolutionName, out var vaporSolution)) { return false; @@ -74,32 +84,29 @@ namespace Content.Server.Chemistry.EntitySystems public override void Update(float frameTime) { - foreach (var (vaporComp, solution) in EntityManager - .EntityQuery()) + foreach (var (vaporComp, solution, xform) in EntityManager + .EntityQuery()) { foreach (var (_, value) in solution.Solutions) { - Update(frameTime, vaporComp, value); + Update(frameTime, vaporComp, value, xform); } } } - private void Update(float frameTime, VaporComponent vapor, Solution contents) + private void Update(float frameTime, VaporComponent vapor, Solution contents, TransformComponent xform) { if (!vapor.Active) return; var entity = vapor.Owner; - var xform = Transform(entity); - vapor.Timer += frameTime; vapor.ReactTimer += frameTime; if (vapor.ReactTimer >= ReactTime && TryComp(xform.GridUid, out IMapGridComponent? gridComp)) { vapor.ReactTimer = 0; - var tile = gridComp.Grid.GetTileRef(xform.Coordinates.ToVector2i(EntityManager, _mapManager)); foreach (var reagentQuantity in contents.Contents.ToArray()) { @@ -110,14 +117,7 @@ namespace Content.Server.Chemistry.EntitySystems } } - // Check if we've reached our target. - if (!vapor.Reached && - (vapor.Target.Position - xform.MapPosition.Position).LengthSquared <= 0.25f) - { - vapor.Reached = true; - } - - if (contents.CurrentVolume == 0 || vapor.Timer > vapor.AliveTime) + if (contents.CurrentVolume == 0) { // Delete this EntityManager.QueueDeleteEntity(entity); diff --git a/Content.Server/Fluids/EntitySystems/SpraySystem.cs b/Content.Server/Fluids/EntitySystems/SpraySystem.cs index a654f5e12a..c674222a1a 100644 --- a/Content.Server/Fluids/EntitySystems/SpraySystem.cs +++ b/Content.Server/Fluids/EntitySystems/SpraySystem.cs @@ -18,11 +18,10 @@ namespace Content.Server.Fluids.EntitySystems; public sealed class SpraySystem : EntitySystem { + [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly VaporSystem _vaporSystem = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IMapManager _mapManager = default!; public override void Initialize() { @@ -58,22 +57,10 @@ public sealed class SpraySystem : EntitySystem return; } - var userXform = Transform(args.User); - - // The grid/map entity to attach the vapor to. - EntityUid vaporSpawnEntityUid; - if (userXform.GridUid != null) - vaporSpawnEntityUid = userXform.GridUid.Value; - else if (userXform.MapUid != null) - vaporSpawnEntityUid = userXform.MapUid.Value; - else - return; - - var gridMapXform = Transform(vaporSpawnEntityUid); - var gridMapInvMatrix = gridMapXform.InvWorldMatrix; + var xformQuery = GetEntityQuery(); + var userXform = xformQuery.GetComponent(args.User); var userMapPos = userXform.MapPosition; - var clickMapPos = args.ClickLocation.ToMap(EntityManager); var diffPos = clickMapPos.Position - userMapPos.Position; @@ -110,9 +97,11 @@ public sealed class SpraySystem : EntitySystem break; // Spawn the vapor cloud onto the grid/map the user is present on. Offset the start position based on how far the target destination is. - var vaporPos = userMapPos.Offset(distance < 1 ? quarter : threeQuarters).Position; - var vapor = Spawn(component.SprayedPrototype, new EntityCoordinates(vaporSpawnEntityUid, gridMapInvMatrix.Transform(vaporPos))); - Transform(vapor).WorldRotation = rotation; + var vaporPos = userMapPos.Offset(distance < 1 ? quarter : threeQuarters); + var vapor = Spawn(component.SprayedPrototype, vaporPos); + var vaporXform = xformQuery.GetComponent(vapor); + + vaporXform.WorldRotation = rotation; if (TryComp(vapor, out AppearanceComponent? appearance)) { @@ -126,11 +115,7 @@ public sealed class SpraySystem : EntitySystem // impulse direction is defined in world-coordinates, not local coordinates var impulseDirection = rotation.ToVec(); - _vaporSystem.Start(vaporComponent, impulseDirection, component.SprayVelocity, target, component.SprayAliveTime); - - // Apply the reaction force to the user. - if (component.Impulse > 0f && TryComp(args.User, out PhysicsComponent? body)) - body.ApplyLinearImpulse(-impulseDirection * component.Impulse); + _vaporSystem.Start(vaporComponent, vaporXform, impulseDirection, component.SprayVelocity, target, component.SprayAliveTime, args.User); } SoundSystem.Play(component.SpraySound.GetSound(), Filter.Pvs(uid), uid, AudioHelpers.WithVariation(0.125f)); diff --git a/Content.Shared/Vapor/SharedVaporComponent.cs b/Content.Shared/Vapor/SharedVaporComponent.cs index 4fe3335a6e..83ad35757e 100644 --- a/Content.Shared/Vapor/SharedVaporComponent.cs +++ b/Content.Shared/Vapor/SharedVaporComponent.cs @@ -2,12 +2,6 @@ namespace Content.Shared.Vapor { - [Virtual] - public class SharedVaporComponent : Component - { - public const string SolutionName = "vapor"; - } - [Serializable, NetSerializable] public enum VaporVisuals {