From de190e4e2f5f69b7b187f5796721c7077fb8e80c Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Thu, 24 Mar 2022 02:33:01 +1300 Subject: [PATCH] Throw out throw helpers (#7195) --- .../Components/ExplosionLaunchedComponent.cs | 5 +- .../EntitySystems/ClusterGrenadeSystem.cs | 9 +- Content.Server/Hands/Systems/HandsSystem.cs | 8 +- .../PneumaticCannon/PneumaticCannonSystem.cs | 8 +- .../Standing/StandingStateSystem.cs | 6 +- Content.Server/Throwing/ThrowHelper.cs | 104 ----------------- .../VendingMachines/VendingMachineSystem.cs | 7 +- Content.Shared/Throwing/ThrowingSystem.cs | 105 ++++++++++++++++++ 8 files changed, 127 insertions(+), 125 deletions(-) delete mode 100644 Content.Server/Throwing/ThrowHelper.cs create mode 100644 Content.Shared/Throwing/ThrowingSystem.cs diff --git a/Content.Server/Explosion/Components/ExplosionLaunchedComponent.cs b/Content.Server/Explosion/Components/ExplosionLaunchedComponent.cs index b760ce1341..4d1ddc2fca 100644 --- a/Content.Server/Explosion/Components/ExplosionLaunchedComponent.cs +++ b/Content.Server/Explosion/Components/ExplosionLaunchedComponent.cs @@ -1,5 +1,6 @@ using Content.Server.Throwing; using Content.Shared.Acts; +using Content.Shared.Throwing; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Maths; @@ -10,6 +11,8 @@ namespace Content.Server.Explosion.Components public sealed class ExplosionLaunchedComponent : Component, IExAct { [Dependency] private readonly IEntityManager _entMan = default!; + [Dependency] private readonly IEntitySystemManager _sysMan = default!; + void IExAct.OnExplosion(ExplosionEventArgs eventArgs) { if (_entMan.Deleted(Owner)) @@ -34,7 +37,7 @@ namespace Content.Server.Explosion.Components _ => 0, }; - Owner.TryThrow(direction, throwForce); + _sysMan.GetEntitySystem().TryThrow(Owner, direction, throwForce); } } } diff --git a/Content.Server/Explosion/EntitySystems/ClusterGrenadeSystem.cs b/Content.Server/Explosion/EntitySystems/ClusterGrenadeSystem.cs index 377de6a7d3..355de065ed 100644 --- a/Content.Server/Explosion/EntitySystems/ClusterGrenadeSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ClusterGrenadeSystem.cs @@ -1,14 +1,10 @@ -using System; using Content.Server.Explosion.Components; using Content.Server.Flash.Components; -using Content.Server.Throwing; using Content.Shared.Explosion; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; +using Content.Shared.Throwing; using Robust.Shared.Containers; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Maths; using Robust.Shared.Random; namespace Content.Server.Explosion.EntitySystems; @@ -18,6 +14,7 @@ public sealed class ClusterGrenadeSystem : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly TriggerSystem _trigger = default!; + [Dependency] private readonly ThrowingSystem _throwingSystem = default!; public override void Initialize() { @@ -83,7 +80,7 @@ public sealed class ClusterGrenadeSystem : EntitySystem thrownCount++; // TODO: Suss out throw strength - grenade.TryThrow(angle.ToVec().Normalized * component.ThrowDistance); + _throwingSystem.TryThrow(grenade, angle.ToVec().Normalized * component.ThrowDistance); grenade.SpawnTimer(delay, () => { diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index 31f8c67483..b3f5e4c8c4 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -7,10 +7,8 @@ using Content.Server.Stack; using Content.Server.Storage.Components; using Content.Server.Strip; using Content.Server.Stunnable; -using Content.Server.Throwing; using Content.Shared.ActionBlocker; using Content.Shared.Database; -using Content.Shared.Examine; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Stunnable; @@ -31,6 +29,7 @@ using Robust.Shared.Utility; using Content.Shared.Pulling.Components; using Content.Server.Pulling; using Content.Shared.Hands.EntitySystems; +using Content.Shared.Throwing; namespace Content.Server.Hands.Systems { @@ -47,7 +46,8 @@ namespace Content.Server.Hands.Systems [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly PullingSystem _pullingSystem = default!; - + [Dependency] private readonly ThrowingSystem _throwingSystem = default!; + public override void Initialize() { base.Initialize(); @@ -224,7 +224,7 @@ namespace Content.Server.Hands.Systems direction = direction.Normalized * Math.Min(direction.Length, hands.ThrowRange); var throwStrength = hands.ThrowForceMultiplier; - throwEnt.TryThrow(direction, throwStrength, player); + _throwingSystem.TryThrow(throwEnt, direction, throwStrength, player); return true; } diff --git a/Content.Server/PneumaticCannon/PneumaticCannonSystem.cs b/Content.Server/PneumaticCannon/PneumaticCannonSystem.cs index 2b07a6f106..0c9b72d1e0 100644 --- a/Content.Server/PneumaticCannon/PneumaticCannonSystem.cs +++ b/Content.Server/PneumaticCannon/PneumaticCannonSystem.cs @@ -1,13 +1,9 @@ -using System; -using System.Collections.Generic; using System.Linq; using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; -using Content.Server.Hands.Components; using Content.Server.Nutrition.Components; using Content.Server.Storage.Components; using Content.Server.Stunnable; -using Content.Server.Throwing; using Content.Server.Tools.Components; using Content.Shared.Camera; using Content.Shared.CombatMode; @@ -17,6 +13,7 @@ using Content.Shared.Item; using Content.Shared.PneumaticCannon; using Content.Shared.Popups; using Content.Shared.StatusEffect; +using Content.Shared.Throwing; using Content.Shared.Verbs; using Robust.Shared.Audio; using Robust.Shared.Containers; @@ -33,6 +30,7 @@ namespace Content.Server.PneumaticCannon [Dependency] private readonly AtmosphereSystem _atmos = default!; [Dependency] private readonly CameraRecoilSystem _cameraRecoil = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly ThrowingSystem _throwingSystem = default!; private HashSet _currentlyFiring = new(); @@ -234,7 +232,7 @@ namespace Content.Server.PneumaticCannon _cameraRecoil.KickCamera(data.User, kick); } - ent.TryThrow(data.Direction, data.Strength, data.User, GetPushbackRatioFromPower(comp.Power)); + _throwingSystem.TryThrow(ent, data.Direction, data.Strength, data.User, GetPushbackRatioFromPower(comp.Power)); // lasagna, anybody? ent.EnsureComponent(); diff --git a/Content.Server/Standing/StandingStateSystem.cs b/Content.Server/Standing/StandingStateSystem.cs index c0b3bc4754..91c04de1d5 100644 --- a/Content.Server/Standing/StandingStateSystem.cs +++ b/Content.Server/Standing/StandingStateSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Standing; +using Content.Shared.Throwing; using Robust.Shared.Random; namespace Content.Server.Standing; @@ -9,6 +10,7 @@ public sealed class StandingStateSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly ThrowingSystem _throwingSystem = default!; private void FallOver(EntityUid uid, StandingStateComponent component, DropHandItemsEvent args) { @@ -26,8 +28,8 @@ public sealed class StandingStateSystem : EntitySystem if (!_handsSystem.TryDrop(uid, hand, null, checkActionBlocker: false, handsComp: handsComp)) continue; - - Throwing.ThrowHelper.TryThrow(held, + + _throwingSystem.TryThrow(held, _random.NextAngle().RotateVec(direction / dropAngle + worldRotation / 50), 0.5f * dropAngle * _random.NextFloat(-0.9f, 1.1f), uid, 0); diff --git a/Content.Server/Throwing/ThrowHelper.cs b/Content.Server/Throwing/ThrowHelper.cs deleted file mode 100644 index 7db9be2c96..0000000000 --- a/Content.Server/Throwing/ThrowHelper.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using Content.Server.Interaction; -using Content.Shared.Item; -using Content.Shared.MobState.Components; -using Content.Shared.Tag; -using Content.Shared.Throwing; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Log; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Timing; - -namespace Content.Server.Throwing -{ - internal static class ThrowHelper - { - private const float ThrowAngularImpulse = 1.5f; - - /// - /// The minimum amount of time an entity needs to be thrown before the timer can be run. - /// Anything below this threshold never enters the air. - /// - private const float FlyTime = 0.15f; - - /// - /// Tries to throw the entity if it has a physics component, otherwise does nothing. - /// - /// The entity being thrown. - /// A vector pointing from the entity to its destination. - /// How much the direction vector should be multiplied for velocity. - /// - /// The ratio of impulse applied to the thrower - defaults to 10 because otherwise it's not enough to properly recover from getting spaced - internal static void TryThrow(this EntityUid entity, Vector2 direction, float strength = 1.0f, EntityUid? user = null, float pushbackRatio = 10.0f) - { - var entities = IoCManager.Resolve(); - if (entities.GetComponent(entity).EntityDeleted || - strength <= 0f || - !entities.TryGetComponent(entity, out PhysicsComponent? physicsComponent)) - { - return; - } - - if (physicsComponent.BodyType != BodyType.Dynamic) - { - Logger.Warning($"Tried to throw entity {entities.ToPrettyString(entity)} but can't throw {physicsComponent.BodyType} bodies!"); - return; - } - - var comp = entity.EnsureComponent(); - if (entities.HasComponent(entity)) - { - comp.Thrower = user; - // Give it a l'il spin. - if (!EntitySystem.Get().HasTag(entity, "NoSpinOnThrow")) - { - physicsComponent.ApplyAngularImpulse(ThrowAngularImpulse); - } - else if(direction != Vector2.Zero) - { - entities.GetComponent(entity).LocalRotation = direction.ToWorldAngle() - Math.PI; - } - - if (user != null) - EntitySystem.Get().ThrownInteraction(user.Value, entity); - } - - var impulseVector = direction.Normalized * strength * physicsComponent.Mass; - physicsComponent.ApplyLinearImpulse(impulseVector); - - // Estimate time to arrival so we can apply OnGround status and slow it much faster. - var time = (direction / strength).Length; - - if (time < FlyTime) - { - physicsComponent.BodyStatus = BodyStatus.OnGround; - EntitySystem.Get().LandComponent(comp); - } - else - { - physicsComponent.BodyStatus = BodyStatus.InAir; - - Timer.Spawn(TimeSpan.FromSeconds(time - FlyTime), () => - { - if (physicsComponent.Deleted) return; - physicsComponent.BodyStatus = BodyStatus.OnGround; - EntitySystem.Get().LandComponent(comp); - }); - } - - // Give thrower an impulse in the other direction - if (user != null && pushbackRatio > 0.0f && entities.TryGetComponent(user.Value, out IPhysBody? body)) - { - var msg = new ThrowPushbackAttemptEvent(); - entities.EventBus.RaiseLocalEvent(body.Owner, msg); - - if (!msg.Cancelled) - { - body.ApplyLinearImpulse(-impulseVector * pushbackRatio); - } - } - } - } -} diff --git a/Content.Server/VendingMachines/VendingMachineSystem.cs b/Content.Server/VendingMachines/VendingMachineSystem.cs index 844f10cb27..6ea90cce20 100644 --- a/Content.Server/VendingMachines/VendingMachineSystem.cs +++ b/Content.Server/VendingMachines/VendingMachineSystem.cs @@ -9,9 +9,9 @@ using Content.Shared.VendingMachines; using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Content.Server.Throwing; using Content.Shared.Acts; using static Content.Shared.VendingMachines.SharedVendingMachineComponent; +using Content.Shared.Throwing; namespace Content.Server.VendingMachines.systems { @@ -20,7 +20,8 @@ namespace Content.Server.VendingMachines.systems [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly ThrowingSystem _throwingSystem = default!; public override void Initialize() { @@ -197,7 +198,7 @@ namespace Content.Server.VendingMachines.systems { float range = vendComponent.NonLimitedEjectRange; Vector2 direction = new Vector2(_random.NextFloat(-range, range), _random.NextFloat(-range, range)); - ent.TryThrow(direction, vendComponent.NonLimitedEjectForce); + _throwingSystem.TryThrow(ent, direction, vendComponent.NonLimitedEjectForce); } }); SoundSystem.Play(Filter.Pvs(vendComponent.Owner), vendComponent.SoundVend.GetSound(), vendComponent.Owner, AudioParams.Default.WithVolume(-2f)); diff --git a/Content.Shared/Throwing/ThrowingSystem.cs b/Content.Shared/Throwing/ThrowingSystem.cs new file mode 100644 index 0000000000..eab04a9c4b --- /dev/null +++ b/Content.Shared/Throwing/ThrowingSystem.cs @@ -0,0 +1,105 @@ +using Content.Shared.Interaction; +using Content.Shared.Tag; +using Robust.Shared.Physics; +using Robust.Shared.Timing; + +namespace Content.Shared.Throwing; + +public sealed class ThrowingSystem : EntitySystem +{ + public const float ThrowAngularImpulse = 1.5f; + + /// + /// The minimum amount of time an entity needs to be thrown before the timer can be run. + /// Anything below this threshold never enters the air. + /// + public const float FlyTime = 0.15f; + + [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; + [Dependency] private readonly ThrownItemSystem _thrownSystem = default!; + [Dependency] private readonly TagSystem _tagSystem = default!; + + /// + /// Tries to throw the entity if it has a physics component, otherwise does nothing. + /// + /// The entity being thrown. + /// A vector pointing from the entity to its destination. + /// How much the direction vector should be multiplied for velocity. + /// + /// The ratio of impulse applied to the thrower - defaults to 10 because otherwise it's not enough to properly recover from getting spaced + public void TryThrow( + EntityUid uid, + Vector2 direction, + float strength = 1.0f, + EntityUid? user = null, + float pushbackRatio = 10.0f, + PhysicsComponent? physics = null, + TransformComponent? transform = null, + EntityQuery? physicsQuery = null, + EntityQuery? xformQuery = null) + { + if (strength <= 0 || direction == Vector2.Infinity || direction == Vector2.NaN || direction == Vector2.Zero) + return; + + physicsQuery ??= GetEntityQuery(); + if (physics == null && !physicsQuery.Value.TryGetComponent(uid, out physics)) + return; + + if (physics.BodyType != BodyType.Dynamic) + { + Logger.Warning($"Tried to throw entity {ToPrettyString(uid)} but can't throw {physics.BodyType} bodies!"); + return; + } + + var comp = EnsureComp(uid); + comp.Thrower = user; + // Give it a l'il spin. + if (!_tagSystem.HasTag(uid, "NoSpinOnThrow")) + physics.ApplyAngularImpulse(ThrowAngularImpulse); + else + { + if (transform == null) + { + xformQuery ??= GetEntityQuery(); + transform = xformQuery.Value.GetComponent(uid); + } + transform.LocalRotation = direction.ToWorldAngle() - Math.PI; + } + + if (user != null) + _interactionSystem.ThrownInteraction(user.Value, uid); + + var impulseVector = direction.Normalized * strength * physics.Mass; + physics.ApplyLinearImpulse(impulseVector); + + // Estimate time to arrival so we can apply OnGround status and slow it much faster. + var time = (direction / strength).Length; + + if (time < FlyTime) + { + physics.BodyStatus = BodyStatus.OnGround; + _thrownSystem.LandComponent(comp); + } + else + { + physics.BodyStatus = BodyStatus.InAir; + + Timer.Spawn(TimeSpan.FromSeconds(time - FlyTime), () => + { + if (physics.Deleted) return; + physics.BodyStatus = BodyStatus.OnGround; + _thrownSystem.LandComponent(comp); + }); + } + + // Give thrower an impulse in the other direction + if (user != null && pushbackRatio > 0.0f && physicsQuery.Value.TryGetComponent(user.Value, out var userPhysics)) + { + var msg = new ThrowPushbackAttemptEvent(); + RaiseLocalEvent(physics.Owner, msg, false); + + if (!msg.Cancelled) + userPhysics.ApplyLinearImpulse(-impulseVector * pushbackRatio); + } + } +}