Gun auto state handlers (#15186)

* battery auto state

* basic entity autostate

* ballistic autostate

* flyby

* cartridge ammo

* gun

* Revert "battery auto state"

This reverts commit 35b7d62f303fddb0edd9eb7a922e3c26b7a5f7fb.

* silly
This commit is contained in:
Kara
2023-04-13 20:08:56 -05:00
committed by GitHub
parent ccf81a6be9
commit 47262a6998
10 changed files with 31 additions and 173 deletions

View File

@@ -20,13 +20,14 @@ public class AmmoComponent : Component, IShootable
/// <summary> /// <summary>
/// Spawns another prototype to be shot instead of itself. /// Spawns another prototype to be shot instead of itself.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent, ComponentReference(typeof(AmmoComponent))] [RegisterComponent, NetworkedComponent, ComponentReference(typeof(AmmoComponent)), AutoGenerateComponentState]
public sealed class CartridgeAmmoComponent : AmmoComponent public sealed partial class CartridgeAmmoComponent : AmmoComponent
{ {
[ViewVariables(VVAccess.ReadWrite), DataField("proto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] [ViewVariables(VVAccess.ReadWrite), DataField("proto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string Prototype = default!; public string Prototype = default!;
[ViewVariables(VVAccess.ReadWrite), DataField("spent")] [ViewVariables(VVAccess.ReadWrite), DataField("spent")]
[AutoNetworkedField]
public bool Spent = false; public bool Spent = false;
/// <summary> /// <summary>

View File

@@ -7,8 +7,8 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
namespace Content.Shared.Weapons.Ranged.Components; namespace Content.Shared.Weapons.Ranged.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed class BallisticAmmoProviderComponent : Component public sealed partial class BallisticAmmoProviderComponent : Component
{ {
[ViewVariables(VVAccess.ReadWrite), DataField("soundRack")] [ViewVariables(VVAccess.ReadWrite), DataField("soundRack")]
public SoundSpecifier? SoundRack = new SoundPathSpecifier("/Audio/Weapons/Guns/Cock/smg_cock.ogg"); public SoundSpecifier? SoundRack = new SoundPathSpecifier("/Audio/Weapons/Guns/Cock/smg_cock.ogg");
@@ -23,6 +23,7 @@ public sealed class BallisticAmmoProviderComponent : Component
public int Capacity = 30; public int Capacity = 30;
[ViewVariables(VVAccess.ReadWrite), DataField("unspawnedCount")] [ViewVariables(VVAccess.ReadWrite), DataField("unspawnedCount")]
[AutoNetworkedField]
public int UnspawnedCount; public int UnspawnedCount;
[ViewVariables(VVAccess.ReadWrite), DataField("whitelist")] [ViewVariables(VVAccess.ReadWrite), DataField("whitelist")]
@@ -32,6 +33,7 @@ public sealed class BallisticAmmoProviderComponent : Component
// TODO: Make this use stacks when the typeserializer is done. // TODO: Make this use stacks when the typeserializer is done.
[DataField("entities")] [DataField("entities")]
[AutoNetworkedField(true)]
public List<EntityUid> Entities = new(); public List<EntityUid> Entities = new();
/// <summary> /// <summary>
@@ -44,6 +46,7 @@ public sealed class BallisticAmmoProviderComponent : Component
/// Is the gun ready to shoot; if AutoCycle is true then this will always stay true and not need to be manually done. /// Is the gun ready to shoot; if AutoCycle is true then this will always stay true and not need to be manually done.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("cycled")] [ViewVariables(VVAccess.ReadWrite), DataField("cycled")]
[AutoNetworkedField]
public bool Cycled = true; public bool Cycled = true;
/// <summary> /// <summary>

View File

@@ -1,4 +1,5 @@
using Robust.Shared.Prototypes; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -8,8 +9,8 @@ namespace Content.Shared.Weapons.Ranged.Components;
/// Simply provides a certain capacity of entities that cannot be reloaded through normal means and have /// Simply provides a certain capacity of entities that cannot be reloaded through normal means and have
/// no special behavior like cycling, magazine /// no special behavior like cycling, magazine
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent, AutoGenerateComponentState]
public sealed class BasicEntityAmmoProviderComponent : AmmoProviderComponent public sealed partial class BasicEntityAmmoProviderComponent : AmmoProviderComponent
{ {
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("proto", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))] [DataField("proto", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
@@ -20,6 +21,7 @@ public sealed class BasicEntityAmmoProviderComponent : AmmoProviderComponent
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("capacity")] [DataField("capacity")]
[AutoNetworkedField]
public int? Capacity = null; public int? Capacity = null;
/// <summary> /// <summary>
@@ -27,18 +29,6 @@ public sealed class BasicEntityAmmoProviderComponent : AmmoProviderComponent
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("count")] [DataField("count")]
[AutoNetworkedField]
public int? Count = null; public int? Count = null;
} }
[Serializable, NetSerializable]
public sealed class BasicEntityAmmoProviderComponentState : ComponentState
{
public int? Capacity;
public int? Count;
public BasicEntityAmmoProviderComponentState(int? capacity, int? count)
{
Capacity = capacity;
Count = count;
}
}

View File

@@ -6,8 +6,8 @@ namespace Content.Shared.Weapons.Ranged.Components;
/// <summary> /// <summary>
/// Plays a sound when its non-hard fixture collides with a player. /// Plays a sound when its non-hard fixture collides with a player.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed class FlyBySoundComponent : Component public sealed partial class FlyBySoundComponent : Component
{ {
/// <summary> /// <summary>
/// Probability that the sound plays /// Probability that the sound plays
@@ -16,10 +16,13 @@ public sealed class FlyBySoundComponent : Component
public float Prob = 0.10f; public float Prob = 0.10f;
[ViewVariables(VVAccess.ReadWrite), DataField("sound")] [ViewVariables(VVAccess.ReadWrite), DataField("sound")]
[AutoNetworkedField]
public SoundSpecifier Sound = new SoundCollectionSpecifier("BulletMiss") public SoundSpecifier Sound = new SoundCollectionSpecifier("BulletMiss")
{ {
Params = AudioParams.Default, Params = AudioParams.Default,
}; };
[DataField("range")] public float Range = 1.5f; [DataField("range")]
[AutoNetworkedField]
public float Range = 1.5f;
} }

View File

@@ -7,7 +7,8 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Weapons.Ranged.Components; namespace Content.Shared.Weapons.Ranged.Components;
[RegisterComponent, NetworkedComponent, Virtual] [RegisterComponent, NetworkedComponent, Virtual]
public class GunComponent : Component [AutoGenerateComponentState]
public partial class GunComponent : Component
{ {
#region Sound #region Sound
@@ -40,6 +41,7 @@ public class GunComponent : Component
/// What the current spread is for shooting. This gets changed every time the gun fires. /// What the current spread is for shooting. This gets changed every time the gun fires.
/// </summary> /// </summary>
[DataField("currentAngle")] [DataField("currentAngle")]
[AutoNetworkedField]
public Angle CurrentAngle; public Angle CurrentAngle;
/// <summary> /// <summary>
@@ -58,12 +60,14 @@ public class GunComponent : Component
/// The maximum angle allowed for <see cref="CurrentAngle"/> /// The maximum angle allowed for <see cref="CurrentAngle"/>
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("maxAngle")] [ViewVariables(VVAccess.ReadWrite), DataField("maxAngle")]
[AutoNetworkedField]
public Angle MaxAngle = Angle.FromDegrees(2); public Angle MaxAngle = Angle.FromDegrees(2);
/// <summary> /// <summary>
/// The minimum angle allowed for <see cref="CurrentAngle"/> /// The minimum angle allowed for <see cref="CurrentAngle"/>
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("minAngle")] [ViewVariables(VVAccess.ReadWrite), DataField("minAngle")]
[AutoNetworkedField]
public Angle MinAngle = Angle.FromDegrees(1); public Angle MinAngle = Angle.FromDegrees(1);
#endregion #endregion
@@ -78,12 +82,14 @@ public class GunComponent : Component
/// Used for tracking semi-auto / burst /// Used for tracking semi-auto / burst
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
[AutoNetworkedField]
public int ShotCounter = 0; public int ShotCounter = 0;
/// <summary> /// <summary>
/// How many times it shoots per second. /// How many times it shoots per second.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("fireRate")] [ViewVariables(VVAccess.ReadWrite), DataField("fireRate")]
[AutoNetworkedField]
public float FireRate = 8f; public float FireRate = 8f;
/// <summary> /// <summary>
@@ -97,18 +103,21 @@ public class GunComponent : Component
/// Can be set multiple times in a single tick due to guns firing faster than a single tick time. /// Can be set multiple times in a single tick due to guns firing faster than a single tick time.
/// </summary> /// </summary>
[DataField("nextFire", customTypeSerializer:typeof(TimeOffsetSerializer))] [DataField("nextFire", customTypeSerializer:typeof(TimeOffsetSerializer))]
[AutoNetworkedField]
public TimeSpan NextFire = TimeSpan.Zero; public TimeSpan NextFire = TimeSpan.Zero;
/// <summary> /// <summary>
/// What firemodes can be selected. /// What firemodes can be selected.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("availableModes")] [ViewVariables(VVAccess.ReadWrite), DataField("availableModes")]
[AutoNetworkedField]
public SelectiveFire AvailableModes = SelectiveFire.SemiAuto; public SelectiveFire AvailableModes = SelectiveFire.SemiAuto;
/// <summary> /// <summary>
/// What firemode is currently selected. /// What firemode is currently selected.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("selectedMode")] [ViewVariables(VVAccess.ReadWrite), DataField("selectedMode")]
[AutoNetworkedField]
public SelectiveFire SelectedMode = SelectiveFire.SemiAuto; public SelectiveFire SelectedMode = SelectiveFire.SemiAuto;
[DataField("selectModeAction")] [DataField("selectModeAction")]

View File

@@ -20,8 +20,6 @@ public abstract class SharedFlyBySoundSystem : EntitySystem
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<FlyBySoundComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<FlyBySoundComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<FlyBySoundComponent, ComponentStartup>(OnStartup); SubscribeLocalEvent<FlyBySoundComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<FlyBySoundComponent, ComponentShutdown>(OnShutdown); SubscribeLocalEvent<FlyBySoundComponent, ComponentShutdown>(OnShutdown);
} }
@@ -46,28 +44,4 @@ public abstract class SharedFlyBySoundSystem : EntitySystem
_fixtures.DestroyFixture(uid, FlyByFixture, body: body); _fixtures.DestroyFixture(uid, FlyByFixture, body: body);
} }
private void OnHandleState(EntityUid uid, FlyBySoundComponent component, ref ComponentHandleState args)
{
if (args.Current is not FlyBySoundComponentState state) return;
component.Sound = state.Sound;
component.Range = state.Range;
}
private void OnGetState(EntityUid uid, FlyBySoundComponent component, ref ComponentGetState args)
{
args.State = new FlyBySoundComponentState()
{
Sound = component.Sound,
Range = component.Range,
};
}
[Serializable, NetSerializable]
private sealed class FlyBySoundComponentState : ComponentState
{
public SoundSpecifier Sound = default!;
public float Range;
}
} }

View File

@@ -19,8 +19,6 @@ public abstract partial class SharedGunSystem
SubscribeLocalEvent<BallisticAmmoProviderComponent, MapInitEvent>(OnBallisticMapInit); SubscribeLocalEvent<BallisticAmmoProviderComponent, MapInitEvent>(OnBallisticMapInit);
SubscribeLocalEvent<BallisticAmmoProviderComponent, TakeAmmoEvent>(OnBallisticTakeAmmo); SubscribeLocalEvent<BallisticAmmoProviderComponent, TakeAmmoEvent>(OnBallisticTakeAmmo);
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetAmmoCountEvent>(OnBallisticAmmoCount); SubscribeLocalEvent<BallisticAmmoProviderComponent, GetAmmoCountEvent>(OnBallisticAmmoCount);
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentGetState>(OnBallisticGetState);
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentHandleState>(OnBallisticHandleState);
SubscribeLocalEvent<BallisticAmmoProviderComponent, ExaminedEvent>(OnBallisticExamine); SubscribeLocalEvent<BallisticAmmoProviderComponent, ExaminedEvent>(OnBallisticExamine);
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<Verb>>(OnBallisticVerb); SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<Verb>>(OnBallisticVerb);
@@ -175,32 +173,6 @@ public abstract partial class SharedGunSystem
protected abstract void Cycle(BallisticAmmoProviderComponent component, MapCoordinates coordinates); protected abstract void Cycle(BallisticAmmoProviderComponent component, MapCoordinates coordinates);
private void OnBallisticGetState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentGetState args)
{
args.State = new BallisticAmmoProviderComponentState()
{
UnspawnedCount = component.UnspawnedCount,
Entities = component.Entities,
Cycled = component.Cycled,
};
}
private void OnBallisticHandleState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentHandleState args)
{
if (args.Current is not BallisticAmmoProviderComponentState state)
return;
component.Cycled = state.Cycled;
component.UnspawnedCount = state.UnspawnedCount;
component.Entities.Clear();
foreach (var ent in state.Entities)
{
component.Entities.Add(ent);
}
}
private void OnBallisticInit(EntityUid uid, BallisticAmmoProviderComponent component, ComponentInit args) private void OnBallisticInit(EntityUid uid, BallisticAmmoProviderComponent component, ComponentInit args)
{ {
component.Container = Containers.EnsureContainer<Container>(uid, "ballistic-ammo"); component.Container = Containers.EnsureContainer<Container>(uid, "ballistic-ammo");
@@ -292,12 +264,4 @@ public abstract partial class SharedGunSystem
Appearance.SetData(uid, AmmoVisuals.AmmoCount, GetBallisticShots(component), appearance); Appearance.SetData(uid, AmmoVisuals.AmmoCount, GetBallisticShots(component), appearance);
Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance); Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance);
} }
[Serializable, NetSerializable]
private sealed class BallisticAmmoProviderComponentState : ComponentState
{
public int UnspawnedCount;
public List<EntityUid> Entities = default!;
public bool Cycled;
}
} }

View File

@@ -11,23 +11,6 @@ public abstract partial class SharedGunSystem
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentInit>(OnBasicEntityInit); SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentInit>(OnBasicEntityInit);
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, TakeAmmoEvent>(OnBasicEntityTakeAmmo); SubscribeLocalEvent<BasicEntityAmmoProviderComponent, TakeAmmoEvent>(OnBasicEntityTakeAmmo);
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, GetAmmoCountEvent>(OnBasicEntityAmmoCount); SubscribeLocalEvent<BasicEntityAmmoProviderComponent, GetAmmoCountEvent>(OnBasicEntityAmmoCount);
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentGetState>(OnBasicEntityGetState);
SubscribeLocalEvent<BasicEntityAmmoProviderComponent, ComponentHandleState>(OnBasicEntityHandleState);
}
private void OnBasicEntityGetState(EntityUid uid, BasicEntityAmmoProviderComponent component, ref ComponentGetState args)
{
args.State = new BasicEntityAmmoProviderComponentState(component.Capacity, component.Count);
}
private void OnBasicEntityHandleState(EntityUid uid, BasicEntityAmmoProviderComponent component, ref ComponentHandleState args)
{
if (args.Current is BasicEntityAmmoProviderComponentState state)
{
component.Capacity = state.Capacity;
component.Count = state.Count;
}
} }
private void OnBasicEntityInit(EntityUid uid, BasicEntityAmmoProviderComponent component, ComponentInit args) private void OnBasicEntityInit(EntityUid uid, BasicEntityAmmoProviderComponent component, ComponentInit args)

View File

@@ -6,31 +6,8 @@ namespace Content.Shared.Weapons.Ranged.Systems;
public abstract partial class SharedGunSystem public abstract partial class SharedGunSystem
{ {
// needed for server system
protected virtual void InitializeCartridge() protected virtual void InitializeCartridge()
{ {
SubscribeLocalEvent<CartridgeAmmoComponent, ComponentGetState>(OnCartridgeGetState);
SubscribeLocalEvent<CartridgeAmmoComponent, ComponentHandleState>(OnCartridgeHandleState);
}
private void OnCartridgeHandleState(EntityUid uid, CartridgeAmmoComponent component, ref ComponentHandleState args)
{
if (args.Current is not CartridgeAmmoComponentState state)
return;
component.Spent = state.Spent;
}
private void OnCartridgeGetState(EntityUid uid, CartridgeAmmoComponent component, ref ComponentGetState args)
{
args.State = new CartridgeAmmoComponentState()
{
Spent = component.Spent,
};
}
[Serializable, NetSerializable]
private sealed class CartridgeAmmoComponentState : ComponentState
{
public bool Spent;
} }
} }

View File

@@ -67,10 +67,8 @@ public abstract partial class SharedGunSystem : EntitySystem
{ {
Sawmill = Logger.GetSawmill("gun"); Sawmill = Logger.GetSawmill("gun");
Sawmill.Level = LogLevel.Info; Sawmill.Level = LogLevel.Info;
SubscribeLocalEvent<GunComponent, ComponentGetState>(OnGetState);
SubscribeAllEvent<RequestShootEvent>(OnShootRequest); SubscribeAllEvent<RequestShootEvent>(OnShootRequest);
SubscribeAllEvent<RequestStopShootEvent>(OnStopShootRequest); SubscribeAllEvent<RequestStopShootEvent>(OnStopShootRequest);
SubscribeLocalEvent<GunComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<GunComponent, MeleeAttackAttemptEvent>(OnGunMeleeAttempt); SubscribeLocalEvent<GunComponent, MeleeAttackAttemptEvent>(OnGunMeleeAttempt);
// Ammo providers // Ammo providers
@@ -144,37 +142,6 @@ public abstract partial class SharedGunSystem : EntitySystem
StopShooting(ev.Gun, gun); StopShooting(ev.Gun, gun);
} }
private void OnGetState(EntityUid uid, GunComponent component, ref ComponentGetState args)
{
args.State = new GunComponentState
{
FireRate = component.FireRate,
CurrentAngle = component.CurrentAngle,
MinAngle = component.MinAngle,
MaxAngle = component.MaxAngle,
NextFire = component.NextFire,
ShotCounter = component.ShotCounter,
SelectiveFire = component.SelectedMode,
AvailableSelectiveFire = component.AvailableModes,
};
}
private void OnHandleState(EntityUid uid, GunComponent component, ref ComponentHandleState args)
{
if (args.Current is not GunComponentState state)
return;
Sawmill.Debug($"Handle state: setting shot count from {component.ShotCounter} to {state.ShotCounter}");
component.FireRate = state.FireRate;
component.CurrentAngle = state.CurrentAngle;
component.MinAngle = state.MinAngle;
component.MaxAngle = state.MaxAngle;
component.NextFire = state.NextFire;
component.ShotCounter = state.ShotCounter;
component.SelectedMode = state.SelectiveFire;
component.AvailableModes = state.AvailableSelectiveFire;
}
public bool CanShoot(GunComponent component) public bool CanShoot(GunComponent component)
{ {
if (component.NextFire > Timing.CurTime) if (component.NextFire > Timing.CurTime)
@@ -418,19 +385,6 @@ public abstract partial class SharedGunSystem : EntitySystem
} }
protected abstract void CreateEffect(EntityUid uid, MuzzleFlashEvent message, EntityUid? user = null); protected abstract void CreateEffect(EntityUid uid, MuzzleFlashEvent message, EntityUid? user = null);
[Serializable, NetSerializable]
protected sealed class GunComponentState : ComponentState
{
public Angle CurrentAngle;
public Angle MinAngle;
public Angle MaxAngle;
public TimeSpan NextFire;
public float FireRate;
public int ShotCounter;
public SelectiveFire SelectiveFire;
public SelectiveFire AvailableSelectiveFire;
}
/// <summary> /// <summary>
/// Used for animated effects on the client. /// Used for animated effects on the client.
/// </summary> /// </summary>