From 98481fb9a250b9db80cc71d144bfc5f68a83fcbf Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Fri, 5 May 2023 21:50:09 -0400 Subject: [PATCH] Spray Nozzle & Backpack Water Tank (#16133) --- .../Weapons/Ranged/Systems/GunSystem.cs | 14 +-- .../Chemistry/Components/VaporComponent.cs | 1 + .../Ranged/Systems/GunSystem.Solution.cs | 82 ++++++++++++++++++ .../ClothingSlotAmmoProviderComponent.cs | 26 ++++++ .../Weapons/Ranged/Components/GunComponent.cs | 7 ++ .../SolutionAmmoProviderComponent.cs | 42 +++++++++ .../Systems/SharedGunSystem.Clothing.cs | 55 ++++++++++++ .../Systems/SharedGunSystem.Solution.cs | 60 +++++++++++++ .../Weapons/Ranged/Systems/SharedGunSystem.cs | 2 + .../Weapons/Guns/Gunshots/attributions.yml | 4 + .../Weapons/Guns/Gunshots/water_spray.ogg | Bin 0 -> 8753 bytes .../catalog/research/technologies.ftl | 3 + .../Catalog/Research/technologies.yml | 14 +++ .../Entities/Clothing/Back/specific.yml | 42 +++++++++ .../Weapons/Guns/Basic/spraynozzle.yml | 26 ++++++ .../Weapons/Guns/Projectiles/projectiles.yml | 41 +++++++++ .../Entities/Structures/Machines/lathe.yml | 2 + .../Prototypes/Recipes/Lathes/janitorial.yml | 16 ++++ Resources/Prototypes/tags.yml | 3 + .../waterbackpack.rsi/equipped-BACKPACK.png | Bin 0 -> 926 bytes .../Back/Backpacks/waterbackpack.rsi/icon.png | Bin 0 -> 828 bytes .../waterbackpack.rsi/inhand-left.png | Bin 0 -> 573 bytes .../waterbackpack.rsi/inhand-right.png | Bin 0 -> 578 bytes .../Backpacks/waterbackpack.rsi/meta.json | 26 ++++++ .../Guns/Basic/spraynozzle.rsi/icon.png | Bin 0 -> 809 bytes .../Basic/spraynozzle.rsi/inhand-left.png | Bin 0 -> 594 bytes .../Basic/spraynozzle.rsi/inhand-right.png | Bin 0 -> 583 bytes .../Guns/Basic/spraynozzle.rsi/meta.json | 22 +++++ .../Guns/Projectiles/water_shot.rsi/icon.png | Bin 0 -> 250 bytes .../Guns/Projectiles/water_shot.rsi/meta.json | 14 +++ 30 files changed, 495 insertions(+), 7 deletions(-) create mode 100644 Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs create mode 100644 Content.Shared/Weapons/Ranged/Components/ClothingSlotAmmoProviderComponent.cs create mode 100644 Content.Shared/Weapons/Ranged/Components/SolutionAmmoProviderComponent.cs create mode 100644 Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Clothing.cs create mode 100644 Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Solution.cs create mode 100644 Resources/Audio/Weapons/Guns/Gunshots/attributions.yml create mode 100644 Resources/Audio/Weapons/Guns/Gunshots/water_spray.ogg create mode 100644 Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/spraynozzle.yml create mode 100644 Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/equipped-BACKPACK.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/meta.json create mode 100644 Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/icon.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/meta.json create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/water_shot.rsi/icon.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/water_shot.rsi/meta.json diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs index fce3139b62..7d82c98469 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs @@ -181,7 +181,7 @@ public sealed partial class GunSystem : SharedGunSystem { if (throwItems) { - Recoil(user, direction); + Recoil(user, direction, gun.CameraRecoilScalar); if (ent!.Value.IsClientSide()) Del(ent.Value); else @@ -197,7 +197,7 @@ public sealed partial class GunSystem : SharedGunSystem SetCartridgeSpent(ent!.Value, cartridge, true); MuzzleFlash(gunUid, cartridge, user); Audio.PlayPredicted(gun.SoundGunshot, gunUid, user); - Recoil(user, direction); + Recoil(user, direction, gun.CameraRecoilScalar); // TODO: Can't predict entity deletions. //if (cartridge.DeleteOnSpawn) // Del(cartridge.Owner); @@ -214,7 +214,7 @@ public sealed partial class GunSystem : SharedGunSystem case AmmoComponent newAmmo: MuzzleFlash(gunUid, newAmmo, user); Audio.PlayPredicted(gun.SoundGunshot, gunUid, user); - Recoil(user, direction); + Recoil(user, direction, gun.CameraRecoilScalar); if (ent!.Value.IsClientSide()) Del(ent.Value); else @@ -222,18 +222,18 @@ public sealed partial class GunSystem : SharedGunSystem break; case HitscanPrototype: Audio.PlayPredicted(gun.SoundGunshot, gunUid, user); - Recoil(user, direction); + Recoil(user, direction, gun.CameraRecoilScalar); break; } } } - private void Recoil(EntityUid? user, Vector2 recoil) + private void Recoil(EntityUid? user, Vector2 recoil, float recoilScalar) { - if (!Timing.IsFirstTimePredicted || user == null || recoil == Vector2.Zero) + if (!Timing.IsFirstTimePredicted || user == null || recoil == Vector2.Zero || recoilScalar == 0) return; - _recoil.KickCamera(user.Value, recoil.Normalized * 0.5f); + _recoil.KickCamera(user.Value, recoil.Normalized * 0.5f * recoilScalar); } protected override void Popup(string message, EntityUid? uid, EntityUid? user) diff --git a/Content.Server/Chemistry/Components/VaporComponent.cs b/Content.Server/Chemistry/Components/VaporComponent.cs index 95259d995c..5517e11ea5 100644 --- a/Content.Server/Chemistry/Components/VaporComponent.cs +++ b/Content.Server/Chemistry/Components/VaporComponent.cs @@ -11,6 +11,7 @@ namespace Content.Server.Chemistry.Components public FixedPoint2 TransferAmount = FixedPoint2.New(0.5); public float ReactTimer; + [DataField("active")] public bool Active; } } diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs new file mode 100644 index 0000000000..4434c23ba5 --- /dev/null +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.Solution.cs @@ -0,0 +1,82 @@ +using Content.Server.Chemistry.Components; +using Content.Server.Chemistry.EntitySystems; +using Content.Shared.Chemistry.Components; +using Content.Shared.FixedPoint; +using Content.Shared.Vapor; +using Content.Shared.Weapons.Ranged; +using Content.Shared.Weapons.Ranged.Components; +using Robust.Shared.Map; + +namespace Content.Server.Weapons.Ranged.Systems; + +public sealed partial class GunSystem +{ + [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; + + protected override void InitializeSolution() + { + base.InitializeSolution(); + + SubscribeLocalEvent(OnSolutionMapInit); + SubscribeLocalEvent(OnSolutionChanged); + } + + private void OnSolutionMapInit(EntityUid uid, SolutionAmmoProviderComponent component, MapInitEvent args) + { + UpdateSolutionShots(uid, component); + } + + private void OnSolutionChanged(EntityUid uid, SolutionAmmoProviderComponent component, SolutionChangedEvent args) + { + if (args.Solution.Name == component.SolutionId) + UpdateSolutionShots(uid, component, args.Solution); + } + + protected override void UpdateSolutionShots(EntityUid uid, SolutionAmmoProviderComponent component, Solution? solution = null) + { + var shots = 0; + var maxShots = 0; + if (solution == null && !_solutionContainer.TryGetSolution(uid, component.SolutionId, out solution)) + { + component.Shots = shots; + component.MaxShots = maxShots; + Dirty(component); + return; + } + + shots = (int) (solution.Volume / component.FireCost); + maxShots = (int) (solution.MaxVolume / component.FireCost); + + component.Shots = shots; + component.MaxShots = maxShots; + Dirty(component); + + UpdateSolutionAppearance(uid, component); + } + + protected override (EntityUid Entity, IShootable) GetSolutionShot(EntityUid uid, SolutionAmmoProviderComponent component, EntityCoordinates position) + { + var (ent, shootable) = base.GetSolutionShot(uid, component, position); + + if (!_solutionContainer.TryGetSolution(uid, component.SolutionId, out var solution)) + return (ent, shootable); + + var newSolution = _solutionContainer.SplitSolution(uid, solution, component.FireCost); + + if (newSolution.Volume <= FixedPoint2.Zero) + return (ent, shootable); + + if (TryComp(ent, out var appearance)) + { + Appearance.SetData(ent, VaporVisuals.Color, newSolution.GetColor(ProtoManager).WithAlpha(1f), appearance); + Appearance.SetData(ent, VaporVisuals.State, true, appearance); + } + + // Add the solution to the vapor and actually send the thing + if (_solutionContainer.TryGetSolution(ent, VaporComponent.SolutionName, out var vaporSolution)) + { + _solutionContainer.TryAddSolution(ent, vaporSolution, newSolution); + } + return (ent, shootable); + } +} diff --git a/Content.Shared/Weapons/Ranged/Components/ClothingSlotAmmoProviderComponent.cs b/Content.Shared/Weapons/Ranged/Components/ClothingSlotAmmoProviderComponent.cs new file mode 100644 index 0000000000..af3fd57b56 --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Components/ClothingSlotAmmoProviderComponent.cs @@ -0,0 +1,26 @@ +using Content.Shared.Inventory; +using Content.Shared.Weapons.Ranged.Systems; +using Content.Shared.Whitelist; +using Robust.Shared.GameStates; + +namespace Content.Shared.Weapons.Ranged.Components; + +/// +/// This is used for relaying ammo events +/// to an entity in the user's clothing slot. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(SharedGunSystem))] +public sealed class ClothingSlotAmmoProviderComponent : AmmoProviderComponent +{ + /// + /// The slot that the ammo provider should be located in. + /// + [DataField("targetSlot", required: true)] + public SlotFlags TargetSlot; + + /// + /// A whitelist for determining whether or not an ammo provider is valid. + /// + [DataField("providerWhitelist")] + public EntityWhitelist? ProviderWhitelist; +} diff --git a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs index 07f84f3252..0ccc839902 100644 --- a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs @@ -30,6 +30,13 @@ public partial class GunComponent : Component // 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. diff --git a/Content.Shared/Weapons/Ranged/Components/SolutionAmmoProviderComponent.cs b/Content.Shared/Weapons/Ranged/Components/SolutionAmmoProviderComponent.cs new file mode 100644 index 0000000000..4a76281d4b --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Components/SolutionAmmoProviderComponent.cs @@ -0,0 +1,42 @@ +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Weapons.Ranged.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedGunSystem))] +public sealed partial class SolutionAmmoProviderComponent : Component +{ + /// + /// The solution where reagents are extracted from for the projectile. + /// + [DataField("solutionId", required: true), AutoNetworkedField] + public string SolutionId = default!; + + /// + /// How much reagent it costs to fire once. + /// + [DataField("fireCost"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float FireCost = 10; + + /// + /// The amount of shots currently available. + /// used for network predictions. + /// + [DataField("shots"), ViewVariables, AutoNetworkedField] + public int Shots; + + /// + /// The max amount of shots the gun can fire. + /// used for network prediction + /// + [DataField("maxShots"), ViewVariables, AutoNetworkedField] + public int MaxShots; + + /// + /// The prototype that's fired by the gun. + /// + [DataField("proto", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)] + public string Prototype = default!; +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Clothing.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Clothing.cs new file mode 100644 index 0000000000..669c49aefa --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Clothing.cs @@ -0,0 +1,55 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Inventory; +using Content.Shared.Weapons.Ranged.Components; +using Content.Shared.Weapons.Ranged.Events; + +namespace Content.Shared.Weapons.Ranged.Systems; + +public partial class SharedGunSystem +{ + [Dependency] private readonly InventorySystem _inventory = default!; + + private void InitializeClothing() + { + SubscribeLocalEvent(OnClothingTakeAmmo); + SubscribeLocalEvent(OnClothingAmmoCount); + } + + private void OnClothingTakeAmmo(EntityUid uid, ClothingSlotAmmoProviderComponent component, TakeAmmoEvent args) + { + if (!TryGetClothingSlotEntity(uid, component, out var entity)) + return; + RaiseLocalEvent(entity.Value, args); + } + + private void OnClothingAmmoCount(EntityUid uid, ClothingSlotAmmoProviderComponent component, ref GetAmmoCountEvent args) + { + if (!TryGetClothingSlotEntity(uid, component, out var entity)) + return; + RaiseLocalEvent(entity.Value, ref args); + } + + private bool TryGetClothingSlotEntity(EntityUid uid, ClothingSlotAmmoProviderComponent component, [NotNullWhen(true)] out EntityUid? slotEntity) + { + slotEntity = null; + if (!_container.TryGetContainingContainer(uid, out var container)) + return false; + var user = container.Owner; + + if (!TryComp(user, out var inventory)) + return false; + var slots = _inventory.GetSlots(user, inventory); + foreach (var slot in slots) + { + if (slot.SlotFlags != component.TargetSlot) + continue; + if (!_inventory.TryGetSlotEntity(user, slot.Name, out var e, inventory)) + continue; + if (component.ProviderWhitelist != null && !component.ProviderWhitelist.IsValid(e.Value, EntityManager)) + continue; + slotEntity = e; + } + + return slotEntity != null; + } +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Solution.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Solution.cs new file mode 100644 index 0000000000..d04b3fad30 --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Solution.cs @@ -0,0 +1,60 @@ +using Content.Shared.Chemistry.Components; +using Content.Shared.Weapons.Ranged.Components; +using Content.Shared.Weapons.Ranged.Events; +using Robust.Shared.Map; + +namespace Content.Shared.Weapons.Ranged.Systems; + +public partial class SharedGunSystem +{ + protected virtual void InitializeSolution() + { + SubscribeLocalEvent(OnSolutionTakeAmmo); + SubscribeLocalEvent(OnSolutionAmmoCount); + } + + private void OnSolutionTakeAmmo(EntityUid uid, SolutionAmmoProviderComponent component, TakeAmmoEvent args) + { + var shots = Math.Min(args.Shots, component.Shots); + + // Don't dirty if it's an empty fire. + if (shots == 0) + return; + + for (var i = 0; i < shots; i++) + { + args.Ammo.Add(GetSolutionShot(uid, component, args.Coordinates)); + component.Shots--; + } + + UpdateSolutionShots(uid, component); + UpdateSolutionAppearance(uid, component); + } + + private void OnSolutionAmmoCount(EntityUid uid, SolutionAmmoProviderComponent component, ref GetAmmoCountEvent args) + { + args.Count = component.Shots; + args.Capacity = component.MaxShots; + } + + protected virtual void UpdateSolutionShots(EntityUid uid, SolutionAmmoProviderComponent component, Solution? solution = null) + { + + } + + protected virtual (EntityUid Entity, IShootable) GetSolutionShot(EntityUid uid, SolutionAmmoProviderComponent component, EntityCoordinates position) + { + var ent = Spawn(component.Prototype, position); + return (ent, EnsureComp(ent)); + } + + protected void UpdateSolutionAppearance(EntityUid uid, SolutionAmmoProviderComponent component) + { + if (!TryComp(uid, out var appearance)) + return; + + Appearance.SetData(uid, AmmoVisuals.HasAmmo, component.Shots != 0, appearance); + Appearance.SetData(uid, AmmoVisuals.AmmoCount, component.Shots, appearance); + Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.MaxShots, appearance); + } +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 2810019f5b..6baa6c38ec 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -79,7 +79,9 @@ public abstract partial class SharedGunSystem : EntitySystem InitializeMagazine(); InitializeRevolver(); InitializeBasicEntity(); + InitializeClothing(); InitializeContainer(); + InitializeSolution(); // Interactions SubscribeLocalEvent>(OnAltVerb); diff --git a/Resources/Audio/Weapons/Guns/Gunshots/attributions.yml b/Resources/Audio/Weapons/Guns/Gunshots/attributions.yml new file mode 100644 index 0000000000..4bbd672461 --- /dev/null +++ b/Resources/Audio/Weapons/Guns/Gunshots/attributions.yml @@ -0,0 +1,4 @@ +- files: ["water_spray.ogg"] + license: "CC0-1.0" + copyright: "Watering by elittle13. Converted to .OGG and MONO by EmoGarbage404 (github)" + source: "https://freesound.org/people/elittle13/sounds/568558" diff --git a/Resources/Audio/Weapons/Guns/Gunshots/water_spray.ogg b/Resources/Audio/Weapons/Guns/Gunshots/water_spray.ogg new file mode 100644 index 0000000000000000000000000000000000000000..aa3dbf7179eff10152fe8e7c945e7d9e304ad41f GIT binary patch literal 8753 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 Ab^rhX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/icon.png b/Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7a5eac53021b0522c4ca91026b36a4c278c9f39e GIT binary patch literal 828 zcmV-C1H=4@P)Px%_DMuRR9J=Wmd#ERQ5462{h(;67KMo|v{V-(5Dh7b#Mp>Jff$$WT^OIhH!%7H zK7nz;*0^NRCYl(lghVDr1=>VX2CzDnR8y#yPOpnHwP2?oV~j5NZ*Jz?d(Qda^EDR^ zafp8mn^nc>z%5bx9bbQB$(GZq^Yb0o@JamuWV8(kAgqwEx2q8LPl_JvPTxFRLV9n zHd2kovxPUNscDITVQeE;K+`l7MFFUiP*oL0QP4E4dj9&wVF3Ch7l1G$(UgE;tWR=r zfA$psnx>IVCP^lf)pLe(fKw;EtbY8;@>(TFdt~a8Xh^_tJ~zL_My^086e68YbMx*4 zwj40%>0l+lOD;e%0x6uG#X{-;uXH_mZ?3{DDN#1FoPsXj9$Kq&t)gjX~*ZXCPPjewbAUN5t)3v#8(`n6a;#S>#A zVrZa`<+V-Ilr-%Eqk@YE2tG86xLU<)gg)MeA-ox2T z`}S))s8K;SOu@5-H@4-qO(P0GrQbijc#O^Iz-F^?!~xFkBP8Rq`(}YLJDQ^Z8nRQ?&g1lx0~MgQzPXpw|&%y6-js z@y&;1^)%a__3E%nrBZ)q4gf@M43pK?X5wV^G?5#_%@ymQtp|iG%VK6`hF~y= zs;VTOEL8~^vREwE^6lFu01$~pgxl>V`%b6V5dtc2f!=ctc6N41Bob}ewDgV(`zOU< z$2gXN4vJ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/inhand-left.png b/Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..3806eeb66732d4645109a6e33e3f448a887815ff GIT binary patch literal 573 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zzk9kkhE&XX zduyY&vZDywhx5u0XXUzYFo?PEavg`#L8C)UPfq;zN>?Z7ss4uxTD=L9m%RV5ui;&( zqq8jDqVIOg1wkz?0YBpEpllxAXT( zwK!o0yB3XK>Y@Gn`}e)8G`Gv}i~W*+eEXTrN7yf{@4vhKt?-xE$?OdFZ|c`qH9xy@ z_on5vi#$=;A7d4)7}jo`y~b_F=3<{P<&3p=&mWCnKkI6@Y)ok1#k}pUyUqwpH(a}= zxpYHM+KyE+$&zOmOgZHCHTmJJ^pkgZt#ywS@+9|!thQWaz2Np+CI+kJ&v%vv?$5h! zK6ly5_~i8h(hWgenX{ZUTW{4VZ`WJ3?f!(U_pXk9jm>8tnaeIZmwkjSVQs4++qI}W zIyrfiOua{7plP$lipy`0j7gF3GPie0`mK{e~6Kr)O@k zaBy*XKQmuU@x=6nMnBU8UDypW{Jj5)DNJ+~kUfz4Yws3Ck5s`UY!_aCy<;?MVU?iT zsZUc<#2j-Nj!7IT>`7eSx;aIzMjWWdMZQtz!~|Apr-^5jSS(pjahRpl7_;PCDSQ+< zspI6jX(L3o@`Q{9gG5;r!!_rRXO${W7BQyo<2LAa`1g+S6Xy$m?m6cgfa!t3)78&q Iol`;+0J8)AW&i*H literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/inhand-right.png b/Resources/Textures/Clothing/Back/Backpacks/waterbackpack.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..ae08447e49da1033e7591d4f8baedb4bc0f565fa GIT binary patch literal 578 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z|9HAMhE&XX zduxC8Z3h|F57Uz-^F^({GG&(3_icQOST3);5umSk&p7+UgOkb2TS`6&y~xhMQ+W?g*G%x(6w?;6uG7WehBa1EN0u#0RwWMmVP|AW1iyL z@9$TwOs`F}-tqbCJ|GrYL&miGIt-LI{I56c^; zTspIt^W0aHP>yR1|IX+sE;UgPZ@0J}JSRrh$t&`Qz^%7tecrn@8gx)yn;<_biTPz7XZC$-36mFTE-;w#4gh z?%&HZYp?Y#k+%JEi2Ja?N2}?7yiS|Mzk9H?qB%c({`C1**KhIJZ)Q}tH1x%GdqFr@ zd&#PlO>Xk9(*ZfL*3A7UWg1?ebGY@$Icg?z!A(gClVi`)w@iO+Ys~&&lW~CEs^oXR z7hZoY`n~oHBSW4QGyB6UJl4J}js^c88uJ5nT$SwT<}3WDsPBJ^apUthJSw8H^R$W? z)>$#H=Gr~wYg7GQ24;rCe!>T0HCDglIpW%G^Z&nh;YE-=Z!`nWPx%<4Ht8R9J=Wl}l(7Q51&1^c85tnT}2Ruu+?mSiPmV(LySs3qgaf6pIj7qANiK z7Zw*Ph!I89g&RQ->_Vi152%7DQf#1fQ59!lM#o4WYEo*{wpy!R7a?iVq)meE%)c3! zbLag3J^wjppok)hD58k}9hQZH?XI0NSAssXd%+yJP?k!PnoKl!WqV@>_amchQI_-I z^EY1FHNPcXqTtsD5$l3=G4_TT~f9dt(Rs@Ke0Yc1g8mmS9Y~ zz~DVUr%#?`@VKAmb%WGQg_3d0HW!PnFIm>Qk?@OtezmsY29|tklckHlrx8U;pJx?d zX?N|EYWY&Ctxb$L?&9%y2!%p;JRY1*Cqr)@;%wSH`y3j=>2z{uD9VW=r#W`xDwlTb z;oz<7oa@-jzMF?xdAW+l+STzYDOO&69AIq9%xafKGCdjmi3g($I2XWUdD4ra9_ zO+ez15F%^yZQAgai|3DW;NU5GZ@X#K)+A%q)+Sz0^rAFR71Rf1a=M%tqiG6tT~GU1 zG@!L3J{waq0j8LxJ%u#;+q{X^5I{23{%MyWPN70MF=4) zzSL4#UX|f%;(T~=VBWH)RiIFE07X#<>W}74UTtk6JUNhy8-S8R$%POy7|eaMd@-+p zxQO*>p(+0)bW&%93{>lE1S_KbIPcS9f$kkM!qfJh|5+hBb67y5V1 zdf4yxOCbcEot?>eAP|rMsiXkoxvVu7B=-5dePxyR0)IkYs5P00000NkvXXu0mjfq5Xbv literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/inhand-left.png b/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..68a944fdaf3d32533d4f9f6e9329ee5c00c9d2ec GIT binary patch literal 594 zcmV-Y0Px%3`s;mRCt{2+COW;Ko|z_$I?Oa85}dTiyt7P;~|+G`WZS1#m!l|6~Q5MM-eBH zjGd&jxM-n+LdJlhh;$IHLrJj~>Y01r)Rgx(Ie2&Ry+4Zg073{Mgb+dqAq0tzKhS^u z45luqJM8!a{k(fDOcBTn005(59nWop0P#9yz&Ff36$*CDnQ;6yIk-9A?F zB2)WSyujq;O*g7d)^midvH;Mk1$tf{12}CK({T#~@`3kVj1(;aH3$(la%s0>bSnl4l<^oJm zX9rkrhHP>HCMdH5MO;5J50F^3VVA@F>_o$d2`7J gP|RFmXJ4GT54k@A#f)k$3IG5A07*qoM6N<$g3(C~vH$=8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..5bc072168e2fed82a8e1813555dd07675aa1593c GIT binary patch literal 583 zcmV-N0=WH&P)Px%0ZBwbRCt{2+COW;KokJ*m(oG<89HWY7e7Eo$3vVP{0togadQ^8A~eCymwJDiJKk>+N#eV^cS-O)0E7@i2qA zgDf|!1BR^`eNCT@odo6ttabs+{icdos%O}m(KPWWA;ielXKL5G#t*)53uJqKFrKQ5 zMv&7*W8J$7C*W|5Ah~;oQLiI1HYJwJrImd?9HWcJ7EZuE+QMKw1v_*EhNe!t-lf6Y z2i-^8i^o}cUuG%v@Y#f?m&e>=bkJ{jbW>XZzobRaufSDV^`nZdae5XUk2 z>xpHD4)hzImQR6x!=rZSfWMwtaU7RFkq|;%*F77wZf}7<<8@uP{Nvoz=YG++erD!D-{P8px!;7< zE)W$9(`pw$npCJxK?tE~;!zb@P}yDuLI`cwyV8S_)vLg@1pvPL2V`b}%wC0C-V2O+ z9e_K4!|`53Jh^1{DsX3j9Xc==Pk~j3=OMFKK}hYtOdbAOvU?S{GXS7m9iE5GUIp$6 zxVjEsQl)zpxa#mFXxXbEdICgUtB8<$z$ua2K-+4rh?P_I$}2nr0K}}EwyTdc^94F% V0nm|#{$l_D002ovPDHLkV1lIh17QFF literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/meta.json new file mode 100644 index 0000000000..5995a4227f --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Guns/Basic/spraynozzle.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "tgstation at https://github.com/tgstation/tgstation/commit/f7337f1aa9efdcc1403ca4771d638e0634074537", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/water_shot.rsi/icon.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/water_shot.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..550578f45bd506fae7d51882d10ce53f3ab383d8 GIT binary patch literal 250 zcmVPx#v`IukR9J=WmN5#$FbqY1J6YGsnX>dmS$Za4#iRa~EH=1-4wc#n7k@Cq2Ep@} zKNy%AT_jge|NUDakpN2=K(pU72DbyM`tbC70hUv}8~`HX>i>%r#E9ftO4&*7wVIL; z?!eFh=jfTD=yIS%&=bY*5t!5`pe<_>tPZ@J_s8!bd;}9<0t^d~MP%y_>ONlrkWzXA zfU2Ue?fmBeRarzfRW;up0B#O|m+!dc_EP|G0Iv5>By*@|pa1{>07*qoM6N<$f