diff --git a/Content.Server/Weapon/Ranged/Ammunition/Components/AmmoComponent.cs b/Content.Server/Weapon/Ranged/Ammunition/Components/AmmoComponent.cs
index a12ca95d19..4481e6a1a5 100644
--- a/Content.Server/Weapon/Ranged/Ammunition/Components/AmmoComponent.cs
+++ b/Content.Server/Weapon/Ranged/Ammunition/Components/AmmoComponent.cs
@@ -3,14 +3,18 @@ using Content.Shared.Examine;
using Content.Shared.Sound;
using Content.Shared.Weapons.Ranged.Barrels.Components;
using Robust.Server.GameObjects;
+using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -21,15 +25,10 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
/// Generally used for bullets but can be used for other things like bananas
///
[RegisterComponent]
-#pragma warning disable 618
- public class AmmoComponent : Component, IExamine, ISerializationHooks
-#pragma warning restore 618
+ [ComponentProtoName("Ammo")]
+ [Friend(typeof(GunSystem))]
+ public sealed class AmmoComponent : Component, ISerializationHooks
{
- [Dependency] private readonly IEntityManager _entMan = default!;
- [Dependency] private readonly IGameTiming _gameTiming = default!;
-
- public override string Name => "Ammo";
-
[DataField("caliber")]
public BallisticCaliber Caliber { get; } = BallisticCaliber.Unspecified;
@@ -37,22 +36,23 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
{
get
{
- if (_ammoIsProjectile)
+ if (AmmoIsProjectile)
{
return false;
}
return _spent;
}
+ set => _spent = value;
}
private bool _spent;
+ // TODO: Make it so null projectile = dis
///
/// Used for anything without a case that fires itself
///
- [DataField("isProjectile")]
- private bool _ammoIsProjectile;
+ [DataField("isProjectile")] public bool AmmoIsProjectile;
///
/// Used for something that is deleted when the projectile is retrieved
@@ -69,8 +69,8 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
[DataField("projectilesFired")]
public int ProjectilesFired { get; } = 1;
- [DataField("projectile")]
- private string? _projectileId;
+ [DataField("projectile", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string? ProjectileId;
// How far apart each entity is if multiple are shot
[DataField("ammoSpread")]
@@ -82,8 +82,8 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
[DataField("ammoVelocity")]
public float Velocity { get; } = 20f;
- [DataField("muzzleFlash")]
- private string _muzzleFlashSprite = "Objects/Weapons/Guns/Projectiles/bullet_muzzle.png";
+ [DataField("muzzleFlash", customTypeSerializer:typeof(ResourcePathSerializer))]
+ public ResourcePath? MuzzleFlashSprite = new("Objects/Weapons/Guns/Projectiles/bullet_muzzle.png");
[DataField("soundCollectionEject")]
public SoundSpecifier SoundCollectionEject { get; } = new SoundCollectionSpecifier("CasingEject");
@@ -91,7 +91,7 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
void ISerializationHooks.AfterDeserialization()
{
// Being both caseless and shooting yourself doesn't make sense
- DebugTools.Assert(!(_ammoIsProjectile == true && Caseless == true));
+ DebugTools.Assert(!(AmmoIsProjectile && Caseless));
if (ProjectilesFired < 1)
{
@@ -104,63 +104,6 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
throw new InvalidOperationException();
}
}
-
- public EntityUid? TakeBullet(EntityCoordinates spawnAt)
- {
- if (_ammoIsProjectile)
- {
- return Owner;
- }
-
- if (_spent)
- {
- return null;
- }
-
- _spent = true;
- if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
- {
- appearanceComponent.SetData(AmmoVisuals.Spent, true);
- }
-
- var entity = _entMan.SpawnEntity(_projectileId, spawnAt);
-
- return entity;
- }
-
- public void MuzzleFlash(EntityUid entity, Angle angle)
- {
- if (_muzzleFlashSprite == null)
- {
- return;
- }
-
- var time = _gameTiming.CurTime;
- var deathTime = time + TimeSpan.FromMilliseconds(200);
- // Offset the sprite so it actually looks like it's coming from the gun
- var offset = angle.ToVec().Normalized / 2;
-
- var message = new EffectSystemMessage
- {
- EffectSprite = _muzzleFlashSprite,
- Born = time,
- DeathTime = deathTime,
- AttachedEntityUid = entity,
- AttachedOffset = offset,
- //Rotated from east facing
- Rotation = (float) angle.Theta,
- Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f),
- ColorDelta = new Vector4(0, 0, 0, -1500f),
- Shaded = false
- };
- EntitySystem.Get().CreateParticle(message);
- }
-
- public void Examine(FormattedMessage message, bool inDetailsRange)
- {
- var text = Loc.GetString("ammo-component-on-examine",("caliber", Caliber));
- message.AddMarkup(text);
- }
}
public enum BallisticCaliber
diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs
index dc6012d76b..d5d6a8a17c 100644
--- a/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs
+++ b/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs
@@ -26,12 +26,11 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
[RegisterComponent]
[NetworkedComponent()]
#pragma warning disable 618
- public sealed class BoltActionBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit, IExamine
+ public sealed class BoltActionBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit
#pragma warning restore 618
{
// Originally I had this logic shared with PumpBarrel and used a couple of variables to control things
// but it felt a lot messier to play around with, especially when adding verbs
- [Dependency] private readonly IEntityManager _entities = default!;
public override string Name => "BoltActionBarrel";
@@ -111,7 +110,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
if (_unspawnedCount > 0)
{
_unspawnedCount--;
- var chamberEntity = _entities.SpawnEntity(_fillPrototype, _entities.GetComponent(Owner).Coordinates);
+ var chamberEntity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent(Owner).Coordinates);
_chamberContainer.Insert(chamberEntity);
}
}
@@ -125,7 +124,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// (Is one chambered?, is the bullet spend)
var chamber = (chamberedExists, false);
- if (chamberedExists && _entities.TryGetComponent(_chamberContainer.ContainedEntity!.Value, out var ammo))
+ if (chamberedExists && Entities.TryGetComponent(_chamberContainer.ContainedEntity!.Value, out var ammo))
{
chamber.Item2 = ammo.Spent;
}
@@ -155,7 +154,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
_chamberContainer = ContainerHelpers.EnsureContainer(Owner, $"{Name}-chamber-container");
- if (_entities.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
+ if (Entities.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
{
_appearanceComponent = appearanceComponent;
}
@@ -188,10 +187,11 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
Dirty();
}
- if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity)
- return null;
+ if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity) return null;
- return _entities.GetComponentOrNull(chamberEntity)?.TakeBullet(spawnAt);
+ var ammoComponent = Entities.GetComponentOrNull(chamberEntity);
+
+ return ammoComponent == null ? null : EntitySystem.Get().TakeBullet(ammoComponent, spawnAt);
}
protected override bool WeaponCanFire()
@@ -229,7 +229,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
public bool TryInsertBullet(EntityUid user, EntityUid ammo)
{
- if (!_entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
+ if (!Entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
{
return false;
}
@@ -297,7 +297,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
{
return false;
}
- if (!_entities.GetComponent(chambered).Caseless)
+ if (!Entities.GetComponent(chambered).Caseless)
{
EjectCasing(chambered);
}
@@ -321,7 +321,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
else if (_unspawnedCount > 0)
{
_unspawnedCount--;
- var ammoEntity = _entities.SpawnEntity(_fillPrototype, _entities.GetComponent(Owner).Coordinates);
+ var ammoEntity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent(Owner).Coordinates);
_chamberContainer.Insert(ammoEntity);
return true;
}
diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs
index 6b90cf9917..ebfd57b9ce 100644
--- a/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs
+++ b/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs
@@ -27,8 +27,6 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
[NetworkedComponent()]
public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit, ISerializationHooks
{
- [Dependency] private readonly IEntityManager _entMan = default!;
-
public override string Name => "PumpBarrel";
public override int ShotsLeft
@@ -87,7 +85,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// (Is one chambered?, is the bullet spend)
var chamber = (chamberedExists, false);
- if (chamberedExists && _entMan.TryGetComponent(_chamberContainer.ContainedEntity!.Value, out var ammo))
+ if (chamberedExists && Entities.TryGetComponent(_chamberContainer.ContainedEntity!.Value, out var ammo))
{
chamber.Item2 = ammo.Spent;
}
@@ -126,7 +124,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
_unspawnedCount--;
}
- if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
+ if (Entities.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
{
_appearanceComponent = appearanceComponent;
}
@@ -158,10 +156,11 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
Dirty();
}
- if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity)
- return null;
+ if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity) return null;
- return _entMan.GetComponentOrNull(chamberEntity)?.TakeBullet(spawnAt);
+ var ammoComponent = Entities.GetComponentOrNull(chamberEntity);
+
+ return ammoComponent == null ? null : EntitySystem.Get().TakeBullet(ammoComponent, spawnAt);
}
private void Cycle(bool manual = false)
@@ -169,7 +168,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
if (_chamberContainer.ContainedEntity is {Valid: true} chamberedEntity)
{
_chamberContainer.Remove(chamberedEntity);
- var ammoComponent = _entMan.GetComponent(chamberedEntity);
+ var ammoComponent = Entities.GetComponent(chamberedEntity);
if (!ammoComponent.Caseless)
{
EjectCasing(chamberedEntity);
@@ -185,7 +184,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
if (_unspawnedCount > 0)
{
_unspawnedCount--;
- var ammoEntity = _entMan.SpawnEntity(_fillPrototype, _entMan.GetComponent(Owner).Coordinates);
+ var ammoEntity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent(Owner).Coordinates);
_chamberContainer.Insert(ammoEntity);
}
@@ -200,7 +199,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
public bool TryInsertBullet(InteractUsingEventArgs eventArgs)
{
- if (!_entMan.TryGetComponent(eventArgs.Using, out AmmoComponent? ammoComponent))
+ if (!Entities.TryGetComponent(eventArgs.Using, out AmmoComponent? ammoComponent))
{
return false;
}
diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs
index 6966a64f88..07ec5d877f 100644
--- a/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs
+++ b/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs
@@ -24,7 +24,6 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
[NetworkedComponent()]
public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, ISerializationHooks
{
- [Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IRobustRandom _random = default!;
public override string Name => "RevolverBarrel";
@@ -82,7 +81,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
{
slotsSpent[i] = null;
var ammoEntity = _ammoSlots[i];
- if (ammoEntity != default && _entMan.TryGetComponent(ammoEntity, out AmmoComponent? ammo))
+ if (ammoEntity != default && Entities.TryGetComponent(ammoEntity, out AmmoComponent? ammo))
{
slotsSpent[i] = ammo.Spent;
}
@@ -114,7 +113,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
for (var i = 0; i < _unspawnedCount; i++)
{
- var entity = _entMan.SpawnEntity(_fillPrototype, _entMan.GetComponent(Owner).Coordinates);
+ var entity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent(Owner).Coordinates);
_ammoSlots[idx] = entity;
_ammoContainer.Insert(entity);
idx++;
@@ -126,7 +125,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
private void UpdateAppearance()
{
- if (!_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance))
+ if (!Entities.TryGetComponent(Owner, out AppearanceComponent? appearance))
{
return;
}
@@ -139,7 +138,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
public bool TryInsertBullet(EntityUid user, EntityUid entity)
{
- if (!_entMan.TryGetComponent(entity, out AmmoComponent? ammoComponent))
+ if (!Entities.TryGetComponent(entity, out AmmoComponent? ammoComponent))
{
return false;
}
@@ -209,8 +208,8 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
EntityUid? bullet = null;
if (ammo != default)
{
- var ammoComponent = _entMan.GetComponent(ammo);
- bullet = ammoComponent.TakeBullet(spawnAt);
+ var ammoComponent = Entities.GetComponent(ammo);
+ bullet = EntitySystem.Get().TakeBullet(ammoComponent, spawnAt);
if (ammoComponent.Caseless)
{
_ammoSlots[_currentSlot] = default;
diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs
index 7e0a30b51f..243d3b1ad6 100644
--- a/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs
+++ b/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs
@@ -205,7 +205,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
var entity = _chamberContainer.ContainedEntity ?? default;
Cycle();
- return entity != default ? _entities.GetComponent(entity).TakeBullet(spawnAt) : null;
+ return entity != default ? EntitySystem.Get().TakeBullet(_entities.GetComponent(entity), spawnAt) : null;
}
private void Cycle(bool manual = false)
diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs
index 6577172f3a..0f84af3763 100644
--- a/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs
+++ b/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs
@@ -42,7 +42,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// it's just when I re-organised it changed me as the contributor
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
- [Dependency] private readonly IEntityManager _entities = default!;
+ [Dependency] protected readonly IEntityManager Entities = default!;
public override FireRateSelector FireRateSelector => _fireRateSelector;
@@ -147,7 +147,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
protected override void OnRemove()
{
base.OnRemove();
- if (_entities.TryGetComponent(Owner, out ServerRangedWeaponComponent? rangedWeaponComponent))
+ if (Entities.TryGetComponent(Owner, out ServerRangedWeaponComponent? rangedWeaponComponent))
{
rangedWeaponComponent.Barrel = null;
rangedWeaponComponent.FireHandler -= Fire;
@@ -198,39 +198,39 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
}
var ammo = PeekAmmo();
- if (TakeProjectile(_entities.GetComponent(shooter).Coordinates) is not {Valid: true} projectile)
+ if (TakeProjectile(Entities.GetComponent(shooter).Coordinates) is not {Valid: true} projectile)
{
SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner);
return;
}
// At this point firing is confirmed
- var direction = (targetPos - _entities.GetComponent(shooter).WorldPosition).ToAngle();
+ var direction = (targetPos - Entities.GetComponent(shooter).WorldPosition).ToAngle();
var angle = GetRecoilAngle(direction);
// This should really be client-side but for now we'll just leave it here
- if (_entities.TryGetComponent(shooter, out CameraRecoilComponent? recoilComponent))
+ if (Entities.TryGetComponent(shooter, out CameraRecoilComponent? recoilComponent))
{
recoilComponent.Kick(-angle.ToVec() * 0.15f);
}
// This section probably needs tweaking so there can be caseless hitscan etc.
- if (_entities.TryGetComponent(projectile, out HitscanComponent? hitscan))
+ if (Entities.TryGetComponent(projectile, out HitscanComponent? hitscan))
{
FireHitscan(shooter, hitscan, angle);
}
- else if (_entities.HasComponent(projectile) &&
- _entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
+ else if (Entities.HasComponent(projectile) &&
+ Entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
{
FireProjectiles(shooter, projectile, ammoComponent.ProjectilesFired, ammoComponent.EvenSpreadAngle, angle, ammoComponent.Velocity, ammo.Value);
if (CanMuzzleFlash)
{
- ammoComponent.MuzzleFlash(Owner, angle);
+ EntitySystem.Get().MuzzleFlash(Owner, ammoComponent, angle);
}
if (ammoComponent.Caseless)
{
- _entities.DeleteEntity(ammo.Value);
+ Entities.DeleteEntity(ammo.Value);
}
}
else
@@ -324,9 +324,9 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
}
else
{
- projectile = _entities.SpawnEntity(
- _entities.GetComponent(baseProjectile).EntityPrototype?.ID,
- _entities.GetComponent(baseProjectile).Coordinates);
+ projectile = Entities.SpawnEntity(
+ Entities.GetComponent(baseProjectile).EntityPrototype?.ID,
+ Entities.GetComponent(baseProjectile).Coordinates);
}
firedProjectiles[i] = projectile;
@@ -342,10 +342,10 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
projectileAngle = angle;
}
- var physics = _entities.GetComponent(projectile);
+ var physics = Entities.GetComponent(projectile);
physics.BodyStatus = BodyStatus.InAir;
- var projectileComponent = _entities.GetComponent(projectile);
+ var projectileComponent = Entities.GetComponent(projectile);
projectileComponent.IgnoreEntity(shooter);
// FIXME: Work around issue where inserting and removing an entity from a container,
@@ -353,16 +353,16 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// See SharedBroadphaseSystem.HandleContainerInsert()... It sets Awake to false, which causes this.
projectile.SpawnTimer(TimeSpan.FromMilliseconds(25), () =>
{
- _entities.GetComponent(projectile)
+ Entities.GetComponent(projectile)
.LinearVelocity = projectileAngle.ToVec() * velocity;
});
- _entities.GetComponent(projectile).WorldRotation = projectileAngle + MathHelper.PiOver2;
+ Entities.GetComponent(projectile).WorldRotation = projectileAngle + MathHelper.PiOver2;
}
- _entities.EventBus.RaiseLocalEvent(Owner, new GunShotEvent(firedProjectiles));
- _entities.EventBus.RaiseLocalEvent(ammo, new AmmoShotEvent(firedProjectiles));
+ Entities.EventBus.RaiseLocalEvent(Owner, new GunShotEvent(firedProjectiles));
+ Entities.EventBus.RaiseLocalEvent(ammo, new AmmoShotEvent(firedProjectiles));
}
///
@@ -386,9 +386,9 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
///
private void FireHitscan(EntityUid shooter, HitscanComponent hitscan, Angle angle)
{
- var ray = new CollisionRay(_entities.GetComponent(Owner).Coordinates.ToMapPos(_entities), angle.ToVec(), (int) hitscan.CollisionMask);
+ var ray = new CollisionRay(Entities.GetComponent(Owner).Coordinates.ToMapPos(Entities), angle.ToVec(), (int) hitscan.CollisionMask);
var physicsManager = EntitySystem.Get();
- var rayCastResults = physicsManager.IntersectRay(_entities.GetComponent(Owner).MapID, ray, hitscan.MaxLength, shooter, false).ToList();
+ var rayCastResults = physicsManager.IntersectRay(Entities.GetComponent(Owner).MapID, ray, hitscan.MaxLength, shooter, false).ToList();
if (rayCastResults.Count >= 1)
{
@@ -398,7 +398,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
var dmg = EntitySystem.Get().TryChangeDamage(result.HitEntity, hitscan.Damage);
if (dmg != null)
EntitySystem.Get().Add(LogType.HitScanHit,
- $"{_entities.ToPrettyString(shooter):user} hit {_entities.ToPrettyString(result.HitEntity):target} using {_entities.ToPrettyString(hitscan.Owner):used} and dealt {dmg.Total:damage} damage");
+ $"{Entities.ToPrettyString(shooter):user} hit {Entities.ToPrettyString(result.HitEntity):target} using {Entities.ToPrettyString(hitscan.Owner):used} and dealt {dmg.Total:damage} damage");
}
else
{
diff --git a/Content.Server/Weapon/Ranged/GunSystem.Ammo.cs b/Content.Server/Weapon/Ranged/GunSystem.Ammo.cs
new file mode 100644
index 0000000000..23b36b4201
--- /dev/null
+++ b/Content.Server/Weapon/Ranged/GunSystem.Ammo.cs
@@ -0,0 +1,95 @@
+using System;
+using Content.Server.Weapon.Ranged.Ammunition.Components;
+using Content.Shared.Examine;
+using Content.Shared.Weapons.Ranged.Barrels.Components;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Localization;
+using Robust.Shared.Map;
+using Robust.Shared.Maths;
+
+namespace Content.Server.Weapon.Ranged;
+
+public sealed partial class GunSystem
+{
+ private void OnAmmoExamine(EntityUid uid, AmmoComponent component, ExaminedEvent args)
+ {
+ var text = Loc.GetString("ammo-component-on-examine",("caliber", component.Caliber));
+ args.PushMarkup(text);
+ }
+
+ public EntityUid? TakeBullet(AmmoComponent component, EntityCoordinates spawnAt)
+ {
+ if (component.AmmoIsProjectile)
+ {
+ return component.Owner;
+ }
+
+ if (component.Spent)
+ {
+ return null;
+ }
+
+ component.Spent = true;
+
+ if (TryComp(component.Owner, out AppearanceComponent? appearanceComponent))
+ {
+ appearanceComponent.SetData(AmmoVisuals.Spent, true);
+ }
+
+ var entity = EntityManager.SpawnEntity(component.ProjectileId, spawnAt);
+
+ return entity;
+ }
+
+ public void MuzzleFlash(EntityUid entity, AmmoComponent component, Angle angle)
+ {
+ if (component.MuzzleFlashSprite == null)
+ {
+ return;
+ }
+
+ var time = _gameTiming.CurTime;
+ var deathTime = time + TimeSpan.FromMilliseconds(200);
+ // Offset the sprite so it actually looks like it's coming from the gun
+ var offset = new Vector2(0.0f, -0.5f);
+
+ var message = new EffectSystemMessage
+ {
+ EffectSprite = component.MuzzleFlashSprite.ToString(),
+ Born = time,
+ DeathTime = deathTime,
+ AttachedEntityUid = entity,
+ AttachedOffset = offset,
+ //Rotated from east facing
+ Rotation = -MathF.PI / 2f,
+ Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f),
+ ColorDelta = new Vector4(0, 0, 0, -1500f),
+ Shaded = false
+ };
+
+ /* TODO: Fix rotation when shooting sideways. This was the closest I got but still had issues.
+ * var time = _gameTiming.CurTime;
+ var deathTime = time + TimeSpan.FromMilliseconds(200);
+ var entityRotation = EntityManager.GetComponent(entity).WorldRotation;
+ var localAngle = entityRotation - (angle + MathF.PI / 2f);
+ // Offset the sprite so it actually looks like it's coming from the gun
+ var offset = localAngle.RotateVec(new Vector2(0.0f, -0.5f));
+
+ var message = new EffectSystemMessage
+ {
+ EffectSprite = component.MuzzleFlashSprite.ToString(),
+ Born = time,
+ DeathTime = deathTime,
+ AttachedEntityUid = entity,
+ AttachedOffset = offset,
+ //Rotated from east facing
+ Rotation = (float) (localAngle - MathF.PI / 2),
+ Color = Vector4.Multiply(new Vector4(255, 255, 255, 255), 1.0f),
+ ColorDelta = new Vector4(0, 0, 0, -1500f),
+ Shaded = false
+ };
+ */
+
+ _effects.CreateParticle(message);
+ }
+}
diff --git a/Content.Server/Weapon/Ranged/GunSystem.AmmoBox.cs b/Content.Server/Weapon/Ranged/GunSystem.AmmoBox.cs
index d9c5024f41..e93cc22db2 100644
--- a/Content.Server/Weapon/Ranged/GunSystem.AmmoBox.cs
+++ b/Content.Server/Weapon/Ranged/GunSystem.AmmoBox.cs
@@ -19,20 +19,6 @@ public sealed partial class GunSystem
{
// Probably needs combining with magazines in future given the common functionality.
- public override void Initialize()
- {
- base.Initialize();
-
- SubscribeLocalEvent(OnAmmoBoxInit);
- SubscribeLocalEvent(OnAmmoBoxMapInit);
- SubscribeLocalEvent(OnAmmoBoxExamine);
-
- SubscribeLocalEvent(OnAmmoBoxInteractUsing);
- SubscribeLocalEvent(OnAmmoBoxUse);
- SubscribeLocalEvent(OnAmmoBoxInteractHand);
- SubscribeLocalEvent(OnAmmoBoxAltVerbs);
- }
-
private void OnAmmoBoxAltVerbs(EntityUid uid, AmmoBoxComponent component, GetAlternativeVerbsEvent args)
{
if (args.Hands == null || !args.CanAccess || !args.CanInteract)
diff --git a/Content.Server/Weapon/Ranged/GunSystem.cs b/Content.Server/Weapon/Ranged/GunSystem.cs
index 872a37ff1d..56e0c495b0 100644
--- a/Content.Server/Weapon/Ranged/GunSystem.cs
+++ b/Content.Server/Weapon/Ranged/GunSystem.cs
@@ -1,10 +1,34 @@
+using Content.Server.Weapon.Ranged.Ammunition.Components;
+using Content.Shared.Examine;
+using Content.Shared.Interaction;
using Content.Shared.Popups;
+using Content.Shared.Verbs;
+using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
+using Robust.Shared.Timing;
namespace Content.Server.Weapon.Ranged;
public sealed partial class GunSystem : EntitySystem
{
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+ [Dependency] private readonly EffectSystem _effects = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnAmmoExamine);
+
+ SubscribeLocalEvent(OnAmmoBoxInit);
+ SubscribeLocalEvent(OnAmmoBoxMapInit);
+ SubscribeLocalEvent(OnAmmoBoxExamine);
+
+ SubscribeLocalEvent(OnAmmoBoxInteractUsing);
+ SubscribeLocalEvent(OnAmmoBoxUse);
+ SubscribeLocalEvent(OnAmmoBoxInteractHand);
+ SubscribeLocalEvent(OnAmmoBoxAltVerbs);
+ }
}