using Content.Shared.Damage; using Content.Shared.Tag; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Weapons.Ranged.Components; [RegisterComponent, NetworkedComponent, Virtual] [AutoGenerateComponentState] public partial class GunComponent : Component { #region Sound [ViewVariables(VVAccess.ReadWrite), DataField("soundGunshot")] public SoundSpecifier? SoundGunshot = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/smg.ogg"); [ViewVariables(VVAccess.ReadWrite), DataField("soundEmpty")] public SoundSpecifier? SoundEmpty = new SoundPathSpecifier("/Audio/Weapons/Guns/Empty/empty.ogg"); /// /// Sound played when toggling the for this gun. /// [ViewVariables(VVAccess.ReadWrite), DataField("soundMode")] public SoundSpecifier? SoundModeToggle = 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 /// /// A scalar value applied to the vector governing camera recoil. /// If 0, there will be no camera recoil. /// [DataField("cameraRecoilScalar"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float CameraRecoilScalar = 1f; /// /// Last time the gun fired. /// Used for recoil purposes. /// [DataField("lastFire")] public TimeSpan LastFire = TimeSpan.Zero; /// /// What the current spread is for shooting. This gets changed every time the gun fires. /// [DataField("currentAngle")] [AutoNetworkedField] public Angle CurrentAngle; /// /// How much the spread increases every time the gun fires. /// [ViewVariables(VVAccess.ReadWrite), DataField("angleIncrease")] public Angle AngleIncrease = Angle.FromDegrees(0.5); /// /// How much the decreases per second. /// [DataField("angleDecay")] public Angle AngleDecay = Angle.FromDegrees(4); /// /// The maximum angle allowed for /// [ViewVariables(VVAccess.ReadWrite), DataField("maxAngle")] [AutoNetworkedField] public Angle MaxAngle = Angle.FromDegrees(2); /// /// The minimum angle allowed for /// [ViewVariables(VVAccess.ReadWrite), DataField("minAngle")] [AutoNetworkedField] public Angle MinAngle = Angle.FromDegrees(1); #endregion /// /// Whether this gun is shot via the use key or the alt-use key. /// [ViewVariables(VVAccess.ReadWrite), DataField("useKey"), AutoNetworkedField] public bool UseKey = true; /// /// Where the gun is being requested to shoot. /// [ViewVariables] public EntityCoordinates? ShootCoordinates = null; /// /// Used for tracking semi-auto / burst /// [ViewVariables] [AutoNetworkedField] public int ShotCounter = 0; /// /// How many times it shoots per second. /// [ViewVariables(VVAccess.ReadWrite), DataField("fireRate")] [AutoNetworkedField] public float FireRate = 8f; /// /// Starts fire cooldown when equipped if true. /// [ViewVariables(VVAccess.ReadWrite), DataField("resetOnHandSelected")] public bool ResetOnHandSelected = true; /// /// Type of ammo the gun can work with /// [ViewVariables(VVAccess.ReadWrite), DataField("compatibleAmmo")] public List>? CompatibleAmmo; /// /// Damage the gun deals when used with wrong ammo /// [ViewVariables(VVAccess.ReadWrite), DataField("damageOnWrongAmmo")] public DamageSpecifier? DamageOnWrongAmmo = null; /// /// How fast the projectile moves. /// [ViewVariables(VVAccess.ReadWrite), DataField("projectileSpeed")] public float ProjectileSpeed = 25f; /// /// 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. /// [DataField("nextFire", customTypeSerializer:typeof(TimeOffsetSerializer))] [AutoNetworkedField] public TimeSpan NextFire = TimeSpan.Zero; /// /// What firemodes can be selected. /// [ViewVariables(VVAccess.ReadWrite), DataField("availableModes")] [AutoNetworkedField] public SelectiveFire AvailableModes = SelectiveFire.SemiAuto; /// /// What firemode is currently selected. /// [ViewVariables(VVAccess.ReadWrite), DataField("selectedMode")] [AutoNetworkedField] public SelectiveFire SelectedMode = SelectiveFire.SemiAuto; /// /// Whether or not information about /// the gun will be shown on examine. /// [DataField("showExamineText")] public bool ShowExamineText = true; /// /// Whether or not someone with the /// clumsy trait can shoot this /// [DataField("clumsyProof"), ViewVariables(VVAccess.ReadWrite)] public bool ClumsyProof = false; } [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! }