diff --git a/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs b/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs index eb02dd06f8..41e1895da2 100644 --- a/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs +++ b/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs @@ -16,7 +16,6 @@ using Robust.Shared.Physics.Dynamics.Joints; using Robust.Shared.Physics.Systems; using Robust.Shared.Serialization; using Robust.Shared.Timing; -using Robust.Shared.Utility; namespace Content.Shared.Weapons.Misc; @@ -27,6 +26,7 @@ public abstract class SharedGrapplingGunSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedJointSystem _joints = default!; + [Dependency] private readonly SharedGunSystem _gun = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; public const string GrapplingJoint = "grappling"; @@ -48,7 +48,8 @@ public abstract class SharedGrapplingGunSystem : EntitySystem private void OnGrappleJointRemoved(EntityUid uid, GrapplingProjectileComponent component, JointRemovedEvent args) { - QueueDel(uid); + if (_netManager.IsServer) + QueueDel(uid); } private void OnGrapplingShot(EntityUid uid, GrapplingGunComponent component, ref GunShotEvent args) @@ -58,12 +59,12 @@ public abstract class SharedGrapplingGunSystem : EntitySystem if (!HasComp(shotUid)) continue; + //todo: this doesn't actually support multigrapple // At least show the visuals. component.Projectile = shotUid.Value; Dirty(uid, component); var visuals = EnsureComp(shotUid.Value); - visuals.Sprite = - new SpriteSpecifier.Rsi(new ResPath("Objects/Weapons/Guns/Launchers/grappling_gun.rsi"), "rope"); + visuals.Sprite = component.RopeSprite; visuals.OffsetA = new Vector2(0f, 0.5f); visuals.Target = uid; Dirty(shotUid.Value, visuals); @@ -71,6 +72,7 @@ public abstract class SharedGrapplingGunSystem : EntitySystem TryComp(uid, out var appearance); _appearance.SetData(uid, SharedTetherGunSystem.TetherVisualsStatus.Key, false, appearance); + Dirty(uid, component); } private void OnGrapplingDeselected(EntityUid uid, GrapplingGunComponent component, HandDeselectedEvent args) @@ -117,23 +119,21 @@ public abstract class SharedGrapplingGunSystem : EntitySystem if (!Timing.IsFirstTimePredicted || args.Handled) return; + if (Deleted(component.Projectile)) + return; + _audio.PlayPredicted(component.CycleSound, uid, args.User); + _appearance.SetData(uid, SharedTetherGunSystem.TetherVisualsStatus.Key, true); - TryComp(uid, out var appearance); - _appearance.SetData(uid, SharedTetherGunSystem.TetherVisualsStatus.Key, true, appearance); - SetReeling(uid, component, false, args.User); - - if (!Deleted(component.Projectile)) + if (_netManager.IsServer) { - if (_netManager.IsServer) - { - QueueDel(component.Projectile.Value); - } - - component.Projectile = null; - Dirty(uid, component); + QueueDel(component.Projectile.Value); } + component.Projectile = null; + SetReeling(uid, component, false, args.User); + _gun.ChangeBasicEntityAmmoCount(uid, 1); + args.Handled = true; } diff --git a/Content.Shared/Weapons/Ranged/Components/GrapplingGunComponent.cs b/Content.Shared/Weapons/Ranged/Components/GrapplingGunComponent.cs index 3ca52b2878..d0af3e8b36 100644 --- a/Content.Shared/Weapons/Ranged/Components/GrapplingGunComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/GrapplingGunComponent.cs @@ -1,5 +1,6 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Utility; namespace Content.Shared.Weapons.Ranged.Components; @@ -10,7 +11,8 @@ public sealed partial class GrapplingGunComponent : Component [DataField("jointId"), AutoNetworkedField] public string Joint = string.Empty; - [DataField("projectile")] public EntityUid? Projectile; + [DataField, AutoNetworkedField] + public EntityUid? Projectile; [ViewVariables(VVAccess.ReadWrite), DataField("reeling"), AutoNetworkedField] public bool Reeling; @@ -24,5 +26,9 @@ public sealed partial class GrapplingGunComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField("cycleSound"), AutoNetworkedField] public SoundSpecifier? CycleSound = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/kinetic_reload.ogg"); + [DataField, ViewVariables] + public SpriteSpecifier RopeSprite = + new SpriteSpecifier.Rsi(new ResPath("Objects/Weapons/Guns/Launchers/grappling_gun.rsi"), "rope"); + public EntityUid? Stream; } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.BasicEntity.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.BasicEntity.cs index 731e7a526d..04f9b52324 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.BasicEntity.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.BasicEntity.cs @@ -62,19 +62,26 @@ public abstract partial class SharedGunSystem } #region Public API + public bool ChangeBasicEntityAmmoCount(EntityUid uid, int delta, BasicEntityAmmoProviderComponent? component = null) + { + if (!Resolve(uid, ref component, false) || component.Count == null) + return false; + + return UpdateBasicEntityAmmoCount(uid, component.Count.Value + delta, component); + } public bool UpdateBasicEntityAmmoCount(EntityUid uid, int count, BasicEntityAmmoProviderComponent? component = null) { - if (!Resolve(uid, ref component)) + if (!Resolve(uid, ref component, false)) return false; if (count > component.Capacity) return false; component.Count = count; - Dirty(uid, component); UpdateBasicEntityAppearance(uid, component); UpdateAmmoCount(uid); + Dirty(uid, component); return true; } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 74f606ddb5..635de1c64b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -240,7 +240,6 @@ - type: Gun soundGunshot: /Audio/Weapons/Guns/Gunshots/harpoon.ogg fireRate: 0.5 - - type: RechargeCycleAmmo - type: BasicEntityAmmoProvider proto: GrapplingHook capacity: 1