Add IItemStatus to some weapon types (#1879)

* Bolt Action

* Shotguns

* Revolver + Outline

* In Magazines: show bullets as numbers plus the usual bullet stuff

* Empty bullets have another texture
This commit is contained in:
Exp
2020-08-24 13:13:26 +02:00
committed by GitHub
parent 969eeb5528
commit 56ebde7f45
14 changed files with 810 additions and 69 deletions

View File

@@ -0,0 +1,206 @@
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
using System;
namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
{
[RegisterComponent]
public class ClientBoltActionBarrelComponent : Component, IItemStatus
{
public override string Name => "BoltActionBarrel";
public override uint? NetID => ContentNetIDs.BOLTACTION_BARREL;
private StatusControl _statusControl;
/// <summary>
/// chambered is true when a bullet is chambered
/// spent is true when the chambered bullet is spent
/// </summary>
[ViewVariables]
public (bool chambered, bool spent) Chamber { get; private set; }
/// <summary>
/// Count of bullets in the magazine.
/// </summary>
/// <remarks>
/// Null if no magazine is inserted.
/// </remarks>
[ViewVariables]
public (int count, int max)? MagazineCount { get; private set; }
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
if (!(curState is BoltActionBarrelComponentState cast))
return;
Chamber = cast.Chamber;
MagazineCount = cast.Magazine;
_statusControl?.Update();
}
public Control MakeControl()
{
_statusControl = new StatusControl(this);
_statusControl.Update();
return _statusControl;
}
public void DestroyControl(Control control)
{
if (_statusControl == control)
{
_statusControl = null;
}
}
private sealed class StatusControl : Control
{
private readonly ClientBoltActionBarrelComponent _parent;
private readonly HBoxContainer _bulletsListTop;
private readonly HBoxContainer _bulletsListBottom;
private readonly TextureRect _chamberedBullet;
private readonly Label _noMagazineLabel;
public StatusControl(ClientBoltActionBarrelComponent parent)
{
_parent = parent;
SizeFlagsHorizontal = SizeFlags.FillExpand;
SizeFlagsVertical = SizeFlags.ShrinkCenter;
AddChild(new VBoxContainer
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0,
Children =
{
(_bulletsListTop = new HBoxContainer {SeparationOverride = 0}),
new HBoxContainer
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
Children =
{
new Control
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
Children =
{
(_bulletsListBottom = new HBoxContainer
{
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0
}),
(_noMagazineLabel = new Label
{
Text = "No Magazine!",
StyleClasses = {StyleNano.StyleClassItemStatus}
})
}
},
(_chamberedBullet = new TextureRect
{
Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered.png"),
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Fill,
})
}
}
}
});
}
public void Update()
{
_chamberedBullet.ModulateSelfOverride =
_parent.Chamber.chambered ?
_parent.Chamber.spent ? Color.Red : Color.FromHex("#d7df60")
: Color.Black;
_bulletsListTop.RemoveAllChildren();
_bulletsListBottom.RemoveAllChildren();
if (_parent.MagazineCount == null)
{
_noMagazineLabel.Visible = true;
return;
}
var (count, capacity) = _parent.MagazineCount.Value;
_noMagazineLabel.Visible = false;
string texturePath;
if (capacity <= 20)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png";
}
else if (capacity <= 30)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/small.png";
}
else
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/tiny.png";
}
var texture = StaticIoC.ResC.GetTexture(texturePath);
const int tinyMaxRow = 60;
if (capacity > tinyMaxRow)
{
FillBulletRow(_bulletsListBottom, Math.Min(tinyMaxRow, count), tinyMaxRow, texture);
FillBulletRow(_bulletsListTop, Math.Max(0, count - tinyMaxRow), capacity - tinyMaxRow, texture);
}
else
{
FillBulletRow(_bulletsListBottom, count, capacity, texture);
}
}
private static void FillBulletRow(Control container, int count, int capacity, Texture texture)
{
var colorA = Color.FromHex("#b68f0e");
var colorB = Color.FromHex("#d7df60");
var colorGoneA = Color.FromHex("#000000");
var colorGoneB = Color.FromHex("#222222");
var altColor = false;
for (var i = count; i < capacity; i++)
{
container.AddChild(new TextureRect
{
Texture = texture,
ModulateSelfOverride = altColor ? colorGoneA : colorGoneB
});
altColor ^= true;
}
for (var i = 0; i < count; i++)
{
container.AddChild(new TextureRect
{
Texture = texture,
ModulateSelfOverride = altColor ? colorA : colorB
});
altColor ^= true;
}
}
protected override Vector2 CalculateMinimumSize()
{
return Vector2.ComponentMax((0, 15), base.CalculateMinimumSize());
}
}
}
}

View File

@@ -1,4 +1,4 @@
using System; using System;
using Content.Client.Animations; using Content.Client.Animations;
using Content.Client.UserInterface.Stylesheets; using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility; using Content.Client.Utility;
@@ -138,54 +138,52 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
private sealed class StatusControl : Control private sealed class StatusControl : Control
{ {
private readonly ClientMagazineBarrelComponent _parent; private readonly ClientMagazineBarrelComponent _parent;
private readonly HBoxContainer _bulletsListTop; private readonly HBoxContainer _bulletsList;
private readonly HBoxContainer _bulletsListBottom;
private readonly TextureRect _chamberedBullet; private readonly TextureRect _chamberedBullet;
private readonly Label _noMagazineLabel; private readonly Label _noMagazineLabel;
private readonly Label _ammoCount;
public StatusControl(ClientMagazineBarrelComponent parent) public StatusControl(ClientMagazineBarrelComponent parent)
{ {
_parent = parent; _parent = parent;
SizeFlagsHorizontal = SizeFlags.FillExpand; SizeFlagsHorizontal = SizeFlags.FillExpand;
SizeFlagsVertical = SizeFlags.ShrinkCenter; SizeFlagsVertical = SizeFlags.ShrinkCenter;
AddChild(new VBoxContainer
AddChild(new HBoxContainer
{ {
SizeFlagsHorizontal = SizeFlags.FillExpand, SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0,
Children = Children =
{ {
(_bulletsListTop = new HBoxContainer {SeparationOverride = 0}), (_chamberedBullet = new TextureRect
new HBoxContainer {
Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered_rotated.png"),
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Fill,
}),
new Control() { CustomMinimumSize = (5,0) },
new Control
{ {
SizeFlagsHorizontal = SizeFlags.FillExpand, SizeFlagsHorizontal = SizeFlags.FillExpand,
Children = Children =
{ {
new Control (_bulletsList = new HBoxContainer
{ {
SizeFlagsHorizontal = SizeFlags.FillExpand,
Children =
{
(_bulletsListBottom = new HBoxContainer
{
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0
}),
(_noMagazineLabel = new Label
{
Text = "No Magazine!",
StyleClasses = {StyleNano.StyleClassItemStatus}
})
}
},
(_chamberedBullet = new TextureRect
{
Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered.png"),
SizeFlagsVertical = SizeFlags.ShrinkCenter, SizeFlagsVertical = SizeFlags.ShrinkCenter,
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Fill, SeparationOverride = 0
}),
(_noMagazineLabel = new Label
{
Text = "No Magazine!",
StyleClasses = {StyleNano.StyleClassItemStatus}
}) })
} }
} },
new Control() { CustomMinimumSize = (5,0) },
(_ammoCount = new Label
{
StyleClasses = {StyleNano.StyleClassItemStatus},
SizeFlagsHorizontal = SizeFlags.ShrinkEnd,
}),
} }
}); });
} }
@@ -195,46 +193,26 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
_chamberedBullet.ModulateSelfOverride = _chamberedBullet.ModulateSelfOverride =
_parent.Chambered ? Color.FromHex("#d7df60") : Color.Black; _parent.Chambered ? Color.FromHex("#d7df60") : Color.Black;
_bulletsListTop.RemoveAllChildren(); _bulletsList.RemoveAllChildren();
_bulletsListBottom.RemoveAllChildren();
if (_parent.MagazineCount == null) if (_parent.MagazineCount == null)
{ {
_noMagazineLabel.Visible = true; _noMagazineLabel.Visible = true;
_ammoCount.Visible = false;
return; return;
} }
var (count, capacity) = _parent.MagazineCount.Value; var (count, capacity) = _parent.MagazineCount.Value;
_noMagazineLabel.Visible = false; _noMagazineLabel.Visible = false;
_ammoCount.Visible = true;
string texturePath; var texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png";
if (capacity <= 20)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png";
}
else if (capacity <= 30)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/small.png";
}
else
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/tiny.png";
}
var texture = StaticIoC.ResC.GetTexture(texturePath); var texture = StaticIoC.ResC.GetTexture(texturePath);
const int tinyMaxRow = 60; _ammoCount.Text = $"x{count:00}";
capacity = Math.Min(capacity, 20);
if (capacity > tinyMaxRow) FillBulletRow(_bulletsList, count, capacity, texture);
{
FillBulletRow(_bulletsListBottom, Math.Min(tinyMaxRow, count), tinyMaxRow, texture);
FillBulletRow(_bulletsListTop, Math.Max(0, count - tinyMaxRow), capacity - tinyMaxRow, texture);
}
else
{
FillBulletRow(_bulletsListBottom, count, capacity, texture);
}
} }
private static void FillBulletRow(Control container, int count, int capacity, Texture texture) private static void FillBulletRow(Control container, int count, int capacity, Texture texture)
@@ -246,23 +224,32 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
var altColor = false; var altColor = false;
// Draw the empty ones
for (var i = count; i < capacity; i++) for (var i = count; i < capacity; i++)
{ {
container.AddChild(new TextureRect container.AddChild(new TextureRect
{ {
Texture = texture, Texture = texture,
ModulateSelfOverride = altColor ? colorGoneA : colorGoneB ModulateSelfOverride = altColor ? colorGoneA : colorGoneB,
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsVertical = SizeFlags.Fill,
Stretch = TextureRect.StretchMode.KeepCentered
}); });
altColor ^= true; altColor ^= true;
} }
// Draw the full ones, but limit the count to the capacity
count = Math.Min(count, capacity);
for (var i = 0; i < count; i++) for (var i = 0; i < count; i++)
{ {
container.AddChild(new TextureRect container.AddChild(new TextureRect
{ {
Texture = texture, Texture = texture,
ModulateSelfOverride = altColor ? colorA : colorB ModulateSelfOverride = altColor ? colorA : colorB,
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsVertical = SizeFlags.Fill,
Stretch = TextureRect.StretchMode.KeepCentered
}); });
altColor ^= true; altColor ^= true;

View File

@@ -0,0 +1,208 @@
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
using System;
using System.Collections.Generic;
using System.Text;
namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
{
[RegisterComponent]
public class ClientPumpBarrelComponent : Component, IItemStatus
{
public override string Name => "PumpBarrel";
public override uint? NetID => ContentNetIDs.PUMP_BARREL;
private StatusControl _statusControl;
/// <summary>
/// chambered is true when a bullet is chambered
/// spent is true when the chambered bullet is spent
/// </summary>
[ViewVariables]
public (bool chambered, bool spent) Chamber { get; private set; }
/// <summary>
/// Count of bullets in the magazine.
/// </summary>
/// <remarks>
/// Null if no magazine is inserted.
/// </remarks>
[ViewVariables]
public (int count, int max)? MagazineCount { get; private set; }
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
if (!(curState is PumpBarrelComponentState cast))
return;
Chamber = cast.Chamber;
MagazineCount = cast.Magazine;
_statusControl?.Update();
}
public Control MakeControl()
{
_statusControl = new StatusControl(this);
_statusControl.Update();
return _statusControl;
}
public void DestroyControl(Control control)
{
if (_statusControl == control)
{
_statusControl = null;
}
}
private sealed class StatusControl : Control
{
private readonly ClientPumpBarrelComponent _parent;
private readonly HBoxContainer _bulletsListTop;
private readonly HBoxContainer _bulletsListBottom;
private readonly TextureRect _chamberedBullet;
private readonly Label _noMagazineLabel;
public StatusControl(ClientPumpBarrelComponent parent)
{
_parent = parent;
SizeFlagsHorizontal = SizeFlags.FillExpand;
SizeFlagsVertical = SizeFlags.ShrinkCenter;
AddChild(new VBoxContainer
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0,
Children =
{
(_bulletsListTop = new HBoxContainer {SeparationOverride = 0}),
new HBoxContainer
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
Children =
{
new Control
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
Children =
{
(_bulletsListBottom = new HBoxContainer
{
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0
}),
(_noMagazineLabel = new Label
{
Text = "No Magazine!",
StyleClasses = {StyleNano.StyleClassItemStatus}
})
}
},
(_chamberedBullet = new TextureRect
{
Texture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/chambered.png"),
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SizeFlagsHorizontal = SizeFlags.ShrinkEnd | SizeFlags.Fill,
})
}
}
}
});
}
public void Update()
{
_chamberedBullet.ModulateSelfOverride =
_parent.Chamber.chambered ?
_parent.Chamber.spent ? Color.Red : Color.FromHex("#d7df60")
: Color.Black;
_bulletsListTop.RemoveAllChildren();
_bulletsListBottom.RemoveAllChildren();
if (_parent.MagazineCount == null)
{
_noMagazineLabel.Visible = true;
return;
}
var (count, capacity) = _parent.MagazineCount.Value;
_noMagazineLabel.Visible = false;
string texturePath;
if (capacity <= 20)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png";
}
else if (capacity <= 30)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/small.png";
}
else
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/tiny.png";
}
var texture = StaticIoC.ResC.GetTexture(texturePath);
const int tinyMaxRow = 60;
if (capacity > tinyMaxRow)
{
FillBulletRow(_bulletsListBottom, Math.Min(tinyMaxRow, count), tinyMaxRow, texture);
FillBulletRow(_bulletsListTop, Math.Max(0, count - tinyMaxRow), capacity - tinyMaxRow, texture);
}
else
{
FillBulletRow(_bulletsListBottom, count, capacity, texture);
}
}
private static void FillBulletRow(Control container, int count, int capacity, Texture texture)
{
var colorA = Color.FromHex("#b68f0e");
var colorB = Color.FromHex("#d7df60");
var colorGoneA = Color.FromHex("#000000");
var colorGoneB = Color.FromHex("#222222");
var altColor = false;
for (var i = count; i < capacity; i++)
{
container.AddChild(new TextureRect
{
Texture = texture,
ModulateSelfOverride = altColor ? colorGoneA : colorGoneB
});
altColor ^= true;
}
for (var i = 0; i < count; i++)
{
container.AddChild(new TextureRect
{
Texture = texture,
ModulateSelfOverride = altColor ? colorA : colorB
});
altColor ^= true;
}
}
protected override Vector2 CalculateMinimumSize()
{
return Vector2.ComponentMax((0, 15), base.CalculateMinimumSize());
}
}
}
}

View File

@@ -0,0 +1,175 @@
using Content.Client.UserInterface.Stylesheets;
using Content.Client.Utility;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
{
[RegisterComponent]
public class ClientRevolverBarrelComponent : Component, IItemStatus
{
public override string Name => "RevolverBarrel";
public override uint? NetID => ContentNetIDs.REVOLVER_BARREL;
private StatusControl _statusControl;
/// <summary>
/// A array that lists the bullet states
/// true means a spent bullet
/// false means a "shootable" bullet
/// null means no bullet
/// </summary>
[ViewVariables]
public bool?[] Bullets { get; private set; }
[ViewVariables]
public int CurrentSlot { get; private set; }
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
if (!(curState is RevolverBarrelComponentState cast))
return;
CurrentSlot = cast.CurrentSlot;
Bullets = cast.Bullets;
_statusControl?.Update();
}
public Control MakeControl()
{
_statusControl = new StatusControl(this);
_statusControl.Update();
return _statusControl;
}
public void DestroyControl(Control control)
{
if (_statusControl == control)
{
_statusControl = null;
}
}
private sealed class StatusControl : Control
{
private readonly ClientRevolverBarrelComponent _parent;
private readonly HBoxContainer _bulletsList;
public StatusControl(ClientRevolverBarrelComponent parent)
{
_parent = parent;
SizeFlagsHorizontal = SizeFlags.FillExpand;
SizeFlagsVertical = SizeFlags.ShrinkCenter;
AddChild((_bulletsList = new HBoxContainer
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.ShrinkCenter,
SeparationOverride = 0
}));
}
public void Update()
{
_bulletsList.RemoveAllChildren();
var capacity = _parent.Bullets.Length;
string texturePath;
if (capacity <= 20)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/normal.png";
}
else if (capacity <= 30)
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/small.png";
}
else
{
texturePath = "/Textures/Interface/ItemStatus/Bullets/tiny.png";
}
var texture = StaticIoC.ResC.GetTexture(texturePath);
var spentTexture = StaticIoC.ResC.GetTexture("/Textures/Interface/ItemStatus/Bullets/empty.png");
FillBulletRow(_bulletsList, texture, spentTexture);
}
private void FillBulletRow(Control container, Texture texture, Texture emptyTexture)
{
var colorA = Color.FromHex("#b68f0e");
var colorB = Color.FromHex("#d7df60");
var colorSpentA = Color.FromHex("#b50e25");
var colorSpentB = Color.FromHex("#d3745f");
var colorGoneA = Color.FromHex("#000000");
var colorGoneB = Color.FromHex("#222222");
var altColor = false;
var scale = 1.3f;
for (var i = 0; i < _parent.Bullets.Length; i++)
{
var bulletSpent = _parent.Bullets[i];
// Add a outline
var box = new Control()
{
CustomMinimumSize = texture.Size * scale,
};
if (i == _parent.CurrentSlot)
{
box.AddChild(new TextureRect
{
Texture = texture,
TextureScale = (scale, scale),
ModulateSelfOverride = Color.Green,
});
}
Color color;
Texture bulletTexture = texture;
if (bulletSpent.HasValue)
{
if (bulletSpent.Value)
{
color = altColor ? colorSpentA : colorSpentB;
bulletTexture = emptyTexture;
}
else
{
color = altColor ? colorA : colorB;
}
}
else
{
color = altColor ? colorGoneA : colorGoneB;
}
box.AddChild(new TextureRect
{
SizeFlagsHorizontal = SizeFlags.Fill,
SizeFlagsVertical = SizeFlags.Fill,
Stretch = TextureRect.StretchMode.KeepCentered,
Texture = bulletTexture,
ModulateSelfOverride = color,
});
altColor ^= true;
container.AddChild(box);
}
}
protected override Vector2 CalculateMinimumSize()
{
return Vector2.ComponentMax((0, 15), base.CalculateMinimumSize());
}
}
}
}

View File

@@ -86,9 +86,6 @@
"CanSpill", "CanSpill",
"SpeedLoader", "SpeedLoader",
"Hitscan", "Hitscan",
"BoltActionBarrel",
"PumpBarrel",
"RevolverBarrel",
"ExplosiveProjectile", "ExplosiveProjectile",
"StunnableProjectile", "StunnableProjectile",
"RandomPottedPlant", "RandomPottedPlant",

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Verbs; using Content.Shared.GameObjects.Verbs;
@@ -32,6 +33,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
// 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
public override string Name => "BoltActionBarrel"; public override string Name => "BoltActionBarrel";
public override uint? NetID => ContentNetIDs.BOLTACTION_BARREL;
public override int ShotsLeft public override int ShotsLeft
{ {
@@ -123,6 +125,24 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
UpdateAppearance(); UpdateAppearance();
} }
public override ComponentState GetComponentState()
{
(int, int)? count = (ShotsLeft, Capacity);
var chamberedExists = _chamberContainer.ContainedEntity != null;
// (Is one chambered?, is the bullet spend)
var chamber = (chamberedExists, false);
if (chamberedExists && _chamberContainer.ContainedEntity.TryGetComponent<AmmoComponent>(out var ammo))
{
chamber.Item2 = ammo.Spent;
}
return new BoltActionBarrelComponentState(
chamber,
FireRateSelector,
count,
SoundGunshot);
}
public override void Initialize() public override void Initialize()
{ {
// TODO: Add existing ammo support on revolvers // TODO: Add existing ammo support on revolvers
@@ -170,6 +190,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
Cycle(); Cycle();
} }
else
{
Dirty();
}
return chamberEntity?.GetComponent<AmmoComponent>().TakeBullet(spawnAtGrid, spawnAtMap); return chamberEntity?.GetComponent<AmmoComponent>().TakeBullet(spawnAtGrid, spawnAtMap);
} }
@@ -256,7 +281,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundInsert, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundInsert, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
} }
// Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
return true; return true;
} }
@@ -269,7 +294,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundInsert, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundInsert, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
} }
// Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
return true; return true;
} }

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Interfaces; using Content.Shared.Interfaces;
@@ -27,6 +28,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IMapInit, IExamine public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IMapInit, IExamine
{ {
public override string Name => "PumpBarrel"; public override string Name => "PumpBarrel";
public override uint? NetID => ContentNetIDs.PUMP_BARREL;
public override int ShotsLeft public override int ShotsLeft
{ {
@@ -81,6 +83,23 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
UpdateAppearance(); UpdateAppearance();
} }
public override ComponentState GetComponentState()
{
(int, int)? count = (ShotsLeft, Capacity);
var chamberedExists = _chamberContainer.ContainedEntity != null;
// (Is one chambered?, is the bullet spend)
var chamber = (chamberedExists, false);
if (chamberedExists && _chamberContainer.ContainedEntity.TryGetComponent<AmmoComponent>(out var ammo))
{
chamber.Item2 = ammo.Spent;
}
return new PumpBarrelComponentState(
chamber,
FireRateSelector,
count,
SoundGunshot);
}
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -110,6 +129,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
_appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, true); _appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, true);
Dirty();
UpdateAppearance(); UpdateAppearance();
} }
@@ -131,6 +151,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
Cycle(); Cycle();
} }
else
{
Dirty();
}
return chamberEntity?.GetComponent<AmmoComponent>().TakeBullet(spawnAtGrid, spawnAtMap); return chamberEntity?.GetComponent<AmmoComponent>().TakeBullet(spawnAtGrid, spawnAtMap);
} }
@@ -168,7 +193,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
} }
// Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
} }
@@ -189,7 +214,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
_ammoContainer.Insert(eventArgs.Using); _ammoContainer.Insert(eventArgs.Using);
_spawnedAmmo.Push(eventArgs.Using); _spawnedAmmo.Push(eventArgs.Using);
// Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
if (_soundInsert != null) if (_soundInsert != null)
{ {

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition; using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels; using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Verbs; using Content.Shared.GameObjects.Verbs;
@@ -25,6 +26,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent
{ {
public override string Name => "RevolverBarrel"; public override string Name => "RevolverBarrel";
public override uint? NetID => ContentNetIDs.REVOLVER_BARREL;
private BallisticCaliber _caliber; private BallisticCaliber _caliber;
private Container _ammoContainer; private Container _ammoContainer;
private int _currentSlot = 0; private int _currentSlot = 0;
@@ -60,6 +63,26 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
serializer.DataField(ref _soundSpin, "soundSpin", "/Audio/Weapons/Guns/Misc/revolver_spin.ogg"); serializer.DataField(ref _soundSpin, "soundSpin", "/Audio/Weapons/Guns/Misc/revolver_spin.ogg");
} }
public override ComponentState GetComponentState()
{
var slotsSpent = new bool?[Capacity];
for (var i = 0; i < Capacity; i++)
{
slotsSpent[i] = null;
if (_ammoSlots[i] != null && _ammoSlots[i].TryGetComponent(out AmmoComponent ammo))
{
slotsSpent[i] = ammo.Spent;
}
}
//TODO: make yaml var to not sent currentSlot/UI? (for russian roulette)
return new RevolverBarrelComponentState(
_currentSlot,
FireRateSelector,
slotsSpent,
SoundGunshot);
}
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -90,6 +113,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
} }
_appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, true); _appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, true);
Dirty();
} }
private void UpdateAppearance() private void UpdateAppearance()
@@ -129,7 +153,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundInsert, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundInsert, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
} }
// Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
return true; return true;
} }
@@ -143,7 +167,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
// Move up a slot // Move up a slot
_currentSlot = (_currentSlot + 1) % _ammoSlots.Length; _currentSlot = (_currentSlot + 1) % _ammoSlots.Length;
// Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
} }
@@ -158,6 +182,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
{ {
EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundSpin, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2)); EntitySystem.Get<AudioSystem>().PlayAtCoords(_soundSpin, Owner.Transform.GridPosition, AudioParams.Default.WithVolume(-2));
} }
Dirty();
} }
public override IEntity PeekAmmo() public override IEntity PeekAmmo()
@@ -227,7 +252,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
public override bool UseEntity(UseEntityEventArgs eventArgs) public override bool UseEntity(UseEntityEventArgs eventArgs)
{ {
EjectAllSlots(); EjectAllSlots();
//Dirty(); Dirty();
UpdateAppearance(); UpdateAppearance();
return true; return true;
} }

View File

@@ -0,0 +1,30 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Text;
namespace Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels
{
[Serializable, NetSerializable]
public class BoltActionBarrelComponentState : ComponentState
{
public (bool chambered, bool spent) Chamber { get; }
public FireRateSelector FireRateSelector { get; }
public (int count, int max)? Magazine { get; }
public string SoundGunshot { get; }
public BoltActionBarrelComponentState(
(bool chambered, bool spent) chamber,
FireRateSelector fireRateSelector,
(int count, int max)? magazine,
string soundGunshot) :
base(ContentNetIDs.BOLTACTION_BARREL)
{
Chamber = chamber;
FireRateSelector = fireRateSelector;
Magazine = magazine;
SoundGunshot = soundGunshot;
}
}
}

View File

@@ -0,0 +1,30 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Text;
namespace Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels
{
[Serializable, NetSerializable]
public class PumpBarrelComponentState : ComponentState
{
public (bool chambered, bool spent) Chamber { get; }
public FireRateSelector FireRateSelector { get; }
public (int count, int max)? Magazine { get; }
public string SoundGunshot { get; }
public PumpBarrelComponentState(
(bool chambered, bool spent) chamber,
FireRateSelector fireRateSelector,
(int count, int max)? magazine,
string soundGunshot) :
base(ContentNetIDs.PUMP_BARREL)
{
Chamber = chamber;
FireRateSelector = fireRateSelector;
Magazine = magazine;
SoundGunshot = soundGunshot;
}
}
}

View File

@@ -0,0 +1,30 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Text;
namespace Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels
{
[Serializable, NetSerializable]
public class RevolverBarrelComponentState : ComponentState
{
public int CurrentSlot { get; }
public FireRateSelector FireRateSelector { get; }
public bool?[] Bullets { get; }
public string SoundGunshot { get; }
public RevolverBarrelComponentState(
int currentSlot,
FireRateSelector fireRateSelector,
bool?[] bullets,
string soundGunshot) :
base(ContentNetIDs.REVOLVER_BARREL)
{
CurrentSlot = currentSlot;
FireRateSelector = fireRateSelector;
Bullets = bullets;
SoundGunshot = soundGunshot;
}
}
}

View File

@@ -65,6 +65,9 @@
public const uint RADIATION_PULSE = 1059; public const uint RADIATION_PULSE = 1059;
public const uint BODY_MANAGER = 1060; public const uint BODY_MANAGER = 1060;
public const uint CLIMBING = 1061; public const uint CLIMBING = 1061;
public const uint BOLTACTION_BARREL = 1062;
public const uint PUMP_BARREL = 1063;
public const uint REVOLVER_BARREL = 1064;
// Net IDs for integration tests. // Net IDs for integration tests.
public const uint PREDICTION_TEST = 10001; public const uint PREDICTION_TEST = 10001;

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B