Bunch of revolver fixes (#19649)

* Bunch of revolver fixes

Some stuff wasn't working with prediction so this should fix all of it.

* a

* fix weh

* Also usedelay
This commit is contained in:
metalgearsloth
2024-01-21 22:16:46 +11:00
committed by GitHub
parent 15f91b0720
commit 9bb2781bfc
5 changed files with 95 additions and 46 deletions

View File

@@ -58,11 +58,11 @@ public sealed partial class GunSystem
RaiseLocalEvent(uid, ev, false); RaiseLocalEvent(uid, ev, false);
} }
protected override void UpdateAmmoCount(EntityUid uid) protected override void UpdateAmmoCount(EntityUid uid, bool prediction = true)
{ {
// Don't use resolves because the method is shared and there's no compref and I'm trying to // Don't use resolves because the method is shared and there's no compref and I'm trying to
// share as much code as possible // share as much code as possible
if (!Timing.IsFirstTimePredicted || if (prediction && !Timing.IsFirstTimePredicted ||
!TryComp<AmmoCounterComponent>(uid, out var clientComp)) !TryComp<AmmoCounterComponent>(uid, out var clientComp))
{ {
return; return;
@@ -98,7 +98,7 @@ public sealed partial class GunSystem
{ {
MinHeight = 15; MinHeight = 15;
HorizontalExpand = true; HorizontalExpand = true;
VerticalAlignment = VAlignment.Center; VerticalAlignment = Control.VAlignment.Center;
AddChild(new BoxContainer AddChild(new BoxContainer
{ {
Orientation = BoxContainer.LayoutOrientation.Vertical, Orientation = BoxContainer.LayoutOrientation.Vertical,
@@ -213,7 +213,7 @@ public sealed partial class GunSystem
{ {
MinHeight = 15; MinHeight = 15;
HorizontalExpand = true; HorizontalExpand = true;
VerticalAlignment = VAlignment.Center; VerticalAlignment = Control.VAlignment.Center;
AddChild(new BoxContainer AddChild(new BoxContainer
{ {
@@ -300,7 +300,7 @@ public sealed partial class GunSystem
{ {
MinHeight = 15; MinHeight = 15;
HorizontalExpand = true; HorizontalExpand = true;
VerticalAlignment = VAlignment.Center; VerticalAlignment = Control.VAlignment.Center;
AddChild(new BoxContainer AddChild(new BoxContainer
{ {
@@ -419,7 +419,7 @@ public sealed partial class GunSystem
{ {
MinHeight = 15; MinHeight = 15;
HorizontalExpand = true; HorizontalExpand = true;
VerticalAlignment = VAlignment.Center; VerticalAlignment = Control.VAlignment.Center;
AddChild((_bulletsList = new BoxContainer AddChild((_bulletsList = new BoxContainer
{ {
Orientation = BoxContainer.LayoutOrientation.Horizontal, Orientation = BoxContainer.LayoutOrientation.Horizontal,

View File

@@ -61,4 +61,12 @@ public sealed class UseDelaySystem : EntitySystem
Dirty(ent); Dirty(ent);
return true; return true;
} }
public bool TryResetDelay(EntityUid uid, bool checkDelayed = false, UseDelayComponent? component = null)
{
if (!Resolve(uid, ref component, false))
return false;
return TryResetDelay((uid, component), checkDelayed);
}
} }

View File

@@ -8,6 +8,7 @@ using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System; using System;
using System.Linq; using System.Linq;
using Content.Shared.Interaction.Events;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Content.Shared.Weapons.Ranged.Systems; namespace Content.Shared.Weapons.Ranged.Systems;
@@ -25,6 +26,17 @@ public partial class SharedGunSystem
SubscribeLocalEvent<RevolverAmmoProviderComponent, GetVerbsEvent<AlternativeVerb>>(OnRevolverVerbs); SubscribeLocalEvent<RevolverAmmoProviderComponent, GetVerbsEvent<AlternativeVerb>>(OnRevolverVerbs);
SubscribeLocalEvent<RevolverAmmoProviderComponent, InteractUsingEvent>(OnRevolverInteractUsing); SubscribeLocalEvent<RevolverAmmoProviderComponent, InteractUsingEvent>(OnRevolverInteractUsing);
SubscribeLocalEvent<RevolverAmmoProviderComponent, GetAmmoCountEvent>(OnRevolverGetAmmoCount); SubscribeLocalEvent<RevolverAmmoProviderComponent, GetAmmoCountEvent>(OnRevolverGetAmmoCount);
SubscribeLocalEvent<RevolverAmmoProviderComponent, UseInHandEvent>(OnRevolverUse);
}
private void OnRevolverUse(EntityUid uid, RevolverAmmoProviderComponent component, UseInHandEvent args)
{
if (!_useDelay.TryResetDelay(uid))
return;
Cycle(component);
UpdateAmmoCount(uid, prediction: false);
Dirty(uid, component);
} }
private void OnRevolverGetAmmoCount(EntityUid uid, RevolverAmmoProviderComponent component, ref GetAmmoCountEvent args) private void OnRevolverGetAmmoCount(EntityUid uid, RevolverAmmoProviderComponent component, ref GetAmmoCountEvent args)
@@ -69,10 +81,9 @@ public partial class SharedGunSystem
} }
// Handle spins // Handle spins
if (Timing.IsFirstTimePredicted) if (oldIndex != state.CurrentIndex)
{ {
if (oldIndex != state.CurrentIndex) UpdateAmmoCount(uid, prediction: false);
UpdateAmmoCount(uid);
} }
} }
@@ -133,6 +144,7 @@ public partial class SharedGunSystem
component.AmmoSlots[index] = ent.Value; component.AmmoSlots[index] = ent.Value;
Containers.Insert(ent.Value, component.AmmoContainer); Containers.Insert(ent.Value, component.AmmoContainer);
SetChamber(index, component, uid);
if (ev.Ammo.Count == 0) if (ev.Ammo.Count == 0)
break; break;
@@ -140,8 +152,8 @@ public partial class SharedGunSystem
DebugTools.Assert(ammo.Count == 0); DebugTools.Assert(ammo.Count == 0);
UpdateRevolverAppearance(revolverUid, component); UpdateRevolverAppearance(revolverUid, component);
UpdateAmmoCount(uid); UpdateAmmoCount(revolverUid);
Dirty(uid, component); Dirty(revolverUid, component);
Audio.PlayPredicted(component.SoundInsert, revolverUid, user); Audio.PlayPredicted(component.SoundInsert, revolverUid, user);
Popup(Loc.GetString("gun-revolver-insert"), revolverUid, user); Popup(Loc.GetString("gun-revolver-insert"), revolverUid, user);
@@ -161,11 +173,12 @@ public partial class SharedGunSystem
component.AmmoSlots[index] = uid; component.AmmoSlots[index] = uid;
Containers.Insert(uid, component.AmmoContainer); Containers.Insert(uid, component.AmmoContainer);
SetChamber(index, component, uid);
Audio.PlayPredicted(component.SoundInsert, revolverUid, user); Audio.PlayPredicted(component.SoundInsert, revolverUid, user);
Popup(Loc.GetString("gun-revolver-insert"), revolverUid, user); Popup(Loc.GetString("gun-revolver-insert"), revolverUid, user);
UpdateRevolverAppearance(revolverUid, component); UpdateRevolverAppearance(revolverUid, component);
UpdateAmmoCount(uid); UpdateAmmoCount(revolverUid);
Dirty(uid, component); Dirty(revolverUid, component);
return true; return true;
} }
@@ -173,6 +186,17 @@ public partial class SharedGunSystem
return false; return false;
} }
private void SetChamber(int index, RevolverAmmoProviderComponent component, EntityUid uid)
{
if (TryComp<CartridgeAmmoComponent>(uid, out var cartridge) && cartridge.Spent)
{
component.Chambers[index] = false;
return;
}
component.Chambers[index] = true;
}
private void OnRevolverVerbs(EntityUid uid, RevolverAmmoProviderComponent component, GetVerbsEvent<AlternativeVerb> args) private void OnRevolverVerbs(EntityUid uid, RevolverAmmoProviderComponent component, GetVerbsEvent<AlternativeVerb> args)
{ {
if (!args.CanAccess || !args.CanInteract || args.Hands == null) if (!args.CanAccess || !args.CanInteract || args.Hands == null)
@@ -252,8 +276,7 @@ public partial class SharedGunSystem
public void EmptyRevolver(EntityUid revolverUid, RevolverAmmoProviderComponent component, EntityUid? user = null) public void EmptyRevolver(EntityUid revolverUid, RevolverAmmoProviderComponent component, EntityUid? user = null)
{ {
var xform = Transform(revolverUid); var mapCoordinates = TransformSystem.GetMapCoordinates(revolverUid);
var mapCoordinates = xform.MapPosition;
var anyEmpty = false; var anyEmpty = false;
for (var i = 0; i < component.Capacity; i++) for (var i = 0; i < component.Capacity; i++)
@@ -284,6 +307,7 @@ public partial class SharedGunSystem
{ {
component.AmmoSlots[i] = null; component.AmmoSlots[i] = null;
Containers.Remove(slot.Value, component.AmmoContainer); Containers.Remove(slot.Value, component.AmmoContainer);
component.Chambers[i] = null;
if (!_netManager.IsClient) if (!_netManager.IsClient)
EjectCartridge(slot.Value); EjectCartridge(slot.Value);
@@ -295,7 +319,7 @@ public partial class SharedGunSystem
if (anyEmpty) if (anyEmpty)
{ {
Audio.PlayPredicted(component.SoundEject, revolverUid, user); Audio.PlayPredicted(component.SoundEject, revolverUid, user);
UpdateAmmoCount(revolverUid); UpdateAmmoCount(revolverUid, prediction: false);
UpdateRevolverAppearance(revolverUid, component); UpdateRevolverAppearance(revolverUid, component);
Dirty(revolverUid, component); Dirty(revolverUid, component);
} }
@@ -328,51 +352,63 @@ public partial class SharedGunSystem
{ {
var index = (currentIndex + i) % component.Capacity; var index = (currentIndex + i) % component.Capacity;
var chamber = component.Chambers[index]; var chamber = component.Chambers[index];
EntityUid? ent = null;
// Get unspawned ent first if possible. // Get contained entity if it exists.
if (chamber != null) if (component.AmmoSlots[index] != null)
{
ent = component.AmmoSlots[index]!;
component.Chambers[index] = false;
}
// Try to spawn a round if it's available.
else if (chamber != null)
{ {
if (chamber == true) if (chamber == true)
{ {
// TODO: This is kinda sussy boy // Pretend it's always been there.
var ent = Spawn(component.FillPrototype, args.Coordinates); ent = Spawn(component.FillPrototype, args.Coordinates);
if (TryComp<CartridgeAmmoComponent>(ent, out var cartridge)) if (!_netManager.IsClient)
{ {
component.Chambers[index] = false; component.AmmoSlots[index] = ent;
SetCartridgeSpent(ent, cartridge, true); Containers.Insert(ent.Value, component.AmmoContainer);
var spawned = Spawn(cartridge.Prototype, args.Coordinates);
args.Ammo.Add((spawned, EnsureShootable(spawned)));
Del(ent);
continue;
} }
component.Chambers[i] = null; component.Chambers[index] = false;
args.Ammo.Add((ent, EnsureShootable(ent)));
} }
} }
else if (component.AmmoSlots[index] != null)
// Chamber empty or spent
if (ent == null)
continue;
if (TryComp<CartridgeAmmoComponent>(ent, out var cartridge))
{ {
var ent = component.AmmoSlots[index]!; if (cartridge.Spent)
if (TryComp<CartridgeAmmoComponent>(ent, out var cartridge))
{
if (cartridge.Spent)
continue;
SetCartridgeSpent(ent.Value, cartridge, true);
var spawned = Spawn(cartridge.Prototype, args.Coordinates);
args.Ammo.Add((spawned, EnsureShootable(spawned)));
continue; continue;
}
Containers.Remove(ent.Value, component.AmmoContainer); // Mark cartridge as spent and if it's caseless delete from the chamber slot.
component.AmmoSlots[index] = null; SetCartridgeSpent(ent.Value, cartridge, true);
args.Ammo.Add((ent.Value, EnsureShootable(ent.Value))); var spawned = Spawn(cartridge.Prototype, args.Coordinates);
TransformSystem.SetCoordinates(ent.Value, args.Coordinates); args.Ammo.Add((spawned, EnsureComp<AmmoComponent>(spawned)));
if (cartridge.DeleteOnSpawn)
component.Chambers[index] = null;
}
else
{
component.Chambers[index] = null;
args.Ammo.Add((ent.Value, EnsureComp<AmmoComponent>(ent.Value)));
}
// Delete the cartridge entity on client
if (_netManager.IsClient)
{
QueueDel(ent);
} }
} }
UpdateAmmoCount(uid, prediction: false);
UpdateRevolverAppearance(uid, component); UpdateRevolverAppearance(uid, component);
Dirty(uid, component); Dirty(uid, component);
} }

View File

@@ -15,6 +15,7 @@ using Content.Shared.Popups;
using Content.Shared.Projectiles; using Content.Shared.Projectiles;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Throwing; using Content.Shared.Throwing;
using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Events;
@@ -61,6 +62,7 @@ public abstract partial class SharedGunSystem : EntitySystem
[Dependency] protected readonly SharedTransformSystem TransformSystem = default!; [Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
[Dependency] protected readonly TagSystem TagSystem = default!; [Dependency] protected readonly TagSystem TagSystem = default!;
[Dependency] protected readonly ThrowingSystem ThrowingSystem = default!; [Dependency] protected readonly ThrowingSystem ThrowingSystem = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
private const float InteractNextFire = 0.3f; private const float InteractNextFire = 0.3f;
private const double SafetyNextFire = 0.5; private const double SafetyNextFire = 0.5;
@@ -408,7 +410,7 @@ public abstract partial class SharedGunSystem : EntitySystem
/// <summary> /// <summary>
/// Call this whenever the ammo count for a gun changes. /// Call this whenever the ammo count for a gun changes.
/// </summary> /// </summary>
protected virtual void UpdateAmmoCount(EntityUid uid) {} protected virtual void UpdateAmmoCount(EntityUid uid, bool prediction = true) {}
protected void SetCartridgeSpent(EntityUid uid, CartridgeAmmoComponent cartridge, bool spent) protected void SetCartridgeSpent(EntityUid uid, CartridgeAmmoComponent cartridge, bool spent)
{ {

View File

@@ -21,6 +21,7 @@
slots: slots:
- suitStorage - suitStorage
- Belt - Belt
- type: AmmoCounter
- type: Gun - type: Gun
selectedMode: SemiAuto selectedMode: SemiAuto
fireRate: 1.5 fireRate: 1.5
@@ -28,6 +29,8 @@
- SemiAuto - SemiAuto
soundGunshot: soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/revolver.ogg path: /Audio/Weapons/Guns/Gunshots/revolver.ogg
- type: UseDelay
delay: 0.66
- type: ContainerContainer - type: ContainerContainer
containers: containers:
revolver-ammo: !type:Container revolver-ammo: !type:Container