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