Spray bottles with visible reagent contents (#42155)

* Spray bottles with visible reagent contents

* Fixed cargo catalog to correctly reference the new spray bottle rsi

* Fixed indentation on rsi meta files

* Updated copyright in spray_bottle.rsi meta

* Update Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml

Co-authored-by: āda <ss.adasts@gmail.com>

* Updated to follow yml convention, modified to inherit from DrinkBase and renamed fill textures

* Fixed solution names

* Updated solution name in BorgMegaSprayBottle

* de-hardcode solution name

* less breaking

---------

Co-authored-by: āda <ss.adasts@gmail.com>
Co-authored-by: iaada <iaada@users.noreply.github.com>
This commit is contained in:
chaisftw 2026-01-13 08:01:35 +10:00 committed by BarryNorfolk
parent 74f7357c40
commit 4ac5f8b1d3
35 changed files with 230 additions and 147 deletions

View File

@ -88,7 +88,7 @@ public sealed class SpraySystem : SharedSpraySystem
public override void Spray(Entity<SprayComponent> entity, MapCoordinates mapcoord, EntityUid? user = null) public override void Spray(Entity<SprayComponent> entity, MapCoordinates mapcoord, EntityUid? user = null)
{ {
if (!_solutionContainer.TryGetSolution(entity.Owner, SprayComponent.SolutionName, out var soln, out var solution)) if (!_solutionContainer.TryGetSolution(entity.Owner, entity.Comp.Solution, out var soln, out var solution))
return; return;
var ev = new SprayAttemptEvent(user); var ev = new SprayAttemptEvent(user);

View File

@ -9,24 +9,25 @@ namespace Content.Shared.Fluids.Components;
[Access(typeof(SharedSpraySystem))] [Access(typeof(SharedSpraySystem))]
public sealed partial class SprayComponent : Component public sealed partial class SprayComponent : Component
{ {
public const string SolutionName = "spray"; [DataField]
public string Solution = "spray";
[ViewVariables(VVAccess.ReadWrite), DataField] [DataField]
public FixedPoint2 TransferAmount = 10; public FixedPoint2 TransferAmount = 10;
[ViewVariables(VVAccess.ReadWrite), DataField] [DataField]
public float SprayDistance = 3.5f; public float SprayDistance = 3.5f;
[ViewVariables(VVAccess.ReadWrite), DataField] [DataField]
public float SprayVelocity = 3.5f; public float SprayVelocity = 3.5f;
[ViewVariables(VVAccess.ReadWrite), DataField] [DataField]
public EntProtoId SprayedPrototype = "Vapor"; public EntProtoId SprayedPrototype = "Vapor";
[ViewVariables(VVAccess.ReadWrite), DataField] [DataField]
public int VaporAmount = 1; public int VaporAmount = 1;
[ViewVariables(VVAccess.ReadWrite), DataField] [DataField]
public float VaporSpread = 90f; public float VaporSpread = 90f;
/// <summary> /// <summary>

View File

@ -1,7 +1,7 @@
- type: cargoProduct - type: cargoProduct
id: ServiceJanitorial id: ServiceJanitorial
icon: icon:
sprite: Objects/Specific/Janitorial/janitorial.rsi sprite: Objects/Specific/Janitorial/spray_bottle.rsi
state: cleaner state: cleaner
product: CrateServiceJanitorialSupplies product: CrateServiceJanitorialSupplies
cost: 560 cost: 560

View File

@ -1,9 +1,9 @@
- type: entity - type: entity
name: Plant-B-Gone parent: SprayBottleBase
id: PlantBGoneSpray id: PlantBGoneSpray
parent: SprayBottle name: Plant-B-Gone
description: Kills those pesky weeds!
suffix: "Filled" suffix: "Filled"
description: Kills those pesky weeds!
components: components:
- type: Tag - type: Tag
tags: tags:
@ -13,38 +13,32 @@
state: plantbgone state: plantbgone
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 100 maxVol: 100
reagents: reagents:
- ReagentId: PlantBGone - ReagentId: PlantBGone
Quantity: 100 Quantity: 100
- type: DrainableSolution
solution: spray
- type: Item - type: Item
sprite: Objects/Tools/Hydroponics/sprays.rsi sprite: Objects/Tools/Hydroponics/sprays.rsi
heldPrefix: plantbgone heldPrefix: plantbgone
- type: entity - type: entity
name: weed spray parent: SprayBottleBase
id: WeedSpray id: WeedSpray
parent: SprayBottle name: weed spray
description: It's a toxic mixture, in spray form, to kill small weeds.
suffix: "Filled" suffix: "Filled"
description: It's a toxic mixture, in spray form, to kill small weeds.
components: components:
- type: Sprite - type: Sprite
sprite: Objects/Tools/Hydroponics/sprays.rsi sprite: Objects/Tools/Hydroponics/sprays.rsi
state: weedspray state: weedspray
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 50 maxVol: 50
reagents: reagents:
- ReagentId: WeedKiller - ReagentId: WeedKiller
Quantity: 50 Quantity: 50
- type: DrainableSolution
solution: spray
- type: Spillable
solution: spray
- type: Tag - type: Tag
tags: tags:
- Spray - Spray
@ -54,22 +48,20 @@
sprite: Objects/Tools/Hydroponics/sprays.rsi sprite: Objects/Tools/Hydroponics/sprays.rsi
- type: entity - type: entity
name: pest spray
id: PestSpray
parent: WeedSpray parent: WeedSpray
description: It's some pest eliminator spray! Do not inhale! id: PestSpray
name: pest spray
suffix: "Filled" suffix: "Filled"
description: It's some pest eliminator spray! Do not inhale!
components: components:
- type: Sprite - type: Sprite
state: pestspray state: pestspray
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 50 maxVol: 50
reagents: reagents:
- ReagentId: PestKiller - ReagentId: PestKiller
Quantity: 50 Quantity: 50
- type: DrainableSolution
solution: spray
- type: Item - type: Item
sprite: Objects/Tools/Hydroponics/sprays.rsi sprite: Objects/Tools/Hydroponics/sprays.rsi

View File

@ -1,15 +1,11 @@
- type: entity - type: entity
name: spray bottle abstract: true
id: SprayBottle parent: [ DrinkBaseMaterialPlastic, DrinkBase ]
parent: BaseItem id: SprayBottleBase
suffix: Empty
description: A spray bottle with an unscrewable top.
components: components:
- type: Edible - type: Edible
edible: Drink edible: Drink
solution: spray solution: drink
destroyOnEmpty: false
utensil: None
transferAmount: 10 transferAmount: 10
useSound: useSound:
path: /Audio/Effects/spray3.ogg path: /Audio/Effects/spray3.ogg
@ -20,47 +16,62 @@
- Spray - Spray
- Trash - Trash
- type: Sprite - type: Sprite
sprite: Objects/Specific/Janitorial/janitorial.rsi sprite: Objects/Specific/Janitorial/spray_bottle.rsi
state: cleaner state: cleaner
- type: Item - type: Item
sprite: Objects/Specific/Janitorial/janitorial.rsi sprite: Objects/Specific/Janitorial/spray_bottle.rsi
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 100 maxVol: 100
- type: RefillableSolution
solution: spray
- type: DrainableSolution
solution: spray
- type: SolutionTransfer
canChangeTransferAmount: true
- type: SolutionItemStatus
solution: spray
- type: UseDelay - type: UseDelay
- type: Spray - type: Spray
solution: drink
transferAmount: 10 transferAmount: 10
sprayVelocity: 2 sprayVelocity: 2
spraySound: spraySound:
path: /Audio/Effects/spray2.ogg path: /Audio/Effects/spray2.ogg
- type: TrashOnSolutionEmpty - type: TrashOnSolutionEmpty
solution: spray solution: drink
- type: ExaminableSolution
solution: spray - type: entity
exactVolume: true parent: [ SprayBottleBase, DrinkVisualsFill ]
id: SprayBottle
name: spray bottle
suffix: Empty
description: A spray bottle with an unscrewable top.
components:
- type: Sprite
sprite: Objects/Specific/Janitorial/spray_bottle.rsi
layers:
- state: cleaner
- state: cleaner-fill-1
map: ["enum.SolutionContainerLayers.Fill"]
visible: false
- type: SolutionContainerVisuals
fillBaseName: cleaner-fill-
inHandsMaxFillLevels: 4
- type: entity - type: entity
name: mega spray bottle
id: MegaSprayBottle
parent: SprayBottle parent: SprayBottle
id: MegaSprayBottle
name: mega spray bottle
suffix: Empty suffix: Empty
description: A huge spray bottle, capable of unrivaled janitorial power. description: A huge spray bottle, capable of unrivaled janitorial power.
components: components:
- type: Sprite - type: Sprite
sprite: Objects/Specific/Janitorial/janitorial.rsi sprite: Objects/Specific/Janitorial/spray_bottle.rsi
state: cleaner_large layers:
- state: cleaner_large
- state: cleaner_large-fill-1
map: ["enum.SolutionContainerLayers.Fill"]
visible: false
- type: SolutionContainerVisuals
maxFillLevels: 7
fillBaseName: cleaner_large-fill-
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 250 maxVol: 250
- type: Spray - type: Spray
transferAmount: 15 transferAmount: 15
@ -71,31 +82,31 @@
path: /Audio/Effects/spray2.ogg path: /Audio/Effects/spray2.ogg
- type: entity - type: entity
name: spray bottle
id: SprayBottleWater
suffix: Filled
parent: SprayBottle parent: SprayBottle
id: SprayBottleWater
name: spray bottle
suffix: Filled
components: components:
- type: Tag - type: Tag
tags: tags:
- Spray - Spray
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 100 maxVol: 100
reagents: reagents:
- ReagentId: Water - ReagentId: Water
Quantity: 100 Quantity: 100
- type: entity - type: entity
description: BLAM!-brand non-foaming space cleaner!
id: SprayBottleSpaceCleaner
parent: SprayBottle parent: SprayBottle
id: SprayBottleSpaceCleaner
suffix: Space Cleaner suffix: Space Cleaner
description: BLAM!-brand non-foaming space cleaner!
components: components:
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 100 maxVol: 100
reagents: reagents:
- ReagentId: SpaceCleaner - ReagentId: SpaceCleaner
@ -109,12 +120,12 @@
- type: entity - type: entity
parent: MegaSprayBottle parent: MegaSprayBottle
id: MegaSprayBottleSpaceCleaner id: MegaSprayBottleSpaceCleaner
description: BLAM!-brand non-foaming space cleaner, now in a bigger package for those huge blood puddles!
suffix: Space Cleaner suffix: Space Cleaner
description: BLAM!-brand non-foaming space cleaner, now in a bigger package for those huge blood puddles!
components: components:
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 250 maxVol: 250
reagents: reagents:
- ReagentId: SpaceCleaner - ReagentId: SpaceCleaner
@ -131,7 +142,7 @@
components: components:
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 200 maxVol: 200
reagents: reagents:
- ReagentId: SpaceCleaner - ReagentId: SpaceCleaner
@ -146,7 +157,7 @@
components: components:
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
spray: drink:
maxVol: 250 maxVol: 250
reagents: reagents:
- ReagentId: SpaceCleaner - ReagentId: SpaceCleaner
@ -154,7 +165,7 @@
- type: SolutionTransfer - type: SolutionTransfer
canSend: false # No giving away infinite space cleaner! canSend: false # No giving away infinite space cleaner!
- type: SolutionRegeneration - type: SolutionRegeneration
solution: spray solution: drink
duration: 5 # Delta-V - Refill borg's mega spray 1 full use per 5 seconds duration: 5 # Delta-V - Refill borg's mega spray 1 full use per 5 seconds
generated: generated:
reagents: reagents:
@ -165,8 +176,8 @@
# Vapor # Vapor
- type: entity - type: entity
id: Vapor id: Vapor
name: "vapor"
categories: [ HideSpawnMenu ] categories: [ HideSpawnMenu ]
name: "vapor"
components: components:
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
@ -200,8 +211,8 @@
- type: VaporVisuals - type: VaporVisuals
- type: entity - type: entity
id: BigVapor
parent: Vapor parent: Vapor
id: BigVapor
categories: [ HideSpawnMenu ] categories: [ HideSpawnMenu ]
components: components:
- type: Sprite - type: Sprite

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

View File

@ -7,12 +7,6 @@
"y": 32 "y": 32
}, },
"states": [ "states": [
{
"name": "cleaner"
},
{
"name": "cleaner_large"
},
{ {
"name": "mopbucket" "name": "mopbucket"
}, },
@ -63,14 +57,6 @@
{ {
"name": "mopbucket_cube" "name": "mopbucket_cube"
}, },
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
},
{ {
"name": "equipped-BELT", "name": "equipped-BELT",
"directions": 4 "directions": 4

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

View File

@ -0,0 +1,93 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "cleaner, cleaner_large and in-hand sprites are from tgstation at commit https://github.com/tgstation/tgstation/commit/f8f4aeda930fcd0805ca4cc76d9bc9412a5b3428 and modified by chaisftw (GitHub), Fill levels created by chaisftw (GitHub) by modifying cleaner, cleaner_large and in-hand sprites",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "cleaner"
},
{
"name": "cleaner-fill-1"
},
{
"name": "cleaner-fill-2"
},
{
"name": "cleaner-fill-3"
},
{
"name": "cleaner-fill-4"
},
{
"name": "cleaner-fill-5"
},
{
"name": "cleaner_large"
},
{
"name": "cleaner_large-fill-1"
},
{
"name": "cleaner_large-fill-2"
},
{
"name": "cleaner_large-fill-3"
},
{
"name": "cleaner_large-fill-4"
},
{
"name": "cleaner_large-fill-5"
},
{
"name": "cleaner_large-fill-6"
},
{
"name": "cleaner_large-fill-7"
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-left-fill-1",
"directions": 4
},
{
"name": "inhand-left-fill-2",
"directions": 4
},
{
"name": "inhand-left-fill-3",
"directions": 4
},
{
"name": "inhand-left-fill-4",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
},
{
"name": "inhand-right-fill-1",
"directions": 4
},
{
"name": "inhand-right-fill-2",
"directions": 4
},
{
"name": "inhand-right-fill-3",
"directions": 4
},
{
"name": "inhand-right-fill-4",
"directions": 4
}
]
}