From e8b2d0a844d43a4f7f87fe0ffe9e1d810951dba9 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sun, 5 Dec 2021 16:23:47 +1300 Subject: [PATCH] Make BatteryBarrelComponent use item slots. (#5591) --- .../ClientBatteryBarrelComponent.cs | 17 ++ .../Weapon/Ranged/Barrels/BarrelSystem.cs | 48 +--- .../Components/BoltActionBarrelComponent.cs | 6 +- .../Barrels/Components/PumpBarrelComponent.cs | 6 +- .../Components/RevolverBarrelComponent.cs | 6 +- .../ServerBatteryBarrelComponent.cs | 122 ++------- .../ServerMagazineBarrelComponent.cs | 6 +- .../Components/ServerRangedBarrelComponent.cs | 10 +- .../Containers/ItemSlot/ItemSlotsComponent.cs | 19 ++ .../Containers/ItemSlot/ItemSlotsSystem.cs | 26 +- .../Weapons/Guns/Battery/battery_guns.yml | 252 ++++++------------ 11 files changed, 184 insertions(+), 334 deletions(-) diff --git a/Content.Client/Weapons/Ranged/Barrels/Components/ClientBatteryBarrelComponent.cs b/Content.Client/Weapons/Ranged/Barrels/Components/ClientBatteryBarrelComponent.cs index f84355b22b..70e2e5c4c2 100644 --- a/Content.Client/Weapons/Ranged/Barrels/Components/ClientBatteryBarrelComponent.cs +++ b/Content.Client/Weapons/Ranged/Barrels/Components/ClientBatteryBarrelComponent.cs @@ -1,6 +1,7 @@ using System; using Content.Client.Items.Components; using Content.Client.Stylesheets; +using Content.Shared.Containers.ItemSlots; using Content.Shared.Weapons.Ranged.Barrels.Components; using Robust.Client.Graphics; using Robust.Client.UserInterface; @@ -8,6 +9,7 @@ using Robust.Client.UserInterface.Controls; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.Maths; +using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; using static Robust.Client.UserInterface.Controls.BoxContainer; @@ -21,6 +23,9 @@ namespace Content.Client.Weapons.Ranged.Barrels.Components private StatusControl? _statusControl; + [DataField("cellSlot", required: true)] + public ItemSlot CellSlot = default!; + /// /// Count of bullets in the magazine. /// @@ -30,6 +35,18 @@ namespace Content.Client.Weapons.Ranged.Barrels.Components [ViewVariables] public (int count, int max)? MagazineCount { get; private set; } + protected override void Initialize() + { + base.Initialize(); + EntitySystem.Get().AddItemSlot(OwnerUid, $"{Name}-powercell-container", CellSlot); + } + + protected override void OnRemove() + { + base.OnRemove(); + EntitySystem.Get().RemoveItemSlot(OwnerUid, CellSlot); + } + public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) { base.HandleComponentState(curState, nextState); diff --git a/Content.Server/Weapon/Ranged/Barrels/BarrelSystem.cs b/Content.Server/Weapon/Ranged/Barrels/BarrelSystem.cs index 7c07749499..c1591926b4 100644 --- a/Content.Server/Weapon/Ranged/Barrels/BarrelSystem.cs +++ b/Content.Server/Weapon/Ranged/Barrels/BarrelSystem.cs @@ -3,9 +3,11 @@ using Content.Server.Weapon.Ranged.Barrels.Components; using Content.Shared.ActionBlocker; using Content.Shared.Popups; using Content.Shared.Verbs; +using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; +using System; namespace Content.Server.Weapon.Ranged.Barrels { @@ -19,8 +21,8 @@ namespace Content.Server.Weapon.Ranged.Barrels SubscribeLocalEvent(AddSpinVerb); - SubscribeLocalEvent(AddEjectCellVerb); - SubscribeLocalEvent(AddInsertCellVerb); + SubscribeLocalEvent(OnCellSlotUpdated); + SubscribeLocalEvent(OnCellSlotUpdated); SubscribeLocalEvent(AddToggleBoltVerb); @@ -28,6 +30,12 @@ namespace Content.Server.Weapon.Ranged.Barrels SubscribeLocalEvent(AddEjectMagazineVerb); } + private void OnCellSlotUpdated(EntityUid uid, ServerBatteryBarrelComponent component, ContainerModifiedMessage args) + { + if (args.Container.ID == component.CellSlot.ID) + component.UpdateAppearance(); + } + private void AddSpinVerb(EntityUid uid, RevolverBarrelComponent component, GetAlternativeVerbsEvent args) { if (args.Hands == null || !args.CanAccess || !args.CanInteract) @@ -62,42 +70,6 @@ namespace Content.Server.Weapon.Ranged.Barrels args.Verbs.Add(verb); } - // TODO VERBS EJECTABLES Standardize eject/insert verbs into a single system? - // Really, why isn't this just PowerCellSlotComponent? - private void AddEjectCellVerb(EntityUid uid, ServerBatteryBarrelComponent component, GetAlternativeVerbsEvent args) - { - if (args.Hands == null || - !args.CanAccess || - !args.CanInteract || - !component.PowerCellRemovable || - component.PowerCell == null || - !_actionBlockerSystem.CanPickup(args.User.Uid)) - return; - - Verb verb = new(); - verb.Text = component.PowerCell.Owner.Name; - verb.Category = VerbCategory.Eject; - verb.Act = () => component.TryEjectCell(args.User); - args.Verbs.Add(verb); - } - - private void AddInsertCellVerb(EntityUid uid, ServerBatteryBarrelComponent component, GetInteractionVerbsEvent args) - { - if (args.Using == null || - !args.CanAccess || - !args.CanInteract || - component.PowerCell != null || - !args.Using.HasComponent() || - !_actionBlockerSystem.CanDrop(args.User.Uid)) - return; - - Verb verb = new(); - verb.Text = args.Using.Name; - verb.Category = VerbCategory.Insert; - verb.Act = () => component.TryInsertPowerCell(args.Using); - args.Verbs.Add(verb); - } - private void AddEjectMagazineVerb(EntityUid uid, ServerMagazineBarrelComponent component, GetAlternativeVerbsEvent args) { if (args.Hands == null || diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs index a59ea86059..1023b1da09 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/BoltActionBarrelComponent.cs @@ -26,7 +26,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components [RegisterComponent] [NetworkedComponent()] #pragma warning disable 618 - public sealed class BoltActionBarrelComponent : ServerRangedBarrelComponent, IMapInit, IExamine + public sealed class BoltActionBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit, IExamine #pragma warning restore 618 { // Originally I had this logic shared with PumpBarrel and used a couple of variables to control things @@ -267,7 +267,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components return false; } - public override bool UseEntity(UseEntityEventArgs eventArgs) + public bool UseEntity(UseEntityEventArgs eventArgs) { if (BoltOpen) { @@ -281,7 +281,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components return true; } - public override async Task InteractUsing(InteractUsingEventArgs eventArgs) + public async Task InteractUsing(InteractUsingEventArgs eventArgs) { return TryInsertBullet(eventArgs.User, eventArgs.Using); } diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs index 5fba188d50..c53f50c58a 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/PumpBarrelComponent.cs @@ -25,7 +25,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components /// [RegisterComponent] [NetworkedComponent()] - public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IMapInit, ISerializationHooks + public sealed class PumpBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IMapInit, ISerializationHooks { public override string Name => "PumpBarrel"; @@ -223,13 +223,13 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components return false; } - public override bool UseEntity(UseEntityEventArgs eventArgs) + public bool UseEntity(UseEntityEventArgs eventArgs) { Cycle(true); return true; } - public override async Task InteractUsing(InteractUsingEventArgs eventArgs) + public async Task InteractUsing(InteractUsingEventArgs eventArgs) { return TryInsertBullet(eventArgs); } diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs index bb74085113..c6f4735ada 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/RevolverBarrelComponent.cs @@ -23,7 +23,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components { [RegisterComponent] [NetworkedComponent()] - public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent, ISerializationHooks + public sealed class RevolverBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, ISerializationHooks { [Dependency] private readonly IRobustRandom _random = default!; @@ -253,7 +253,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components /// /// /// - public override bool UseEntity(UseEntityEventArgs eventArgs) + public bool UseEntity(UseEntityEventArgs eventArgs) { EjectAllSlots(); Dirty(); @@ -261,7 +261,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components return true; } - public override async Task InteractUsing(InteractUsingEventArgs eventArgs) + public async Task InteractUsing(InteractUsingEventArgs eventArgs) { return TryInsertBullet(eventArgs.User, eventArgs.Using); } diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs index 71a7ccab61..256d3732b6 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/ServerBatteryBarrelComponent.cs @@ -1,18 +1,12 @@ using System; -using System.Threading.Tasks; -using Content.Server.Hands.Components; -using Content.Server.Items; using Content.Server.Power.Components; using Content.Server.Projectiles.Components; -using Content.Shared.Interaction; -using Content.Shared.Sound; +using Content.Shared.Containers.ItemSlots; using Content.Shared.Weapons.Ranged.Barrels.Components; -using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.Map; -using Robust.Shared.Player; using Robust.Shared.Players; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; @@ -25,6 +19,9 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components { public override string Name => "BatteryBarrel"; + [DataField("cellSlot", required: true)] + public ItemSlot CellSlot = new(); + // The minimum change we need before we can fire [DataField("lowerChargeLimit")] [ViewVariables] private float _lowerChargeLimit = 10; @@ -34,20 +31,14 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components [DataField("ammoPrototype")] [ViewVariables] private string? _ammoPrototype; - [ViewVariables] public IEntity? PowerCellEntity => _powerCellContainer.ContainedEntity; - public BatteryComponent? PowerCell => _powerCellContainer.ContainedEntity?.GetComponentOrNull(); - private ContainerSlot _powerCellContainer = default!; + public BatteryComponent? PowerCell => CellSlot.Item?.GetComponentOrNull(); private ContainerSlot _ammoContainer = default!; - [DataField("powerCellPrototype")] - private string? _powerCellPrototype = default; - [DataField("powerCellRemovable")] - [ViewVariables] public bool PowerCellRemovable = default; public override int ShotsLeft { get { - var powerCell = _powerCellContainer.ContainedEntity; + var powerCell = CellSlot.Item; if (powerCell == null) { @@ -62,7 +53,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components { get { - var powerCell = _powerCellContainer.ContainedEntity; + var powerCell = CellSlot.Item; if (powerCell == null) { @@ -75,12 +66,6 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components private AppearanceComponent? _appearanceComponent; - // Sounds - [DataField("soundPowerCellInsert", required: true)] - private SoundSpecifier _soundPowerCellInsert = default!; - [DataField("soundPowerCellEject", required: true)] - private SoundSpecifier _soundPowerCellEject = default!; - public override ComponentState GetComponentState() { (int, int)? count = (ShotsLeft, Capacity); @@ -93,12 +78,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components protected override void Initialize() { base.Initialize(); - _powerCellContainer = ContainerHelpers.EnsureContainer(Owner, $"{Name}-powercell-container", out var existing); - if (!existing && _powerCellPrototype != null) - { - var powerCellEntity = Owner.EntityManager.SpawnEntity(_powerCellPrototype, Owner.Transform.Coordinates); - _powerCellContainer.Insert(powerCellEntity); - } + EntitySystem.Get().AddItemSlot(OwnerUid, $"{Name}-powercell-container", CellSlot); if (_ammoPrototype != null) { @@ -112,6 +92,12 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components Dirty(); } + protected override void OnRemove() + { + base.OnRemove(); + EntitySystem.Get().RemoveItemSlot(OwnerUid, CellSlot); + } + protected override void Startup() { base.Startup(); @@ -120,7 +106,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components public void UpdateAppearance() { - _appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, _powerCellContainer.ContainedEntity != null); + _appearanceComponent?.SetData(MagazineBarrelVisuals.MagLoaded, CellSlot.HasItem); _appearanceComponent?.SetData(AmmoVisuals.AmmoCount, ShotsLeft); _appearanceComponent?.SetData(AmmoVisuals.AmmoMax, Capacity); Dirty(); @@ -142,7 +128,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components public override IEntity? TakeProjectile(EntityCoordinates spawnAt) { - var powerCellEntity = _powerCellContainer.ContainedEntity; + var powerCellEntity = CellSlot.Item; if (powerCellEntity == null) { @@ -197,81 +183,5 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components UpdateAppearance(); return entity; } - - public bool TryInsertPowerCell(IEntity entity) - { - if (_powerCellContainer.ContainedEntity != null) - { - return false; - } - - if (!entity.HasComponent()) - { - return false; - } - - SoundSystem.Play(Filter.Pvs(Owner), _soundPowerCellInsert.GetSound(), Owner, AudioParams.Default.WithVolume(-2)); - - _powerCellContainer.Insert(entity); - - Dirty(); - UpdateAppearance(); - return true; - } - - public override bool UseEntity(UseEntityEventArgs eventArgs) - { - if (!PowerCellRemovable) - { - return false; - } - - if (PowerCellEntity == null) - { - return false; - } - - return TryEjectCell(eventArgs.User); - } - - public bool TryEjectCell(IEntity user) - { - if (PowerCell == null || !PowerCellRemovable) - { - return false; - } - - if (!user.TryGetComponent(out HandsComponent? hands)) - { - return false; - } - - var cell = PowerCell; - if (!_powerCellContainer.Remove(cell.Owner)) - { - return false; - } - - Dirty(); - UpdateAppearance(); - - if (!hands.PutInHand(cell.Owner.GetComponent())) - { - cell.Owner.Transform.Coordinates = user.Transform.Coordinates; - } - - SoundSystem.Play(Filter.Pvs(Owner), _soundPowerCellEject.GetSound(), Owner, AudioParams.Default.WithVolume(-2)); - return true; - } - - public override async Task InteractUsing(InteractUsingEventArgs eventArgs) - { - if (!eventArgs.Using.HasComponent()) - { - return false; - } - - return TryInsertPowerCell(eventArgs.Using); - } } } diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs index 67fd481c56..e7c055bb29 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/ServerMagazineBarrelComponent.cs @@ -27,7 +27,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components [RegisterComponent] [NetworkedComponent()] #pragma warning disable 618 - public sealed class ServerMagazineBarrelComponent : ServerRangedBarrelComponent, IExamine + public sealed class ServerMagazineBarrelComponent : ServerRangedBarrelComponent, IUse, IInteractUsing, IExamine #pragma warning restore 618 { public override string Name => "MagazineBarrel"; @@ -248,7 +248,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components _appearanceComponent?.SetData(AmmoVisuals.AmmoMax, Capacity); } - public override bool UseEntity(UseEntityEventArgs eventArgs) + public bool UseEntity(UseEntityEventArgs eventArgs) { // Behavior: // If bolt open just close it @@ -393,7 +393,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components UpdateAppearance(); } - public override async Task InteractUsing(InteractUsingEventArgs eventArgs) + public async Task InteractUsing(InteractUsingEventArgs eventArgs) { if (CanInsertMagazine(eventArgs.User, eventArgs.Using, quiet: false)) { diff --git a/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs b/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs index 2ed5f793da..208ec83e33 100644 --- a/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs +++ b/Content.Server/Weapon/Ranged/Barrels/Components/ServerRangedBarrelComponent.cs @@ -38,7 +38,7 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components /// Only difference between them is how they retrieve a projectile to shoot (battery, magazine, etc.) /// #pragma warning disable 618 - public abstract class ServerRangedBarrelComponent : SharedRangedBarrelComponent, IUse, IInteractUsing, IExamine, ISerializationHooks + public abstract class ServerRangedBarrelComponent : SharedRangedBarrelComponent, IExamine, ISerializationHooks #pragma warning restore 618 { // There's still some of py01 and PJB's work left over, especially in underlying shooting logic, @@ -135,9 +135,9 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components } } - protected override void OnAdd() + protected override void Initialize() { - base.OnAdd(); + base.Initialize(); Owner.EnsureComponentWarn(out ServerRangedWeaponComponent rangedWeaponComponent); @@ -169,10 +169,6 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components return angle; } - public abstract bool UseEntity(UseEntityEventArgs eventArgs); - - public abstract Task InteractUsing(InteractUsingEventArgs eventArgs); - public void ChangeFireSelector(FireRateSelector rateSelector) { if ((rateSelector & AllRateSelectors) != 0) diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs index 601759450a..9410b748c6 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs @@ -1,6 +1,7 @@ using Content.Shared.Sound; using Content.Shared.Whitelist; using Robust.Shared.Analyzers; +using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Prototypes; @@ -81,6 +82,12 @@ namespace Content.Shared.Containers.ItemSlots public SoundSpecifier? EjectSound; // maybe default to /Audio/Machines/id_swipe.ogg? + /// + /// Options used for playing the insert/eject sounds. + /// + [DataField("soundOptions")] + public AudioParams SoundOptions = AudioParams.Default; + /// /// The name of this item slot. This will be shown to the user in the verb menu. /// @@ -116,6 +123,18 @@ namespace Content.Shared.Containers.ItemSlots [DataField("ejectOnInteract")] public bool EjectOnInteract = false; + /// + /// If true, and if this slot is attached to an item, then it will attempt to eject slot when to the slot is + /// used in the user's hands. + /// + /// + /// Desirable for things like ranged weapons ('Z' to eject), but not desirable for others (e.g., PDA uses + /// 'Z' to open UI). Unlike , this will not make any changes to the context + /// menu, nor will it disable alt-click interactions. + /// + [DataField("ejectOnUse")] + public bool EjectOnUse = false; + /// /// Override the insert verb text. Defaults to [insert category] -> [item-name]. If not null, the verb will /// not be given a category. diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs index 7150f409e0..881ffab042 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs @@ -34,6 +34,7 @@ namespace Content.Shared.Containers.ItemSlots SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnInteractHand); + SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(AddEjectVerbs); SubscribeLocalEvent(AddInteractionVerbsVerbs); @@ -125,6 +126,25 @@ namespace Content.Shared.Containers.ItemSlots } } + /// + /// Attempt to eject an item from the first valid item slot. + /// + private void OnUseInHand(EntityUid uid, ItemSlotsComponent itemSlots, UseInHandEvent args) + { + if (args.Handled) + return; + + foreach (var slot in itemSlots.Slots.Values) + { + if (slot.Locked || !slot.EjectOnUse || slot.Item == null) + continue; + + args.Handled = true; + TryEjectToHands(uid, slot, args.UserUid); + break; + } + } + /// /// Tries to insert a held item in any fitting item slot. If a valid slot already contains an item, it will /// swap it out and place the old one in the user's hand. @@ -172,7 +192,7 @@ namespace Content.Shared.Containers.ItemSlots // ContainerSlot automatically raises a directed EntInsertedIntoContainerMessage if (slot.InsertSound != null) - SoundSystem.Play(Filter.Pvs(uid), slot.InsertSound.GetSound(), uid); + SoundSystem.Play(Filter.Pvs(uid), slot.InsertSound.GetSound(), uid, slot.SoundOptions); } /// @@ -267,7 +287,7 @@ namespace Content.Shared.Containers.ItemSlots // ContainerSlot automatically raises a directed EntRemovedFromContainerMessage if (slot.EjectSound != null) - SoundSystem.Play(Filter.Pvs(uid), slot.EjectSound.GetSound(), uid); + SoundSystem.Play(Filter.Pvs(uid), slot.EjectSound.GetSound(), uid, slot.SoundOptions); } /// @@ -317,7 +337,7 @@ namespace Content.Shared.Containers.ItemSlots return false; if (user != null && EntityManager.TryGetComponent(user.Value, out SharedHandsComponent? hands)) - hands.TryPutInAnyHand(item); + hands.TryPutInActiveHandOrAny(item); return true; } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 3943ce4fa3..3af39fcf6b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -1,6 +1,41 @@ +- type: entity + id: BatteryGunBase + parent: BaseItem + abstract: true + components: + - type: RangedWeapon + - type: BatteryBarrel + fireRate: 2 + minAngle: 0 + maxAngle: 45 + angleIncrease: 15 + angleDecay: 45 + ammoPrototype: RedLaser + currentSelector: Single + allSelectors: + - Single + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/laser.ogg + cellSlot: + ejectOnUse: true + insertSound: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + soundOptions: + volume: -2 + startingItem: PowerCellSmallStandard + whitelist: + components: + - Battery + - type: Appearance + visuals: + - type: MagVisualizer + magState: mag + steps: 5 + zeroVisible: false + - type: entity name: retro laser gun - parent: BaseItem + parent: BatteryGunBase id: LaserGun description: A weapon using light amplified by the stimulated emission of radiation. components: @@ -19,23 +54,7 @@ - type: RangedWeapon - type: BatteryBarrel minAngle: 10 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - currentSelector: Single - allSelectors: - - Single - fireRate: 2 - powerCellPrototype: PowerCellSmallStandard - powerCellRemovable: true fireCost: 40 - ammoPrototype: RedLaser - soundGunshot: - path: /Audio/Weapons/Guns/Gunshots/laser.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg - type: Appearance visuals: - type: MagVisualizer @@ -45,7 +64,7 @@ - type: entity name: makeshift laser gun - parent: BaseItem + parent: BatteryGunBase id: MakeshiftLaser description: Better pray it won't burn your hands off. components: @@ -61,36 +80,12 @@ - type: Item size: 24 sprite: Objects/Weapons/Guns/Battery/makeshift.rsi - - type: RangedWeapon - type: BatteryBarrel - currentSelector: Single - allSelectors: - - Single - fireRate: 2 - minAngle: 0 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - powerCellPrototype: PowerCellSmallStandard - powerCellRemovable: true fireCost: 40 - ammoPrototype: RedLaser - soundGunshot: - path: /Audio/Weapons/Guns/Gunshots/laser.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg - - type: Appearance - visuals: - - type: MagVisualizer - magState: mag - steps: 5 - zeroVisible: false - type: entity name: svalinn laser pistol - parent: BaseItem + parent: BatteryGunBase id: LaserPistolSvalinn description: A cheap and widely used laser pistol. components: @@ -106,36 +101,12 @@ - type: Item size: 24 sprite: Objects/Weapons/Guns/Battery/svalinn.rsi - - type: RangedWeapon - type: BatteryBarrel - currentSelector: Single - allSelectors: - - Single - fireRate: 2 - minAngle: 0 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - powerCellPrototype: PowerCellSmallStandard - powerCellRemovable: true fireCost: 20 - ammoPrototype: RedLaser - soundGunshot: - path: /Audio/Weapons/Guns/Gunshots/laser.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg - - type: Appearance - visuals: - - type: MagVisualizer - magState: mag - steps: 5 - zeroVisible: false - type: entity name: cog laser carbine - parent: BaseItem + parent: BatteryGunBase id: LaserRifleCog description: Favoured by Nanotrasen Security for being cheap and easy to use. components: @@ -151,36 +122,12 @@ - type: Item size: 24 sprite: Objects/Weapons/Guns/Battery/cog.rsi - - type: RangedWeapon - type: BatteryBarrel - currentSelector: Single - allSelectors: - - Single - fireRate: 2 - minAngle: 0 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - powerCellPrototype: PowerCellSmallStandard - powerCellRemovable: true fireCost: 10 - ammoPrototype: RedLaser - soundGunshot: - path: /Audio/Weapons/Guns/Gunshots/laser.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg - - type: Appearance - visuals: - - type: MagVisualizer - magState: mag - steps: 5 - zeroVisible: false - type: entity name: laser cannon - parent: BaseItem + parent: BatteryGunBase id: LaserCannon description: A heavy duty, high powered laser weapon. components: @@ -196,36 +143,25 @@ - type: Item size: 24 sprite: Objects/Weapons/Guns/Battery/laser_cannon.rsi - - type: RangedWeapon - type: BatteryBarrel - currentSelector: Single - allSelectors: - - Single - fireRate: 2 - minAngle: 0 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - powerCellPrototype: PowerCellSmallSuper - powerCellRemovable: true fireCost: 600 ammoPrototype: RedHeavyLaser soundGunshot: path: /Audio/Weapons/Guns/Gunshots/laser_cannon.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg - - type: Appearance - visuals: - - type: MagVisualizer - magState: mag - steps: 5 - zeroVisible: false + cellSlot: + ejectOnUse: true + insertSound: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + soundOptions: + volume: -2 + startingItem: PowerCellSmallSuper + whitelist: + components: + - Battery - type: entity name: x-ray cannon - parent: BaseItem + parent: BatteryGunBase id: XrayCannon description: An experimental weapon that uses concentrated x-ray energy against its target. components: @@ -241,26 +177,21 @@ - type: Item size: 24 sprite: Objects/Weapons/Guns/Battery/xray.rsi - - type: RangedWeapon - type: BatteryBarrel - currentSelector: Single - allSelectors: - - Single - fireRate: 2 - minAngle: 0 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - powerCellPrototype: PowerCellSmallSuper - powerCellRemovable: true fireCost: 600 ammoPrototype: XrayLaser soundGunshot: path: /Audio/Weapons/Guns/Gunshots/laser3.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + cellSlot: + ejectOnUse: true + insertSound: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + soundOptions: + volume: -2 + startingItem: PowerCellSmallSuper + whitelist: + components: + - Battery - type: Appearance visuals: - type: MagVisualizer @@ -270,7 +201,7 @@ - type: entity name: taser - parent: BaseItem + parent: BatteryGunBase id: TaserGun description: A low-capacity, energy-based stun gun used by security teams to subdue targets at range. components: @@ -293,26 +224,23 @@ Slots: - Belt HeldPrefix: taser4 - - type: RangedWeapon - type: BatteryBarrel - currentSelector: Single - allSelectors: - - Single - fireRate: 2 minAngle: 5 - maxAngle: 45 angleIncrease: 20 - angleDecay: 15 - powerCellPrototype: PowerCellSmallStandard - powerCellRemovable: false fireCost: 80 ammoPrototype: BulletTaser soundGunshot: path: /Audio/Weapons/Guns/Gunshots/taser.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + cellSlot: + insertSound: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + soundOptions: + volume: -2 + locked: true + startingItem: PowerCellSmallStandard + whitelist: + components: + - Battery - type: Appearance visuals: - type: MagVisualizer @@ -322,7 +250,7 @@ - type: entity name: laser gun - parent: BaseItem + parent: BatteryGunBase id: LaserSecGun description: A laser gun. components: @@ -338,28 +266,16 @@ - type: Item size: 24 sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi - - type: RangedWeapon - type: BatteryBarrel - minAngle: 10 - maxAngle: 45 - angleIncrease: 15 - angleDecay: 45 - currentSelector: Single - allSelectors: - - Single + minAngle: 1 fireRate: 6 - powerCellPrototype: PowerCellMediumStandard - powerCellRemovable: true - ammoPrototype: RedLaser - soundGunshot: - path: /Audio/Weapons/Guns/Gunshots/laser.ogg - soundPowerCellInsert: - path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg - soundPowerCellEject: - path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg - - type: Appearance - visuals: - - type: MagVisualizer - magState: mag - steps: 5 - zeroVisible: false + cellSlot: + ejectOnUse: true + insertSound: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg + soundOptions: + volume: -2 + startingItem: PowerCellMediumStandard + whitelist: + components: + - Battery