diff --git a/Content.Shared/Weapons/Melee/Components/MeleeRequiresWieldComponent.cs b/Content.Shared/Weapons/Melee/Components/MeleeRequiresWieldComponent.cs index 6cf12d58f2..cc05574224 100644 --- a/Content.Shared/Weapons/Melee/Components/MeleeRequiresWieldComponent.cs +++ b/Content.Shared/Weapons/Melee/Components/MeleeRequiresWieldComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Wieldable; using Robust.Shared.GameStates; namespace Content.Shared.Weapons.Melee.Components; @@ -5,7 +6,7 @@ namespace Content.Shared.Weapons.Melee.Components; /// /// Indicates that this meleeweapon requires wielding to be useable. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, Access(typeof(WieldableSystem))] public sealed class MeleeRequiresWieldComponent : Component { diff --git a/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs index b0aca3af14..e8b93c60fd 100644 --- a/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Wieldable; using Robust.Shared.GameStates; namespace Content.Shared.Weapons.Ranged.Components; @@ -5,7 +6,7 @@ namespace Content.Shared.Weapons.Ranged.Components; /// /// Indicates that this gun requires wielding to be useable. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, Access(typeof(WieldableSystem))] public sealed class GunRequiresWieldComponent : Component { diff --git a/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs new file mode 100644 index 0000000000..58c5fec2d8 --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs @@ -0,0 +1,20 @@ +using Content.Shared.Wieldable; +using Robust.Shared.GameStates; + +namespace Content.Shared.Weapons.Ranged.Components; + +/// +/// Applies an accuracy bonus upon wielding. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(WieldableSystem))] +public sealed partial class GunWieldBonusComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("minAngle"), AutoNetworkedField] + public Angle MinAngle = Angle.FromDegrees(-43); + + /// + /// Angle bonus applied upon being wielded. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("maxAngle"), AutoNetworkedField] + public Angle MaxAngle = Angle.FromDegrees(-43); +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs index abafb4c95f..fd60b4fbf1 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs @@ -29,6 +29,9 @@ public abstract partial class SharedGunSystem private void OnBallisticUse(EntityUid uid, BallisticAmmoProviderComponent component, UseInHandEvent args) { + if (args.Handled) + return; + ManualCycle(uid, component, Transform(uid).MapPosition, args.User); args.Handled = true; } diff --git a/Content.Shared/Wieldable/Components/WieldableComponent.cs b/Content.Shared/Wieldable/Components/WieldableComponent.cs index 541a5a6fde..5a8c533c29 100644 --- a/Content.Shared/Wieldable/Components/WieldableComponent.cs +++ b/Content.Shared/Wieldable/Components/WieldableComponent.cs @@ -26,7 +26,7 @@ public sealed partial class WieldableComponent : Component public bool Wielded = false; [DataField("wieldedInhandPrefix")] - public string WieldedInhandPrefix = "wielded"; + public string? WieldedInhandPrefix = "wielded"; public string? OldInhandPrefix = null; diff --git a/Content.Shared/Wieldable/ItemWieldedEvent.cs b/Content.Shared/Wieldable/ItemWieldedEvent.cs new file mode 100644 index 0000000000..15e204728a --- /dev/null +++ b/Content.Shared/Wieldable/ItemWieldedEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Wieldable; + +/// +/// Raised directed on an entity when it is wielded. +/// +[ByRefEvent] +public readonly record struct ItemWieldedEvent; diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index df73ff636c..0e2b52b9e2 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -39,6 +39,8 @@ public sealed class WieldableSystem : EntitySystem SubscribeLocalEvent(OnMeleeAttempt); SubscribeLocalEvent(OnShootAttempt); + SubscribeLocalEvent(OnGunWielded); + SubscribeLocalEvent(OnGunUnwielded); SubscribeLocalEvent(OnGetMeleeDamage); } @@ -63,6 +65,26 @@ public sealed class WieldableSystem : EntitySystem } } + private void OnGunUnwielded(EntityUid uid, GunWieldBonusComponent component, ItemUnwieldedEvent args) + { + if (!TryComp(uid, out var gun)) + return; + + gun.MinAngle -= component.MinAngle; + gun.MaxAngle -= component.MaxAngle; + Dirty(gun); + } + + private void OnGunWielded(EntityUid uid, GunWieldBonusComponent component, ref ItemWieldedEvent args) + { + if (!TryComp(uid, out var gun)) + return; + + gun.MinAngle += component.MinAngle; + gun.MaxAngle += component.MaxAngle; + Dirty(gun); + } + private void OnDisarmAttemptEvent(EntityUid uid, WieldableComponent component, DisarmAttemptEvent args) { if (component.Wielded) @@ -197,6 +219,9 @@ public sealed class WieldableSystem : EntitySystem _popupSystem.PopupClient(Loc.GetString("wieldable-component-successful-wield", ("item", uid)), args.Args.User, args.Args.User); _popupSystem.PopupEntity(Loc.GetString("wieldable-component-successful-wield-other", ("user", args.Args.User),("item", uid)), args.Args.User, Filter.PvsExcept(args.Args.User), true); + var ev = new ItemWieldedEvent(); + RaiseLocalEvent(uid, ref ev); + Dirty(component); args.Handled = true; } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml index 34dac2a80e..d5fd65554b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_pka.yml @@ -8,9 +8,17 @@ - type: Item sprite: Objects/Weapons/Guns/Basic/kinetic_accelerator.rsi size: 30 + - type: GunWieldBonus + minAngle: -43 + maxAngle: -43 + - type: Wieldable + wieldedInhandPrefix: null - type: Gun fireRate: 0.75 selectedMode: SemiAuto + angleDecay: 45 + minAngle: 44 + maxAngle: 45 availableModes: - SemiAuto soundGunshot: @@ -24,7 +32,7 @@ True: { visible: False } False: { visible: True } - type: RechargeBasicEntityAmmo - rechargeCooldown: 1 + rechargeCooldown: 0.75 rechargeSound: path: /Audio/Weapons/Guns/MagIn/kinetic_reload.ogg - type: BasicEntityAmmoProvider