This commit is contained in:
metalgearsloth
2021-12-23 15:46:43 +11:00
committed by GitHub
parent 00ec491f6f
commit 573e3a1744
9 changed files with 184 additions and 138 deletions

View File

@@ -3,14 +3,18 @@ using Content.Shared.Examine;
using Content.Shared.Sound; using Content.Shared.Sound;
using Content.Shared.Weapons.Ranged.Barrels.Components; using Content.Shared.Weapons.Ranged.Barrels.Components;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Log; using Robust.Shared.Log;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes; 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.Timing;
using Robust.Shared.Utility; 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 /// Generally used for bullets but can be used for other things like bananas
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent]
#pragma warning disable 618 [ComponentProtoName("Ammo")]
public class AmmoComponent : Component, IExamine, ISerializationHooks [Friend(typeof(GunSystem))]
#pragma warning restore 618 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")] [DataField("caliber")]
public BallisticCaliber Caliber { get; } = BallisticCaliber.Unspecified; public BallisticCaliber Caliber { get; } = BallisticCaliber.Unspecified;
@@ -37,22 +36,23 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
{ {
get get
{ {
if (_ammoIsProjectile) if (AmmoIsProjectile)
{ {
return false; return false;
} }
return _spent; return _spent;
} }
set => _spent = value;
} }
private bool _spent; private bool _spent;
// TODO: Make it so null projectile = dis
/// <summary> /// <summary>
/// Used for anything without a case that fires itself /// Used for anything without a case that fires itself
/// </summary> /// </summary>
[DataField("isProjectile")] [DataField("isProjectile")] public bool AmmoIsProjectile;
private bool _ammoIsProjectile;
/// <summary> /// <summary>
/// Used for something that is deleted when the projectile is retrieved /// Used for something that is deleted when the projectile is retrieved
@@ -69,8 +69,8 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
[DataField("projectilesFired")] [DataField("projectilesFired")]
public int ProjectilesFired { get; } = 1; public int ProjectilesFired { get; } = 1;
[DataField("projectile")] [DataField("projectile", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
private string? _projectileId; public string? ProjectileId;
// How far apart each entity is if multiple are shot // How far apart each entity is if multiple are shot
[DataField("ammoSpread")] [DataField("ammoSpread")]
@@ -82,8 +82,8 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
[DataField("ammoVelocity")] [DataField("ammoVelocity")]
public float Velocity { get; } = 20f; public float Velocity { get; } = 20f;
[DataField("muzzleFlash")] [DataField("muzzleFlash", customTypeSerializer:typeof(ResourcePathSerializer))]
private string _muzzleFlashSprite = "Objects/Weapons/Guns/Projectiles/bullet_muzzle.png"; public ResourcePath? MuzzleFlashSprite = new("Objects/Weapons/Guns/Projectiles/bullet_muzzle.png");
[DataField("soundCollectionEject")] [DataField("soundCollectionEject")]
public SoundSpecifier SoundCollectionEject { get; } = new SoundCollectionSpecifier("CasingEject"); public SoundSpecifier SoundCollectionEject { get; } = new SoundCollectionSpecifier("CasingEject");
@@ -91,7 +91,7 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
void ISerializationHooks.AfterDeserialization() void ISerializationHooks.AfterDeserialization()
{ {
// Being both caseless and shooting yourself doesn't make sense // Being both caseless and shooting yourself doesn't make sense
DebugTools.Assert(!(_ammoIsProjectile == true && Caseless == true)); DebugTools.Assert(!(AmmoIsProjectile && Caseless));
if (ProjectilesFired < 1) if (ProjectilesFired < 1)
{ {
@@ -104,63 +104,6 @@ namespace Content.Server.Weapon.Ranged.Ammunition.Components
throw new InvalidOperationException(); 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<EffectSystem>().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 public enum BallisticCaliber

View File

@@ -26,12 +26,11 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
[RegisterComponent] [RegisterComponent]
[NetworkedComponent()] [NetworkedComponent()]
#pragma warning disable 618 #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 #pragma warning restore 618
{ {
// Originally I had this logic shared with PumpBarrel and used a couple of variables to control things // 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 // 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"; public override string Name => "BoltActionBarrel";
@@ -111,7 +110,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
if (_unspawnedCount > 0) if (_unspawnedCount > 0)
{ {
_unspawnedCount--; _unspawnedCount--;
var chamberEntity = _entities.SpawnEntity(_fillPrototype, _entities.GetComponent<TransformComponent>(Owner).Coordinates); var chamberEntity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent<TransformComponent>(Owner).Coordinates);
_chamberContainer.Insert(chamberEntity); _chamberContainer.Insert(chamberEntity);
} }
} }
@@ -125,7 +124,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// (Is one chambered?, is the bullet spend) // (Is one chambered?, is the bullet spend)
var chamber = (chamberedExists, false); var chamber = (chamberedExists, false);
if (chamberedExists && _entities.TryGetComponent<AmmoComponent?>(_chamberContainer.ContainedEntity!.Value, out var ammo)) if (chamberedExists && Entities.TryGetComponent<AmmoComponent?>(_chamberContainer.ContainedEntity!.Value, out var ammo))
{ {
chamber.Item2 = ammo.Spent; chamber.Item2 = ammo.Spent;
} }
@@ -155,7 +154,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
_chamberContainer = ContainerHelpers.EnsureContainer<ContainerSlot>(Owner, $"{Name}-chamber-container"); _chamberContainer = ContainerHelpers.EnsureContainer<ContainerSlot>(Owner, $"{Name}-chamber-container");
if (_entities.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent)) if (Entities.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
{ {
_appearanceComponent = appearanceComponent; _appearanceComponent = appearanceComponent;
} }
@@ -188,10 +187,11 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
Dirty(); Dirty();
} }
if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity) if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity) return null;
return null;
return _entities.GetComponentOrNull<AmmoComponent>(chamberEntity)?.TakeBullet(spawnAt); var ammoComponent = Entities.GetComponentOrNull<AmmoComponent>(chamberEntity);
return ammoComponent == null ? null : EntitySystem.Get<GunSystem>().TakeBullet(ammoComponent, spawnAt);
} }
protected override bool WeaponCanFire() protected override bool WeaponCanFire()
@@ -229,7 +229,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
public bool TryInsertBullet(EntityUid user, EntityUid ammo) public bool TryInsertBullet(EntityUid user, EntityUid ammo)
{ {
if (!_entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent)) if (!Entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
{ {
return false; return false;
} }
@@ -297,7 +297,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
{ {
return false; return false;
} }
if (!_entities.GetComponent<AmmoComponent>(chambered).Caseless) if (!Entities.GetComponent<AmmoComponent>(chambered).Caseless)
{ {
EjectCasing(chambered); EjectCasing(chambered);
} }
@@ -321,7 +321,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
else if (_unspawnedCount > 0) else if (_unspawnedCount > 0)
{ {
_unspawnedCount--; _unspawnedCount--;
var ammoEntity = _entities.SpawnEntity(_fillPrototype, _entities.GetComponent<TransformComponent>(Owner).Coordinates); var ammoEntity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent<TransformComponent>(Owner).Coordinates);
_chamberContainer.Insert(ammoEntity); _chamberContainer.Insert(ammoEntity);
return true; return true;
} }

View File

@@ -27,8 +27,6 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
[NetworkedComponent()] [NetworkedComponent()]
public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit, ISerializationHooks public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit, ISerializationHooks
{ {
[Dependency] private readonly IEntityManager _entMan = default!;
public override string Name => "PumpBarrel"; public override string Name => "PumpBarrel";
public override int ShotsLeft public override int ShotsLeft
@@ -87,7 +85,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// (Is one chambered?, is the bullet spend) // (Is one chambered?, is the bullet spend)
var chamber = (chamberedExists, false); var chamber = (chamberedExists, false);
if (chamberedExists && _entMan.TryGetComponent<AmmoComponent?>(_chamberContainer.ContainedEntity!.Value, out var ammo)) if (chamberedExists && Entities.TryGetComponent<AmmoComponent?>(_chamberContainer.ContainedEntity!.Value, out var ammo))
{ {
chamber.Item2 = ammo.Spent; chamber.Item2 = ammo.Spent;
} }
@@ -126,7 +124,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
_unspawnedCount--; _unspawnedCount--;
} }
if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent)) if (Entities.TryGetComponent(Owner, out AppearanceComponent? appearanceComponent))
{ {
_appearanceComponent = appearanceComponent; _appearanceComponent = appearanceComponent;
} }
@@ -158,10 +156,11 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
Dirty(); Dirty();
} }
if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity) if (_chamberContainer.ContainedEntity is not {Valid: true} chamberEntity) return null;
return null;
return _entMan.GetComponentOrNull<AmmoComponent>(chamberEntity)?.TakeBullet(spawnAt); var ammoComponent = Entities.GetComponentOrNull<AmmoComponent>(chamberEntity);
return ammoComponent == null ? null : EntitySystem.Get<GunSystem>().TakeBullet(ammoComponent, spawnAt);
} }
private void Cycle(bool manual = false) private void Cycle(bool manual = false)
@@ -169,7 +168,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
if (_chamberContainer.ContainedEntity is {Valid: true} chamberedEntity) if (_chamberContainer.ContainedEntity is {Valid: true} chamberedEntity)
{ {
_chamberContainer.Remove(chamberedEntity); _chamberContainer.Remove(chamberedEntity);
var ammoComponent = _entMan.GetComponent<AmmoComponent>(chamberedEntity); var ammoComponent = Entities.GetComponent<AmmoComponent>(chamberedEntity);
if (!ammoComponent.Caseless) if (!ammoComponent.Caseless)
{ {
EjectCasing(chamberedEntity); EjectCasing(chamberedEntity);
@@ -185,7 +184,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
if (_unspawnedCount > 0) if (_unspawnedCount > 0)
{ {
_unspawnedCount--; _unspawnedCount--;
var ammoEntity = _entMan.SpawnEntity(_fillPrototype, _entMan.GetComponent<TransformComponent>(Owner).Coordinates); var ammoEntity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent<TransformComponent>(Owner).Coordinates);
_chamberContainer.Insert(ammoEntity); _chamberContainer.Insert(ammoEntity);
} }
@@ -200,7 +199,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
public bool TryInsertBullet(InteractUsingEventArgs eventArgs) public bool TryInsertBullet(InteractUsingEventArgs eventArgs)
{ {
if (!_entMan.TryGetComponent(eventArgs.Using, out AmmoComponent? ammoComponent)) if (!Entities.TryGetComponent(eventArgs.Using, out AmmoComponent? ammoComponent))
{ {
return false; return false;
} }

View File

@@ -24,7 +24,6 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
[NetworkedComponent()] [NetworkedComponent()]
public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, ISerializationHooks public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, ISerializationHooks
{ {
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
public override string Name => "RevolverBarrel"; public override string Name => "RevolverBarrel";
@@ -82,7 +81,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
{ {
slotsSpent[i] = null; slotsSpent[i] = null;
var ammoEntity = _ammoSlots[i]; 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; slotsSpent[i] = ammo.Spent;
} }
@@ -114,7 +113,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
for (var i = 0; i < _unspawnedCount; i++) for (var i = 0; i < _unspawnedCount; i++)
{ {
var entity = _entMan.SpawnEntity(_fillPrototype, _entMan.GetComponent<TransformComponent>(Owner).Coordinates); var entity = Entities.SpawnEntity(_fillPrototype, Entities.GetComponent<TransformComponent>(Owner).Coordinates);
_ammoSlots[idx] = entity; _ammoSlots[idx] = entity;
_ammoContainer.Insert(entity); _ammoContainer.Insert(entity);
idx++; idx++;
@@ -126,7 +125,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
private void UpdateAppearance() private void UpdateAppearance()
{ {
if (!_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance)) if (!Entities.TryGetComponent(Owner, out AppearanceComponent? appearance))
{ {
return; return;
} }
@@ -139,7 +138,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
public bool TryInsertBullet(EntityUid user, EntityUid entity) public bool TryInsertBullet(EntityUid user, EntityUid entity)
{ {
if (!_entMan.TryGetComponent(entity, out AmmoComponent? ammoComponent)) if (!Entities.TryGetComponent(entity, out AmmoComponent? ammoComponent))
{ {
return false; return false;
} }
@@ -209,8 +208,8 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
EntityUid? bullet = null; EntityUid? bullet = null;
if (ammo != default) if (ammo != default)
{ {
var ammoComponent = _entMan.GetComponent<AmmoComponent>(ammo); var ammoComponent = Entities.GetComponent<AmmoComponent>(ammo);
bullet = ammoComponent.TakeBullet(spawnAt); bullet = EntitySystem.Get<GunSystem>().TakeBullet(ammoComponent, spawnAt);
if (ammoComponent.Caseless) if (ammoComponent.Caseless)
{ {
_ammoSlots[_currentSlot] = default; _ammoSlots[_currentSlot] = default;

View File

@@ -205,7 +205,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
var entity = _chamberContainer.ContainedEntity ?? default; var entity = _chamberContainer.ContainedEntity ?? default;
Cycle(); Cycle();
return entity != default ? _entities.GetComponent<AmmoComponent>(entity).TakeBullet(spawnAt) : null; return entity != default ? EntitySystem.Get<GunSystem>().TakeBullet(_entities.GetComponent<AmmoComponent>(entity), spawnAt) : null;
} }
private void Cycle(bool manual = false) private void Cycle(bool manual = false)

View File

@@ -42,7 +42,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
// it's just when I re-organised it changed me as the contributor // it's just when I re-organised it changed me as the contributor
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly IEntityManager _entities = default!; [Dependency] protected readonly IEntityManager Entities = default!;
public override FireRateSelector FireRateSelector => _fireRateSelector; public override FireRateSelector FireRateSelector => _fireRateSelector;
@@ -147,7 +147,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
protected override void OnRemove() protected override void OnRemove()
{ {
base.OnRemove(); base.OnRemove();
if (_entities.TryGetComponent(Owner, out ServerRangedWeaponComponent? rangedWeaponComponent)) if (Entities.TryGetComponent(Owner, out ServerRangedWeaponComponent? rangedWeaponComponent))
{ {
rangedWeaponComponent.Barrel = null; rangedWeaponComponent.Barrel = null;
rangedWeaponComponent.FireHandler -= Fire; rangedWeaponComponent.FireHandler -= Fire;
@@ -198,39 +198,39 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
} }
var ammo = PeekAmmo(); var ammo = PeekAmmo();
if (TakeProjectile(_entities.GetComponent<TransformComponent>(shooter).Coordinates) is not {Valid: true} projectile) if (TakeProjectile(Entities.GetComponent<TransformComponent>(shooter).Coordinates) is not {Valid: true} projectile)
{ {
SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner); SoundSystem.Play(Filter.Broadcast(), SoundEmpty.GetSound(), Owner);
return; return;
} }
// At this point firing is confirmed // At this point firing is confirmed
var direction = (targetPos - _entities.GetComponent<TransformComponent>(shooter).WorldPosition).ToAngle(); var direction = (targetPos - Entities.GetComponent<TransformComponent>(shooter).WorldPosition).ToAngle();
var angle = GetRecoilAngle(direction); var angle = GetRecoilAngle(direction);
// This should really be client-side but for now we'll just leave it here // 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); recoilComponent.Kick(-angle.ToVec() * 0.15f);
} }
// This section probably needs tweaking so there can be caseless hitscan etc. // 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); FireHitscan(shooter, hitscan, angle);
} }
else if (_entities.HasComponent<ProjectileComponent>(projectile) && else if (Entities.HasComponent<ProjectileComponent>(projectile) &&
_entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent)) Entities.TryGetComponent(ammo, out AmmoComponent? ammoComponent))
{ {
FireProjectiles(shooter, projectile, ammoComponent.ProjectilesFired, ammoComponent.EvenSpreadAngle, angle, ammoComponent.Velocity, ammo.Value); FireProjectiles(shooter, projectile, ammoComponent.ProjectilesFired, ammoComponent.EvenSpreadAngle, angle, ammoComponent.Velocity, ammo.Value);
if (CanMuzzleFlash) if (CanMuzzleFlash)
{ {
ammoComponent.MuzzleFlash(Owner, angle); EntitySystem.Get<GunSystem>().MuzzleFlash(Owner, ammoComponent, angle);
} }
if (ammoComponent.Caseless) if (ammoComponent.Caseless)
{ {
_entities.DeleteEntity(ammo.Value); Entities.DeleteEntity(ammo.Value);
} }
} }
else else
@@ -324,9 +324,9 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
} }
else else
{ {
projectile = _entities.SpawnEntity( projectile = Entities.SpawnEntity(
_entities.GetComponent<MetaDataComponent>(baseProjectile).EntityPrototype?.ID, Entities.GetComponent<MetaDataComponent>(baseProjectile).EntityPrototype?.ID,
_entities.GetComponent<TransformComponent>(baseProjectile).Coordinates); Entities.GetComponent<TransformComponent>(baseProjectile).Coordinates);
} }
firedProjectiles[i] = projectile; firedProjectiles[i] = projectile;
@@ -342,10 +342,10 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
projectileAngle = angle; projectileAngle = angle;
} }
var physics = _entities.GetComponent<IPhysBody>(projectile); var physics = Entities.GetComponent<IPhysBody>(projectile);
physics.BodyStatus = BodyStatus.InAir; physics.BodyStatus = BodyStatus.InAir;
var projectileComponent = _entities.GetComponent<ProjectileComponent>(projectile); var projectileComponent = Entities.GetComponent<ProjectileComponent>(projectile);
projectileComponent.IgnoreEntity(shooter); projectileComponent.IgnoreEntity(shooter);
// FIXME: Work around issue where inserting and removing an entity from a container, // 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. // See SharedBroadphaseSystem.HandleContainerInsert()... It sets Awake to false, which causes this.
projectile.SpawnTimer(TimeSpan.FromMilliseconds(25), () => projectile.SpawnTimer(TimeSpan.FromMilliseconds(25), () =>
{ {
_entities.GetComponent<IPhysBody>(projectile) Entities.GetComponent<IPhysBody>(projectile)
.LinearVelocity = projectileAngle.ToVec() * velocity; .LinearVelocity = projectileAngle.ToVec() * velocity;
}); });
_entities.GetComponent<TransformComponent>(projectile).WorldRotation = projectileAngle + MathHelper.PiOver2; Entities.GetComponent<TransformComponent>(projectile).WorldRotation = projectileAngle + MathHelper.PiOver2;
} }
_entities.EventBus.RaiseLocalEvent(Owner, new GunShotEvent(firedProjectiles)); Entities.EventBus.RaiseLocalEvent(Owner, new GunShotEvent(firedProjectiles));
_entities.EventBus.RaiseLocalEvent(ammo, new AmmoShotEvent(firedProjectiles)); Entities.EventBus.RaiseLocalEvent(ammo, new AmmoShotEvent(firedProjectiles));
} }
/// <summary> /// <summary>
@@ -386,9 +386,9 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
/// </summary> /// </summary>
private void FireHitscan(EntityUid shooter, HitscanComponent hitscan, Angle angle) private void FireHitscan(EntityUid shooter, HitscanComponent hitscan, Angle angle)
{ {
var ray = new CollisionRay(_entities.GetComponent<TransformComponent>(Owner).Coordinates.ToMapPos(_entities), angle.ToVec(), (int) hitscan.CollisionMask); var ray = new CollisionRay(Entities.GetComponent<TransformComponent>(Owner).Coordinates.ToMapPos(Entities), angle.ToVec(), (int) hitscan.CollisionMask);
var physicsManager = EntitySystem.Get<SharedPhysicsSystem>(); var physicsManager = EntitySystem.Get<SharedPhysicsSystem>();
var rayCastResults = physicsManager.IntersectRay(_entities.GetComponent<TransformComponent>(Owner).MapID, ray, hitscan.MaxLength, shooter, false).ToList(); var rayCastResults = physicsManager.IntersectRay(Entities.GetComponent<TransformComponent>(Owner).MapID, ray, hitscan.MaxLength, shooter, false).ToList();
if (rayCastResults.Count >= 1) if (rayCastResults.Count >= 1)
{ {
@@ -398,7 +398,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
var dmg = EntitySystem.Get<DamageableSystem>().TryChangeDamage(result.HitEntity, hitscan.Damage); var dmg = EntitySystem.Get<DamageableSystem>().TryChangeDamage(result.HitEntity, hitscan.Damage);
if (dmg != null) if (dmg != null)
EntitySystem.Get<AdminLogSystem>().Add(LogType.HitScanHit, EntitySystem.Get<AdminLogSystem>().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 else
{ {

View File

@@ -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<TransformComponent>(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);
}
}

View File

@@ -19,20 +19,6 @@ public sealed partial class GunSystem
{ {
// Probably needs combining with magazines in future given the common functionality. // Probably needs combining with magazines in future given the common functionality.
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AmmoBoxComponent, ComponentInit>(OnAmmoBoxInit);
SubscribeLocalEvent<AmmoBoxComponent, MapInitEvent>(OnAmmoBoxMapInit);
SubscribeLocalEvent<AmmoBoxComponent, ExaminedEvent>(OnAmmoBoxExamine);
SubscribeLocalEvent<AmmoBoxComponent, InteractUsingEvent>(OnAmmoBoxInteractUsing);
SubscribeLocalEvent<AmmoBoxComponent, UseInHandEvent>(OnAmmoBoxUse);
SubscribeLocalEvent<AmmoBoxComponent, InteractHandEvent>(OnAmmoBoxInteractHand);
SubscribeLocalEvent<AmmoBoxComponent, GetAlternativeVerbsEvent>(OnAmmoBoxAltVerbs);
}
private void OnAmmoBoxAltVerbs(EntityUid uid, AmmoBoxComponent component, GetAlternativeVerbsEvent args) private void OnAmmoBoxAltVerbs(EntityUid uid, AmmoBoxComponent component, GetAlternativeVerbsEvent args)
{ {
if (args.Hands == null || !args.CanAccess || !args.CanInteract) if (args.Hands == null || !args.CanAccess || !args.CanInteract)

View File

@@ -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.Popups;
using Content.Shared.Verbs;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Timing;
namespace Content.Server.Weapon.Ranged; namespace Content.Server.Weapon.Ranged;
public sealed partial class GunSystem : EntitySystem public sealed partial class GunSystem : EntitySystem
{ {
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly EffectSystem _effects = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AmmoComponent, ExaminedEvent>(OnAmmoExamine);
SubscribeLocalEvent<AmmoBoxComponent, ComponentInit>(OnAmmoBoxInit);
SubscribeLocalEvent<AmmoBoxComponent, MapInitEvent>(OnAmmoBoxMapInit);
SubscribeLocalEvent<AmmoBoxComponent, ExaminedEvent>(OnAmmoBoxExamine);
SubscribeLocalEvent<AmmoBoxComponent, InteractUsingEvent>(OnAmmoBoxInteractUsing);
SubscribeLocalEvent<AmmoBoxComponent, UseInHandEvent>(OnAmmoBoxUse);
SubscribeLocalEvent<AmmoBoxComponent, InteractHandEvent>(OnAmmoBoxInteractHand);
SubscribeLocalEvent<AmmoBoxComponent, GetAlternativeVerbsEvent>(OnAmmoBoxAltVerbs);
}
} }