Gun verb changes (#1888)

* Bolt action ver fixes

* Fixes bolt-action playing two sounds when cycling on empty magazine

* MagazineBarrel open/close bolt verb visibility

* mag stuff

* Dirty checks on guns

Co-authored-by: py01 <pyronetics01@gmail.com>
This commit is contained in:
py01
2020-08-24 05:20:11 -06:00
committed by GitHub
parent 501c8a9f6a
commit 9e6459ac79
2 changed files with 144 additions and 92 deletions

View File

@@ -69,6 +69,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
if (value) if (value)
{ {
TryEjectChamber();
if (_soundBoltOpen != null) if (_soundBoltOpen != null)
{ {
soundSystem.PlayAtCoords(_soundBoltOpen, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); soundSystem.PlayAtCoords(_soundBoltOpen, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
@@ -76,6 +77,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
else else
{ {
TryFeedChamber();
if (_soundBoltClosed != null) if (_soundBoltClosed != null)
{ {
soundSystem.PlayAtCoords(_soundBoltClosed, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); soundSystem.PlayAtCoords(_soundBoltClosed, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
@@ -84,6 +86,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
_boltOpen = value; _boltOpen = value;
UpdateAppearance(); UpdateAppearance();
Dirty();
} }
} }
private bool _boltOpen; private bool _boltOpen;
@@ -210,29 +213,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
private void Cycle(bool manual = false) private void Cycle(bool manual = false)
{ {
var chamberedEntity = _chamberContainer.ContainedEntity; TryEjectChamber();
if (chamberedEntity != null) TryFeedChamber();
{
_chamberContainer.Remove(chamberedEntity);
var ammoComponent = chamberedEntity.GetComponent<AmmoComponent>();
if (!ammoComponent.Caseless)
{
EjectCasing(chamberedEntity);
}
}
if (_spawnedAmmo.TryPop(out var next))
{
_ammoContainer.Remove(next);
_chamberContainer.Insert(next);
}
if (_unspawnedCount > 0)
{
_unspawnedCount--;
var ammoEntity = Owner.EntityManager.SpawnEntity(_fillPrototype, Owner.Transform.GridPosition);
_chamberContainer.Insert(ammoEntity);
}
if (_chamberContainer.ContainedEntity == null && manual) if (_chamberContainer.ContainedEntity == null && manual)
{ {
@@ -241,9 +223,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
Owner.PopupMessage(container.Owner, Loc.GetString("Bolt opened")); Owner.PopupMessage(container.Owner, Loc.GetString("Bolt opened"));
} }
return;
} }
else
if (manual)
{ {
if (_soundCycle != null) if (_soundCycle != null)
{ {
@@ -310,11 +292,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
BoltOpen = false; BoltOpen = false;
Owner.PopupMessage(eventArgs.User, Loc.GetString("Bolt closed")); Owner.PopupMessage(eventArgs.User, Loc.GetString("Bolt closed"));
// Dirty();
return true; return true;
} }
Cycle(true); Cycle(true);
return true; return true;
} }
@@ -323,6 +305,46 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return TryInsertBullet(eventArgs.User, eventArgs.Using); return TryInsertBullet(eventArgs.User, eventArgs.Using);
} }
private bool TryEjectChamber()
{
var chamberedEntity = _chamberContainer.ContainedEntity;
if (chamberedEntity != null)
{
if (!_chamberContainer.Remove(chamberedEntity))
{
return false;
}
if (!chamberedEntity.GetComponent<AmmoComponent>().Caseless)
{
EjectCasing(chamberedEntity);
}
return true;
}
return false;
}
private bool TryFeedChamber()
{
if (_chamberContainer.ContainedEntity != null)
{
return false;
}
if (_spawnedAmmo.TryPop(out var next))
{
_ammoContainer.Remove(next);
_chamberContainer.Insert(next);
return true;
}
else if (_unspawnedCount > 0)
{
_unspawnedCount--;
var ammoEntity = Owner.EntityManager.SpawnEntity(_fillPrototype, Owner.Transform.GridPosition);
_chamberContainer.Insert(ammoEntity);
return true;
}
return false;
}
public override void Examine(FormattedMessage message, bool inDetailsRange) public override void Examine(FormattedMessage message, bool inDetailsRange)
{ {
base.Examine(message, inDetailsRange); base.Examine(message, inDetailsRange);
@@ -342,7 +364,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
data.Text = Loc.GetString("Open bolt"); data.Text = Loc.GetString("Open bolt");
data.Visibility = component.BoltOpen ? VerbVisibility.Disabled : VerbVisibility.Visible; data.Visibility = component.BoltOpen ? VerbVisibility.Invisible : VerbVisibility.Visible;
} }
protected override void Activate(IEntity user, BoltActionBarrelComponent component) protected override void Activate(IEntity user, BoltActionBarrelComponent component)
@@ -363,7 +385,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
data.Text = Loc.GetString("Close bolt"); data.Text = Loc.GetString("Close bolt");
data.Visibility = component.BoltOpen ? VerbVisibility.Visible : VerbVisibility.Disabled; data.Visibility = component.BoltOpen ? VerbVisibility.Visible : VerbVisibility.Invisible;
} }
protected override void Activate(IEntity user, BoltActionBarrelComponent component) protected override void Activate(IEntity user, BoltActionBarrelComponent component)

View File

@@ -81,7 +81,42 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
private string _magFillPrototype; private string _magFillPrototype;
public bool BoltOpen { get; private set; } = true; public bool BoltOpen
{
get => _boltOpen;
set
{
if (_boltOpen == value)
{
return;
}
var soundSystem = EntitySystem.Get<AudioSystem>();
if (value)
{
TryEjectChamber();
if (_soundBoltOpen != null)
{
soundSystem.PlayAtCoords(_soundBoltOpen, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
}
}
else
{
TryFeedChamber();
if (_soundBoltClosed != null)
{
soundSystem.PlayAtCoords(_soundBoltClosed, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
}
}
_boltOpen = value;
UpdateAppearance();
Dirty();
}
}
private bool _boltOpen = true;
private bool _autoEjectMag; private bool _autoEjectMag;
// If the bolt needs to be open before we can insert / remove the mag (i.e. for LMGs) // If the bolt needs to be open before we can insert / remove the mag (i.e. for LMGs)
public bool MagNeedsOpenBolt => _magNeedsOpenBolt; public bool MagNeedsOpenBolt => _magNeedsOpenBolt;
@@ -170,30 +205,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
UpdateAppearance(); UpdateAppearance();
} }
public void ToggleBolt()
{
// For magazines only when we normally set BoltOpen we'll defer the UpdateAppearance until everything is done
// Whereas this will just call it straight up.
BoltOpen = !BoltOpen;
var soundSystem = EntitySystem.Get<AudioSystem>();
if (BoltOpen)
{
if (_soundBoltOpen != null)
{
soundSystem.PlayAtCoords(_soundBoltOpen, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-5));
}
}
else
{
if (_soundBoltClosed != null)
{
soundSystem.PlayAtCoords(_soundBoltClosed, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-5));
}
}
Dirty();
UpdateAppearance();
}
public override IEntity PeekAmmo() public override IEntity PeekAmmo()
{ {
return BoltOpen ? null : _chamberContainer.ContainedEntity; return BoltOpen ? null : _chamberContainer.ContainedEntity;
@@ -218,41 +229,13 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return; return;
} }
var chamberEntity = _chamberContainer.ContainedEntity; TryEjectChamber();
if (chamberEntity != null)
{
_chamberContainer.Remove(chamberEntity);
var ammoComponent = chamberEntity.GetComponent<AmmoComponent>();
if (!ammoComponent.Caseless)
{
EjectCasing(chamberEntity);
}
}
// Try and pull a round from the magazine to replace the chamber if possible TryFeedChamber();
var magazine = _magazineContainer.ContainedEntity;
var nextRound = magazine?.GetComponent<RangedMagazineComponent>().TakeAmmo();
if (nextRound != null)
{
// If you're really into gunporn you could put a sound here
_chamberContainer.Insert(nextRound);
}
var soundSystem = EntitySystem.Get<AudioSystem>(); var soundSystem = EntitySystem.Get<AudioSystem>();
if (_autoEjectMag && magazine != null && magazine.GetComponent<RangedMagazineComponent>().ShotsLeft == 0) if (_chamberContainer.ContainedEntity == null && !BoltOpen)
{
if (_soundAutoEject != null)
{
soundSystem.PlayAtCoords(_soundAutoEject, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
}
_magazineContainer.Remove(magazine);
SendNetworkMessage(new MagazineAutoEjectMessage());
}
if (nextRound == null && !BoltOpen)
{ {
if (_soundBoltOpen != null) if (_soundBoltOpen != null)
{ {
@@ -264,8 +247,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
Owner.PopupMessage(container.Owner, Loc.GetString("Bolt open")); Owner.PopupMessage(container.Owner, Loc.GetString("Bolt open"));
} }
BoltOpen = true; BoltOpen = true;
Dirty();
UpdateAppearance();
return; return;
} }
@@ -305,8 +286,6 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
Owner.PopupMessage(eventArgs.User, Loc.GetString("Bolt closed")); Owner.PopupMessage(eventArgs.User, Loc.GetString("Bolt closed"));
BoltOpen = false; BoltOpen = false;
Dirty();
UpdateAppearance();
return true; return true;
} }
@@ -316,6 +295,57 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return true; return true;
} }
public bool TryEjectChamber()
{
var chamberEntity = _chamberContainer.ContainedEntity;
if (chamberEntity != null)
{
if (!_chamberContainer.Remove(chamberEntity))
{
return false;
}
var ammoComponent = chamberEntity.GetComponent<AmmoComponent>();
if (!ammoComponent.Caseless)
{
EjectCasing(chamberEntity);
}
return true;
}
return false;
}
public bool TryFeedChamber()
{
if (_chamberContainer.ContainedEntity != null)
{
return false;
}
// Try and pull a round from the magazine to replace the chamber if possible
var magazine = _magazineContainer.ContainedEntity;
var nextRound = magazine?.GetComponent<RangedMagazineComponent>().TakeAmmo();
if (nextRound == null)
{
return false;
}
_chamberContainer.Insert(nextRound);
if (_autoEjectMag && magazine != null && magazine.GetComponent<RangedMagazineComponent>().ShotsLeft == 0)
{
if (_soundAutoEject != null)
{
var soundSystem = EntitySystem.Get<AudioSystem>();
soundSystem.PlayAtCoords(_soundAutoEject, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
}
_magazineContainer.Remove(magazine);
SendNetworkMessage(new MagazineAutoEjectMessage());
}
return true;
}
public void RemoveMagazine(IEntity user) public void RemoveMagazine(IEntity user)
{ {
var mag = _magazineContainer.ContainedEntity; var mag = _magazineContainer.ContainedEntity;
@@ -470,12 +500,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
data.Text = Loc.GetString("Open bolt"); data.Text = Loc.GetString("Open bolt");
data.Visibility = component.BoltOpen ? VerbVisibility.Disabled : VerbVisibility.Visible; data.Visibility = component.BoltOpen ? VerbVisibility.Invisible : VerbVisibility.Visible;
} }
protected override void Activate(IEntity user, ServerMagazineBarrelComponent component) protected override void Activate(IEntity user, ServerMagazineBarrelComponent component)
{ {
component.ToggleBolt(); component.BoltOpen = true;
} }
} }
@@ -491,12 +521,12 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
data.Text = Loc.GetString("Close bolt"); data.Text = Loc.GetString("Close bolt");
data.Visibility = component.BoltOpen ? VerbVisibility.Visible : VerbVisibility.Disabled; data.Visibility = component.BoltOpen ? VerbVisibility.Visible : VerbVisibility.Invisible;
} }
protected override void Activate(IEntity user, ServerMagazineBarrelComponent component) protected override void Activate(IEntity user, ServerMagazineBarrelComponent component)
{ {
component.ToggleBolt(); component.BoltOpen = false;
} }
} }
} }