Requires https://github.com/space-wizards/space-station-14/pull/768 - [x] Play sounds - [x] SoundSchedules actually work - [x] Send sound to specific users - [x] Make existing components use SoundComponent - [x] Add ScheduledSounds from prototypes - [x] Add Play methods equivalent to those of AudioSystem. - [x] Document most code.
127 lines
3.6 KiB
C#
127 lines
3.6 KiB
C#
using System;
|
|
using Content.Server.GameObjects.Components.Interactable;
|
|
using Content.Server.GameObjects.Components.Sound;
|
|
using Content.Shared.GameObjects;
|
|
using SS14.Server.Chat;
|
|
using SS14.Server.GameObjects.Components.Container;
|
|
using SS14.Server.GameObjects.EntitySystems;
|
|
using SS14.Shared.Interfaces.GameObjects;
|
|
using SS14.Shared.IoC;
|
|
using SS14.Shared.Serialization;
|
|
|
|
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
|
|
{
|
|
public abstract class BallisticWeaponComponent : ProjectileWeaponComponent
|
|
{
|
|
private BallisticCaliber _caliber;
|
|
private Chamber[] _chambers;
|
|
|
|
public BallisticCaliber Caliber => _caliber;
|
|
protected abstract int ChamberCount { get; }
|
|
|
|
private string _soundGunEmpty;
|
|
|
|
public override void ExposeData(ObjectSerializer serializer)
|
|
{
|
|
base.ExposeData(serializer);
|
|
|
|
serializer.DataField(ref _caliber, "caliber", BallisticCaliber.Unspecified);
|
|
serializer.DataField(ref _soundGunEmpty, "sound_empty", null);
|
|
}
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
_chambers = new Chamber[ChamberCount];
|
|
for (var i = 0; i < _chambers.Length; i++)
|
|
{
|
|
var container = ContainerManagerComponent.Ensure<ContainerSlot>($"ballistics_chamber_{i}", Owner);
|
|
_chambers[i] = new Chamber(container);
|
|
}
|
|
}
|
|
|
|
public IEntity GetChambered(int chamber) => _chambers[chamber].Slot.ContainedEntity;
|
|
|
|
public bool LoadIntoChamber(int chamber, IEntity bullet)
|
|
{
|
|
if (!bullet.TryGetComponent(out BallisticBulletComponent component))
|
|
{
|
|
throw new ArgumentException("entity isn't a bullet.", nameof(bullet));
|
|
}
|
|
|
|
if (component.Caliber != Caliber)
|
|
{
|
|
throw new ArgumentException("entity is of the wrong caliber.", nameof(bullet));
|
|
}
|
|
|
|
if (GetChambered(chamber) != null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_chambers[chamber].Slot.Insert(bullet);
|
|
return true;
|
|
}
|
|
|
|
protected sealed override IEntity GetFiredProjectile()
|
|
{
|
|
void PlayEmpty()
|
|
{
|
|
if (_soundGunEmpty != null)
|
|
{
|
|
Owner.GetComponent<SoundComponent>().Play(_soundGunEmpty);
|
|
}
|
|
}
|
|
var chambered = GetChambered(0);
|
|
if (chambered != null)
|
|
{
|
|
var bullet = chambered.GetComponent<BallisticBulletComponent>();
|
|
if (bullet.Spent)
|
|
{
|
|
PlayEmpty();
|
|
return null;
|
|
}
|
|
|
|
var projectile = Owner.EntityManager.SpawnEntity(bullet.ProjectileType);
|
|
bullet.Spent = true;
|
|
|
|
CycleChamberedBullet(0);
|
|
|
|
// Load a new bullet into the chamber from magazine.
|
|
return projectile;
|
|
}
|
|
|
|
PlayEmpty();
|
|
return null;
|
|
}
|
|
|
|
protected virtual void CycleChamberedBullet(int chamber)
|
|
{
|
|
|
|
}
|
|
|
|
public IEntity RemoveFromChamber(int chamber)
|
|
{
|
|
var c = _chambers[chamber];
|
|
var loaded = c.Slot.ContainedEntity;
|
|
if (loaded != null)
|
|
{
|
|
c.Slot.Remove(loaded);
|
|
}
|
|
return loaded;
|
|
}
|
|
|
|
private sealed class Chamber
|
|
{
|
|
public Chamber(ContainerSlot slot)
|
|
{
|
|
Slot = slot;
|
|
}
|
|
|
|
public ContainerSlot Slot { get; }
|
|
}
|
|
|
|
}
|
|
}
|