using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
-using Robust.Client.Serialization;
using Robust.Client.UserInterface;
using Robust.Shared.Enums;
-using Robust.Shared.Graphics;
using Robust.Shared.Utility;
namespace Content.Client.CombatMode;
/// <summary>
/// What RsiState we use.
/// </summary>
- [DataField("magState")] public string? MagState;
+ [DataField]
+ public string? MagState;
/// <summary>
/// How many steps there are
/// </summary>
- [DataField("steps")] public int MagSteps;
+ [DataField("steps")]
+ public int MagSteps;
/// <summary>
/// Should we hide when the count is 0
/// </summary>
- [DataField("zeroVisible")] public bool ZeroVisible;
+ [DataField]
+ public bool ZeroVisible;
}
public enum GunVisualLayers : byte
/// <summary>
/// Should we do "{_state}-spent" or just "spent"
/// </summary>
- [DataField("suffix")] public bool Suffix = true;
+ [DataField]
+ public bool Suffix = true;
- [DataField("state")]
+ [DataField]
public string State = "base";
}
if (mapPos.MapId == MapId.Nullspace)
return;
- if (!_guns.TryGetGun(player.Value, out var gunUid, out var gun))
+ if (!_guns.TryGetGun(player.Value, out var gun))
return;
var mouseScreenPos = _input.MouseScreenPosition;
return;
// (☞゚ヮ゚)☞
- var maxSpread = gun.MaxAngleModified;
- var minSpread = gun.MinAngleModified;
- var timeSinceLastFire = (_timing.CurTime - gun.NextFire).TotalSeconds;
- var currentAngle = new Angle(MathHelper.Clamp(gun.CurrentAngle.Theta - gun.AngleDecayModified.Theta * timeSinceLastFire,
- gun.MinAngleModified.Theta, gun.MaxAngleModified.Theta));
- var direction = (mousePos.Position - mapPos.Position);
+ var maxSpread = gun.Comp.MaxAngleModified;
+ var minSpread = gun.Comp.MinAngleModified;
+ var timeSinceLastFire = (_timing.CurTime - gun.Comp.NextFire).TotalSeconds;
+ var currentAngle = new Angle(MathHelper.Clamp(gun.Comp.CurrentAngle.Theta - gun.Comp.AngleDecayModified.Theta * timeSinceLastFire,
+ gun.Comp.MinAngleModified.Theta, gun.Comp.MaxAngleModified.Theta));
+ var direction = mousePos.Position - mapPos.Position;
worldHandle.DrawLine(mapPos.Position, mousePos.Position + direction, Color.Orange);
{
var countPerRow = Math.Min(Capacity, CountPerRow(availableSize.X));
- var rows = Math.Min((int) MathF.Ceiling(Capacity / (float) countPerRow), Rows);
+ var rows = Math.Min((int)MathF.Ceiling(Capacity / (float)countPerRow), Rows);
var height = _params.ItemHeight * rows + (_params.VerticalSeparation * rows - 1);
var width = RowWidth(countPerRow);
private int CountPerRow(float width)
{
- return (int) ((width - _params.ItemWidth + _params.ItemSeparation) / _params.ItemSeparation);
+ return (int)((width - _params.ItemWidth + _params.ItemSeparation) / _params.ItemSeparation);
}
private int RowWidth(int count)
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Client.Player;
-using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Physics.Events;
-using Robust.Shared.Player;
using Robust.Shared.Random;
namespace Content.Client.Weapons.Ranged.Systems;
SubscribeLocalEvent<FlyBySoundComponent, StartCollideEvent>(OnCollide);
}
- private void OnCollide(EntityUid uid, FlyBySoundComponent component, ref StartCollideEvent args)
+ private void OnCollide(Entity<FlyBySoundComponent> ent, ref StartCollideEvent args)
{
var attachedEnt = _player.LocalEntity;
// If it's not our ent or we shot it.
if (attachedEnt == null ||
args.OtherEntity != attachedEnt ||
- TryComp<ProjectileComponent>(uid, out var projectile) &&
+ TryComp<ProjectileComponent>(ent, out var projectile) &&
projectile.Shooter == attachedEnt)
{
return;
}
if (args.OurFixtureId != FlyByFixture ||
- !_random.Prob(component.Prob))
+ !_random.Prob(ent.Comp.Prob))
{
return;
}
// Play attached to our entity because the projectile may immediately delete or the likes.
- _audio.PlayPredicted(component.Sound, attachedEnt.Value, attachedEnt.Value);
+ _audio.PlayPredicted(ent.Comp.Sound, attachedEnt.Value, attachedEnt.Value);
}
}
public sealed partial class GunSystem
{
- private void OnAmmoCounterCollect(EntityUid uid, AmmoCounterComponent component, ItemStatusCollectMessage args)
+ private void OnAmmoCounterCollect(Entity<AmmoCounterComponent> ent, ref ItemStatusCollectMessage args)
{
- RefreshControl(uid, component);
+ RefreshControl(ent);
- if (component.Control != null)
- args.Controls.Add(component.Control);
+ if (ent.Comp.Control != null)
+ args.Controls.Add(ent.Comp.Control);
}
/// <summary>
/// </summary>
/// <param name="uid"></param>
/// <param name="component"></param>
- private void RefreshControl(EntityUid uid, AmmoCounterComponent? component = null)
+ private void RefreshControl(Entity<AmmoCounterComponent> ent)
{
- if (!Resolve(uid, ref component, false))
- return;
-
- component.Control?.Dispose();
- component.Control = null;
+ ent.Comp.Control?.Dispose();
+ ent.Comp.Control = null;
var ev = new AmmoCounterControlEvent();
- RaiseLocalEvent(uid, ev, false);
+ RaiseLocalEvent(ent, ev, false);
// Fallback to default if none specified
ev.Control ??= new DefaultStatusControl();
- component.Control = ev.Control;
- UpdateAmmoCount(uid, component);
+ ent.Comp.Control = ev.Control;
+ UpdateAmmoCount(ent);
}
- private void UpdateAmmoCount(EntityUid uid, AmmoCounterComponent component)
+ private void UpdateAmmoCount(Entity<AmmoCounterComponent> ent)
{
- if (component.Control == null)
+ if (ent.Comp.Control == null)
return;
var ev = new UpdateAmmoCounterEvent()
{
- Control = component.Control
+ Control = ent.Comp.Control
};
- RaiseLocalEvent(uid, ev, false);
+ RaiseLocalEvent(ent, ev, false);
}
protected override void UpdateAmmoCount(EntityUid uid, bool prediction = true)
return;
}
- UpdateAmmoCount(uid, clientComp);
+ UpdateAmmoCount((uid, clientComp));
}
/// <summary>
SubscribeLocalEvent<BallisticAmmoProviderComponent, UpdateAmmoCounterEvent>(OnBallisticAmmoCount);
}
- private void OnBallisticAmmoCount(EntityUid uid, BallisticAmmoProviderComponent component, UpdateAmmoCounterEvent args)
+ private void OnBallisticAmmoCount(Entity<BallisticAmmoProviderComponent> ent, ref UpdateAmmoCounterEvent args)
{
if (args.Control is DefaultStatusControl control)
{
- control.Update(GetBallisticShots(component), component.Capacity);
+ control.Update(GetBallisticShots(ent.Comp), ent.Comp.Capacity);
}
}
- protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates)
+ protected override void Cycle(Entity<BallisticAmmoProviderComponent> ent, MapCoordinates coordinates)
{
if (!Timing.IsFirstTimePredicted)
return;
- EntityUid? ent = null;
+ EntityUid? ammoEnt = null;
// TODO: Combine with TakeAmmo
- if (component.Entities.Count > 0)
+ if (ent.Comp.Entities.Count > 0)
{
- var existing = component.Entities[^1];
- component.Entities.RemoveAt(component.Entities.Count - 1);
+ var existing = ent.Comp.Entities[^1];
+ ent.Comp.Entities.RemoveAt(ent.Comp.Entities.Count - 1);
- Containers.Remove(existing, component.Container);
+ Containers.Remove(existing, ent.Comp.Container);
EnsureShootable(existing);
}
- else if (component.UnspawnedCount > 0)
+ else if (ent.Comp.UnspawnedCount > 0)
{
- component.UnspawnedCount--;
- ent = Spawn(component.Proto, coordinates);
- EnsureShootable(ent.Value);
+ ent.Comp.UnspawnedCount--;
+ ammoEnt = Spawn(ent.Comp.Proto, coordinates);
+ EnsureShootable(ammoEnt.Value);
}
- if (ent != null && IsClientSide(ent.Value))
- Del(ent.Value);
+ if (ammoEnt != null && IsClientSide(ammoEnt.Value))
+ Del(ammoEnt.Value);
var cycledEvent = new GunCycledEvent();
- RaiseLocalEvent(uid, ref cycledEvent);
+ RaiseLocalEvent(ent, ref cycledEvent);
}
}
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, UpdateAmmoCounterEvent>(OnBasicEntityAmmoCount);
}
- private void OnBasicEntityAmmoCount(EntityUid uid, BasicEntityAmmoProviderComponent component, UpdateAmmoCounterEvent args)
+ private void OnBasicEntityAmmoCount(Entity<BasicEntityAmmoProviderComponent> ent, ref UpdateAmmoCounterEvent args)
{
- if (args.Control is DefaultStatusControl control && component.Count != null && component.Capacity != null)
+ if (args.Control is DefaultStatusControl control && ent.Comp.Count != null && ent.Comp.Capacity != null)
{
- control.Update(component.Count.Value, component.Capacity.Value);
+ control.Update(ent.Comp.Count.Value, ent.Comp.Capacity.Value);
}
}
}
SubscribeLocalEvent<ChamberMagazineAmmoProviderComponent, AppearanceChangeEvent>(OnChamberMagazineAppearance);
}
- private void OnChamberMagazineAppearance(EntityUid uid, ChamberMagazineAmmoProviderComponent component, ref AppearanceChangeEvent args)
+ private void OnChamberMagazineAppearance(Entity<ChamberMagazineAmmoProviderComponent> ent, ref AppearanceChangeEvent args)
{
if (args.Sprite == null ||
- !_sprite.LayerMapTryGet((uid, args.Sprite), GunVisualLayers.Base, out var boltLayer, false) ||
- !Appearance.TryGetData(uid, AmmoVisuals.BoltClosed, out bool boltClosed))
+ !_sprite.LayerMapTryGet((ent, args.Sprite), GunVisualLayers.Base, out var boltLayer, false) ||
+ !Appearance.TryGetData(ent, AmmoVisuals.BoltClosed, out bool boltClosed))
{
return;
}
// Maybe re-using base layer for this will bite me someday but screw you future sloth.
if (boltClosed)
{
- _sprite.LayerSetRsiState((uid, args.Sprite), boltLayer, "base");
+ _sprite.LayerSetRsiState((ent, args.Sprite), boltLayer, "base");
}
else
{
- _sprite.LayerSetRsiState((uid, args.Sprite), boltLayer, "bolt-open");
+ _sprite.LayerSetRsiState((ent, args.Sprite), boltLayer, "bolt-open");
}
}
// to avoid 6-7 additional entity spawns.
}
- private void OnChamberMagazineCounter(EntityUid uid, ChamberMagazineAmmoProviderComponent component, AmmoCounterControlEvent args)
+ private void OnChamberMagazineCounter(Entity<ChamberMagazineAmmoProviderComponent> ent, ref AmmoCounterControlEvent args)
{
args.Control = new ChamberMagazineStatusControl();
}
- private void OnChamberMagazineAmmoUpdate(EntityUid uid, ChamberMagazineAmmoProviderComponent component, UpdateAmmoCounterEvent args)
+ private void OnChamberMagazineAmmoUpdate(Entity<ChamberMagazineAmmoProviderComponent> ent, ref UpdateAmmoCounterEvent args)
{
if (args.Control is not ChamberMagazineStatusControl control) return;
- var chambered = GetChamberEntity(uid);
- var magEntity = GetMagazineEntity(uid);
+ var chambered = GetChamberEntity(ent);
+ var magEntity = GetMagazineEntity(ent);
var ammoCountEv = new GetAmmoCountEvent();
if (magEntity != null)
SubscribeLocalEvent<MagazineAmmoProviderComponent, AmmoCounterControlEvent>(OnMagazineControl);
}
- private void OnMagazineAmmoUpdate(EntityUid uid, MagazineAmmoProviderComponent component, UpdateAmmoCounterEvent args)
+ private void OnMagazineAmmoUpdate(Entity<MagazineAmmoProviderComponent> ent, ref UpdateAmmoCounterEvent args)
{
- var ent = GetMagazineEntity(uid);
+ var magEnt = GetMagazineEntity(ent);
- if (ent == null)
+ if (magEnt == null)
{
if (args.Control is DefaultStatusControl control)
{
return;
}
- RaiseLocalEvent(ent.Value, args, false);
+ RaiseLocalEvent(magEnt.Value, args, false);
}
- private void OnMagazineControl(EntityUid uid, MagazineAmmoProviderComponent component, AmmoCounterControlEvent args)
+ private void OnMagazineControl(Entity<MagazineAmmoProviderComponent> ent, ref AmmoCounterControlEvent args)
{
- var ent = GetMagazineEntity(uid);
- if (ent == null)
+ var magEnt = GetMagazineEntity(ent);
+ if (magEnt == null)
return;
- RaiseLocalEvent(ent.Value, args, false);
+ RaiseLocalEvent(magEnt.Value, args, false);
}
}
SubscribeLocalEvent<MagazineVisualsComponent, AppearanceChangeEvent>(OnMagazineVisualsChange);
}
- private void OnMagazineVisualsInit(EntityUid uid, MagazineVisualsComponent component, ComponentInit args)
+ private void OnMagazineVisualsInit(Entity<MagazineVisualsComponent> ent, ref ComponentInit args)
{
- if (!TryComp<SpriteComponent>(uid, out var sprite)) return;
+ if (!TryComp<SpriteComponent>(ent, out var sprite)) return;
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.Mag, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.Mag, out _, false))
{
- _sprite.LayerSetRsiState((uid, sprite), GunVisualLayers.Mag, $"{component.MagState}-{component.MagSteps - 1}");
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.Mag, false);
+ _sprite.LayerSetRsiState((ent, sprite), GunVisualLayers.Mag, $"{ent.Comp.MagState}-{ent.Comp.MagSteps - 1}");
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.Mag, false);
}
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.MagUnshaded, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.MagUnshaded, out _, false))
{
- _sprite.LayerSetRsiState((uid, sprite), GunVisualLayers.MagUnshaded, $"{component.MagState}-unshaded-{component.MagSteps - 1}");
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.MagUnshaded, false);
+ _sprite.LayerSetRsiState((ent, sprite), GunVisualLayers.MagUnshaded, $"{ent.Comp.MagState}-unshaded-{ent.Comp.MagSteps - 1}");
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.MagUnshaded, false);
}
}
- private void OnMagazineVisualsChange(EntityUid uid, MagazineVisualsComponent component, ref AppearanceChangeEvent args)
+ private void OnMagazineVisualsChange(Entity<MagazineVisualsComponent> ent, ref AppearanceChangeEvent args)
{
// tl;dr
// 1.If no mag then hide it OR
{
if (!args.AppearanceData.TryGetValue(AmmoVisuals.AmmoMax, out var capacity))
{
- capacity = component.MagSteps;
+ capacity = ent.Comp.MagSteps;
}
if (!args.AppearanceData.TryGetValue(AmmoVisuals.AmmoCount, out var current))
{
- current = component.MagSteps;
+ current = ent.Comp.MagSteps;
}
- var step = ContentHelpers.RoundToLevels((int)current, (int)capacity, component.MagSteps);
+ var step = ContentHelpers.RoundToLevels((int)current, (int)capacity, ent.Comp.MagSteps);
- if (step == 0 && !component.ZeroVisible)
+ if (step == 0 && !ent.Comp.ZeroVisible)
{
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.Mag, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.Mag, out _, false))
{
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.Mag, false);
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.Mag, false);
}
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.MagUnshaded, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.MagUnshaded, out _, false))
{
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.MagUnshaded, false);
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.MagUnshaded, false);
}
return;
}
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.Mag, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.Mag, out _, false))
{
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.Mag, true);
- _sprite.LayerSetRsiState((uid, sprite), GunVisualLayers.Mag, $"{component.MagState}-{step}");
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.Mag, true);
+ _sprite.LayerSetRsiState((ent, sprite), GunVisualLayers.Mag, $"{ent.Comp.MagState}-{step}");
}
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.MagUnshaded, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.MagUnshaded, out _, false))
{
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.MagUnshaded, true);
- _sprite.LayerSetRsiState((uid, sprite), GunVisualLayers.MagUnshaded, $"{component.MagState}-unshaded-{step}");
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.MagUnshaded, true);
+ _sprite.LayerSetRsiState((ent, sprite), GunVisualLayers.MagUnshaded, $"{ent.Comp.MagState}-unshaded-{step}");
}
}
else
{
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.Mag, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.Mag, out _, false))
{
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.Mag, false);
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.Mag, false);
}
- if (_sprite.LayerMapTryGet((uid, sprite), GunVisualLayers.MagUnshaded, out _, false))
+ if (_sprite.LayerMapTryGet((ent, sprite), GunVisualLayers.MagUnshaded, out _, false))
{
- _sprite.LayerSetVisible((uid, sprite), GunVisualLayers.MagUnshaded, false);
+ _sprite.LayerSetVisible((ent, sprite), GunVisualLayers.MagUnshaded, false);
}
}
}
SubscribeLocalEvent<RevolverAmmoProviderComponent, EntRemovedFromContainerMessage>(OnRevolverEntRemove);
}
- private void OnRevolverEntRemove(EntityUid uid, RevolverAmmoProviderComponent component, EntRemovedFromContainerMessage args)
+ private void OnRevolverEntRemove(Entity<RevolverAmmoProviderComponent> ent, ref EntRemovedFromContainerMessage args)
{
if (args.Container.ID != RevolverContainer)
return;
- // See ChamberMagazineAmmoProvider
+ // <See ChamberMagazineAmmoProvider>
if (!IsClientSide(args.Entity))
return;
QueueDel(args.Entity);
}
- private void OnRevolverAmmoUpdate(EntityUid uid, RevolverAmmoProviderComponent component, UpdateAmmoCounterEvent args)
+ private void OnRevolverAmmoUpdate(Entity<RevolverAmmoProviderComponent> ent, ref UpdateAmmoCounterEvent args)
{
if (args.Control is not RevolverStatusControl control) return;
- control.Update(component.CurrentIndex, component.Chambers);
+ control.Update(ent.Comp.CurrentIndex, ent.Comp.Chambers);
}
- private void OnRevolverCounter(EntityUid uid, RevolverAmmoProviderComponent component, AmmoCounterControlEvent args)
+ private void OnRevolverCounter(Entity<RevolverAmmoProviderComponent> ent, ref AmmoCounterControlEvent args)
{
args.Control = new RevolverStatusControl();
}
SubscribeLocalEvent<SpentAmmoVisualsComponent, AppearanceChangeEvent>(OnSpentAmmoAppearance);
}
- private void OnSpentAmmoAppearance(EntityUid uid, SpentAmmoVisualsComponent component, ref AppearanceChangeEvent args)
+ private void OnSpentAmmoAppearance(Entity<SpentAmmoVisualsComponent> ent, ref AppearanceChangeEvent args)
{
var sprite = args.Sprite;
if (sprite == null) return;
return;
}
- var spent = (bool) varSpent;
+ var spent = (bool)varSpent;
string state;
if (spent)
- state = component.Suffix ? $"{component.State}-spent" : "spent";
+ state = ent.Comp.Suffix ? $"{ent.Comp.State}-spent" : "spent";
else
- state = component.State;
+ state = ent.Comp.State;
- _sprite.LayerSetRsiState((uid, sprite), AmmoVisualLayers.Base, state);
- _sprite.RemoveLayer((uid, sprite), AmmoVisualLayers.Tip, false);
+ _sprite.LayerSetRsiState((ent, sprite), AmmoVisualLayers.Base, state);
+ _sprite.RemoveLayer((ent, sprite), AmmoVisualLayers.Tip, false);
}
}
public sealed partial class GunSystem : SharedGunSystem
{
+ [Dependency] private readonly AnimationPlayerSystem _animPlayer = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
+ [Dependency] private readonly InputSystem _inputSystem = default!;
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IStateManager _state = default!;
- [Dependency] private readonly AnimationPlayerSystem _animPlayer = default!;
- [Dependency] private readonly InputSystem _inputSystem = default!;
[Dependency] private readonly SharedCameraRecoilSystem _recoil = default!;
[Dependency] private readonly SharedMapSystem _maps = default!;
[Dependency] private readonly SharedTransformSystem _xform = default!;
var entity = entityNull.Value;
- if (!TryGetGun(entity, out var gunUid, out var gun))
+ if (!TryGetGun(entity, out var gun))
{
return;
}
- var useKey = gun.UseKey ? EngineKeyFunctions.Use : EngineKeyFunctions.UseSecondary;
+ var useKey = gun.Comp.UseKey ? EngineKeyFunctions.Use : EngineKeyFunctions.UseSecondary;
- if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down && !gun.BurstActivated)
+ if (_inputSystem.CmdStates.GetState(useKey) != BoundKeyState.Down && !gun.Comp.BurstActivated)
{
- if (gun.ShotCounter != 0)
- RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
+ if (gun.Comp.ShotCounter != 0)
+ RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gun) });
return;
}
- if (gun.NextFire > Timing.CurTime)
+ if (gun.Comp.NextFire > Timing.CurTime)
return;
var mousePos = _eyeManager.PixelToMap(_inputManager.MouseScreenPosition);
if (mousePos.MapId == MapId.Nullspace)
{
- if (gun.ShotCounter != 0)
- RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gunUid) });
+ if (gun.Comp.ShotCounter != 0)
+ RaisePredictiveEvent(new RequestStopShootEvent { Gun = GetNetEntity(gun) });
return;
}
{
Target = target,
Coordinates = GetNetCoordinates(coordinates),
- Gun = GetNetEntity(gunUid),
+ Gun = GetNetEntity(gun),
});
}
- public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid? Entity, IShootable Shootable)> ammo,
+ public override void Shoot(Entity<GunComponent> gun, List<(EntityUid? Entity, IShootable Shootable)> ammo,
EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, out bool userImpulse, EntityUid? user = null, bool throwItems = false)
{
userImpulse = true;
{
if (throwItems)
{
- Recoil(user, direction, gun.CameraRecoilScalarModified);
+ Recoil(user, direction, gun.Comp.CameraRecoilScalarModified);
if (IsClientSide(ent!.Value))
Del(ent.Value);
else
if (!cartridge.Spent)
{
SetCartridgeSpent(ent!.Value, cartridge, true);
- MuzzleFlash(gunUid, cartridge, worldAngle, user);
- Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
- Recoil(user, direction, gun.CameraRecoilScalarModified);
+ MuzzleFlash(gun, cartridge, worldAngle, user);
+ Audio.PlayPredicted(gun.Comp.SoundGunshotModified, gun, user);
+ Recoil(user, direction, gun.Comp.CameraRecoilScalarModified);
// TODO: Can't predict entity deletions.
//if (cartridge.DeleteOnSpawn)
// Del(cartridge.Owner);
else
{
userImpulse = false;
- Audio.PlayPredicted(gun.SoundEmpty, gunUid, user);
+ Audio.PlayPredicted(gun.Comp.SoundEmpty, gun, user);
}
if (IsClientSide(ent!.Value))
break;
case AmmoComponent newAmmo:
- MuzzleFlash(gunUid, newAmmo, worldAngle, user);
- Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
- Recoil(user, direction, gun.CameraRecoilScalarModified);
+ MuzzleFlash(gun, newAmmo, worldAngle, user);
+ Audio.PlayPredicted(gun.Comp.SoundGunshotModified, gun, user);
+ Recoil(user, direction, gun.Comp.CameraRecoilScalarModified);
if (IsClientSide(ent!.Value))
Del(ent.Value);
else
RemoveShootable(ent.Value);
break;
case HitscanAmmoComponent:
- Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
- Recoil(user, direction, gun.CameraRecoilScalarModified);
+ Audio.PlayPredicted(gun.Comp.SoundGunshotModified, gun, user);
+ Recoil(user, direction, gun.Comp.CameraRecoilScalarModified);
break;
}
}
}
// TODO: Move RangedDamageSoundComponent to shared so this can be predicted.
- public override void PlayImpactSound(EntityUid otherEntity, DamageSpecifier? modifiedDamage, SoundSpecifier? weaponSound, bool forceWeaponSound) {}
+ public override void PlayImpactSound(EntityUid otherEntity, DamageSpecifier? modifiedDamage, SoundSpecifier? weaponSound, bool forceWeaponSound) { }
}
var wasInCombatMode = IsInCombatMode();
await SetCombatMode(true);
- Assert.That(SGun.TryGetGun(SPlayer, out var gunUid, out var gunComp), "Player was not holding a gun!");
+ Assert.That(SGun.TryGetGun(SPlayer, out var gun), "Player was not holding a gun!");
await Server.WaitAssertion(() =>
{
- var success = SGun.AttemptShoot(SPlayer, gunUid, gunComp!, actualTarget);
+ var success = SGun.AttemptShoot(SPlayer, gun, actualTarget);
if (assert)
Assert.That(success, "Gun failed to shoot.");
});
var wasInCombatMode = IsInCombatMode();
await SetCombatMode(true);
- Assert.That(SGun.TryGetGun(SPlayer, out var gunUid, out var gunComp), "Player was not holding a gun!");
+ Assert.That(SGun.TryGetGun(SPlayer, out var gun), "Player was not holding a gun!");
await Server.WaitAssertion(() =>
{
- var success = SGun.AttemptShoot(SPlayer, gunUid, gunComp!, Position(actualTarget!.Value), ToServer(actualTarget));
+ var success = SGun.AttemptShoot(SPlayer, gun, Position(actualTarget!.Value), ToServer(actualTarget));
if (assert)
Assert.That(success, "Gun failed to shoot.");
});
/// <param name="uid">The entity at which the events were directed</param>
/// <param name="count">How many new events are expected</param>
/// <param name="predicate">A predicate that can be used to filter the recorded events</param>
- protected void AssertEvent<TEvent>(EntityUid? uid = null, int count = 1, Func<TEvent,bool>? predicate = null)
+ protected void AssertEvent<TEvent>(EntityUid? uid = null, int count = 1, Func<TEvent, bool>? predicate = null)
where TEvent : notnull
{
Assert.That(GetEvents(uid, predicate).Count, Is.EqualTo(count));
where TEvent : notnull
{
if (_listenerCache.TryGetValue(typeof(TEvent), out var listener))
- return (TestListenerSystem<TEvent>) listener;
+ return (TestListenerSystem<TEvent>)listener;
var type = Server.Resolve<IReflectionManager>().GetAllChildren<TestListenerSystem<TEvent>>().Single();
if (!SEntMan.EntitySysManager.TryGetEntitySystem(type, out var systemObj))
return;
_gun.SetBallisticUnspawned((args.Target, ballisticAmmo), result);
- _gun.UpdateBallisticAppearance(args.Target, ballisticAmmo);
+ _gun.UpdateBallisticAppearance((args.Target, ballisticAmmo));
});
},
Impact = LogImpact.Medium,
return;
if (args.Port == gunControl.Comp.TriggerPort)
- _gun.AttemptShoot(gunControl, gun);
+ _gun.AttemptShoot((gunControl, gun));
if (!TryComp<AutoShootGunComponent>(gunControl, out var autoShoot))
return;
if (args.Port == gunControl.Comp.TogglePort)
- _gun.SetEnabled(gunControl, autoShoot, !autoShoot.Enabled);
+ _gun.SetEnabled((gunControl, autoShoot), !autoShoot.Enabled);
if (args.Port == gunControl.Comp.OnPort)
- _gun.SetEnabled(gunControl, autoShoot, true);
+ _gun.SetEnabled((gunControl, autoShoot), true);
if (args.Port == gunControl.Comp.OffPort)
- _gun.SetEnabled(gunControl, autoShoot, false);
+ _gun.SetEnabled((gunControl, autoShoot), false);
}
}
{
[Dependency] private readonly IEntityManager _entManager = default!;
- [DataField("minPercent")]
+ [DataField]
public float MinPercent = 0f;
- [DataField("maxPercent")]
+ [DataField]
public float MaxPercent = 1f;
public override bool IsMet(NPCBlackboard blackboard)
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
var gunSystem = _entManager.System<GunSystem>();
- if (!gunSystem.TryGetGun(owner, out var gunUid, out _))
+ if (!gunSystem.TryGetGun(owner, out var gun))
{
return false;
}
var ammoEv = new GetAmmoCountEvent();
- _entManager.EventBus.RaiseLocalEvent(gunUid, ref ammoEv);
+ _entManager.EventBus.RaiseLocalEvent(gun, ref ammoEv);
float percent;
if (ammoEv.Capacity == 0)
percent = 0f;
else
- percent = ammoEv.Count / (float) ammoEv.Capacity;
+ percent = ammoEv.Count / (float)ammoEv.Capacity;
percent = System.Math.Clamp(percent, 0f, 1f);
_combat.SetInCombatMode(uid, true, combatMode);
}
- if (!_gun.TryGetGun(uid, out var gunUid, out var gun))
+ if (!_gun.TryGetGun(uid, out var gun))
{
comp.Status = CombatStatus.NoWeapon;
comp.ShootAccumulator = 0f;
}
var ammoEv = new GetAmmoCountEvent();
- RaiseLocalEvent(gunUid, ref ammoEv);
+ RaiseLocalEvent(gun, ref ammoEv);
if (ammoEv.Count == 0)
{
// Recharging then?
- if (_rechargeQuery.HasComponent(gunUid))
+ if (_rechargeQuery.HasComponent(gun))
{
continue;
}
comp.Status = CombatStatus.Normal;
- if (gun.NextFire > _timing.CurTime)
+ if (gun.Comp.NextFire > _timing.CurTime)
{
return;
}
- _gun.AttemptShoot(uid, gunUid, gun, targetCordinates, comp.Target);
+ _gun.AttemptShoot(uid, gun, targetCordinates, comp.Target);
}
}
}
var targetPos = new EntityCoordinates(uid, new Vector2(0, -1));
- _gun.Shoot(uid, gunComponent, ent, xform.Coordinates, targetPos, out _);
+ _gun.Shoot((uid, gunComponent), ent, xform.Coordinates, targetPos, out _);
}
private void UpdateAppearance(EntityUid uid, EmitterComponent component)
args.Data.TryGetValue(command, out int? armamentState))
{
if (TryComp<BatteryWeaponFireModesComponent>(ent, out var batteryWeaponFireModes))
- _fireModes.TrySetFireMode(ent, batteryWeaponFireModes, armamentState.Value);
+ _fireModes.TrySetFireMode((ent, batteryWeaponFireModes), armamentState.Value);
TrySetState(ent, armamentState.Value >= 0);
return;
namespace Content.Server.Weapons;
-public sealed class DamageMarkerSystem : SharedDamageMarkerSystem
-{
-
-}
+public sealed class DamageMarkerSystem : SharedDamageMarkerSystem { }
namespace Content.Server.Weapons.Ranged.Components;
[RegisterComponent]
-public sealed partial class AmmoCounterComponent : SharedAmmoCounterComponent {}
+public sealed partial class AmmoCounterComponent : SharedAmmoCounterComponent { }
-namespace Content.Server.Weapons.Ranged.Components
+namespace Content.Server.Weapons.Ranged.Components;
+
+[RegisterComponent]
+public sealed partial class ChemicalAmmoComponent : Component
{
- [RegisterComponent]
- public sealed partial class ChemicalAmmoComponent : Component
- {
- public const string DefaultSolutionName = "ammo";
+ public const string DefaultSolutionName = "ammo";
- [DataField("solution")]
- public string SolutionName { get; set; } = DefaultSolutionName;
- }
+ [DataField("solution")]
+ public string SolutionName { get; set; } = DefaultSolutionName;
}
/// Specified sounds to apply when the entity takes damage with the specified group.
/// Will fallback to defaults if none specified.
/// </summary>
- [DataField("soundGroups",
- customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageGroupPrototype>))]
+ [DataField(customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageGroupPrototype>))]
public Dictionary<string, SoundSpecifier>? SoundGroups;
/// <summary>
/// Specified sounds to apply when the entity takes damage with the specified type.
/// Will fallback to defaults if none specified.
/// </summary>
- [DataField("soundTypes",
- customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageTypePrototype>))]
+ [DataField(customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageTypePrototype>))]
public Dictionary<string, SoundSpecifier>? SoundTypes;
}
using Content.Server.Weapons.Ranged.Components;
using Content.Shared.Chemistry.Components;
-using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Chemistry.EntitySystems;
+using Content.Shared.Weapons.Ranged.Events;
using System.Linq;
-namespace Content.Server.Weapons.Ranged.Systems
+namespace Content.Server.Weapons.Ranged.Systems;
+
+public sealed class ChemicalAmmoSystem : EntitySystem
{
- public sealed class ChemicalAmmoSystem : EntitySystem
- {
- [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
+ [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
- public override void Initialize()
- {
- SubscribeLocalEvent<ChemicalAmmoComponent, AmmoShotEvent>(OnFire);
- }
+ public override void Initialize()
+ {
+ SubscribeLocalEvent<ChemicalAmmoComponent, AmmoShotEvent>(OnFire);
+ }
- private void OnFire(Entity<ChemicalAmmoComponent> entity, ref AmmoShotEvent args)
- {
- if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var ammoSoln, out var ammoSolution))
- return;
+ private void OnFire(Entity<ChemicalAmmoComponent> entity, ref AmmoShotEvent args)
+ {
+ if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var ammoSoln, out var ammoSolution))
+ return;
- var projectiles = args.FiredProjectiles;
+ var projectiles = args.FiredProjectiles;
- var projectileSolutionContainers = new List<(EntityUid, Entity<SolutionComponent>)>();
- foreach (var projectile in projectiles)
+ var projectileSolutionContainers = new List<(EntityUid, Entity<SolutionComponent>)>();
+ foreach (var projectile in projectiles)
+ {
+ if (_solutionContainerSystem
+ .TryGetSolution(projectile, entity.Comp.SolutionName, out var projectileSoln, out _))
{
- if (_solutionContainerSystem
- .TryGetSolution(projectile, entity.Comp.SolutionName, out var projectileSoln, out _))
- {
- projectileSolutionContainers.Add((projectile, projectileSoln.Value));
- }
+ projectileSolutionContainers.Add((projectile, projectileSoln.Value));
}
+ }
- if (!projectileSolutionContainers.Any())
- return;
-
- var solutionPerProjectile = ammoSolution.Volume * (1 / projectileSolutionContainers.Count);
+ if (!projectileSolutionContainers.Any())
+ return;
- foreach (var (_, projectileSolution) in projectileSolutionContainers)
- {
- var solutionToTransfer = _solutionContainerSystem.SplitSolution(ammoSoln.Value, solutionPerProjectile);
- _solutionContainerSystem.TryAddSolution(projectileSolution, solutionToTransfer);
- }
+ var solutionPerProjectile = ammoSolution.Volume * (1 / projectileSolutionContainers.Count);
- _solutionContainerSystem.RemoveAllSolution(ammoSoln.Value);
+ foreach (var (_, projectileSolution) in projectileSolutionContainers)
+ {
+ var solutionToTransfer = _solutionContainerSystem.SplitSolution(ammoSoln.Value, solutionPerProjectile);
+ _solutionContainerSystem.TryAddSolution(projectileSolution, solutionToTransfer);
}
+
+ _solutionContainerSystem.RemoveAllSolution(ammoSoln.Value);
}
}
namespace Content.Server.Weapons.Ranged.Systems;
-public sealed class FlyBySoundSystem : SharedFlyBySoundSystem {}
+public sealed class FlyBySoundSystem : SharedFlyBySoundSystem { }
if (!autoShoot.Enabled)
continue;
- AttemptShoot(uid, gun);
+ AttemptShoot((uid, gun));
}
else if (gun.BurstActivated)
{
var parent = TransformSystem.GetParentUid(uid);
if (HasComp<DamageableComponent>(parent))
- AttemptShoot(parent, uid, gun, gun.ShootCoordinates ?? new EntityCoordinates(uid, gun.DefaultDirection));
+ AttemptShoot(parent, (uid, gun), gun.ShootCoordinates ?? new EntityCoordinates(uid, gun.DefaultDirection));
else
- AttemptShoot(uid, gun);
+ AttemptShoot((uid, gun));
}
}
}
public sealed partial class GunSystem
{
- protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates)
+ protected override void Cycle(Entity<BallisticAmmoProviderComponent> ent, MapCoordinates coordinates)
{
- EntityUid? ent = null;
+ EntityUid? ammoEnt = null;
// TODO: Combine with TakeAmmo
- if (component.Entities.Count > 0)
+ if (ent.Comp.Entities.Count > 0)
{
- var existing = component.Entities[^1];
- component.Entities.RemoveAt(component.Entities.Count - 1);
- DirtyField(uid, component, nameof(BallisticAmmoProviderComponent.Entities));
+ var existing = ent.Comp.Entities[^1];
+ ent.Comp.Entities.RemoveAt(ent.Comp.Entities.Count - 1);
+ DirtyField(ent.AsNullable(), nameof(BallisticAmmoProviderComponent.Entities));
- Containers.Remove(existing, component.Container);
+ Containers.Remove(existing, ent.Comp.Container);
EnsureShootable(existing);
}
- else if (component.UnspawnedCount > 0)
+ else if (ent.Comp.UnspawnedCount > 0)
{
- component.UnspawnedCount--;
- DirtyField(uid, component, nameof(BallisticAmmoProviderComponent.UnspawnedCount));
- ent = Spawn(component.Proto, coordinates);
- EnsureShootable(ent.Value);
+ ent.Comp.UnspawnedCount--;
+ DirtyField(ent.AsNullable(), nameof(BallisticAmmoProviderComponent.UnspawnedCount));
+ ammoEnt = Spawn(ent.Comp.Proto, coordinates);
+ EnsureShootable(ammoEnt.Value);
}
- if (ent != null)
- EjectCartridge(ent.Value);
+ if (ammoEnt != null)
+ EjectCartridge(ammoEnt.Value);
var cycledEvent = new GunCycledEvent();
- RaiseLocalEvent(uid, ref cycledEvent);
+ RaiseLocalEvent(ent, ref cycledEvent);
}
}
public sealed partial class GunSystem
{
- protected override void SpinRevolver(EntityUid revolverUid, RevolverAmmoProviderComponent component, EntityUid? user = null)
+ protected override void SpinRevolver(Entity<RevolverAmmoProviderComponent> ent, EntityUid? user = null)
{
- base.SpinRevolver(revolverUid, component, user);
- var index = Random.Next(component.Capacity);
+ base.SpinRevolver(ent, user);
+ var index = Random.Next(ent.Comp.Capacity);
- if (component.CurrentIndex == index)
+ if (ent.Comp.CurrentIndex == index)
return;
- component.CurrentIndex = index;
- Dirty(revolverUid, component);
+ ent.Comp.CurrentIndex = index;
+ Dirty(ent);
}
}
private void OnSolutionMapInit(Entity<SolutionAmmoProviderComponent> entity, ref MapInitEvent args)
{
- UpdateSolutionShots(entity.Owner, entity.Comp);
+ UpdateSolutionShots(entity);
}
private void OnSolutionChanged(Entity<SolutionAmmoProviderComponent> entity, ref SolutionContainerChangedEvent args)
{
if (args.Solution.Name == entity.Comp.SolutionId)
- UpdateSolutionShots(entity.Owner, entity.Comp, args.Solution);
+ UpdateSolutionShots(entity, args.Solution);
}
- protected override void UpdateSolutionShots(EntityUid uid, SolutionAmmoProviderComponent component, Solution? solution = null)
+ protected override void UpdateSolutionShots(Entity<SolutionAmmoProviderComponent> ent, Solution? solution = null)
{
var shots = 0;
var maxShots = 0;
- if (solution == null && !_solutionContainer.TryGetSolution(uid, component.SolutionId, out _, out solution))
+ if (solution == null && !_solutionContainer.TryGetSolution(ent.Owner, ent.Comp.SolutionId, out _, out solution))
{
- component.Shots = shots;
- DirtyField(uid, component, nameof(SolutionAmmoProviderComponent.Shots));
- component.MaxShots = maxShots;
- DirtyField(uid, component, nameof(SolutionAmmoProviderComponent.MaxShots));
+ ent.Comp.Shots = shots;
+ DirtyField(ent.AsNullable(), nameof(SolutionAmmoProviderComponent.Shots));
+ ent.Comp.MaxShots = maxShots;
+ DirtyField(ent.AsNullable(), nameof(SolutionAmmoProviderComponent.MaxShots));
return;
}
- shots = (int) (solution.Volume / component.FireCost);
- maxShots = (int) (solution.MaxVolume / component.FireCost);
+ shots = (int)(solution.Volume / ent.Comp.FireCost);
+ maxShots = (int)(solution.MaxVolume / ent.Comp.FireCost);
- component.Shots = shots;
- DirtyField(uid, component, nameof(SolutionAmmoProviderComponent.Shots));
+ ent.Comp.Shots = shots;
+ DirtyField(ent.AsNullable(), nameof(SolutionAmmoProviderComponent.Shots));
- component.MaxShots = maxShots;
- DirtyField(uid, component, nameof(SolutionAmmoProviderComponent.MaxShots));
+ ent.Comp.MaxShots = maxShots;
+ DirtyField(ent.AsNullable(), nameof(SolutionAmmoProviderComponent.MaxShots));
- UpdateSolutionAppearance(uid, component);
+ UpdateSolutionAppearance(ent);
}
- protected override (EntityUid Entity, IShootable) GetSolutionShot(EntityUid uid, SolutionAmmoProviderComponent component, EntityCoordinates position)
+ protected override (EntityUid Entity, IShootable) GetSolutionShot(Entity<SolutionAmmoProviderComponent> ent, EntityCoordinates position)
{
- var (ent, shootable) = base.GetSolutionShot(uid, component, position);
+ var (shot, shootable) = base.GetSolutionShot(ent, position);
- if (!_solutionContainer.TryGetSolution(uid, component.SolutionId, out var solution, out _))
- return (ent, shootable);
+ if (!_solutionContainer.TryGetSolution(ent.Owner, ent.Comp.SolutionId, out var solution, out _))
+ return (shot, shootable);
- var newSolution = _solutionContainer.SplitSolution(solution.Value, component.FireCost);
+ var newSolution = _solutionContainer.SplitSolution(solution.Value, ent.Comp.FireCost);
if (newSolution.Volume <= FixedPoint2.Zero)
- return (ent, shootable);
+ return (shot, shootable);
- if (TryComp<AppearanceComponent>(ent, out var appearance))
+ if (TryComp<AppearanceComponent>(shot, out var appearance))
{
- Appearance.SetData(ent, VaporVisuals.Color, newSolution.GetColor(ProtoManager).WithAlpha(1f), appearance);
- Appearance.SetData(ent, VaporVisuals.State, true, appearance);
+ Appearance.SetData(shot, VaporVisuals.Color, newSolution.GetColor(ProtoManager).WithAlpha(1f), appearance);
+ Appearance.SetData(shot, VaporVisuals.State, true, appearance);
}
// Add the solution to the vapor and actually send the thing
- if (_solutionContainer.TryGetSolution(ent, VaporComponent.SolutionName, out var vaporSolution, out _))
+ if (_solutionContainer.TryGetSolution(shot, VaporComponent.SolutionName, out var vaporSolution, out _))
{
_solutionContainer.TryAddSolution(vaporSolution.Value, newSolution);
}
- return (ent, shootable);
+ return (shot, shootable);
}
}
SubscribeLocalEvent<BallisticAmmoProviderComponent, PriceCalculationEvent>(OnBallisticPrice);
}
- private void OnBallisticPrice(EntityUid uid, BallisticAmmoProviderComponent component, ref PriceCalculationEvent args)
+ private void OnBallisticPrice(Entity<BallisticAmmoProviderComponent> ent, ref PriceCalculationEvent args)
{
- if (string.IsNullOrEmpty(component.Proto) || component.UnspawnedCount == 0)
+ if (string.IsNullOrEmpty(ent.Comp.Proto) || ent.Comp.UnspawnedCount == 0)
return;
- if (!ProtoManager.TryIndex<EntityPrototype>(component.Proto, out var proto))
+ if (!ProtoManager.TryIndex<EntityPrototype>(ent.Comp.Proto, out var proto))
{
- Log.Error($"Unable to find fill prototype for price on {component.Proto} on {ToPrettyString(uid)}");
+ Log.Error($"Unable to find fill prototype for price on {ent.Comp.Proto} on {ToPrettyString(ent)}");
return;
}
// Probably good enough for most.
var price = _pricing.GetEstimatedPrice(proto);
- args.Price += price * component.UnspawnedCount;
+ args.Price += price * ent.Comp.UnspawnedCount;
}
- public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid? Entity, IShootable Shootable)> ammo,
+ public override void Shoot(Entity<GunComponent> gun, List<(EntityUid? Entity, IShootable Shootable)> ammo,
EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, out bool userImpulse, EntityUid? user = null, bool throwItems = false)
{
userImpulse = true;
if (user != null)
{
- var selfEvent = new SelfBeforeGunShotEvent(user.Value, (gunUid, gun), ammo);
+ var selfEvent = new SelfBeforeGunShotEvent(user.Value, gun, ammo);
RaiseLocalEvent(user.Value, selfEvent);
if (selfEvent.Cancelled)
{
// pneumatic cannon doesn't shoot bullets it just throws them, ignore ammo handling
if (throwItems && ent != null)
{
- ShootOrThrow(ent.Value, mapDirection, gunVelocity, gun, gunUid, user);
+ ShootOrThrow(ent.Value, mapDirection, gunVelocity, gun, user);
continue;
}
else
{
userImpulse = false;
- Audio.PlayPredicted(gun.SoundEmpty, gunUid, user);
+ Audio.PlayPredicted(gun.Comp.SoundEmpty, gun, user);
}
// Something like ballistic might want to leave it in the container still
{
FromCoordinates = fromCoordinates,
ShotDirection = mapDirection.Normalized(),
- Gun = gunUid,
+ Gun = gun,
Shooter = user,
- Target = gun.Target,
+ Target = gun.Comp.Target,
};
RaiseLocalEvent(ent.Value, ref hitscanEv);
Del(ent);
- Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
+ Audio.PlayPredicted(gun.Comp.SoundGunshotModified, gun, user);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
- RaiseLocalEvent(gunUid, new AmmoShotEvent()
+ RaiseLocalEvent(gun, new AmmoShotEvent()
{
FiredProjectiles = shotProjectiles,
});
if (TryComp<ProjectileSpreadComponent>(ammoEnt, out var ammoSpreadComp))
{
var spreadEvent = new GunGetAmmoSpreadEvent(ammoSpreadComp.Spread);
- RaiseLocalEvent(gunUid, ref spreadEvent);
+ RaiseLocalEvent(gun, ref spreadEvent);
var angles = LinearSpread(mapAngle - spreadEvent.Spread / 2,
mapAngle + spreadEvent.Spread / 2, ammoSpreadComp.Count);
- ShootOrThrow(ammoEnt, angles[0].ToVec(), gunVelocity, gun, gunUid, user);
+ ShootOrThrow(ammoEnt, angles[0].ToVec(), gunVelocity, gun, user);
shotProjectiles.Add(ammoEnt);
for (var i = 1; i < ammoSpreadComp.Count; i++)
{
var newuid = Spawn(ammoSpreadComp.Proto, fromEnt);
- ShootOrThrow(newuid, angles[i].ToVec(), gunVelocity, gun, gunUid, user);
+ ShootOrThrow(newuid, angles[i].ToVec(), gunVelocity, gun, user);
shotProjectiles.Add(newuid);
}
}
else
{
- ShootOrThrow(ammoEnt, mapDirection, gunVelocity, gun, gunUid, user);
+ ShootOrThrow(ammoEnt, mapDirection, gunVelocity, gun, user);
shotProjectiles.Add(ammoEnt);
}
- MuzzleFlash(gunUid, ammoComp, mapDirection.ToAngle(), user);
- Audio.PlayPredicted(gun.SoundGunshotModified, gunUid, user);
+ MuzzleFlash(gun, ammoComp, mapDirection.ToAngle(), user);
+ Audio.PlayPredicted(gun.Comp.SoundGunshotModified, gun, user);
}
}
- private void ShootOrThrow(EntityUid uid, Vector2 mapDirection, Vector2 gunVelocity, GunComponent gun, EntityUid gunUid, EntityUid? user)
+ private void ShootOrThrow(EntityUid uid, Vector2 mapDirection, Vector2 gunVelocity, Entity<GunComponent> gun, EntityUid? user)
{
- if (gun.Target is { } target && !TerminatingOrDeleted(target))
+ if (gun.Comp.Target is { } target && !TerminatingOrDeleted(target))
{
var targeted = EnsureComp<TargetedProjectileComponent>(uid);
targeted.Target = target;
{
RemoveShootable(uid);
// TODO: Someone can probably yeet this a billion miles so need to pre-validate input somewhere up the call stack.
- ThrowingSystem.TryThrow(uid, mapDirection, gun.ProjectileSpeedModified, user);
+ ThrowingSystem.TryThrow(uid, mapDirection, gun.Comp.ProjectileSpeedModified, user);
return;
}
- ShootProjectile(uid, mapDirection, gunVelocity, gunUid, user, gun.ProjectileSpeedModified);
+ ShootProjectile(uid, mapDirection, gunVelocity, gun, user, gun.Comp.ProjectileSpeedModified);
}
/// <summary>
return;
if (TryComp<BasicEntityAmmoProviderComponent>(wand, out var basicAmmoComp) && basicAmmoComp.Count != null)
- _gunSystem.UpdateBasicEntityAmmoCount(wand.Value, basicAmmoComp.Count.Value + ev.Charge, basicAmmoComp);
+ _gunSystem.UpdateBasicEntityAmmoCount((wand.Value, basicAmmoComp), basicAmmoComp.Count.Value + ev.Charge);
else if (TryComp<LimitedChargesComponent>(wand, out var charges))
_charges.AddCharges((wand.Value, charges), ev.Charge);
}
/// <summary>
/// If the gun has a bolt and whether that bolt is closed. Firing is impossible
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("boltClosed"), AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public bool? BoltClosed = false;
/// <summary>
/// Does the gun automatically open and close the bolt upon shooting.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("autoCycle"), AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public bool AutoCycle = true;
/// <summary>
/// Can the gun be racked, which opens and then instantly closes the bolt to cycle a round.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("canRack"), AutoNetworkedField]
+ [DataField, AutoNetworkedField]
public bool CanRack = true;
- [ViewVariables(VVAccess.ReadWrite), DataField("soundBoltClosed"), AutoNetworkedField]
+ [DataField("soundBoltClosed"), AutoNetworkedField]
public SoundSpecifier? BoltClosedSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Bolt/rifle_bolt_closed.ogg");
- [ViewVariables(VVAccess.ReadWrite), DataField("soundBoltOpened"), AutoNetworkedField]
+ [DataField("soundBoltOpened"), AutoNetworkedField]
public SoundSpecifier? BoltOpenedSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Bolt/rifle_bolt_open.ogg");
- [ViewVariables(VVAccess.ReadWrite), DataField("soundRack"), AutoNetworkedField]
+ [DataField("soundRack"), AutoNetworkedField]
public SoundSpecifier? RackSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Cock/ltrifle_cock.ogg");
}
/// When the gun is next available to be shot.
/// Can be set multiple times in a single tick due to guns firing faster than a single tick time.
/// </summary>
- [DataField(customTypeSerializer:typeof(TimeOffsetSerializer))]
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoNetworkedField]
[AutoPausedField]
public TimeSpan NextFire = TimeSpan.Zero;
/// This component modifies the spread of the gun it is attached to.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
-public sealed partial class GunSpreadModifierComponent: Component
+public sealed partial class GunSpreadModifierComponent : Component
{
/// <summary>
/// A scalar value multiplied by the spread built into the ammo itself.
[Access(typeof(SharedGunSystem))]
public partial class MagazineAmmoProviderComponent : AmmoProviderComponent
{
- [ViewVariables(VVAccess.ReadWrite), DataField("soundAutoEject")]
+ [DataField]
public SoundSpecifier? SoundAutoEject = new SoundPathSpecifier("/Audio/Weapons/Guns/EmptyAlarm/smg_empty_alarm.ogg");
/// <summary>
/// Should the magazine automatically eject when empty.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("autoEject")]
+ [DataField]
public bool AutoEject = false;
}
namespace Content.Shared.Weapons.Ranged.Events;
/// <summary>
-/// Raised on the client to request it would like to stop hooting.
+/// Raised on the client to request it would like to stop shooting.
/// </summary>
[Serializable, NetSerializable]
public sealed class RequestStopShootEvent : EntityEventArgs
private void OnShutdown(Entity<ActionGunComponent> ent, ref ComponentShutdown args)
{
- if (ent.Comp.Gun is {} gun)
+ if (ent.Comp.Gun is { } gun)
QueueDel(gun);
}
private void OnShoot(Entity<ActionGunComponent> ent, ref ActionGunShootEvent args)
{
if (TryComp<GunComponent>(ent.Comp.Gun, out var gun))
- _gun.AttemptShoot(ent, ent.Comp.Gun.Value, gun, args.Target);
+ _gun.AttemptShoot(ent, (ent.Comp.Gun.Value, gun), args.Target);
}
}
-using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Popups;
using Content.Shared.Verbs;
using Content.Shared.Weapons.Ranged.Components;
-using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.Prototypes;
namespace Content.Shared.Weapons.Ranged.Systems;
public sealed class BatteryWeaponFireModesSystem : EntitySystem
{
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly SharedGunSystem _gun = default!;
+ [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
public override void Initialize()
{
SubscribeLocalEvent<BatteryWeaponFireModesComponent, ExaminedEvent>(OnExamined);
}
- private void OnExamined(EntityUid uid, BatteryWeaponFireModesComponent component, ExaminedEvent args)
+ private void OnExamined(Entity<BatteryWeaponFireModesComponent> ent, ref ExaminedEvent args)
{
- if (component.FireModes.Count < 2)
+ if (ent.Comp.FireModes.Count < 2)
return;
- var fireMode = GetMode(component);
+ var fireMode = GetMode(ent.Comp);
if (!_prototypeManager.TryIndex<EntityPrototype>(fireMode.Prototype, out var proto))
return;
DoContactInteraction = true,
Act = () =>
{
- TrySetFireMode(uid, component, index, args.User);
+ TrySetFireMode((uid, component), index, args.User);
}
};
}
}
- private void OnUseInHandEvent(EntityUid uid, BatteryWeaponFireModesComponent component, UseInHandEvent args)
+ private void OnUseInHandEvent(Entity<BatteryWeaponFireModesComponent> ent, ref UseInHandEvent args)
{
- if(args.Handled)
+ if (args.Handled)
return;
args.Handled = true;
- TryCycleFireMode(uid, component, args.User);
+ TryCycleFireMode(ent, args.User);
}
- public void TryCycleFireMode(EntityUid uid, BatteryWeaponFireModesComponent component, EntityUid? user = null)
+ public void TryCycleFireMode(Entity<BatteryWeaponFireModesComponent> ent, EntityUid? user = null)
{
- if (component.FireModes.Count < 2)
+ if (ent.Comp.FireModes.Count < 2)
return;
- var index = (component.CurrentFireMode + 1) % component.FireModes.Count;
- TrySetFireMode(uid, component, index, user);
+ var index = (ent.Comp.CurrentFireMode + 1) % ent.Comp.FireModes.Count;
+ TrySetFireMode(ent, index, user);
}
- public bool TrySetFireMode(EntityUid uid, BatteryWeaponFireModesComponent component, int index, EntityUid? user = null)
+ public bool TrySetFireMode(Entity<BatteryWeaponFireModesComponent> ent, int index, EntityUid? user = null)
{
- if (index < 0 || index >= component.FireModes.Count)
+ if (index < 0 || index >= ent.Comp.FireModes.Count)
return false;
- if (user != null && !_accessReaderSystem.IsAllowed(user.Value, uid))
+ if (user != null && !_accessReaderSystem.IsAllowed(user.Value, ent))
return false;
- SetFireMode(uid, component, index, user);
+ SetFireMode(ent, index, user);
return true;
}
- private void SetFireMode(EntityUid uid, BatteryWeaponFireModesComponent component, int index, EntityUid? user = null)
+ private void SetFireMode(Entity<BatteryWeaponFireModesComponent> ent, int index, EntityUid? user = null)
{
- var fireMode = component.FireModes[index];
- component.CurrentFireMode = index;
- Dirty(uid, component);
+ var fireMode = ent.Comp.FireModes[index];
+ ent.Comp.CurrentFireMode = index;
+ Dirty(ent);
if (_prototypeManager.TryIndex<EntityPrototype>(fireMode.Prototype, out var prototype))
{
- if (TryComp<AppearanceComponent>(uid, out var appearance))
- _appearanceSystem.SetData(uid, BatteryWeaponFireModeVisuals.State, prototype.ID, appearance);
+ if (TryComp<AppearanceComponent>(ent, out var appearance))
+ _appearanceSystem.SetData(ent, BatteryWeaponFireModeVisuals.State, prototype.ID, appearance);
if (user != null)
- _popupSystem.PopupClient(Loc.GetString("gun-set-fire-mode-popup", ("mode", prototype.Name)), uid, user.Value);
+ _popupSystem.PopupClient(Loc.GetString("gun-set-fire-mode-popup", ("mode", prototype.Name)), ent, user.Value);
}
- if (TryComp(uid, out BatteryAmmoProviderComponent? batteryAmmoProviderComponent))
+ if (TryComp(ent, out BatteryAmmoProviderComponent? batteryAmmoProviderComponent))
{
batteryAmmoProviderComponent.Prototype = fireMode.Prototype;
batteryAmmoProviderComponent.FireCost = fireMode.FireCost;
- Dirty(uid, batteryAmmoProviderComponent);
+ Dirty(ent, batteryAmmoProviderComponent);
- _gun.UpdateShots((uid, batteryAmmoProviderComponent));
+ _gun.UpdateShots((ent, batteryAmmoProviderComponent));
}
}
}
namespace Content.Shared.Weapons.Ranged.Systems;
-
-public sealed class GunSpreadModifierSystem: EntitySystem
+public sealed class GunSpreadModifierSystem : EntitySystem
{
public override void Initialize()
{
SubscribeLocalEvent<GunSpreadModifierComponent, ExaminedEvent>(OnExamine);
}
- private void OnGunGetAmmoSpread(EntityUid uid, GunSpreadModifierComponent comp, ref GunGetAmmoSpreadEvent args)
+ private void OnGunGetAmmoSpread(Entity<GunSpreadModifierComponent> ent, ref GunGetAmmoSpreadEvent args)
{
- args.Spread *= comp.Spread;
+ args.Spread *= ent.Comp.Spread;
}
- private void OnExamine(EntityUid uid, GunSpreadModifierComponent comp, ExaminedEvent args)
+ private void OnExamine(Entity<GunSpreadModifierComponent> ent, ref ExaminedEvent args)
{
- var percentage = Math.Round(comp.Spread * 100);
+ var percentage = Math.Round(ent.Comp.Spread * 100);
var loc = percentage < 100 ? "examine-gun-spread-modifier-reduction" : "examine-gun-spread-modifier-increase";
percentage = percentage < 100 ? 100 - percentage : percentage - 100;
var msg = Loc.GetString(loc, ("percentage", percentage));
using Content.Shared.Examine;
using Content.Shared.Weapons.Ranged.Components;
-using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Network;
-using Robust.Shared.Player;
using Robust.Shared.Timing;
-using Robust.Shared.Utility;
namespace Content.Shared.Weapons.Ranged.Systems;
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly INetManager _netManager = default!;
+ [Dependency] private readonly MetaDataSystem _metadata = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedGunSystem _gun = default!;
- [Dependency] private readonly MetaDataSystem _metadata = default!;
public override void Initialize()
{
if (recharge.NextCharge > _timing.CurTime)
continue;
- if (_gun.UpdateBasicEntityAmmoCount(uid, ammo.Count.Value + 1, ammo))
+ if (_gun.UpdateBasicEntityAmmoCount((uid, ammo), ammo.Count.Value + 1))
{
// We don't predict this because occasionally on client it may not play.
// PlayPredicted will still be predicted on the client.
}
}
- private void OnInit(EntityUid uid, RechargeBasicEntityAmmoComponent component, MapInitEvent args)
+ private void OnInit(Entity<RechargeBasicEntityAmmoComponent> ent, ref MapInitEvent args)
{
- component.NextCharge = _timing.CurTime;
- Dirty(uid, component);
+ ent.Comp.NextCharge = _timing.CurTime;
+ Dirty(ent);
}
- private void OnExamined(EntityUid uid, RechargeBasicEntityAmmoComponent component, ExaminedEvent args)
+ private void OnExamined(Entity<RechargeBasicEntityAmmoComponent> ent, ref ExaminedEvent args)
{
- if (!component.ShowExamineText)
+ if (!ent.Comp.ShowExamineText)
return;
- if (!TryComp<BasicEntityAmmoProviderComponent>(uid, out var ammo)
+ if (!TryComp<BasicEntityAmmoProviderComponent>(ent, out var ammo)
|| ammo.Count == ammo.Capacity ||
- component.NextCharge == null)
+ ent.Comp.NextCharge == null)
{
args.PushMarkup(Loc.GetString("recharge-basic-entity-ammo-full"));
return;
}
- var timeLeft = component.NextCharge + _metadata.GetPauseTime(uid) - _timing.CurTime;
+ var timeLeft = ent.Comp.NextCharge + _metadata.GetPauseTime(ent) - _timing.CurTime;
args.PushMarkup(Loc.GetString("recharge-basic-entity-ammo-can-recharge", ("seconds", Math.Round(timeLeft.Value.TotalSeconds, 1))));
}
- public void Reset(EntityUid uid, RechargeBasicEntityAmmoComponent? recharge = null)
+ public void Reset(Entity<RechargeBasicEntityAmmoComponent?> ent)
{
- if (!Resolve(uid, ref recharge, false))
+ if (!Resolve(ent, ref ent.Comp, false))
return;
- if (recharge.NextCharge == null || recharge.NextCharge < _timing.CurTime)
+ if (ent.Comp.NextCharge == null || ent.Comp.NextCharge < _timing.CurTime)
{
- recharge.NextCharge = _timing.CurTime + TimeSpan.FromSeconds(recharge.RechargeCooldown);
- Dirty(uid, recharge);
+ ent.Comp.NextCharge = _timing.CurTime + TimeSpan.FromSeconds(ent.Comp.RechargeCooldown);
+ Dirty(ent);
}
}
}
SubscribeLocalEvent<RechargeCycleAmmoComponent, ActivateInWorldEvent>(OnRechargeCycled);
}
- private void OnRechargeCycled(EntityUid uid, RechargeCycleAmmoComponent component, ActivateInWorldEvent args)
+ private void OnRechargeCycled(Entity<RechargeCycleAmmoComponent> ent, ref ActivateInWorldEvent args)
{
if (!args.Complex)
return;
- if (!TryComp<BasicEntityAmmoProviderComponent>(uid, out var basic) || args.Handled)
+ if (!TryComp<BasicEntityAmmoProviderComponent>(ent, out var basic) || args.Handled)
return;
if (basic.Count >= basic.Capacity || basic.Count == null)
return;
- _gun.UpdateBasicEntityAmmoCount(uid, basic.Count.Value + 1, basic);
- Dirty(uid, basic);
+ _gun.UpdateBasicEntityAmmoCount((ent, basic), basic.Count.Value + 1);
+ Dirty(ent, basic);
args.Handled = true;
}
}
SubscribeLocalEvent<FlyBySoundComponent, ComponentShutdown>(OnShutdown);
}
- private void OnStartup(EntityUid uid, FlyBySoundComponent component, ComponentStartup args)
+ private void OnStartup(Entity<FlyBySoundComponent> ent, ref ComponentStartup args)
{
- if (!TryComp<PhysicsComponent>(uid, out var body))
+ if (!TryComp<PhysicsComponent>(ent, out var body))
return;
- var shape = new PhysShapeCircle(component.Range);
+ var shape = new PhysShapeCircle(ent.Comp.Range);
- _fixtures.TryCreateFixture(uid, shape, FlyByFixture, collisionLayer: (int) CollisionGroup.MobMask, hard: false, body: body);
+ _fixtures.TryCreateFixture(ent, shape, FlyByFixture, collisionLayer: (int)CollisionGroup.MobMask, hard: false, body: body);
}
- private void OnShutdown(EntityUid uid, FlyBySoundComponent component, ComponentShutdown args)
+ private void OnShutdown(Entity<FlyBySoundComponent> ent, ref ComponentShutdown args)
{
- if (!TryComp<PhysicsComponent>(uid, out var body) ||
- MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating)
+ if (!TryComp<PhysicsComponent>(ent, out var body) ||
+ MetaData(ent).EntityLifeStage >= EntityLifeStage.Terminating)
{
return;
}
- _fixtures.DestroyFixture(uid, FlyByFixture, body: body);
+ _fixtures.DestroyFixture(ent, FlyByFixture, body: body);
}
}
public partial class SharedGunSystem
{
- public void SetEnabled(EntityUid uid, AutoShootGunComponent component, bool status)
+ public void SetEnabled(Entity<AutoShootGunComponent> ent, bool status)
{
- component.Enabled = status;
+ ent.Comp.Enabled = status;
}
}
SubscribeLocalEvent<BallisticAmmoSelfRefillerComponent, EmpPulseEvent>(OnRefillerEmpPulsed);
}
- private void OnBallisticRefillerMapInit(Entity<BallisticAmmoSelfRefillerComponent> entity, ref MapInitEvent args)
+ private void OnBallisticRefillerMapInit(Entity<BallisticAmmoSelfRefillerComponent> entity, ref MapInitEvent _)
{
entity.Comp.NextAutoRefill = Timing.CurTime + entity.Comp.AutoRefillRate;
}
- private void OnBallisticUse(EntityUid uid, BallisticAmmoProviderComponent component, UseInHandEvent args)
+ private void OnBallisticUse(Entity<BallisticAmmoProviderComponent> ent, ref UseInHandEvent args)
{
if (args.Handled)
return;
- ManualCycle(uid, component, TransformSystem.GetMapCoordinates(uid), args.User);
+ ManualCycle(ent, TransformSystem.GetMapCoordinates(ent), args.User);
args.Handled = true;
}
- private void OnBallisticInteractUsing(EntityUid uid, BallisticAmmoProviderComponent component, InteractUsingEvent args)
+ private void OnBallisticInteractUsing(Entity<BallisticAmmoProviderComponent> ent, ref InteractUsingEvent args)
{
if (args.Handled)
return;
- if (TryBallisticInsert((uid, component), args.Used, args.User))
+ if (TryBallisticInsert(ent, args.Used, args.User))
args.Handled = true;
}
{
Text = Loc.GetString("gun-ballistic-cycle"),
Disabled = GetBallisticShots(component) == 0,
- Act = () => ManualCycle(uid, component, TransformSystem.GetMapCoordinates(uid), args.User),
+ Act = () => ManualCycle((uid, component), TransformSystem.GetMapCoordinates(uid), args.User),
});
}
}
- private void OnBallisticExamine(EntityUid uid, BallisticAmmoProviderComponent component, ExaminedEvent args)
+ private void OnBallisticExamine(Entity<BallisticAmmoProviderComponent> ent, ref ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;
- args.PushMarkup(Loc.GetString("gun-magazine-examine", ("color", AmmoExamineColor), ("count", GetBallisticShots(component))));
+ args.PushMarkup(Loc.GetString("gun-magazine-examine", ("color", AmmoExamineColor), ("count", GetBallisticShots(ent.Comp))));
}
- private void ManualCycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates, EntityUid? user = null, GunComponent? gunComp = null)
+ private void ManualCycle(Entity<BallisticAmmoProviderComponent> ent, MapCoordinates coordinates, EntityUid? user = null, GunComponent? gunComp = null)
{
- if (!component.Cycleable)
+ if (!ent.Comp.Cycleable)
return;
// Reset shotting for cycling
- if (Resolve(uid, ref gunComp, false) &&
+ if (Resolve(ent, ref gunComp, false) &&
gunComp is { FireRateModified: > 0f } &&
- !Paused(uid))
+ !Paused(ent))
{
gunComp.NextFire = Timing.CurTime + TimeSpan.FromSeconds(1 / gunComp.FireRateModified);
- DirtyField(uid, gunComp, nameof(GunComponent.NextFire));
+ DirtyField(ent, gunComp, nameof(GunComponent.NextFire));
}
- Audio.PlayPredicted(component.SoundRack, uid, user);
+ Audio.PlayPredicted(ent.Comp.SoundRack, ent, user);
- var shots = GetBallisticShots(component);
- Cycle(uid, component, coordinates);
+ var shots = GetBallisticShots(ent.Comp);
+ Cycle(ent, coordinates);
var text = Loc.GetString(shots == 0 ? "gun-ballistic-cycled-empty" : "gun-ballistic-cycled");
- Popup(text, uid, user);
- UpdateBallisticAppearance(uid, component);
- UpdateAmmoCount(uid);
+ Popup(text, ent, user);
+ UpdateBallisticAppearance(ent);
+ UpdateAmmoCount(ent);
}
- protected abstract void Cycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates);
+ protected abstract void Cycle(Entity<BallisticAmmoProviderComponent> ent, MapCoordinates coordinates);
- private void OnBallisticInit(EntityUid uid, BallisticAmmoProviderComponent component, ComponentInit args)
+ private void OnBallisticInit(Entity<BallisticAmmoProviderComponent> ent, ref ComponentInit args)
{
- component.Container = Containers.EnsureContainer<Container>(uid, "ballistic-ammo");
+ ent.Comp.Container = Containers.EnsureContainer<Container>(ent, "ballistic-ammo");
// TODO: This is called twice though we need to support loading appearance data (and we need to call it on MapInit
// to ensure it's correct).
- UpdateBallisticAppearance(uid, component);
+ UpdateBallisticAppearance(ent);
}
- private void OnBallisticMapInit(EntityUid uid, BallisticAmmoProviderComponent component, MapInitEvent args)
+ private void OnBallisticMapInit(Entity<BallisticAmmoProviderComponent> ent, ref MapInitEvent args)
{
// TODO this should be part of the prototype, not set on map init.
// Alternatively, just track spawned count, instead of unspawned count.
- if (component.Proto != null)
+ if (ent.Comp.Proto != null)
{
- component.UnspawnedCount = Math.Max(0, component.Capacity - component.Container.ContainedEntities.Count);
- UpdateBallisticAppearance(uid, component);
- DirtyField(uid, component, nameof(BallisticAmmoProviderComponent.UnspawnedCount));
+ ent.Comp.UnspawnedCount = Math.Max(0, ent.Comp.Capacity - ent.Comp.Container.ContainedEntities.Count);
+ UpdateBallisticAppearance(ent);
+ DirtyField(ent.AsNullable(), nameof(BallisticAmmoProviderComponent.UnspawnedCount));
}
}
return component.Entities.Count + component.UnspawnedCount;
}
- private void OnBallisticTakeAmmo(EntityUid uid, BallisticAmmoProviderComponent component, TakeAmmoEvent args)
+ private void OnBallisticTakeAmmo(Entity<BallisticAmmoProviderComponent> ent, ref TakeAmmoEvent args)
{
for (var i = 0; i < args.Shots; i++)
{
EntityUid? ammoEntity = null;
- if (component.Entities.Count > 0)
+ if (ent.Comp.Entities.Count > 0)
{
- var existingEnt = component.Entities[^1];
- component.Entities.RemoveAt(component.Entities.Count - 1);
- DirtyField(uid, component, nameof(BallisticAmmoProviderComponent.Entities));
- Containers.Remove(existingEnt, component.Container);
+ var existingEnt = ent.Comp.Entities[^1];
+ ent.Comp.Entities.RemoveAt(ent.Comp.Entities.Count - 1);
+ DirtyField(ent.AsNullable(), nameof(BallisticAmmoProviderComponent.Entities));
+ Containers.Remove(existingEnt, ent.Comp.Container);
ammoEntity = existingEnt;
}
- else if (component.UnspawnedCount > 0)
+ else if (ent.Comp.UnspawnedCount > 0)
{
- component.UnspawnedCount--;
- DirtyField(uid, component, nameof(BallisticAmmoProviderComponent.UnspawnedCount));
- ammoEntity = Spawn(component.Proto, args.Coordinates);
+ ent.Comp.UnspawnedCount--;
+ DirtyField(ent.AsNullable(), nameof(BallisticAmmoProviderComponent.UnspawnedCount));
+ ammoEntity = Spawn(ent.Comp.Proto, args.Coordinates);
}
- if (ammoEntity is { } ent)
+ if (ammoEntity is not { } ammoEnt)
+ continue;
+
+ args.Ammo.Add((ammoEnt, EnsureShootable(ammoEnt)));
+ if (TryComp<BallisticAmmoSelfRefillerComponent>(ent, out var refiller))
{
- args.Ammo.Add((ent, EnsureShootable(ent)));
- if (TryComp<BallisticAmmoSelfRefillerComponent>(uid, out var refiller))
- {
- PauseSelfRefill((uid, refiller));
- }
+ PauseSelfRefill((ent, refiller));
}
}
- UpdateBallisticAppearance(uid, component);
+ UpdateBallisticAppearance(ent);
}
- private void OnBallisticAmmoCount(EntityUid uid, BallisticAmmoProviderComponent component, ref GetAmmoCountEvent args)
+ private void OnBallisticAmmoCount(Entity<BallisticAmmoProviderComponent> ent, ref GetAmmoCountEvent args)
{
- args.Count = GetBallisticShots(component);
- args.Capacity = component.Capacity;
+ args.Count = GetBallisticShots(ent.Comp);
+ args.Capacity = ent.Comp.Capacity;
}
/// <summary>
Audio.PlayPredicted(entity.Comp.SoundInsert, entity, user);
}
- UpdateBallisticAppearance(entity, entity.Comp);
+ UpdateBallisticAppearance(entity);
UpdateAmmoCount(entity);
DirtyField(entity.AsNullable(), nameof(BallisticAmmoProviderComponent.Entities));
return true;
}
- public void UpdateBallisticAppearance(EntityUid uid, BallisticAmmoProviderComponent component)
+ public void UpdateBallisticAppearance(Entity<BallisticAmmoProviderComponent> ent)
{
- if (!Timing.IsFirstTimePredicted || !TryComp<AppearanceComponent>(uid, out var appearance))
+ if (!Timing.IsFirstTimePredicted || !TryComp<AppearanceComponent>(ent, out var appearance))
return;
- Appearance.SetData(uid, AmmoVisuals.AmmoCount, GetBallisticShots(component), appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoCount, GetBallisticShots(ent.Comp), appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoMax, ent.Comp.Capacity, appearance);
}
public void SetBallisticUnspawned(Entity<BallisticAmmoProviderComponent> entity, int count)
return;
entity.Comp.UnspawnedCount = count;
- UpdateBallisticAppearance(entity.Owner, entity.Comp);
+ UpdateBallisticAppearance(entity);
UpdateAmmoCount(entity.Owner);
Dirty(entity);
}
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Events;
-using Robust.Shared.GameStates;
namespace Content.Shared.Weapons.Ranged.Systems;
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, GetAmmoCountEvent>(OnBasicEntityAmmoCount);
}
- private void OnBasicEntityMapInit(EntityUid uid, BasicEntityAmmoProviderComponent component, MapInitEvent args)
+ private void OnBasicEntityMapInit(Entity<BasicEntityAmmoProviderComponent> ent, ref MapInitEvent args)
{
- if (component.Count is null)
+ if (ent.Comp.Count is null)
{
- component.Count = component.Capacity;
- Dirty(uid, component);
+ ent.Comp.Count = ent.Comp.Capacity;
+ Dirty(ent);
}
- UpdateBasicEntityAppearance(uid, component);
+ UpdateBasicEntityAppearance(ent);
}
- private void OnBasicEntityTakeAmmo(EntityUid uid, BasicEntityAmmoProviderComponent component, TakeAmmoEvent args)
+ private void OnBasicEntityTakeAmmo(Entity<BasicEntityAmmoProviderComponent> ent, ref TakeAmmoEvent args)
{
for (var i = 0; i < args.Shots; i++)
{
- if (component.Count <= 0)
+ if (ent.Comp.Count <= 0)
return;
- if (component.Count != null)
- {
- component.Count--;
- }
+ if (ent.Comp.Count != null)
+ ent.Comp.Count--;
- var ent = Spawn(component.Proto, args.Coordinates);
- args.Ammo.Add((ent, EnsureShootable(ent)));
+ var ammoEnt = Spawn(ent.Comp.Proto, args.Coordinates);
+ args.Ammo.Add((ammoEnt, EnsureShootable(ammoEnt)));
}
- _recharge.Reset(uid);
- UpdateBasicEntityAppearance(uid, component);
- Dirty(uid, component);
+ _recharge.Reset(ent.Owner);
+ UpdateBasicEntityAppearance(ent);
+ Dirty(ent);
}
- private void OnBasicEntityAmmoCount(EntityUid uid, BasicEntityAmmoProviderComponent component, ref GetAmmoCountEvent args)
+ private void OnBasicEntityAmmoCount(Entity<BasicEntityAmmoProviderComponent> ent, ref GetAmmoCountEvent args)
{
- args.Capacity = component.Capacity ?? int.MaxValue;
- args.Count = component.Count ?? int.MaxValue;
+ args.Capacity = ent.Comp.Capacity ?? int.MaxValue;
+ args.Count = ent.Comp.Count ?? int.MaxValue;
}
- private void UpdateBasicEntityAppearance(EntityUid uid, BasicEntityAmmoProviderComponent component)
+ private void UpdateBasicEntityAppearance(Entity<BasicEntityAmmoProviderComponent> ent)
{
- if (!Timing.IsFirstTimePredicted || !TryComp<AppearanceComponent>(uid, out var appearance))
+ if (!Timing.IsFirstTimePredicted || !TryComp<AppearanceComponent>(ent, out var appearance))
return;
- Appearance.SetData(uid, AmmoVisuals.HasAmmo, component.Count != 0, appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoCount, component.Count ?? int.MaxValue, appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity ?? int.MaxValue, appearance);
+ Appearance.SetData(ent, AmmoVisuals.HasAmmo, ent.Comp.Count != 0, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoCount, ent.Comp.Count ?? int.MaxValue, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoMax, ent.Comp.Capacity ?? int.MaxValue, appearance);
}
#region Public API
- public bool ChangeBasicEntityAmmoCount(EntityUid uid, int delta, BasicEntityAmmoProviderComponent? component = null)
+ public bool ChangeBasicEntityAmmoCount(Entity<BasicEntityAmmoProviderComponent?> ent, int delta)
{
- if (!Resolve(uid, ref component, false) || component.Count == null)
+ if (!Resolve(ent, ref ent.Comp, false) || ent.Comp.Count == null)
return false;
- return UpdateBasicEntityAmmoCount(uid, component.Count.Value + delta, component);
+ return UpdateBasicEntityAmmoCount((ent.Owner, ent.Comp), ent.Comp.Count.Value + delta);
}
- public bool UpdateBasicEntityAmmoCount(EntityUid uid, int count, BasicEntityAmmoProviderComponent? component = null)
+ public bool UpdateBasicEntityAmmoCount(Entity<BasicEntityAmmoProviderComponent?> ent, int count)
{
- if (!Resolve(uid, ref component, false))
+ if (!Resolve(ent, ref ent.Comp, false) || count > ent.Comp.Capacity)
return false;
- if (count > component.Capacity)
- return false;
-
- component.Count = count;
- UpdateBasicEntityAppearance(uid, component);
- UpdateAmmoCount(uid);
- Dirty(uid, component);
+ ent.Comp.Count = count;
+ UpdateBasicEntityAppearance((ent.Owner, ent.Comp));
+ UpdateAmmoCount(ent);
+ Dirty(ent);
return true;
}
: Loc.GetString("gun-cartridge-unspent"));
}
- private void OnCartridgeDamageExamine(EntityUid uid, CartridgeAmmoComponent component, ref DamageExamineEvent args)
+ private void OnCartridgeDamageExamine(Entity<CartridgeAmmoComponent> ent, ref DamageExamineEvent args)
{
- var damageSpec = GetProjectileDamage(component.Prototype);
+ var damageSpec = GetProjectileDamage(ent.Comp.Prototype);
if (damageSpec == null)
return;
public abstract partial class SharedGunSystem
{
- protected const string ChamberSlot = "gun_chamber";
-
protected virtual void InitializeChamberMagazine()
{
SubscribeLocalEvent<ChamberMagazineAmmoProviderComponent, ComponentStartup>(OnChamberStartup);
// Appearance data doesn't get serialized and want to make sure this is correct on spawn (regardless of MapInit) so.
if (component.BoltClosed != null)
{
- Appearance.SetData(uid, AmmoVisuals.BoltClosed, component.BoltClosed.Value);
+ Appearance.SetData(uid, AmmoVisuals.BoltClosed, component.BoltClosed.Value);
}
}
{
var getConnectedContainerEvent = new GetConnectedContainerEvent();
RaiseLocalEvent(uid, ref getConnectedContainerEvent);
- if(!getConnectedContainerEvent.ContainerEntity.HasValue)
+ if (!getConnectedContainerEvent.ContainerEntity.HasValue)
return;
RaiseLocalEvent(getConnectedContainerEvent.ContainerEntity.Value, args);
SubscribeLocalEvent<ContainerAmmoProviderComponent, GetAmmoCountEvent>(OnContainerAmmoCount);
}
- private void OnContainerTakeAmmo(EntityUid uid, ContainerAmmoProviderComponent component, TakeAmmoEvent args)
+ private void OnContainerTakeAmmo(Entity<ContainerAmmoProviderComponent> ent, ref TakeAmmoEvent args)
{
- component.ProviderUid ??= uid;
- if (!Containers.TryGetContainer(component.ProviderUid.Value, component.Container, out var container))
+ ent.Comp.ProviderUid ??= ent;
+ if (!Containers.TryGetContainer(ent.Comp.ProviderUid.Value, ent.Comp.Container, out var container))
return;
for (var i = 0; i < args.Shots; i++)
if (!container.ContainedEntities.Any())
break;
- var ent = container.ContainedEntities[0];
+ var ammoEnt = container.ContainedEntities[0];
if (_netManager.IsServer)
- Containers.Remove(ent, container);
+ Containers.Remove(ammoEnt, container);
- args.Ammo.Add((ent, EnsureShootable(ent)));
+ args.Ammo.Add((ammoEnt, EnsureShootable(ammoEnt)));
}
}
- private void OnContainerAmmoCount(EntityUid uid, ContainerAmmoProviderComponent component, ref GetAmmoCountEvent args)
+ private void OnContainerAmmoCount(Entity<ContainerAmmoProviderComponent> ent, ref GetAmmoCountEvent args)
{
- component.ProviderUid ??= uid;
- if (!Containers.TryGetContainer(component.ProviderUid.Value, component.Container, out var container))
+ ent.Comp.ProviderUid ??= ent;
+ if (!Containers.TryGetContainer(ent.Comp.ProviderUid.Value, ent.Comp.Container, out var container))
{
args.Capacity = 0;
args.Count = 0;
if (component.SelectedMode == fire)
return;
- DebugTools.Assert((component.AvailableModes & fire) != 0x0);
+ DebugTools.Assert((component.AvailableModes & fire) != 0x0);
component.SelectedMode = fire;
if (!Paused(uid))
private void OnGunSelected(EntityUid uid, GunComponent component, HandSelectedEvent args)
{
if (Timing.ApplyingState)
- return;
+ return;
if (component.FireRateModified <= 0)
return;
public abstract partial class SharedGunSystem
{
- protected const string MagazineSlot = "gun_magazine";
-
protected virtual void InitializeMagazine()
{
SubscribeLocalEvent<MagazineAmmoProviderComponent, MapInitEvent>(OnMagazineMapInit);
SubscribeLocalEvent<RevolverAmmoProviderComponent, UseInHandEvent>(OnRevolverUse);
}
- private void OnRevolverUse(EntityUid uid, RevolverAmmoProviderComponent component, UseInHandEvent args)
+ private void OnRevolverUse(Entity<RevolverAmmoProviderComponent> ent, ref UseInHandEvent args)
{
if (args.Handled)
return;
- if (!_useDelay.TryResetDelay(uid))
+ if (!_useDelay.TryResetDelay(ent))
return;
args.Handled = true;
- Cycle(component);
- UpdateAmmoCount(uid, prediction: false);
- Dirty(uid, component);
+ Cycle(ent.Comp);
+ UpdateAmmoCount(ent, prediction: false);
+ Dirty(ent);
}
- private void OnRevolverGetAmmoCount(EntityUid uid, RevolverAmmoProviderComponent component, ref GetAmmoCountEvent args)
+ private void OnRevolverGetAmmoCount(Entity<RevolverAmmoProviderComponent> ent, ref GetAmmoCountEvent args)
{
- args.Count += GetRevolverCount(component);
- args.Capacity += component.Capacity;
+ args.Count += GetRevolverCount(ent.Comp);
+ args.Capacity += ent.Comp.Capacity;
}
- private void OnRevolverInteractUsing(EntityUid uid, RevolverAmmoProviderComponent component, InteractUsingEvent args)
+ private void OnRevolverInteractUsing(Entity<RevolverAmmoProviderComponent> ent, ref InteractUsingEvent args)
{
if (args.Handled)
return;
- if (TryRevolverInsert(uid, component, args.Used, args.User))
+ if (TryRevolverInsert(ent, args.Used, args.User))
args.Handled = true;
}
- private void OnRevolverGetState(EntityUid uid, RevolverAmmoProviderComponent component, ref ComponentGetState args)
+ private void OnRevolverGetState(Entity<RevolverAmmoProviderComponent> ent, ref ComponentGetState args)
{
args.State = new RevolverAmmoProviderComponentState
{
- CurrentIndex = component.CurrentIndex,
- AmmoSlots = GetNetEntityList(component.AmmoSlots),
- Chambers = component.Chambers,
+ CurrentIndex = ent.Comp.CurrentIndex,
+ AmmoSlots = GetNetEntityList(ent.Comp.AmmoSlots),
+ Chambers = ent.Comp.Chambers,
};
}
- private void OnRevolverHandleState(EntityUid uid, RevolverAmmoProviderComponent component, ref ComponentHandleState args)
+ private void OnRevolverHandleState(Entity<RevolverAmmoProviderComponent> ent, ref ComponentHandleState args)
{
if (args.Current is not RevolverAmmoProviderComponentState state)
return;
- var oldIndex = component.CurrentIndex;
- component.CurrentIndex = state.CurrentIndex;
- component.Chambers = new bool?[state.Chambers.Length];
+ var oldIndex = ent.Comp.CurrentIndex;
+ ent.Comp.CurrentIndex = state.CurrentIndex;
+ ent.Comp.Chambers = new bool?[state.Chambers.Length];
// Need to copy across the state rather than the ref.
- for (var i = 0; i < component.AmmoSlots.Count; i++)
+ for (var i = 0; i < ent.Comp.AmmoSlots.Count; i++)
{
- component.AmmoSlots[i] = EnsureEntity<RevolverAmmoProviderComponent>(state.AmmoSlots[i], uid);
- component.Chambers[i] = state.Chambers[i];
+ ent.Comp.AmmoSlots[i] = EnsureEntity<RevolverAmmoProviderComponent>(state.AmmoSlots[i], ent);
+ ent.Comp.Chambers[i] = state.Chambers[i];
}
// Handle spins
if (oldIndex != state.CurrentIndex)
{
- UpdateAmmoCount(uid, prediction: false);
+ UpdateAmmoCount(ent, prediction: false);
}
}
- public bool TryRevolverInsert(EntityUid revolverUid, RevolverAmmoProviderComponent component, EntityUid uid, EntityUid? user)
+ public bool TryRevolverInsert(Entity<RevolverAmmoProviderComponent> ent, EntityUid insertEnt, EntityUid? user)
{
- if (_whitelistSystem.IsWhitelistFail(component.Whitelist, uid))
+ if (_whitelistSystem.IsWhitelistFail(ent.Comp.Whitelist, insertEnt))
return false;
// If it's a speedloader try to get ammo from it.
- if (HasComp<SpeedLoaderComponent>(uid))
+ if (HasComp<SpeedLoaderComponent>(insertEnt))
{
var freeSlots = 0;
- for (var i = 0; i < component.Capacity; i++)
+ for (var i = 0; i < ent.Comp.Capacity; i++)
{
- if (component.AmmoSlots[i] != null || component.Chambers[i] != null)
+ if (ent.Comp.AmmoSlots[i] != null || ent.Comp.Chambers[i] != null)
continue;
freeSlots++;
if (freeSlots == 0)
{
- Popup(Loc.GetString("gun-revolver-full"), revolverUid, user);
+ Popup(Loc.GetString("gun-revolver-full"), ent, user);
return false;
}
var xformQuery = GetEntityQuery<TransformComponent>();
- var xform = xformQuery.GetComponent(uid);
+ var xform = xformQuery.GetComponent(insertEnt);
var ammo = new List<(EntityUid? Entity, IShootable Shootable)>(freeSlots);
var ev = new TakeAmmoEvent(freeSlots, ammo, xform.Coordinates, user);
- RaiseLocalEvent(uid, ev);
+ RaiseLocalEvent(insertEnt, ev);
if (ev.Ammo.Count == 0)
{
- Popup(Loc.GetString("gun-speedloader-empty"), revolverUid, user);
+ Popup(Loc.GetString("gun-speedloader-empty"), ent, user);
return false;
}
- for (var i = 0; i < component.Capacity; i++)
+ for (var i = 0; i < ent.Comp.Capacity; i++)
{
- var index = (component.CurrentIndex + i) % component.Capacity;
+ var index = (ent.Comp.CurrentIndex + i) % ent.Comp.Capacity;
- if (component.AmmoSlots[index] != null ||
- component.Chambers[index] != null)
+ if (ent.Comp.AmmoSlots[index] != null ||
+ ent.Comp.Chambers[index] != null)
{
continue;
}
- var ent = ev.Ammo.Last().Entity;
+ var ammoEnt = ev.Ammo.Last().Entity;
ev.Ammo.RemoveAt(ev.Ammo.Count - 1);
- if (ent == null)
+ if (ammoEnt == null)
{
Log.Error($"Tried to load hitscan into a revolver which is unsupported");
continue;
}
- component.AmmoSlots[index] = ent.Value;
- Containers.Insert(ent.Value, component.AmmoContainer);
- SetChamber(index, component, uid);
+ ent.Comp.AmmoSlots[index] = ammoEnt.Value;
+ Containers.Insert(ammoEnt.Value, ent.Comp.AmmoContainer);
+ SetChamber(ent, insertEnt, index);
if (ev.Ammo.Count == 0)
break;
}
DebugTools.Assert(ammo.Count == 0);
- UpdateRevolverAppearance(revolverUid, component);
- UpdateAmmoCount(revolverUid);
- Dirty(revolverUid, component);
+ UpdateRevolverAppearance(ent);
+ UpdateAmmoCount(ent);
+ Dirty(ent);
- Audio.PlayPredicted(component.SoundInsert, revolverUid, user);
- Popup(Loc.GetString("gun-revolver-insert"), revolverUid, user);
+ Audio.PlayPredicted(ent.Comp.SoundInsert, ent, user);
+ Popup(Loc.GetString("gun-revolver-insert"), ent, user);
return true;
}
// Try to insert the entity directly.
- for (var i = 0; i < component.Capacity; i++)
+ for (var i = 0; i < ent.Comp.Capacity; i++)
{
- var index = (component.CurrentIndex + i) % component.Capacity;
+ var index = (ent.Comp.CurrentIndex + i) % ent.Comp.Capacity;
- if (component.AmmoSlots[index] != null ||
- component.Chambers[index] != null)
+ if (ent.Comp.AmmoSlots[index] != null ||
+ ent.Comp.Chambers[index] != null)
{
continue;
}
- component.AmmoSlots[index] = uid;
- Containers.Insert(uid, component.AmmoContainer);
- SetChamber(index, component, uid);
- Audio.PlayPredicted(component.SoundInsert, revolverUid, user);
- Popup(Loc.GetString("gun-revolver-insert"), revolverUid, user);
- UpdateRevolverAppearance(revolverUid, component);
- UpdateAmmoCount(revolverUid);
- Dirty(revolverUid, component);
+ ent.Comp.AmmoSlots[index] = insertEnt;
+ Containers.Insert(insertEnt, ent.Comp.AmmoContainer);
+ SetChamber(ent, insertEnt, index);
+ Audio.PlayPredicted(ent.Comp.SoundInsert, ent, user);
+ Popup(Loc.GetString("gun-revolver-insert"), ent, user);
+ UpdateRevolverAppearance(ent);
+ UpdateAmmoCount(ent);
+ Dirty(ent);
return true;
}
- Popup(Loc.GetString("gun-revolver-full"), revolverUid, user);
+ Popup(Loc.GetString("gun-revolver-full"), ent, user);
return false;
}
- private void SetChamber(int index, RevolverAmmoProviderComponent component, EntityUid uid)
+ private void SetChamber(Entity<RevolverAmmoProviderComponent> ent, Entity<CartridgeAmmoComponent?> ammo, int index)
{
- if (TryComp<CartridgeAmmoComponent>(uid, out var cartridge) && cartridge.Spent)
+ if (!Resolve(ammo, ref ammo.Comp, false) || ammo.Comp.Spent)
{
- component.Chambers[index] = false;
+ ent.Comp.Chambers[index] = false;
return;
}
- component.Chambers[index] = true;
+ ent.Comp.Chambers[index] = true;
}
private void OnRevolverVerbs(EntityUid uid, RevolverAmmoProviderComponent component, GetVerbsEvent<AlternativeVerb> args)
{
Text = Loc.GetString("gun-revolver-empty"),
Disabled = !AnyRevolverCartridges(component),
- Act = () => EmptyRevolver(uid, component, args.User),
+ Act = () => EmptyRevolver((uid, component), args.User),
Priority = 1
});
{
Text = Loc.GetString("gun-revolver-spin"),
// Category = VerbCategory.G,
- Act = () => SpinRevolver(uid, component, args.User)
+ Act = () => SpinRevolver((uid, component), args.User)
});
}
return count;
}
- public void EmptyRevolver(EntityUid revolverUid, RevolverAmmoProviderComponent component, EntityUid? user = null)
+ public void EmptyRevolver(Entity<RevolverAmmoProviderComponent> ent, EntityUid? user = null)
{
- var mapCoordinates = TransformSystem.GetMapCoordinates(revolverUid);
+ var mapCoordinates = TransformSystem.GetMapCoordinates(ent);
var anyEmpty = false;
- for (var i = 0; i < component.Capacity; i++)
+ for (var i = 0; i < ent.Comp.Capacity; i++)
{
- var chamber = component.Chambers[i];
- var slot = component.AmmoSlots[i];
+ var chamber = ent.Comp.Chambers[i];
+ var slot = ent.Comp.AmmoSlots[i];
if (slot == null)
{
// Too lazy to make a new method don't sue me.
if (!_netManager.IsClient)
{
- var uid = Spawn(component.FillPrototype, mapCoordinates);
+ var uid = Spawn(ent.Comp.FillPrototype, mapCoordinates);
if (TryComp<CartridgeAmmoComponent>(uid, out var cartridge))
- SetCartridgeSpent(uid, cartridge, !(bool) chamber);
+ SetCartridgeSpent(uid, cartridge, !(bool)chamber);
EjectCartridge(uid);
}
- component.Chambers[i] = null;
+ ent.Comp.Chambers[i] = null;
anyEmpty = true;
}
else
{
- component.AmmoSlots[i] = null;
- Containers.Remove(slot.Value, component.AmmoContainer);
- component.Chambers[i] = null;
+ ent.Comp.AmmoSlots[i] = null;
+ Containers.Remove(slot.Value, ent.Comp.AmmoContainer);
+ ent.Comp.Chambers[i] = null;
if (!_netManager.IsClient)
EjectCartridge(slot.Value);
if (anyEmpty)
{
- Audio.PlayPredicted(component.SoundEject, revolverUid, user);
- UpdateAmmoCount(revolverUid, prediction: false);
- UpdateRevolverAppearance(revolverUid, component);
- Dirty(revolverUid, component);
+ Audio.PlayPredicted(ent.Comp.SoundEject, ent, user);
+ UpdateAmmoCount(ent, prediction: false);
+ UpdateRevolverAppearance(ent);
+ Dirty(ent);
}
}
- private void UpdateRevolverAppearance(EntityUid uid, RevolverAmmoProviderComponent component)
+ private void UpdateRevolverAppearance(Entity<RevolverAmmoProviderComponent> ent)
{
- if (!TryComp<AppearanceComponent>(uid, out var appearance))
+ if (!TryComp<AppearanceComponent>(ent, out var appearance))
return;
- var count = GetRevolverCount(component);
- Appearance.SetData(uid, AmmoVisuals.HasAmmo, count != 0, appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoCount, count, appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance);
+ var count = GetRevolverCount(ent.Comp);
+ Appearance.SetData(ent, AmmoVisuals.HasAmmo, count != 0, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoCount, count, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoMax, ent.Comp.Capacity, appearance);
}
- protected virtual void SpinRevolver(EntityUid revolverUid, RevolverAmmoProviderComponent component, EntityUid? user = null)
+ protected virtual void SpinRevolver(Entity<RevolverAmmoProviderComponent> ent, EntityUid? user = null)
{
- Audio.PlayPredicted(component.SoundSpin, revolverUid, user);
- Popup(Loc.GetString("gun-revolver-spun"), revolverUid, user);
+ Audio.PlayPredicted(ent.Comp.SoundSpin, ent, user);
+ Popup(Loc.GetString("gun-revolver-spun"), ent, user);
}
- private void OnRevolverTakeAmmo(EntityUid uid, RevolverAmmoProviderComponent component, TakeAmmoEvent args)
+ private void OnRevolverTakeAmmo(Entity<RevolverAmmoProviderComponent> ent, ref TakeAmmoEvent args)
{
- var currentIndex = component.CurrentIndex;
- Cycle(component, args.Shots);
+ var currentIndex = ent.Comp.CurrentIndex;
+ Cycle(ent.Comp, args.Shots);
// Revolvers provide the bullets themselves rather than the cartridges so they stay in the revolver.
for (var i = 0; i < args.Shots; i++)
{
- var index = (currentIndex + i) % component.Capacity;
- var chamber = component.Chambers[index];
- EntityUid? ent = null;
+ var index = (currentIndex + i) % ent.Comp.Capacity;
+ var chamber = ent.Comp.Chambers[index];
+ EntityUid? ammoEnt = null;
// Get contained entity if it exists.
- if (component.AmmoSlots[index] != null)
+ if (ent.Comp.AmmoSlots[index] != null)
{
- ent = component.AmmoSlots[index]!;
- component.Chambers[index] = false;
+ ammoEnt = ent.Comp.AmmoSlots[index]!;
+ ent.Comp.Chambers[index] = false;
}
// Try to spawn a round if it's available.
else if (chamber != null)
if (chamber == true)
{
// Pretend it's always been there.
- ent = Spawn(component.FillPrototype, args.Coordinates);
+ ammoEnt = Spawn(ent.Comp.FillPrototype, args.Coordinates);
if (!_netManager.IsClient)
{
- component.AmmoSlots[index] = ent;
- Containers.Insert(ent.Value, component.AmmoContainer);
+ ent.Comp.AmmoSlots[index] = ammoEnt;
+ Containers.Insert(ammoEnt.Value, ent.Comp.AmmoContainer);
}
- component.Chambers[index] = false;
+ ent.Comp.Chambers[index] = false;
}
}
// Chamber empty or spent
- if (ent == null)
+ if (ammoEnt == null)
continue;
- if (TryComp<CartridgeAmmoComponent>(ent, out var cartridge))
+ if (TryComp<CartridgeAmmoComponent>(ammoEnt, out var cartridge))
{
if (cartridge.Spent)
continue;
// Mark cartridge as spent and if it's caseless delete from the chamber slot.
- SetCartridgeSpent(ent.Value, cartridge, true);
+ SetCartridgeSpent(ammoEnt.Value, cartridge, true);
var spawned = Spawn(cartridge.Prototype, args.Coordinates);
args.Ammo.Add((spawned, EnsureComp<AmmoComponent>(spawned)));
if (cartridge.DeleteOnSpawn)
{
- component.AmmoSlots[index] = null;
- component.Chambers[index] = null;
+ ent.Comp.AmmoSlots[index] = null;
+ ent.Comp.Chambers[index] = null;
}
}
else
{
- component.AmmoSlots[index] = null;
- component.Chambers[index] = null;
- args.Ammo.Add((ent.Value, EnsureComp<AmmoComponent>(ent.Value)));
+ ent.Comp.AmmoSlots[index] = null;
+ ent.Comp.Chambers[index] = null;
+ args.Ammo.Add((ammoEnt.Value, EnsureComp<AmmoComponent>(ammoEnt.Value)));
}
// Delete the cartridge entity on client
if (_netManager.IsClient)
{
- QueueDel(ent);
+ QueueDel(ammoEnt);
}
}
- UpdateAmmoCount(uid, prediction: false);
- UpdateRevolverAppearance(uid, component);
- Dirty(uid, component);
+ UpdateAmmoCount(ent, prediction: false);
+ UpdateRevolverAppearance(ent);
+ Dirty(ent);
}
private void Cycle(RevolverAmmoProviderComponent component, int count = 1)
component.CurrentIndex = (component.CurrentIndex + count) % component.Capacity;
}
- private void OnRevolverInit(EntityUid uid, RevolverAmmoProviderComponent component, ComponentInit args)
+ private void OnRevolverInit(Entity<RevolverAmmoProviderComponent> ent, ref ComponentInit args)
{
- component.AmmoContainer = Containers.EnsureContainer<Container>(uid, RevolverContainer);
- component.AmmoSlots.EnsureCapacity(component.Capacity);
- var remainder = component.Capacity - component.AmmoSlots.Count;
+ ent.Comp.AmmoContainer = Containers.EnsureContainer<Container>(ent, RevolverContainer);
+ ent.Comp.AmmoSlots.EnsureCapacity(ent.Comp.Capacity);
+ var remainder = ent.Comp.Capacity - ent.Comp.AmmoSlots.Count;
for (var i = 0; i < remainder; i++)
{
- component.AmmoSlots.Add(null);
+ ent.Comp.AmmoSlots.Add(null);
}
- component.Chambers = new bool?[component.Capacity];
+ ent.Comp.Chambers = new bool?[ent.Comp.Capacity];
- if (component.FillPrototype != null)
+ if (ent.Comp.FillPrototype != null)
{
- for (var i = 0; i < component.Capacity; i++)
+ for (var i = 0; i < ent.Comp.Capacity; i++)
{
- if (component.AmmoSlots[i] != null)
+ if (ent.Comp.AmmoSlots[i] != null)
{
- component.Chambers[i] = null;
+ ent.Comp.Chambers[i] = null;
continue;
}
- component.Chambers[i] = true;
+ ent.Comp.Chambers[i] = true;
}
}
- DebugTools.Assert(component.AmmoSlots.Count == component.Capacity);
+ DebugTools.Assert(ent.Comp.AmmoSlots.Count == ent.Comp.Capacity);
}
[Serializable, NetSerializable]
SubscribeLocalEvent<SolutionAmmoProviderComponent, GetAmmoCountEvent>(OnSolutionAmmoCount);
}
- private void OnSolutionTakeAmmo(EntityUid uid, SolutionAmmoProviderComponent component, TakeAmmoEvent args)
+ private void OnSolutionTakeAmmo(Entity<SolutionAmmoProviderComponent> ent, ref TakeAmmoEvent args)
{
- var shots = Math.Min(args.Shots, component.Shots);
+ var shots = Math.Min(args.Shots, ent.Comp.Shots);
// Don't dirty if it's an empty fire.
if (shots == 0)
for (var i = 0; i < shots; i++)
{
- args.Ammo.Add(GetSolutionShot(uid, component, args.Coordinates));
- component.Shots--;
+ args.Ammo.Add(GetSolutionShot(ent, args.Coordinates));
+ ent.Comp.Shots--;
}
- UpdateSolutionShots(uid, component);
- UpdateSolutionAppearance(uid, component);
+ UpdateSolutionShots(ent);
+ UpdateSolutionAppearance(ent);
}
- private void OnSolutionAmmoCount(EntityUid uid, SolutionAmmoProviderComponent component, ref GetAmmoCountEvent args)
+ private void OnSolutionAmmoCount(Entity<SolutionAmmoProviderComponent> ent, ref GetAmmoCountEvent args)
{
- args.Count = component.Shots;
- args.Capacity = component.MaxShots;
+ args.Count = ent.Comp.Shots;
+ args.Capacity = ent.Comp.MaxShots;
}
- protected virtual void UpdateSolutionShots(EntityUid uid, SolutionAmmoProviderComponent component, Solution? solution = null)
- {
-
- }
+ protected virtual void UpdateSolutionShots(Entity<SolutionAmmoProviderComponent> ent, Solution? solution = null) { }
- protected virtual (EntityUid Entity, IShootable) GetSolutionShot(EntityUid uid, SolutionAmmoProviderComponent component, EntityCoordinates position)
+ protected virtual (EntityUid Entity, IShootable) GetSolutionShot(Entity<SolutionAmmoProviderComponent> ent, EntityCoordinates position)
{
- var ent = Spawn(component.Prototype, position);
- return (ent, EnsureShootable(ent));
+ var shot = Spawn(ent.Comp.Prototype, position);
+ return (shot, EnsureShootable(shot));
}
- protected void UpdateSolutionAppearance(EntityUid uid, SolutionAmmoProviderComponent component)
+ protected void UpdateSolutionAppearance(Entity<SolutionAmmoProviderComponent> ent)
{
- if (!TryComp<AppearanceComponent>(uid, out var appearance))
+ if (!TryComp<AppearanceComponent>(ent, out var appearance))
return;
- Appearance.SetData(uid, AmmoVisuals.HasAmmo, component.Shots != 0, appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoCount, component.Shots, appearance);
- Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.MaxShots, appearance);
+ Appearance.SetData(ent, AmmoVisuals.HasAmmo, ent.Comp.Shots != 0, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoCount, ent.Comp.Shots, appearance);
+ Appearance.SetData(ent, AmmoVisuals.AmmoMax, ent.Comp.MaxShots, appearance);
}
}
public abstract partial class SharedGunSystem : EntitySystem
{
- [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
+ [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
+ [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
+ [Dependency] private readonly INetManager _netManager = default!;
+ [Dependency] private readonly ItemSlotsSystem _slots = default!;
+ [Dependency] private readonly RechargeBasicEntityAmmoSystem _recharge = default!;
+ [Dependency] private readonly SharedCombatModeSystem _combatMode = default!;
+ [Dependency] private readonly SharedHandsSystem _hands = default!;
+ [Dependency] private readonly UseDelaySystem _useDelay = default!;
+ [Dependency] protected readonly DamageableSystem Damageable = default!;
+ [Dependency] protected readonly ExamineSystemShared Examine = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] protected readonly IMapManager MapManager = default!;
- [Dependency] private readonly INetManager _netManager = default!;
[Dependency] protected readonly IPrototypeManager ProtoManager = default!;
[Dependency] protected readonly IRobustRandom Random = default!;
[Dependency] protected readonly ISharedAdminLogManager Logs = default!;
- [Dependency] protected readonly DamageableSystem Damageable = default!;
- [Dependency] protected readonly ExamineSystemShared Examine = default!;
- [Dependency] private readonly SharedHandsSystem _hands = default!;
- [Dependency] private readonly ItemSlotsSystem _slots = default!;
- [Dependency] private readonly RechargeBasicEntityAmmoSystem _recharge = default!;
[Dependency] protected readonly SharedActionsSystem Actions = default!;
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
[Dependency] protected readonly SharedAudioSystem Audio = default!;
- [Dependency] private readonly SharedCombatModeSystem _combatMode = default!;
[Dependency] protected readonly SharedContainerSystem Containers = default!;
+ [Dependency] protected readonly SharedPhysicsSystem Physics = default!;
[Dependency] protected readonly SharedPointLightSystem Lights = default!;
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
- [Dependency] protected readonly SharedPhysicsSystem Physics = default!;
[Dependency] protected readonly SharedProjectileSystem Projectiles = default!;
[Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
[Dependency] protected readonly TagSystem TagSystem = default!;
[Dependency] protected readonly ThrowingSystem ThrowingSystem = default!;
- [Dependency] private readonly UseDelaySystem _useDelay = default!;
- [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
/// <summary>
/// Default projectile speed
/// </summary>
public const float ProjectileSpeed = 40f;
+ /// <summary>
+ /// Name of the container slot used as the gun's chamber
+ /// </summary>
+ public const string ChamberSlot = "gun_chamber";
+
+ /// <summary>
+ /// Name of the container slot used as the gun's magazine
+ /// </summary>
+ public const string MagazineSlot = "gun_magazine";
+
private static readonly ProtoId<TagPrototype> TrashTag = "Trash";
private const float InteractNextFire = 0.3f;
RefreshModifiers((gun, gun));
}
- private void OnGunMelee(EntityUid uid, GunComponent component, MeleeHitEvent args)
+ private void OnGunMelee(Entity<GunComponent> ent, ref MeleeHitEvent args)
{
- if (!TryComp<MeleeWeaponComponent>(uid, out var melee))
+ if (!TryComp<MeleeWeaponComponent>(ent, out var melee))
return;
- if (melee.NextAttack > component.NextFire)
+ if (melee.NextAttack > ent.Comp.NextFire)
{
- component.NextFire = melee.NextAttack;
- DirtyField(uid, component, nameof(GunComponent.NextFire));
+ ent.Comp.NextFire = melee.NextAttack;
+ DirtyField(ent.AsNullable(), nameof(GunComponent.NextFire));
}
}
if (user == null ||
!_combatMode.IsInCombatMode(user) ||
- !TryGetGun(user.Value, out var ent, out var gun))
+ !TryGetGun(user.Value, out var gun))
{
return;
}
- if (ent != GetEntity(msg.Gun))
+ if (gun.Owner != GetEntity(msg.Gun))
return;
- gun.ShootCoordinates = GetCoordinates(msg.Coordinates);
- gun.Target = GetEntity(msg.Target);
- AttemptShoot(user.Value, ent, gun);
+ gun.Comp.ShootCoordinates = GetCoordinates(msg.Coordinates);
+ gun.Comp.Target = GetEntity(msg.Target);
+ AttemptShoot(user.Value, gun);
}
private void OnStopShootRequest(RequestStopShootEvent ev, EntitySessionEventArgs args)
if (args.SenderSession.AttachedEntity == null ||
!TryComp<GunComponent>(gunUid, out var gun) ||
- !TryGetGun(args.SenderSession.AttachedEntity.Value, out _, out var userGun))
+ !TryGetGun(args.SenderSession.AttachedEntity.Value, out var userGun))
{
return;
}
- if (userGun != gun)
+ if (userGun != (gunUid, gun))
return;
- StopShooting(gunUid, gun);
+ StopShooting(userGun);
}
public bool CanShoot(GunComponent component)
return true;
}
- public bool TryGetGun(EntityUid entity, out EntityUid gunEntity, [NotNullWhen(true)] out GunComponent? gunComp)
+ /// <summary>
+ /// Tries to get an entity with <see cref="GunComponent"/> from the specified entity's hands, or from the entity itself.
+ /// </summary>
+ /// <param name="entity">Entity that is holding the gun, or is the gun</param>
+ /// <param name="gun">Gun entity to return</param>
+ /// <returns>True if gun was found</returns>
+ public bool TryGetGun(EntityUid entity, out Entity<GunComponent> gun)
{
- gunEntity = default;
- gunComp = null;
+ gun = default;
if (_hands.GetActiveItem(entity) is { } held &&
- TryComp(held, out GunComponent? gun))
+ TryComp(held, out GunComponent? gunComp))
{
- gunEntity = held;
- gunComp = gun;
+ gun = (held, gunComp);
return true;
}
// Last resort is check if the entity itself is a gun.
- if (TryComp(entity, out gun))
+ if (TryComp(entity, out gunComp))
{
- gunEntity = entity;
- gunComp = gun;
+ gun = (entity, gunComp);
return true;
}
return false;
}
- private void StopShooting(EntityUid uid, GunComponent gun)
+ private void StopShooting(Entity<GunComponent> ent)
{
- if (gun.ShotCounter == 0)
+ if (ent.Comp.ShotCounter == 0)
return;
- gun.ShotCounter = 0;
- gun.ShootCoordinates = null;
- gun.Target = null;
- DirtyField(uid, gun, nameof(GunComponent.ShotCounter));
+ ent.Comp.ShotCounter = 0;
+ ent.Comp.ShootCoordinates = null;
+ ent.Comp.Target = null;
+ DirtyField(ent.AsNullable(), nameof(GunComponent.ShotCounter));
}
/// <summary>
/// Attempts to shoot at the target coordinates. Resets the shot counter after every shot.
/// </summary>
- public bool AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun, EntityCoordinates toCoordinates, EntityUid? target = null)
+ public bool AttemptShoot(EntityUid user, Entity<GunComponent> gun, EntityCoordinates toCoordinates, EntityUid? target = null)
{
- gun.ShootCoordinates = toCoordinates;
- gun.Target = target;
- var result = AttemptShoot(user, gunUid, gun);
- gun.ShotCounter = 0;
- DirtyField(gunUid, gun, nameof(GunComponent.ShotCounter));
+ gun.Comp.ShootCoordinates = toCoordinates;
+ gun.Comp.Target = target;
+ var result = AttemptShoot(user, gun);
+ gun.Comp.ShotCounter = 0;
+ DirtyField(gun.AsNullable(), nameof(GunComponent.ShotCounter));
return result;
}
/// <summary>
/// Shoots by assuming the gun is the user at default coordinates.
/// </summary>
- public bool AttemptShoot(EntityUid gunUid, GunComponent gun)
+ public bool AttemptShoot(Entity<GunComponent> gun)
{
- var coordinates = new EntityCoordinates(gunUid, gun.DefaultDirection);
- gun.ShootCoordinates = coordinates;
- var result = AttemptShoot(gunUid, gunUid, gun);
- gun.ShotCounter = 0;
+ var coordinates = new EntityCoordinates(gun, gun.Comp.DefaultDirection);
+ gun.Comp.ShootCoordinates = coordinates;
+ var result = AttemptShoot(gun, gun);
+ gun.Comp.ShotCounter = 0;
return result;
}
- private bool AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun)
+ private bool AttemptShoot(EntityUid user, Entity<GunComponent> gun)
{
- if (gun.FireRateModified <= 0f ||
+ if (gun.Comp.FireRateModified <= 0f ||
!_actionBlockerSystem.CanAttack(user))
{
return false;
}
- var toCoordinates = gun.ShootCoordinates;
+ var toCoordinates = gun.Comp.ShootCoordinates;
if (toCoordinates == null)
return false;
var prevention = new ShotAttemptedEvent
{
User = user,
- Used = (gunUid, gun)
+ Used = gun
};
- RaiseLocalEvent(gunUid, ref prevention);
+ RaiseLocalEvent(gun, ref prevention);
if (prevention.Cancelled)
return false;
// Need to do this to play the clicking sound for empty automatic weapons
// but not play anything for burst fire.
- if (gun.NextFire > curTime)
+ if (gun.Comp.NextFire > curTime)
return false;
- var fireRate = TimeSpan.FromSeconds(1f / gun.FireRateModified);
+ var fireRate = TimeSpan.FromSeconds(1f / gun.Comp.FireRateModified);
- if (gun.SelectedMode == SelectiveFire.Burst || gun.BurstActivated)
- fireRate = TimeSpan.FromSeconds(1f / gun.BurstFireRate);
+ if (gun.Comp.SelectedMode == SelectiveFire.Burst || gun.Comp.BurstActivated)
+ fireRate = TimeSpan.FromSeconds(1f / gun.Comp.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.
- if (gun.NextFire < curTime - fireRate || gun.ShotCounter == 0 && gun.NextFire < curTime)
- gun.NextFire = curTime;
+ if (gun.Comp.NextFire < curTime - fireRate || gun.Comp.ShotCounter == 0 && gun.Comp.NextFire < curTime)
+ gun.Comp.NextFire = curTime;
var shots = 0;
- var lastFire = gun.NextFire;
+ var lastFire = gun.Comp.NextFire;
- while (gun.NextFire <= curTime)
+ while (gun.Comp.NextFire <= curTime)
{
- gun.NextFire += fireRate;
+ gun.Comp.NextFire += fireRate;
shots++;
}
// NextFire has been touched regardless so need to dirty the gun.
- DirtyField(gunUid, gun, nameof(GunComponent.NextFire));
+ DirtyField(gun.AsNullable(), nameof(GunComponent.NextFire));
// 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)
+ if (!gun.Comp.BurstActivated)
{
- switch (gun.SelectedMode)
+ switch (gun.Comp.SelectedMode)
{
case SelectiveFire.SemiAuto:
- shots = Math.Min(shots, 1 - gun.ShotCounter);
+ shots = Math.Min(shots, 1 - gun.Comp.ShotCounter);
break;
case SelectiveFire.Burst:
- shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
+ shots = Math.Min(shots, gun.Comp.ShotsPerBurstModified - gun.Comp.ShotCounter);
break;
case SelectiveFire.FullAuto:
break;
default:
- throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.SelectedMode}!");
+ throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.Comp.SelectedMode}!");
}
- } else
+ }
+ else
{
- shots = Math.Min(shots, gun.ShotsPerBurstModified - gun.ShotCounter);
+ shots = Math.Min(shots, gun.Comp.ShotsPerBurstModified - gun.Comp.ShotCounter);
}
var attemptEv = new AttemptShootEvent(user, null);
- RaiseLocalEvent(gunUid, ref attemptEv);
+ RaiseLocalEvent(gun, ref attemptEv);
if (attemptEv.Cancelled)
{
if (attemptEv.Message != null)
{
- PopupSystem.PopupClient(attemptEv.Message, gunUid, user);
+ PopupSystem.PopupClient(attemptEv.Message, gun, user);
}
- gun.BurstActivated = false;
- gun.BurstShotsCount = 0;
- gun.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.NextFire.TotalSeconds));
+ gun.Comp.BurstActivated = false;
+ gun.Comp.BurstShotsCount = 0;
+ gun.Comp.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.Comp.NextFire.TotalSeconds));
return false;
}
var fromCoordinates = Transform(user).Coordinates;
// Remove ammo
- var ev = new TakeAmmoEvent(shots, new List<(EntityUid? Entity, IShootable Shootable)>(), fromCoordinates, user);
+ var ev = new TakeAmmoEvent(shots, [], fromCoordinates, user);
// Listen it just makes the other code around it easier if shots == 0 to do this.
if (shots > 0)
- RaiseLocalEvent(gunUid, ev);
+ RaiseLocalEvent(gun, ev);
DebugTools.Assert(ev.Ammo.Count <= shots);
DebugTools.Assert(shots >= 0);
- UpdateAmmoCount(gunUid);
+ UpdateAmmoCount(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;
- DirtyField(gunUid, gun, nameof(GunComponent.ShotCounter));
+ gun.Comp.ShotCounter += shots;
+ DirtyField(gun.AsNullable(), nameof(GunComponent.ShotCounter));
if (ev.Ammo.Count <= 0)
{
// triggers effects on the gun if it's empty
var emptyGunShotEvent = new OnEmptyGunShotEvent(user);
- RaiseLocalEvent(gunUid, ref emptyGunShotEvent);
+ RaiseLocalEvent(gun, ref emptyGunShotEvent);
- gun.BurstActivated = false;
- gun.BurstShotsCount = 0;
- gun.NextFire += TimeSpan.FromSeconds(gun.BurstCooldown);
+ gun.Comp.BurstActivated = false;
+ gun.Comp.BurstShotsCount = 0;
+ gun.Comp.NextFire += TimeSpan.FromSeconds(gun.Comp.BurstCooldown);
// Play empty gun sounds if relevant
// If they're firing an existing clip then don't play anything.
// Don't spam safety sounds at gun fire rate, play it at a reduced rate.
// May cause prediction issues? Needs more tweaking
- gun.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.NextFire.TotalSeconds));
- Audio.PlayPredicted(gun.SoundEmpty, gunUid, user);
+ gun.Comp.NextFire = TimeSpan.FromSeconds(Math.Max(lastFire.TotalSeconds + SafetyNextFire, gun.Comp.NextFire.TotalSeconds));
+ Audio.PlayPredicted(gun.Comp.SoundEmpty, gun, user);
return false;
}
}
// Handle burstfire
- if (gun.SelectedMode == SelectiveFire.Burst)
+ if (gun.Comp.SelectedMode == SelectiveFire.Burst)
{
- gun.BurstActivated = true;
+ gun.Comp.BurstActivated = true;
}
- if (gun.BurstActivated)
+ if (gun.Comp.BurstActivated)
{
- gun.BurstShotsCount += shots;
- if (gun.BurstShotsCount >= gun.ShotsPerBurstModified)
+ gun.Comp.BurstShotsCount += shots;
+ if (gun.Comp.BurstShotsCount >= gun.Comp.ShotsPerBurstModified)
{
- gun.NextFire += TimeSpan.FromSeconds(gun.BurstCooldown);
- gun.BurstActivated = false;
- gun.BurstShotsCount = 0;
+ gun.Comp.NextFire += TimeSpan.FromSeconds(gun.Comp.BurstCooldown);
+ gun.Comp.BurstActivated = false;
+ gun.Comp.BurstShotsCount = 0;
}
}
// Shoot confirmed - sounds also played here in case it's invalid (e.g. cartridge already spent).
- Shoot(gunUid, gun, ev.Ammo, fromCoordinates, toCoordinates.Value, out var userImpulse, user, throwItems: attemptEv.ThrowItems);
+ Shoot(gun, ev.Ammo, fromCoordinates, toCoordinates.Value, out var userImpulse, user, throwItems: attemptEv.ThrowItems);
var shotEv = new GunShotEvent(user, ev.Ammo);
- RaiseLocalEvent(gunUid, ref shotEv);
+ RaiseLocalEvent(gun, ref shotEv);
if (!userImpulse || !TryComp<PhysicsComponent>(user, out var userPhysics))
return true;
RaiseLocalEvent(user, ref shooterEv);
if (shooterEv.Push)
- CauseImpulse(fromCoordinates, toCoordinates.Value, user, userPhysics);
+ CauseImpulse(fromCoordinates, toCoordinates.Value, (user, userPhysics));
return true;
}
public void Shoot(
- EntityUid gunUid,
- GunComponent gun,
+ Entity<GunComponent> gun,
EntityUid ammo,
EntityCoordinates fromCoordinates,
EntityCoordinates toCoordinates,
bool throwItems = false)
{
var shootable = EnsureShootable(ammo);
- Shoot(gunUid, gun, new List<(EntityUid? Entity, IShootable Shootable)>(1) { (ammo, shootable) }, fromCoordinates, toCoordinates, out userImpulse, user, throwItems);
+ Shoot(gun, new List<(EntityUid? Entity, IShootable Shootable)>(1) { (ammo, shootable) }, fromCoordinates, toCoordinates, out userImpulse, user, throwItems);
}
public abstract void Shoot(
- EntityUid gunUid,
- GunComponent gun,
+ Entity<GunComponent> gun,
List<(EntityUid? Entity, IShootable Shootable)> ammo,
EntityCoordinates fromCoordinates,
EntityCoordinates toCoordinates,
/// <summary>
/// Call this whenever the ammo count for a gun changes.
/// </summary>
- protected virtual void UpdateAmmoCount(EntityUid uid, bool prediction = true) {}
+ protected virtual void UpdateAmmoCount(EntityUid uid, bool prediction = true) { }
protected void SetCartridgeSpent(EntityUid uid, CartridgeAmmoComponent cartridge, bool spent)
{
// decides direction the casing ejects and only when not cycling
if (angle != null)
{
- Angle ejectAngle = angle.Value;
+ var ejectAngle = angle.Value;
ejectAngle += 3.7f; // 212 degrees; casings should eject slightly to the right and behind of a gun
ThrowingSystem.TryThrow(entity, ejectAngle.ToVec().Normalized() / 100, 5f);
}
CreateEffect(gun, ev, user);
}
- public void CauseImpulse(EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, EntityUid user, PhysicsComponent userPhysics)
+ public void CauseImpulse(EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, Entity<PhysicsComponent> user)
{
var fromMap = TransformSystem.ToMapCoordinates(fromCoordinates).Position;
var toMap = TransformSystem.ToMapCoordinates(toCoordinates).Position;
var shotDirection = (toMap - fromMap).Normalized();
const float impulseStrength = 25.0f;
- var impulseVector = shotDirection * impulseStrength;
- Physics.ApplyLinearImpulse(user, -impulseVector, body: userPhysics);
+ var impulseVector = shotDirection * impulseStrength;
+ Physics.ApplyLinearImpulse(user, -impulseVector, body: user.Comp);
}
public void RefreshModifiers(Entity<GunComponent?> gun)
[Serializable, NetSerializable]
public sealed class HitscanEvent : EntityEventArgs
{
- public List<(NetCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = new();
+ public List<(NetCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = [];
}
/// <summary>
SubscribeLocalEvent<UseDelayOnShootComponent, GunShotEvent>(OnUseShoot);
}
- private void OnUseShoot(EntityUid uid, UseDelayOnShootComponent component, ref GunShotEvent args)
+ private void OnUseShoot(Entity<UseDelayOnShootComponent> ent, ref GunShotEvent args)
{
- if (TryComp(uid, out UseDelayComponent? useDelay))
- _delay.TryResetDelay((uid, useDelay));
+ if (TryComp(ent, out UseDelayComponent? useDelay))
+ _delay.TryResetDelay((ent, useDelay));
}
}