From 4efb41aa587f57d501f6a2dd16bc1257020b421a Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 19 May 2023 17:10:31 +1000 Subject: [PATCH] Adds force-gun (#16561) --- .../Weapons/Misc/TetherGunOverlay.cs | 15 +++- .../Weapons/Misc/TetherGunSystem.cs | 23 ++++- .../Weapons/Misc/TetherGunSystem.cs | 12 +-- Content.Shared/Sound/SharedEmitSoundSystem.cs | 5 +- Content.Shared/Throwing/LandEvent.cs | 2 +- Content.Shared/Throwing/ThrowingSystem.cs | 34 +++++-- Content.Shared/Throwing/ThrownItemSystem.cs | 4 +- .../Weapons/Misc/BaseForceGunComponent.cs | 56 ++++++++++++ .../Weapons/Misc/ForceGunComponent.cs | 29 ++++++ .../Misc/SharedTetherGunSystem.Force.cs | 54 +++++++++++ .../Weapons/Misc/SharedTetherGunSystem.cs | 32 ++++--- .../Weapons/Misc/TetherGunComponent.cs | 48 +--------- Resources/Audio/Weapons/licenses.txt | 6 +- Resources/Audio/Weapons/soup.ogg | Bin 0 -> 12138 bytes .../Weapons/Guns/Launchers/launchers.yml | 85 ++++++++++++++++++ .../Entities/Structures/Machines/lathe.yml | 1 + .../Prototypes/Recipes/Lathes/devices.yml | 9 ++ .../Prototypes/Research/experimental.yml | 1 + .../Launchers/force_gun.rsi/base-unshaded.png | Bin 0 -> 5749 bytes .../Guns/Launchers/force_gun.rsi/base.png | Bin 0 -> 6289 bytes .../force_gun.rsi/inhand-left-unshaded.png | Bin 0 -> 5772 bytes .../Launchers/force_gun.rsi/inhand-left.png | Bin 0 -> 6134 bytes .../force_gun.rsi/inhand-right-unshaded.png | Bin 0 -> 5765 bytes .../Launchers/force_gun.rsi/inhand-right.png | Bin 0 -> 6854 bytes .../Guns/Launchers/force_gun.rsi/meta.json | 33 +++++++ .../Launchers/tether_gun.rsi/inhand-right.png | Bin 6110 -> 6854 bytes 26 files changed, 373 insertions(+), 76 deletions(-) create mode 100644 Content.Shared/Weapons/Misc/BaseForceGunComponent.cs create mode 100644 Content.Shared/Weapons/Misc/ForceGunComponent.cs create mode 100644 Content.Shared/Weapons/Misc/SharedTetherGunSystem.Force.cs create mode 100644 Resources/Audio/Weapons/soup.ogg create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/base-unshaded.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/base.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/inhand-left-unshaded.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/inhand-right-unshaded.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/meta.json diff --git a/Content.Client/Weapons/Misc/TetherGunOverlay.cs b/Content.Client/Weapons/Misc/TetherGunOverlay.cs index 215589c38d..142d9da823 100644 --- a/Content.Client/Weapons/Misc/TetherGunOverlay.cs +++ b/Content.Client/Weapons/Misc/TetherGunOverlay.cs @@ -19,6 +19,8 @@ public sealed class TetherGunOverlay : Overlay { var query = _entManager.EntityQueryEnumerator(); var xformQuery = _entManager.GetEntityQuery(); + var tetherQuery = _entManager.GetEntityQuery(); + var forceQuery = _entManager.GetEntityQuery(); var worldHandle = args.WorldHandle; var xformSystem = _entManager.System(); @@ -46,7 +48,18 @@ public sealed class TetherGunOverlay : Overlay var box = new Box2(-Width, -length, Width, length); var rotated = new Box2Rotated(box.Translated(midPoint), angle, midPoint); - worldHandle.DrawRect(rotated, Color.Orange.WithAlpha(0.3f)); + var color = Color.Red; + + if (forceQuery.TryGetComponent(tethered.Tetherer, out var force)) + { + color = force.LineColor; + } + else if (tetherQuery.TryGetComponent(tethered.Tetherer, out var tether)) + { + color = tether.LineColor; + } + + worldHandle.DrawRect(rotated, color.WithAlpha(0.3f)); } } } diff --git a/Content.Client/Weapons/Misc/TetherGunSystem.cs b/Content.Client/Weapons/Misc/TetherGunSystem.cs index 1219fe1357..9ceda9291d 100644 --- a/Content.Client/Weapons/Misc/TetherGunSystem.cs +++ b/Content.Client/Weapons/Misc/TetherGunSystem.cs @@ -22,16 +22,26 @@ public sealed class TetherGunSystem : SharedTetherGunSystem base.Initialize(); SubscribeLocalEvent(OnTetheredStartup); SubscribeLocalEvent(OnTetheredShutdown); + SubscribeLocalEvent(OnAfterState); + SubscribeLocalEvent(OnAfterState); _overlay.AddOverlay(new TetherGunOverlay(EntityManager)); } + private void OnAfterState(EntityUid uid, BaseForceGunComponent component, ref AfterAutoHandleStateEvent args) + { + if (!TryComp(component.Tethered, out var sprite)) + return; + + sprite.Color = component.LineColor; + } + public override void Shutdown() { base.Shutdown(); _overlay.RemoveOverlay(); } - protected override bool CanTether(EntityUid uid, TetherGunComponent component, EntityUid target, EntityUid? user) + protected override bool CanTether(EntityUid uid, BaseForceGunComponent component, EntityUid target, EntityUid? user) { // Need powercells predicted sadly :< return false; @@ -88,9 +98,18 @@ public sealed class TetherGunSystem : SharedTetherGunSystem private void OnTetheredStartup(EntityUid uid, TetheredComponent component, ComponentStartup args) { if (!TryComp(uid, out var sprite)) + { return; + } - sprite.Color = Color.Orange; + if (TryComp(component.Tetherer, out var force)) + { + sprite.Color = force.LineColor; + } + else if (TryComp(component.Tetherer, out var tether)) + { + sprite.Color = tether.LineColor; + } } private void OnTetheredShutdown(EntityUid uid, TetheredComponent component, ComponentShutdown args) diff --git a/Content.Server/Weapons/Misc/TetherGunSystem.cs b/Content.Server/Weapons/Misc/TetherGunSystem.cs index 3b62e3f8ca..44d0c49e3f 100644 --- a/Content.Server/Weapons/Misc/TetherGunSystem.cs +++ b/Content.Server/Weapons/Misc/TetherGunSystem.cs @@ -1,5 +1,4 @@ using Content.Server.PowerCell; -using Content.Shared.PowerCell.Components; using Content.Shared.Weapons.Misc; using Robust.Shared.Physics.Components; @@ -13,14 +12,15 @@ public sealed class TetherGunSystem : SharedTetherGunSystem { base.Initialize(); SubscribeLocalEvent(OnGunEmpty); + SubscribeLocalEvent(OnGunEmpty); } - private void OnGunEmpty(EntityUid uid, TetherGunComponent component, ref PowerCellSlotEmptyEvent args) + private void OnGunEmpty(EntityUid uid, BaseForceGunComponent component, ref PowerCellSlotEmptyEvent args) { StopTether(uid, component); } - protected override bool CanTether(EntityUid uid, TetherGunComponent component, EntityUid target, EntityUid? user) + protected override bool CanTether(EntityUid uid, BaseForceGunComponent component, EntityUid target, EntityUid? user) { if (!base.CanTether(uid, component, target, user)) return false; @@ -31,16 +31,16 @@ public sealed class TetherGunSystem : SharedTetherGunSystem return true; } - protected override void StartTether(EntityUid gunUid, TetherGunComponent component, EntityUid target, EntityUid? user, + protected override void StartTether(EntityUid gunUid, BaseForceGunComponent component, EntityUid target, EntityUid? user, PhysicsComponent? targetPhysics = null, TransformComponent? targetXform = null) { base.StartTether(gunUid, component, target, user, targetPhysics, targetXform); _cell.SetPowerCellDrawEnabled(gunUid, true); } - protected override void StopTether(EntityUid gunUid, TetherGunComponent component, bool transfer = false) + protected override void StopTether(EntityUid gunUid, BaseForceGunComponent component, bool land = true, bool transfer = false) { - base.StopTether(gunUid, component, transfer); + base.StopTether(gunUid, component, land, transfer); _cell.SetPowerCellDrawEnabled(gunUid, false); } } diff --git a/Content.Shared/Sound/SharedEmitSoundSystem.cs b/Content.Shared/Sound/SharedEmitSoundSystem.cs index 3dc1cb793f..a2fa038101 100644 --- a/Content.Shared/Sound/SharedEmitSoundSystem.cs +++ b/Content.Shared/Sound/SharedEmitSoundSystem.cs @@ -51,9 +51,12 @@ public abstract class SharedEmitSoundSystem : EntitySystem private void OnEmitSoundOnLand(EntityUid uid, BaseEmitSoundComponent component, ref LandEvent args) { - if (!TryComp(uid, out var xform) || + if (!args.PlaySound || + !TryComp(uid, out var xform) || !_mapManager.TryGetGrid(xform.GridUid, out var grid)) + { return; + } var tile = grid.GetTileRef(xform.Coordinates); diff --git a/Content.Shared/Throwing/LandEvent.cs b/Content.Shared/Throwing/LandEvent.cs index def0278816..1bf1f20371 100644 --- a/Content.Shared/Throwing/LandEvent.cs +++ b/Content.Shared/Throwing/LandEvent.cs @@ -6,7 +6,7 @@ namespace Content.Shared.Throwing /// Raised when an entity that was thrown lands. This occurs before they stop moving and is when their tile-friction is reapplied. /// [ByRefEvent] - public readonly record struct LandEvent(EntityUid? User); + public readonly record struct LandEvent(EntityUid? User, bool PlaySound); /// /// Raised when a thrown entity is no longer moving. diff --git a/Content.Shared/Throwing/ThrowingSystem.cs b/Content.Shared/Throwing/ThrowingSystem.cs index 44cfdc33fb..4368dac6b7 100644 --- a/Content.Shared/Throwing/ThrowingSystem.cs +++ b/Content.Shared/Throwing/ThrowingSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Interaction; using Content.Shared.Movement.Components; using Content.Shared.Projectiles; using Content.Shared.Tag; +using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -25,9 +26,27 @@ public sealed class ThrowingSystem : EntitySystem [Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly ThrownItemSystem _thrownSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; + public void TryThrow( + EntityUid uid, + EntityCoordinates coordinates, + float strength = 1.0f, + EntityUid? user = null, + float pushbackRatio = PushbackDefault, + bool playSound = true) + { + var thrownPos = Transform(uid).MapPosition; + var mapPos = coordinates.ToMap(EntityManager, _transform); + + if (mapPos.MapId != thrownPos.MapId) + return; + + TryThrow(uid, mapPos.Position - thrownPos.Position, strength, user, pushbackRatio, playSound); + } + /// /// Tries to throw the entity if it has a physics component, otherwise does nothing. /// @@ -39,7 +58,8 @@ public sealed class ThrowingSystem : EntitySystem Vector2 direction, float strength = 1.0f, EntityUid? user = null, - float pushbackRatio = PushbackDefault) + float pushbackRatio = PushbackDefault, + bool playSound = true) { var physicsQuery = GetEntityQuery(); if (!physicsQuery.TryGetComponent(uid, out var physics)) @@ -57,7 +77,8 @@ public sealed class ThrowingSystem : EntitySystem tagQuery, strength, user, - pushbackRatio); + pushbackRatio, + playSound); } /// @@ -75,7 +96,8 @@ public sealed class ThrowingSystem : EntitySystem EntityQuery tagQuery, float strength = 1.0f, EntityUid? user = null, - float pushbackRatio = PushbackDefault) + float pushbackRatio = PushbackDefault, + bool playSound = true) { if (strength <= 0 || direction == Vector2.Infinity || direction == Vector2.NaN || direction == Vector2.Zero) return; @@ -105,11 +127,11 @@ public sealed class ThrowingSystem : EntitySystem _physics.ApplyLinearImpulse(uid, impulseVector, body: physics); // Estimate time to arrival so we can apply OnGround status and slow it much faster. - var time = (direction / strength).Length; + var time = direction.Length / strength; if (time < FlyTime) { - _thrownSystem.LandComponent(uid, comp, physics); + _thrownSystem.LandComponent(uid, comp, physics, playSound); } else { @@ -120,7 +142,7 @@ public sealed class ThrowingSystem : EntitySystem if (physics.Deleted) return; - _thrownSystem.LandComponent(uid, comp, physics); + _thrownSystem.LandComponent(uid, comp, physics, playSound); }); } diff --git a/Content.Shared/Throwing/ThrownItemSystem.cs b/Content.Shared/Throwing/ThrownItemSystem.cs index 6467ea2d77..39e357a32c 100644 --- a/Content.Shared/Throwing/ThrownItemSystem.cs +++ b/Content.Shared/Throwing/ThrownItemSystem.cs @@ -116,7 +116,7 @@ namespace Content.Shared.Throwing EntityManager.RemoveComponent(uid); } - public void LandComponent(EntityUid uid, ThrownItemComponent thrownItem, PhysicsComponent physics) + public void LandComponent(EntityUid uid, ThrownItemComponent thrownItem, PhysicsComponent physics, bool playSound) { _physics.SetBodyStatus(physics, BodyStatus.OnGround); @@ -138,7 +138,7 @@ namespace Content.Shared.Throwing _adminLogger.Add(LogType.Landed, LogImpact.Low, $"{ToPrettyString(landing):entity} thrown by {ToPrettyString(thrownItem.Thrower.Value):thrower} landed."); _broadphase.RegenerateContacts(physics); - var landEvent = new LandEvent(thrownItem.Thrower); + var landEvent = new LandEvent(thrownItem.Thrower, playSound); RaiseLocalEvent(landing, ref landEvent); } diff --git a/Content.Shared/Weapons/Misc/BaseForceGunComponent.cs b/Content.Shared/Weapons/Misc/BaseForceGunComponent.cs new file mode 100644 index 0000000000..45c81fa3f1 --- /dev/null +++ b/Content.Shared/Weapons/Misc/BaseForceGunComponent.cs @@ -0,0 +1,56 @@ +using Robust.Shared.Audio; + +namespace Content.Shared.Weapons.Misc; + +public abstract class BaseForceGunComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("lineColor"), AutoNetworkedField] + public Color LineColor = Color.Orange; + + /// + /// The entity the tethered target has a joint to. + /// + [DataField("tetherEntity"), AutoNetworkedField] + public EntityUid? TetherEntity; + + /// + /// The entity currently tethered. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("tethered"), AutoNetworkedField] + public virtual EntityUid? Tethered { get; set; } + + /// + /// Can the tethergun unanchor entities. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("canUnanchor"), AutoNetworkedField] + public bool CanUnanchor = false; + + [ViewVariables(VVAccess.ReadWrite), DataField("canTetherAlive"), AutoNetworkedField] + public bool CanTetherAlive = false; + + /// + /// Max force between the tether entity and the tethered target. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("maxForce"), AutoNetworkedField] + public float MaxForce = 200f; + + [ViewVariables(VVAccess.ReadWrite), DataField("frequency"), AutoNetworkedField] + public float Frequency = 10f; + + [ViewVariables(VVAccess.ReadWrite), DataField("dampingRatio"), AutoNetworkedField] + public float DampingRatio = 2f; + + /// + /// Maximum amount of mass a tethered entity can have. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("massLimit"), AutoNetworkedField] + public float MassLimit = 100f; + + [ViewVariables(VVAccess.ReadWrite), DataField("sound"), AutoNetworkedField] + public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Weapons/weoweo.ogg") + { + Params = AudioParams.Default.WithLoop(true).WithVolume(-8f), + }; + + public IPlayingAudioStream? Stream; +} diff --git a/Content.Shared/Weapons/Misc/ForceGunComponent.cs b/Content.Shared/Weapons/Misc/ForceGunComponent.cs new file mode 100644 index 0000000000..f3aca0d4d0 --- /dev/null +++ b/Content.Shared/Weapons/Misc/ForceGunComponent.cs @@ -0,0 +1,29 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; + +namespace Content.Shared.Weapons.Misc; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class ForceGunComponent : BaseForceGunComponent +{ + /// + /// Maximum distance to throw entities. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("throwDistance"), AutoNetworkedField] + public float ThrowDistance = 15f; + + [ViewVariables(VVAccess.ReadWrite), DataField("throwForce"), AutoNetworkedField] + public float ThrowForce = 30f; + + /// + /// The entity currently tethered. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("tethered"), AutoNetworkedField] + public override EntityUid? Tethered { get; set; } + + [ViewVariables(VVAccess.ReadWrite), DataField("soundLaunch")] + public SoundSpecifier? LaunchSound = new SoundPathSpecifier("/Audio/Weapons/soup.ogg") + { + Params = AudioParams.Default.WithVolume(5f), + }; +} diff --git a/Content.Shared/Weapons/Misc/SharedTetherGunSystem.Force.cs b/Content.Shared/Weapons/Misc/SharedTetherGunSystem.Force.cs new file mode 100644 index 0000000000..9b5665f1c4 --- /dev/null +++ b/Content.Shared/Weapons/Misc/SharedTetherGunSystem.Force.cs @@ -0,0 +1,54 @@ +using Content.Shared.Interaction; +using Robust.Shared.Map; + +namespace Content.Shared.Weapons.Misc; + +public abstract partial class SharedTetherGunSystem +{ + private void InitializeForce() + { + SubscribeLocalEvent(OnForceRanged); + SubscribeLocalEvent(OnForceActivate); + } + + private void OnForceActivate(EntityUid uid, ForceGunComponent component, ActivateInWorldEvent args) + { + StopTether(uid, component); + } + + private void OnForceRanged(EntityUid uid, ForceGunComponent component, AfterInteractEvent args) + { + if (IsTethered(component)) + { + if (!args.ClickLocation.TryDistance(EntityManager, TransformSystem, Transform(uid).Coordinates, + out var distance) || + distance > component.ThrowDistance) + { + return; + } + + // URGH, soon + // Need auto states to be nicer + powercelldraw to be nicer + if (!_netManager.IsServer) + return; + + // Launch + var tethered = component.Tethered; + StopTether(uid, component, land: false); + _throwing.TryThrow(tethered!.Value, args.ClickLocation, component.ThrowForce, playSound: false); + + _audio.PlayPredicted(component.LaunchSound, uid, null); + } + else if (args.Target != null) + { + // Pickup + if (TryTether(uid, args.Target.Value, args.User, component)) + TransformSystem.SetCoordinates(component.TetherEntity!.Value, new EntityCoordinates(uid, new Vector2(0.0f, -0.8f))); + } + } + + private bool IsTethered(ForceGunComponent component) + { + return component.Tethered != null; + } +} diff --git a/Content.Shared/Weapons/Misc/SharedTetherGunSystem.cs b/Content.Shared/Weapons/Misc/SharedTetherGunSystem.cs index f6d65c862d..1e4e890224 100644 --- a/Content.Shared/Weapons/Misc/SharedTetherGunSystem.cs +++ b/Content.Shared/Weapons/Misc/SharedTetherGunSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Events; using Content.Shared.Throwing; using Content.Shared.Toggleable; +using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Physics; @@ -16,16 +17,18 @@ using Robust.Shared.Serialization; namespace Content.Shared.Weapons.Misc; -public abstract class SharedTetherGunSystem : EntitySystem +public abstract partial class SharedTetherGunSystem : EntitySystem { [Dependency] private readonly INetManager _netManager = default!; [Dependency] private readonly ActionBlockerSystem _blocker = default!; [Dependency] private readonly MobStateSystem _mob = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly SharedJointSystem _joints = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] protected readonly SharedTransformSystem TransformSystem = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; [Dependency] private readonly ThrownItemSystem _thrown = default!; private const string TetherJoint = "tether"; @@ -42,6 +45,8 @@ public abstract class SharedTetherGunSystem : EntitySystem SubscribeLocalEvent(OnTetheredBuckleAttempt); SubscribeLocalEvent(OnTetheredUpdateCanMove); + + InitializeForce(); } private void OnTetheredBuckleAttempt(EntityUid uid, TetheredComponent component, ref BuckleAttemptEvent args) @@ -115,7 +120,8 @@ public abstract class SharedTetherGunSystem : EntitySystem gun = null; if (!TryComp(user, out var hands) || - !TryComp(hands.ActiveHandEntity, out gun)) + !TryComp(hands.ActiveHandEntity, out gun) || + _container.IsEntityInContainer(user)) { return false; } @@ -129,18 +135,19 @@ public abstract class SharedTetherGunSystem : EntitySystem StopTether(uid, component); } - public void TryTether(EntityUid gun, EntityUid target, EntityUid? user, TetherGunComponent? component = null) + public bool TryTether(EntityUid gun, EntityUid target, EntityUid? user, BaseForceGunComponent? component = null) { if (!Resolve(gun, ref component)) - return; + return false; if (!CanTether(gun, component, target, user)) - return; + return false; StartTether(gun, component, target, user); + return true; } - protected virtual bool CanTether(EntityUid uid, TetherGunComponent component, EntityUid target, EntityUid? user) + protected virtual bool CanTether(EntityUid uid, BaseForceGunComponent component, EntityUid target, EntityUid? user) { if (HasComp(target) || !TryComp(target, out var physics)) return false; @@ -160,7 +167,7 @@ public abstract class SharedTetherGunSystem : EntitySystem return true; } - protected virtual void StartTether(EntityUid gunUid, TetherGunComponent component, EntityUid target, EntityUid? user, + protected virtual void StartTether(EntityUid gunUid, BaseForceGunComponent component, EntityUid target, EntityUid? user, PhysicsComponent? targetPhysics = null, TransformComponent? targetXform = null) { if (!Resolve(target, ref targetPhysics, ref targetXform)) @@ -212,7 +219,7 @@ public abstract class SharedTetherGunSystem : EntitySystem Dirty(component); } - protected virtual void StopTether(EntityUid gunUid, TetherGunComponent component, bool transfer = false) + protected virtual void StopTether(EntityUid gunUid, BaseForceGunComponent component, bool land = true, bool transfer = false) { if (component.Tethered == null) return; @@ -229,8 +236,11 @@ public abstract class SharedTetherGunSystem : EntitySystem if (TryComp(component.Tethered, out var targetPhysics)) { - var thrown = EnsureComp(component.Tethered.Value); - _thrown.LandComponent(component.Tethered.Value, thrown, targetPhysics); + if (land) + { + var thrown = EnsureComp(component.Tethered.Value); + _thrown.LandComponent(component.Tethered.Value, thrown, targetPhysics, true); + } _physics.SetBodyStatus(targetPhysics, BodyStatus.OnGround); _physics.SetSleepingAllowed(component.Tethered.Value, targetPhysics, true); diff --git a/Content.Shared/Weapons/Misc/TetherGunComponent.cs b/Content.Shared/Weapons/Misc/TetherGunComponent.cs index 7feaf7f518..06e7da6df4 100644 --- a/Content.Shared/Weapons/Misc/TetherGunComponent.cs +++ b/Content.Shared/Weapons/Misc/TetherGunComponent.cs @@ -1,58 +1,16 @@ -using Robust.Shared.Audio; using Robust.Shared.GameStates; namespace Content.Shared.Weapons.Misc; -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class TetherGunComponent : Component +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class TetherGunComponent : BaseForceGunComponent { [ViewVariables(VVAccess.ReadWrite), DataField("maxDistance"), AutoNetworkedField] public float MaxDistance = 10f; - /// - /// The entity the tethered target has a joint to. - /// - [DataField("tetherEntity"), AutoNetworkedField] - public EntityUid? TetherEntity; - /// /// The entity currently tethered. /// [ViewVariables(VVAccess.ReadWrite), DataField("tethered"), AutoNetworkedField] - public EntityUid? Tethered; - - /// - /// Can the tethergun unanchor entities. - /// - [ViewVariables(VVAccess.ReadWrite), DataField("canUnanchor"), AutoNetworkedField] - public bool CanUnanchor = false; - - [ViewVariables(VVAccess.ReadWrite), DataField("canTetherAlive"), AutoNetworkedField] - public bool CanTetherAlive = false; - - /// - /// Max force between the tether entity and the tethered target. - /// - [ViewVariables(VVAccess.ReadWrite), DataField("maxForce"), AutoNetworkedField] - public float MaxForce = 200f; - - [ViewVariables(VVAccess.ReadWrite), DataField("frequency"), AutoNetworkedField] - public float Frequency = 10f; - - [ViewVariables(VVAccess.ReadWrite), DataField("dampingRatio"), AutoNetworkedField] - public float DampingRatio = 2f; - - /// - /// Maximum amount of mass a tethered entity can have. - /// - [ViewVariables(VVAccess.ReadWrite), DataField("massLimit"), AutoNetworkedField] - public float MassLimit = 100f; - - [ViewVariables(VVAccess.ReadWrite), DataField("sound"), AutoNetworkedField] - public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Weapons/weoweo.ogg") - { - Params = AudioParams.Default.WithLoop(true).WithVolume(-8f), - }; - - public IPlayingAudioStream? Stream; + public override EntityUid? Tethered { get; set; } } diff --git a/Resources/Audio/Weapons/licenses.txt b/Resources/Audio/Weapons/licenses.txt index 7b077ffc71..4dbd19401a 100644 --- a/Resources/Audio/Weapons/licenses.txt +++ b/Resources/Audio/Weapons/licenses.txt @@ -16,4 +16,8 @@ pierce.ogg taken from: https://github.com/tgstation/tgstation/commit/106cd26fc00 - files: ["weoweo.ogg"] license: "SONNISS #GAMEAUDIOGDC BUNDLE LICENSING" - copyright: "Taken from Sonniss.com - GDC 2023 - Systematic Sound - TonalElements Obscurum - Dark Drones" \ No newline at end of file + copyright: "Taken from Sonniss.com - GDC 2023 - Systematic Sound - TonalElements Obscurum - Dark Drones" + +- files: ["soup.ogg"] + license: "SONNISS #GAMEAUDIOGDC BUNDLE LICENSING" + copyright: "Taken from Sonniss.com - GDC 2023 - 344 AUdio - Epic Impacts Vol. 1" \ No newline at end of file diff --git a/Resources/Audio/Weapons/soup.ogg b/Resources/Audio/Weapons/soup.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b3dfe57f4a3adcf846273e61e5af53b378ff029b GIT binary patch literal 12138 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 literal 0 HcmV?d00001 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 4356efa474..0c0940b85e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -186,6 +186,49 @@ True: { visible: true } False: { visible: false } +- type: entity + name: force gun + parent: + - BaseItem + - PowerCellSlotMediumItem + id: WeaponForceGun + description: Manipulates gravity around objects to fling them at high velocities. + components: + - type: ForceGun + frequency: 15 + dampingRatio: 4 + massLimit: 50 + lineColor: "#18a2d5" + soundLaunch: + path: /Audio/Weapons/soup.ogg + params: + volume: 2 + - type: PowerCellDraw + - type: Sprite + sprite: Objects/Weapons/Guns/Launchers/force_gun.rsi + layers: + - state: base + - state: base-unshaded + map: [ "unshaded" ] + shader: unshaded + visible: false + - type: ToggleableLightVisuals + spriteLayer: unshaded + inhandVisuals: + left: + - state: inhand-left-unshaded + shader: unshaded + right: + - state: inhand-right-unshaded + shader: unshaded + - type: Appearance + - type: GenericVisualizer + visuals: + enum.TetherVisualsStatus.Key: + unshaded: + True: { visible: true } + False: { visible: false } + # Admeme - type: entity name: tether gun @@ -226,6 +269,48 @@ True: { visible: true } False: { visible: false } +- type: entity + name: force gun + parent: BaseItem + id: WeaponForceGunAdmin + suffix: Admin + description: Manipulates gravity around objects to fling them at high velocities. + components: + - type: ForceGun + canTetherAlive: true + canUnanchor: true + maxForce: 10000 + massLimit: 10000 + frequency: 15 + dampingRatio: 4 + throwForce: 50 + throwDistance: 100 + lineColor: "#18a2d5" + - type: Sprite + sprite: Objects/Weapons/Guns/Launchers/force_gun.rsi + layers: + - state: base + - state: base-unshaded + map: [ "unshaded" ] + shader: unshaded + visible: false + - type: ToggleableLightVisuals + spriteLayer: unshaded + inhandVisuals: + left: + - state: inhand-left-unshaded + shader: unshaded + right: + - state: inhand-right-unshaded + shader: unshaded + - type: Appearance + - type: GenericVisualizer + visuals: + enum.TetherVisualsStatus.Key: + unshaded: + True: { visible: true } + False: { visible: false } + - type: entity name: meteor launcher parent: WeaponLauncherMultipleRocket diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 888e37bd86..7c58249ef0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -239,6 +239,7 @@ - ClothingShoesBootsMag - NodeScanner - HolofanProjector + - WeaponForceGun - WeaponTetherGun - ClothingBackpackHolding - ClothingBackpackSatchelHolding diff --git a/Resources/Prototypes/Recipes/Lathes/devices.yml b/Resources/Prototypes/Recipes/Lathes/devices.yml index b0cb852142..cf9954b48b 100644 --- a/Resources/Prototypes/Recipes/Lathes/devices.yml +++ b/Resources/Prototypes/Recipes/Lathes/devices.yml @@ -100,6 +100,15 @@ Plastic: 750 Plasma: 1000 +- type: latheRecipe + id: WeaponForceGun + result: WeaponForceGun + completetime: 5 + materials: + Steel: 500 + Glass: 400 + Silver: 200 + - type: latheRecipe id: WeaponTetherGun result: WeaponTetherGun diff --git a/Resources/Prototypes/Research/experimental.yml b/Resources/Prototypes/Research/experimental.yml index 5bc6c623c7..c2e96fd0a7 100644 --- a/Resources/Prototypes/Research/experimental.yml +++ b/Resources/Prototypes/Research/experimental.yml @@ -171,4 +171,5 @@ tier: 3 cost: 10000 recipeUnlocks: + - WeaponForceGun - WeaponTetherGun diff --git a/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/base-unshaded.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/base-unshaded.png new file mode 100644 index 0000000000000000000000000000000000000000..99a23fa9b88a03e80effbc5a9c03a3d93ec2d15f GIT binary patch literal 5749 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/base.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/base.png new file mode 100644 index 0000000000000000000000000000000000000000..5ccd70e2bf76755ebbf8e7fc49bab178faab4902 GIT binary patch literal 6289 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..519a10b6345a499f8b6a0dd1951c035f2d44c617 GIT binary patch literal 6854 zcmeHMc|26@+aE2qkV=Tk7;TnW&0vPHZ$tJqvdnTYwqa&66CqJrM6@t|B&m2rMb;>l zR1{Jo+vE|7tWheJ_Y6Hf^?85)JfHV{{_D(~Gw0m*b$ze<`d;62fA0G;N9=7aB*hiP zArOcp$je6`b^=uycLG3es-KoN?&F>zAY7 z8q|lScQ-j&s}BvF_6W?K$@QMQoO8MEY4usR$Xf#oIrsY>$i?M8B=Q$J-aTGGPZ&t_ zR<`7SX|&I7m3#FX*?rx(z(<0(%B;tszdll;{DHm1oZL6`lS!)AMVC+e5=tiLKZmD9 zF5qiS@f8M1`@R~8@jZEW|RF$aPc^h|MN&k-WsAEC#}P3K`X2^bOUE-Oid=W? z-Frzm1s&VJFx(S8C*(3yJm>axYW+NHUQ&b+niK&j9Og!6Wv0Z(*4EvU=oCHBRU54O zG;FNOCTT48@``E5CSFGM%aH+qC>*xN+F$FHis=5#lrFhglIQ?2xd_tU6?s@yLV60H z*s#syXvuy_-o2-Kux~ph@u)HR{ERr$^@m)tD9(TAl9h z*mzM!)m5g(lw?~fv*wSd7dqXYn#-O4D6i=D3`jlC^Q1ow3@YYyjJZ$f_3@s}i>f4J zOBI2K1$oEy#d3IlXMv`o>&>_B9zFKCq$$nC%`YoIc@uy)q#IPfptU6apq<*8B?ydrDS2>YllU`(W0Vnd^5bB=gUao>&F65 z8GJls<5wTN*F<8)vk%Ib7vi#4X`esT`|@rx>9bhnlv^rGxKBGZs$qOn;G=+m&G#lW zu=(DpW3T4Dq6+#RP7F=Nyl>!4F35kbLu1X;`bevx_P3>7bV7;tS-ND-H1wx~(qT*J~Af_;R3!ML|mWx2W z`KEnE>izXxoLl?8;__o-M7@RQB@eby^LDH^c6%Jr+i3AFtsQavsQj4%vEtNlMzfA{ z^Neu)tvYeT#XLyX!i=#j?9vX9|`IjP9 z;C$Fh@3)4*in|NWI*vQ3ohrP0>EliySR}Zk^>nUuH*b?FJ3GKI*Sc*y!7TlQh7s#t z-^s9~tjg*4XG&IyPw+j|DsVk3JUwsOYr+lBls;6r61v-Ubzn%&Xtg_KJH-@s(q390 zc-C7N%ZbI_@$c_$?6>-8t3_v@czd%mI8A>Y&t-S9anU+_cRaA(_AdOkY%@GFNR##S zs@GS^i0Oz(3_E@ZMpv^v+!F7!<&2+tJqL3y?N~s8g7C&twui0umGn!=$d`k*?$Om` z{gQ+`+hdLgL}eFUhq&cqJZLgEs`y$Xk3VdvKlpggn(RX*mroSXbZzf;_0>HXcQZe1 z4%?f*ZhR_p>r?%`SGRDRNiRc`e0Pmr80x8c8;kn0wRd?Uha)?-eN{n3mvxzaeNciz z$^8;F#ZeKq3lG_i$&Hmo+|h)YFLqh|n;lPV)CJZaI&!^_Rw8AD zRoqA9Iqjv? zag(*rG>M{V*&fGC3!S5_b{)dpNE9NAT1JOZg}2narrpALe&%QBU<$YFk%@G2Fbf~k zQ48#HwmKOen}7Wr)3vIy*IM?Oh3ozN=bMhp42MM4lNJgipq%K-h6KHfH;;~|zIMZp zmB+(-v)(I5clJ9FdVGfeJoo5=$u{@Wk`fBK)Jx^?!7oC=r)s9;E{r5@yZ&=U zA#3#pGG%ALso@ut^|KpZXB4qsFMrTK7TAAOyFcj@ZZnV7_jol=<$V~Qre%`rWpQp~ ze~aR>s1}PY&jK^IW!(^q3&aL1`?i)yO*GKgPs-}L=qH9>(oXX6A$c%5hc~(tZlXcE;>D`tFM~+JH>Ho2Xd%j^ zZw;<#Z@D&c+o*~-h8XtMtyMZ#U?*(;OdV@xE&b5I?Szxz?&$V=m$|lehn_8aC48mt zwld5Raq3&gT43ARilbXDtbX(AW~5Y)Ri)yapTVMoa*k{DV8=b1{O5PLROh9Rd#3x35S+?}pT#_%b!^fb z?pw#?+-{wnEqpK@S2n=6LjnfuQ@YEx<|`SYXRo-+X*`|wbv7tITD)&KYqVng^_c(( z<4wNwuB=@lUYDu)N!fd@R*h|^agt*lB5L1nS#uPFYAN!Y=thX zViUQ!vD~UPIr)=anMOX9oX4mou@$weJD;2v3Wzx5YcXQZcUy3&n^C-3-MVe+o$BnL zs@|39DJdz5c8MQL=h=k+)ac$wPK%CejqGd)6q7xYD1Lv|8fzi@Ny%tH-=guozE5nI zdvD0t*QBVEgAr41ZiyUkjK;||#w^N?!i$azeJXs;!U!s-<-prsYfiRp>&K#*9!$dY zq^tg%_B=0T-Umlp)7Bd+1mWuL8=QH68UhhINH;ODCz+W1wcY|(Sy|DkM9X@^jSW6d z)-GxXWY>g0w9nQ!EE|4GP4!K)lj17ZEvsuT8sG8ci*~ z_q>7BW@h!p$0=aVt2^Na{JyB(o68d-d4KqIZaEitCN;^dVP}NPY~9^Np;_nw?BYbAqX;!K>-llkT7t841wqwaKp&dAb<^}0RHq) zB5bmz4hE&uh%h&t4az3W1PGv8Mlu1XNLy!WWDpfkgBj?H>v0JnKnTDlL%AWrp)3NI z2wTJ@fcJuCBn-M}!VV(B+->ZkCJZJ3#Uii>6x@tUkHEn6#i4pknjgW@)ciXH_(X&S zu-Rb*B$C77AUK)`2Gbvj#^dow6b6aGz(ET*Yi}r<%!P-tR0I%97^VP=%A|*}>5NdQ z0Fz8%>|qmOFt8u`*Z4xhY;1nOhqAu20P=z4lEaW_1PU1vg8bQo#WsroLB0>@zk0Bo z!F>eM5nwU)FsXo91Q5zr`5A&n{ox4vmTgf`Jgwlm$jb{}R%IWMlusLqLH) zJtS<=3ncp&OE%r_Z?b+Fo1kYgou3B+y8poa#rm(@7mYzH8ykWtgStmBJd!C9CWud< zF{pGJVewWQkHTo<@i;i%4~vFl{qPhxMH`EOqfjU^9`A>v;x#EhL6JgPY;q_S5I}+8 z2s((PqeY?lX<<=t0H>)1$6~c=ZC|geuA)L(m_>{gMS{C0Ez}e z0T@3V1@ET?r|4kta4a6J1E=6AC^(s-1!!qfQ2>gJU4)`h3FZuD2pKFVJ%sEJAj3la z7dr%m6O8OhL>LCK6m_x1KA6n*10BG3fF4R?a9DpEJJUk|CpKBYCt6Dfi$&oyaVQ-f zv=&z9ZzETL$pW<~Kt-bvn57;;VF+M4Ahl$HQbB-44=@{o2@@c*8BAveBbW#i3;`cPnbQWl_SD^Xts&@jym!6hhf?)b$7ZkcETmqT86of^N0BDPWK)kj{0*?dk)f|1kq=EZ9VT!edDP%$LId?PvB-kPrX1R+6 zfvj35IE5gYS@K|`2%BVMCh~gaT5;LUn}IBF^C)CTGBt7r|0d}+O0I`WthA4hTv>W_ zp9oCq?i~lIJ89Oa%Si#&mhzGg(1nohOY{a#-)Wl_Ae7*+Q?X(wPzOHfB^dIf!siSh zZ_KBEjvmiaKl{l=T)$Ow&6?u3-DX@^cgu!!pbOF9s7yoDvTOs2NvhBHM5$l246u2Zi)*K8{Z1QSI*V@CsB)CUw%Aw<_n`yPSouHL@zi^f~VYX+9y>IpHeuTF3of zkqN$7^-Q$iryGg9>u|njPp8ZfoE2HWBezvXrAI7J_Pkn8f!DQkYklP}PVa=4Mhjjy z24db_$!<$8<2!K6cNmT*-IA$&pL`&=j}pskTV0Z8ubJ0c9cW?njq_%fVNcAnyE|8v zcP*-_ena$d-*-3zloI3;p@3qB#@J?D;`e?K@hXc%WIx^ THVrj431X7WY)!8i`yTio1ild< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/meta.json new file mode 100644 index 0000000000..66511d0404 --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Guns/Launchers/force_gun.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprited by discord Kheprep#7153, modified by metalgearsloth", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "base" + }, + { + "name": "base-unshaded" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "inhand-left-unshaded", + "directions": 4 + }, + { + "name": "inhand-right-unshaded", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Weapons/Guns/Launchers/tether_gun.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Launchers/tether_gun.rsi/inhand-right.png index 913d55638007ba109bda3464fd4209b5d334ee9d..519a10b6345a499f8b6a0dd1951c035f2d44c617 100644 GIT binary patch delta 3308 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