| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- using System.Numerics;
- using Content.Shared.Weapons.Ranged.Events;
- using Content.Shared.Weapons.Ranged.Systems;
- using Robust.Shared.Audio;
- using Robust.Shared.GameStates;
- using Robust.Shared.Map;
- using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
- namespace Content.Shared.Weapons.Ranged.Components;
- [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true), AutoGenerateComponentPause]
- [Access(typeof(SharedGunSystem))]
- public sealed partial class GunComponent : Component
- {
- #region Sound
- /// <summary>
- /// The base sound to use when the gun is fired.
- /// </summary>
- [DataField]
- public SoundSpecifier? SoundGunshot = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/smg.ogg");
- /// <summary>
- /// The sound to use when the gun is fired.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public SoundSpecifier? SoundGunshotModified;
- [DataField]
- public SoundSpecifier? SoundEmpty = new SoundPathSpecifier("/Audio/Weapons/Guns/Empty/empty.ogg");
- /// <summary>
- /// Sound played when toggling the <see cref="SelectedMode"/> for this gun.
- /// </summary>
- [DataField]
- public SoundSpecifier? SoundMode = new SoundPathSpecifier("/Audio/Weapons/Guns/Misc/selector.ogg");
- #endregion
- #region Recoil
- // These values are very small for now until we get a debug overlay and fine tune it
- /// <summary>
- /// The base scalar value applied to the vector governing camera recoil.
- /// </summary>
- [DataField, AutoNetworkedField]
- public float CameraRecoilScalar = 1f;
- /// <summary>
- /// A scalar value applied to the vector governing camera recoil.
- /// If 0, there will be no camera recoil.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public float CameraRecoilScalarModified = 1f;
- /// <summary>
- /// Last time the gun fired.
- /// Used for recoil purposes.
- /// </summary>
- [DataField]
- public TimeSpan LastFire = TimeSpan.Zero;
- /// <summary>
- /// What the current spread is for shooting. This gets changed every time the gun fires.
- /// </summary>
- [DataField]
- [AutoNetworkedField]
- public Angle CurrentAngle;
- /// <summary>
- /// The base value for how much the spread increases every time the gun fires.
- /// </summary>
- [DataField]
- public Angle AngleIncrease = Angle.FromDegrees(0.5);
- /// <summary>
- /// How much the spread increases every time the gun fires.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public Angle AngleIncreaseModified;
- /// <summary>
- /// The base value for how much the <see cref="CurrentAngle"/> decreases per second.
- /// </summary>
- [DataField]
- public Angle AngleDecay = Angle.FromDegrees(4);
- /// <summary>
- /// How much the <see cref="CurrentAngle"/> decreases per second.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public Angle AngleDecayModified;
- /// <summary>
- /// The base value for the maximum angle allowed for <see cref="CurrentAngle"/>
- /// </summary>
- [DataField]
- [AutoNetworkedField]
- public Angle MaxAngle = Angle.FromDegrees(2);
- /// <summary>
- /// The maximum angle allowed for <see cref="CurrentAngle"/>
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public Angle MaxAngleModified;
- /// <summary>
- /// The base value for the minimum angle allowed for <see cref="CurrentAngle"/>
- /// </summary>
- [DataField]
- [AutoNetworkedField]
- public Angle MinAngle = Angle.FromDegrees(1);
- /// <summary>
- /// The minimum angle allowed for <see cref="CurrentAngle"/>.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public Angle MinAngleModified;
- #endregion
- /// <summary>
- /// Whether this gun is shot via the use key or the alt-use key.
- /// </summary>
- [DataField, AutoNetworkedField]
- public bool UseKey = true;
- /// <summary>
- /// Where the gun is being requested to shoot.
- /// </summary>
- [ViewVariables]
- public EntityCoordinates? ShootCoordinates = null;
- /// <summary>
- /// Who the gun is being requested to shoot at directly.
- /// </summary>
- [ViewVariables]
- public EntityUid? Target = null;
- /// <summary>
- /// The base value for how many shots to fire per burst.
- /// </summary>
- [DataField, AutoNetworkedField]
- public int ShotsPerBurst = 3;
- /// <summary>
- /// How many shots to fire per burst.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public int ShotsPerBurstModified = 3;
- /// <summary>
- /// How long time must pass between burstfire shots.
- /// </summary>
- [DataField, AutoNetworkedField]
- public float BurstCooldown = 0.25f;
- /// <summary>
- /// The fire rate of the weapon in burst fire mode.
- /// </summary>
- [DataField, AutoNetworkedField]
- public float BurstFireRate = 8f;
- /// <summary>
- /// Whether the burst fire mode has been activated.
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public bool BurstActivated = false;
- /// <summary>
- /// The burst fire bullet count.
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public int BurstShotsCount = 0;
- /// <summary>
- /// Used for tracking semi-auto / burst
- /// </summary>
- [ViewVariables]
- [AutoNetworkedField]
- public int ShotCounter = 0;
- /// <summary>
- /// The base value for how many times it shoots per second.
- /// </summary>
- [DataField]
- [AutoNetworkedField]
- public float FireRate = 8f;
- /// <summary>
- /// How many times it shoots per second.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public float FireRateModified;
- /// <summary>
- /// Starts fire cooldown when equipped if true.
- /// </summary>
- [DataField]
- public bool ResetOnHandSelected = true;
- /// <summary>
- /// The base value for how fast the projectile moves.
- /// </summary>
- [DataField]
- public float ProjectileSpeed = 25f;
- /// <summary>
- /// How fast the projectile moves.
- /// <seealso cref="GunRefreshModifiersEvent"/>
- /// </summary>
- [AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
- public float ProjectileSpeedModified;
- /// <summary>
- /// When the gun is next available to be shot.
- /// Can be set multiple times in a single tick due to guns firing faster than a single tick time.
- /// </summary>
- [DataField(customTypeSerializer:typeof(TimeOffsetSerializer))]
- [AutoNetworkedField]
- [AutoPausedField]
- public TimeSpan NextFire = TimeSpan.Zero;
- /// <summary>
- /// What firemodes can be selected.
- /// </summary>
- [DataField]
- [AutoNetworkedField]
- public SelectiveFire AvailableModes = SelectiveFire.SemiAuto;
- /// <summary>
- /// What firemode is currently selected.
- /// </summary>
- [DataField]
- [AutoNetworkedField]
- public SelectiveFire SelectedMode = SelectiveFire.SemiAuto;
- /// <summary>
- /// Whether or not information about
- /// the gun will be shown on examine.
- /// </summary>
- [DataField]
- public bool ShowExamineText = true;
- /// <summary>
- /// Whether or not someone with the
- /// clumsy trait can shoot this
- /// </summary>
- [DataField]
- public bool ClumsyProof = false;
- /// <summary>
- /// Firing direction for an item not being held (e.g. shuttle cannons, thrown guns still firing).
- /// </summary>
- [DataField]
- public Vector2 DefaultDirection = new Vector2(0, -1);
- }
- [Flags]
- public enum SelectiveFire : byte
- {
- Invalid = 0,
- // Combat mode already functions as the equivalent of Safety
- SemiAuto = 1 << 0,
- Burst = 1 << 1,
- FullAuto = 1 << 2, // Not in the building!
- }
|