Skip to content

Commit

Permalink
Fixes (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: DrSmugleaf <[email protected]>
Co-authored-by: Skye <[email protected]>
Co-authored-by: DrSmugleaf <[email protected]>
  • Loading branch information
4 people authored Dec 17, 2024
1 parent 5f662c2 commit 4335a42
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 117 deletions.
2 changes: 1 addition & 1 deletion Content.Client/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public override void Update(float frameTime)

var useKey = gun.UseKey ? EngineKeyFunctions.Use : EngineKeyFunctions.UseSecondary;

if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down && !gun.BurstActivated)
if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down)
{
if (gun.ShotCounter != 0)
EntityManager.RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public sealed class GunPredictionSystem : SharedGunPredictionSystem
private EntityQuery<IgnorePredictionHideComponent> _ignorePredictionHideQuery;
private EntityQuery<SpriteComponent> _spriteQuery;


public override void Initialize()
{
base.Initialize();
Expand Down
25 changes: 6 additions & 19 deletions Content.Server/Weapons/Ranged/Systems/GunSystem.AutoFire.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Content.Shared.Damage;
using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Map;

namespace Content.Server.Weapons.Ranged.Systems;

Expand All @@ -15,28 +13,17 @@ public override void Update(float frameTime)
*/

// Automatic firing without stopping if the AutoShootGunComponent component is exist and enabled
var query = EntityQueryEnumerator<GunComponent>();
var query = EntityQueryEnumerator<AutoShootGunComponent, GunComponent>();

while (query.MoveNext(out var uid, out var gun))
while (query.MoveNext(out var uid, out var autoShoot, out var gun))
{
if (gun.NextFire > Timing.CurTime)
if (!autoShoot.Enabled)
continue;

if (TryComp(uid, out AutoShootGunComponent? autoShoot))
{
if (!autoShoot.Enabled)
continue;
if (gun.NextFire > Timing.CurTime)
continue;

AttemptShoot(uid, gun);
}
else if (gun.BurstActivated)
{
var parent = _transform.GetParentUid(uid);
if (HasComp<DamageableComponent>(parent))
AttemptShoot(parent, uid, gun, gun.ShootCoordinates ?? new EntityCoordinates(uid, gun.DefaultDirection));
else
AttemptShoot(uid, gun);
}
AttemptShoot(uid, gun);
}
}
}
5 changes: 4 additions & 1 deletion Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
using System.Numerics;
using Content.Server.Cargo.Systems;
using Content.Server.Power.EntitySystems;
using Content.Server.Stunnable;
using Content.Shared.Damage.Systems;
using Content.Shared.Effects;
using Content.Shared.Weapons.Ranged;
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using Robust.Shared.Containers;

namespace Content.Server.Weapons.Ranged.Systems;

Expand All @@ -19,7 +23,6 @@ public sealed partial class GunSystem : SharedGunSystem
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly DamageExamineSystem _damageExamine = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;

public override void Initialize()
{
Expand Down
31 changes: 0 additions & 31 deletions Content.Shared/Weapons/Ranged/Components/GunComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Numerics;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio;
Expand Down Expand Up @@ -157,30 +156,6 @@ public sealed partial class GunComponent : Component
[AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public int ShotsPerBurstModified = 3;

/// <summary>
/// How long time must pass between burstfire shots.
/// </summary>
[DataField, AutoNetworkedField]
public float BurstCooldown = 0.25f;

/// <summary>
/// The fire rate of the weapon in burst fire mode.
/// </summary>
[DataField, AutoNetworkedField]
public float BurstFireRate = 8f;

/// <summary>
/// Whether the burst fire mode has been activated.
/// </summary>
[AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public bool BurstActivated = false;

/// <summary>
/// The burst fire bullet count.
/// </summary>
[AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public int BurstShotsCount = 0;

/// <summary>
/// Used for tracking semi-auto / burst
/// </summary>
Expand Down Expand Up @@ -257,12 +232,6 @@ public sealed partial class GunComponent : Component
/// </summary>
[DataField]
public bool ClumsyProof = false;

/// <summary>
/// Firing direction for an item not being held (e.g. shuttle cannons, thrown guns still firing).
/// </summary>
[DataField]
public Vector2 DefaultDirection = new Vector2(0, -1);
}

[Flags]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public bool TryRevolverInsert(EntityUid revolverUid, RevolverAmmoProviderCompone
return false;
}

for (var i = Math.Min(ev.Ammo.Count - 1, component.Capacity - 1); i >= 0; i--)
for (var i = 0; i < component.Capacity; i++)
{
var index = (component.CurrentIndex + i) % component.Capacity;

Expand Down
101 changes: 47 additions & 54 deletions Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun, Ent
/// </summary>
public void AttemptShoot(EntityUid gunUid, GunComponent gun)
{
var coordinates = new EntityCoordinates(gunUid, gun.DefaultDirection);
var coordinates = new EntityCoordinates(gunUid, new Vector2(0, -1));
gun.ShootCoordinates = coordinates;
AttemptShoot(gunUid, gunUid, gun);
gun.ShotCounter = 0;
Expand Down Expand Up @@ -259,9 +259,6 @@ public void AttemptShoot(EntityUid gunUid, GunComponent gun)

var fireRate = TimeSpan.FromSeconds(1f / gun.FireRateModified);

if (gun.SelectedMode == SelectiveFire.Burst || gun.BurstActivated)
fireRate = TimeSpan.FromSeconds(1f / gun.BurstFireRate);

// First shot
// Previously we checked shotcounter but in some cases all the bullets got dumped at once
// curTime - fireRate is insufficient because if you time it just right you can get a 3rd shot out slightly quicker.
Expand All @@ -282,24 +279,18 @@ public void AttemptShoot(EntityUid gunUid, GunComponent gun)

// Get how many shots we're actually allowed to make, due to clip size or otherwise.
// Don't do this in the loop so we still reset NextFire.
if (!gun.BurstActivated)
switch (gun.SelectedMode)
{
switch (gun.SelectedMode)
{
case SelectiveFire.SemiAuto:
shots = Math.Min(shots, 1 - gun.ShotCounter);
break;
case SelectiveFire.Burst:
shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
break;
case SelectiveFire.FullAuto:
break;
default:
throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.SelectedMode}!");
}
} else
{
shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
case SelectiveFire.SemiAuto:
shots = Math.Min(shots, 1 - gun.ShotCounter);
break;
case SelectiveFire.Burst:
shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
break;
case SelectiveFire.FullAuto:
break;
default:
throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.SelectedMode}!");
}

var attemptEv = new AttemptShootEvent(user, null);
Expand All @@ -311,15 +302,11 @@ public void AttemptShoot(EntityUid gunUid, GunComponent gun)
{
PopupSystem.PopupClient(attemptEv.Message, gunUid, user);
}
gun.BurstActivated = false;
gun.BurstShotsCount = 0;

gun.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.NextFire.TotalSeconds));
return null;
}

if (!Timing.IsFirstTimePredicted)
return null;

var fromCoordinates = Transform(user).Coordinates;
// Remove ammo
var ev = new TakeAmmoEvent(shots, new List<(EntityUid? Entity, IShootable Shootable)>(), fromCoordinates, user);
Expand All @@ -335,17 +322,32 @@ public void AttemptShoot(EntityUid gunUid, GunComponent gun)
// Even if we don't actually shoot update the ShotCounter. This is to avoid spamming empty sounds
// where the gun may be SemiAuto or Burst.
gun.ShotCounter += shots;
Dirty(gunUid, gun);

void CleanupClient()
{
foreach (var (ent, _) in ev.Ammo)
{
if (ent == null)
continue;

if (_netManager.IsServer || IsClientSide(ent.Value))
Del(ent);
}
}

if (!Timing.IsFirstTimePredicted)
{
CleanupClient();
return null;
}

if (ev.Ammo.Count <= 0)
{
// triggers effects on the gun if it's empty
var emptyGunShotEvent = new OnEmptyGunShotEvent();
RaiseLocalEvent(gunUid, ref emptyGunShotEvent);

gun.BurstActivated = false;
gun.BurstShotsCount = 0;
gun.NextFire += TimeSpan.FromSeconds(gun.BurstCooldown);

// Play empty gun sounds if relevant
// If they're firing an existing clip then don't play anything.
if (shots > 0)
Expand All @@ -365,21 +367,11 @@ public void AttemptShoot(EntityUid gunUid, GunComponent gun)
return null;
}

// Handle burstfire
if (gun.SelectedMode == SelectiveFire.Burst)
{
gun.BurstActivated = true;
}
if (gun.BurstActivated)
{
gun.BurstShotsCount += shots;
if (gun.BurstShotsCount >= gun.ShotsPerBurstModified)
{
gun.NextFire += TimeSpan.FromSeconds(gun.BurstCooldown);
gun.BurstActivated = false;
gun.BurstShotsCount = 0;
}
}
// if (_netManager.IsClient && HasComp<GunIgnorePredictionComponent>(gunUid))
// {
// CleanupClient();
// return null;
// }

// Shoot confirmed - sounds also played here in case it's invalid (e.g. cartridge already spent).
var projectiles = Shoot(gunUid, gun, ev.Ammo, fromCoordinates, toCoordinates.Value, out var userImpulse, user, throwItems: attemptEv.ThrowItems, predictedProjectiles, userSession);
Expand Down Expand Up @@ -495,9 +487,14 @@ void MarkPredicted(EntityUid projectile, int index)
if (_netManager.IsServer || GunPrediction)
{
var uid = Spawn(cartridge.Prototype, fromEnt);
shotProjectiles.Add(uid);
CreateAndFireProjectiles(uid, cartridge);

if (_netManager.IsClient && HasComp<GunIgnorePredictionComponent>(gunUid))
{
predictedProjectiles?.RemoveAll(i => i == uid.Id);
QueueDel(uid);
}

RaiseLocalEvent(ent!.Value, new AmmoShotEvent()
{
FiredProjectiles = shotProjectiles,
Expand Down Expand Up @@ -538,8 +535,7 @@ void MarkPredicted(EntityUid projectile, int index)
case AmmoComponent newAmmo:
if (_netManager.IsServer || GunPrediction)
{
shotProjectiles.Add(ent!.Value);
CreateAndFireProjectiles(ent.Value, newAmmo);
CreateAndFireProjectiles(ent!.Value, newAmmo);
}
else
{
Expand All @@ -549,10 +545,8 @@ void MarkPredicted(EntityUid projectile, int index)

Recoil(user, mapDirection, gun.CameraRecoilScalarModified);

if (IsClientSide(ent!.Value))
Del(ent.Value);
else if (_netManager.IsClient)
RemoveShootable(ent.Value);
if (_netManager.IsClient)
RemoveShootable(ent!.Value);
MarkPredicted(ent!.Value, 0);
break;
case HitscanPrototype hitscan:
Expand Down Expand Up @@ -689,7 +683,7 @@ void CreateAndFireProjectiles(EntityUid ammoEnt, AmmoComponent ammoComp)
var newuid = Spawn(ammoSpreadComp.Proto, fromEnt);
ShootOrThrow(newuid, angles[i].ToVec(), gunVelocity, gun, gunUid, user);
shotProjectiles.Add(newuid);
MarkPredicted(newuid, i + 1);
MarkPredicted(newuid, i);
}
}
else
Expand All @@ -716,7 +710,6 @@ private Angle GetRecoilAngle(TimeSpan curTime, GunComponent component, Angle dir
long tick = Timing.CurTick.Value;
tick = tick << 32;
tick = tick | (uint) GetNetEntity(component.Owner).Id;
Logger.Info(Timing.CurTick.ToString());
var random = new Xoroshiro64S(tick).NextFloat(-0.5f, 0.5f);
var spread = component.CurrentAngle.Theta * random;
var angle = new Angle(direction.Theta + component.CurrentAngle.Theta * random);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Robust.Shared.GameStates;

namespace Content.Shared._RMC14.Weapons.Ranged.Prediction;

[RegisterComponent, NetworkedComponent]
[Access(typeof(SharedGunPredictionSystem))]
public sealed partial class GunIgnorePredictionComponent : Component;
13 changes: 3 additions & 10 deletions Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
minAngle: 2
maxAngle: 16
fireRate: 8
burstFireRate: 8
angleIncrease: 3
angleDecay: 16
selectedMode: FullAuto
Expand All @@ -28,7 +27,6 @@
- FullAuto
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/smg.ogg
defaultDirection: 1, 0
- type: ChamberMagazineAmmoProvider
soundRack:
path: /Audio/Weapons/Guns/Cock/smg_cock.ogg
Expand Down Expand Up @@ -142,15 +140,12 @@
- type: Gun
minAngle: 21
maxAngle: 32
fireRate: 12
burstFireRate: 12
selectedMode: Burst
fireRate: 6
selectedMode: FullAuto
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/atreides.ogg
availableModes:
- Burst
shotsPerBurst: 3
burstCooldown: 0.25
- FullAuto
- type: ItemSlots
slots:
gun_magazine:
Expand Down Expand Up @@ -255,8 +250,6 @@
angleDecay: 6
selectedMode: FullAuto
shotsPerBurst: 5
burstCooldown: 0.2
burstFireRate: 7
availableModes:
- SemiAuto
- Burst
Expand Down

0 comments on commit 4335a42

Please sign in to comment.