From e441324abc0b6d752cf07e6b82aef0adab512ca0 Mon Sep 17 00:00:00 2001
From: hazelrat <83198434+hazelrat@users.noreply.github.com>
Date: Fri, 6 Jun 2025 16:08:20 +0100
Subject: [PATCH] Hydroponics fixes and additions (#20792)
Adds a few new recipes to the biogenerator in the interest of making the
hydroponicist more useful, including synthetic blood which I didn't
notice had been removed until now.
Fixes broken handheld icons for horticultural magazines, and introduces
a simple set of handhelds for them.
Fixes dyn cartons being invisible out of the Condimaster.
Adds sounds for watering, weeding, and sampling hydroponics trays, in
addition to a one second timer for weeding and sampling specifically.
Intended to add more feedback to hydroponics work - right now it's very
mute and lacking in visible messages.
Adds a new functionality to hatchets! They can now uproot plants,
killing them instantly, on a two second timer. This is to avoid the
tedious and arthritis inducing process of clicking on a single tray
several times to kill one plant.
Transitioned some tray documentation to DMDocs.
---
code/game/machinery/biogenerator.dm | 30 ++++
code/game/objects/items/toys.dm | 8 +-
code/modules/hydroponics/trays/tray.dm | 148 ++++++++++++------
.../food_drink_species_skrell.dm | 2 +-
html/changelogs/hazelmouse-bloodreturn.yml | 64 ++++++++
icons/obj/library.dmi | Bin 68342 -> 68948 bytes
6 files changed, 195 insertions(+), 57 deletions(-)
create mode 100644 html/changelogs/hazelmouse-bloodreturn.yml
diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm
index a66b185eb0b..6232ed66147 100644
--- a/code/game/machinery/biogenerator.dm
+++ b/code/game/machinery/biogenerator.dm
@@ -120,6 +120,10 @@ FOODSTUFFS
name = "Universal Enzyme (50u)"
object = /obj/item/reagent_containers/food/condiment/enzyme
+/singleton/biorecipe/food/blood
+ name = "Synthetic Blood (50u)"
+ object = /obj/item/reagent_containers/food/condiment/blood
+
/singleton/biorecipe/food/pepper
name = "Pepper Grinder"
object = /obj/item/reagent_containers/food/condiment/shaker/peppermill
@@ -245,6 +249,28 @@ ITEMS
object = /obj/item/storage/bag/plants
cost = 250
+// Like soap, but better!
+/singleton/biorecipe/item/mop
+ name = "Mop"
+ object = /obj/item/mop
+ cost = 400
+
+/singleton/biorecipe/item/filterbox
+ name = "Cigarette Filters"
+ object = /obj/item/storage/cigfilters
+ cost = 200
+
+/singleton/biorecipe/item/cigarettepaper
+ name = "Cigarette Paper"
+ object = /obj/item/storage/box/fancy/cigpaper
+ cost = 200
+
+// Intended to accomodate hydroponicists preparing their own first-aid kits for themselves or the crew.
+/singleton/biorecipe/item/emptyfirstaid
+ name = "Empty First Aid Kit"
+ object = /obj/item/storage/firstaid/empty
+ cost = 200
+
/*
FLAGS
*/
@@ -355,6 +381,10 @@ CONSTRUCTION
object = /obj/item/stack/material/plastic
cost = 75
+/singleton/biorecipe/construction/wood
+ name = "Wood"
+ object = /obj/item/stack/material/wood
+
/*
CLOTHING
*/
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 394272822d8..f93beca1e55 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -413,37 +413,31 @@
itself in every unconnected station, frontier colony, and doctors office across the spur. The magazine's fame largely comes from its writing, maintaining a perfect blend \
of entertaining commentary and nuanced summaries of recent discoveries."
icon_state = "horticulture1"
- item_state = "horticulture1"
+ item_state = "horticulture"
/obj/item/toy/comic/magazine/horticulturetoday/issue1
desc = "A staple publication of all things horticulture. This issue is about sunflowers."
icon_state = "horticulture1"
- item_state = "horticulture1"
/obj/item/toy/comic/magazine/horticulturetoday/issue2
desc = "A staple publication of all things horticulture. This issue is about root systems."
icon_state = "horticulture2"
- item_state = "horticulture2"
/obj/item/toy/comic/magazine/horticulturetoday/issue3
desc = "A staple publication of all things horticulture. This issue is about garden flowers."
icon_state = "horticulture3"
- item_state = "horticulture3"
/obj/item/toy/comic/magazine/horticulturetoday/issue4
desc = "A staple publication of all things horticulture. This issue is about wild flowers."
icon_state = "horticulture4"
- item_state = "horticulture4"
/obj/item/toy/comic/magazine/horticulturetoday/issue5
desc = "A staple publication of all things horticulture. This issue is about tomatoes of all kinds."
icon_state = "horticulture5"
- item_state = "horticulture5"
/obj/item/toy/comic/magazine/horticulturetoday/issue6
desc = "A staple publication of all things horticulture. This issue is about the genus Allium. Everything from Onions to Leeks."
icon_state = "horticulture6"
- item_state = "horticulture6"
//
// Toy Crossbows
diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm
index 395fdfd025e..4a5933f71e7 100644
--- a/code/modules/hydroponics/trays/tray.dm
+++ b/code/modules/hydroponics/trays/tray.dm
@@ -8,49 +8,74 @@
atom_flags = ATOM_FLAG_OPEN_CONTAINER
volume = 100
- var/mechanical = 1 // Set to 0 to stop it from drawing the alert lights.
+ /// Set to 0 to stop it from drawing the alert lights.
+ var/mechanical = 1
var/base_name = "tray"
- // Plant maintenance vars.
- var/waterlevel = 100 // Water (max 100)
- var/nutrilevel = 10 // Nutrient (max 10)
- var/pestlevel = 0 // Pests (max 10)
- var/weedlevel = 0 // Weeds (max 10)
+ // --- Plant maintenance vars. ---
+ /// Water (max 100)
+ var/waterlevel = 100
+ /// Nutrient (max 10)
+ var/nutrilevel = 10
+ /// Pests (max 10)
+ var/pestlevel = 0
+ // Weeds (max 10)
+ var/weedlevel = 0
var/maxWaterLevel = 100
var/maxNutriLevel = 10
var/maxPestLevel = 10
- var/maxWeedLevel = 0 // Hydroponics systems don't grow weeds irl. Pests are still an issue.
+ /// Hydroponics systems don't grow weeds irl. Pests are still an issue.
+ var/maxWeedLevel = 0
- // Tray state vars.
- var/dead = 0 // Is it dead?
- var/harvest = 0 // Is it ready to harvest?
- var/age = 0 // Current plant age
- var/sampled = 0 // Have we taken a sample?
- var/last_biolum // What was the bioluminescence last tick?
+ // --- Tray state vars. ---
+ /// Is it dead?
+ var/dead = 0
+ /// Is it ready to harvest?
+ var/harvest = 0
+ /// Current plant age
+ var/age = 0
+ /// Have we taken a sample?
+ var/sampled = 0
+ /// What was the bioluminescence last tick?
+ var/last_biolum
- // Harvest/mutation mods.
- var/yield_mod = 0 // Modifier to yield
- var/mutation_mod = 0 // Modifier to mutation chance
- var/toxins = 0 // Toxicity in the tray?
- var/mutation_level = 0 // When it hits 100, the plant mutates.
- var/tray_light = 5 // Supplied lighting.
+ // --- Harvest/mutation mods. ---
+ /// Modifier to yield
+ var/yield_mod = 0
+ /// Modifier to mutation chance
+ var/mutation_mod = 0
+ /// Toxicity in the tray?
+ var/toxins = 0
+ /// When it hits 100, the plant mutates.
+ var/mutation_level = 0
+ /// Supplied lighting.
+ var/tray_light = 5
// Mechanical concerns.
- var/health = 0 // Plant health.
- var/lastproduce = 0 // Last time tray was harvested
- var/lastcycle = 0 // Cycle timing/tracking var.
- var/cycledelay = 150 // Delay per cycle.
- var/closed_system // If set, the tray will attempt to take atmos from a pipe.
- var/force_update // Set this to bypass the cycle time check.
- var/obj/temp_chem_holder // Something to hold reagents during process_reagents()
+ /// Plant health.
+ var/health = 0
+ /// Last time tray was harvested
+ var/lastproduce = 0
+ /// Cycle timing/tracking var.
+ var/lastcycle = 0
+ /// Delay per cycle.
+ var/cycledelay = 150
+ /// If set, the tray will attempt to take atmos from a pipe.
+ var/closed_system
+ /// Set this to bypass the cycle time check.
+ var/force_update
+ /// Something to hold reagents during process_reagents()
+ var/obj/temp_chem_holder
var/labelled
- // Seed details/line data.
+ /// Seed details/line data.
var/datum/seed/seed = null // The currently planted seed
- // Reagent information for process(), consider moving this to a controller along
- // with cycle information under 'mechanical concerns' at some point.
+ /**
+ Reagent information for process(), consider moving this to a controller along
+ with cycle information under 'mechanical concerns' at some point.
+ */
var/global/list/toxic_reagents = list(
/singleton/reagent/dylovene = -2,
/singleton/reagent/toxin = 2,
@@ -106,7 +131,7 @@
/singleton/reagent/drink/sodawater = 1
)
- // Beneficial reagents also have values for modifying yield_mod and mut_mod (in that order).
+ /// Beneficial reagents also have values for modifying yield_mod and mut_mod (in that order).
var/global/list/beneficial_reagents = list(
/singleton/reagent/alcohol/beer=list( -0.05, 0, 0 ),
/singleton/reagent/hydrazine = list( -2, 0, 0 ),
@@ -127,8 +152,10 @@
/singleton/reagent/toxin/fertilizer/left4zed = list( 0, 0, 0.2)
)
- // Mutagen list specifies minimum value for the mutation to take place, rather
- // than a bound as the lists above specify.
+ /**
+ Mutagen list specifies minimum value for the mutation to take place, rather
+ than a bound as the lists above specify.
+ */
var/global/list/mutagenic_reagents = list(
/singleton/reagent/radium = 8,
/singleton/reagent/mutagen = 15
@@ -258,7 +285,7 @@
seed.create_spores(get_turf(src))
visible_message(SPAN_DANGER("\The [src] releases its spores!"))
-//Process reagents being input into the tray.
+/// Process reagents being input into the tray.
/obj/machinery/portable_atmospherics/hydroponics/proc/process_reagents()
if(!reagents) return
@@ -309,7 +336,7 @@
temp_chem_holder.reagents.clear_reagents()
check_health()
-//Harvests the product of a plant.
+/// Harvests the product of a plant.
/obj/machinery/portable_atmospherics/hydroponics/proc/harvest(var/mob/user)
//Harvest the product of the plant,
@@ -342,7 +369,7 @@
check_health()
return
-//Clears out a dead plant.
+/// Clears out a dead plant.
/obj/machinery/portable_atmospherics/hydroponics/proc/remove_dead(var/mob/user)
if(!user || !dead || !seed)
return
@@ -363,7 +390,7 @@
check_health()
return
-// If a weed growth is sufficient, this proc is called.
+/// If a weed growth is sufficient, this proc is called.
/obj/machinery/portable_atmospherics/hydroponics/proc/weed_invasion()
//Remove the seed if something is already planted.
@@ -477,6 +504,7 @@
RC.reagents.remove_reagent(/singleton/reagent/water, amountToRemove, 1)
waterlevel += amountToRemove
user.visible_message("[user] transfers some water to the tray.", "You transfer about [amountToRemove] units of water to the tray.")
+ playsound(src, /singleton/sound_category/generic_pour_sound, 25, 1)
else
to_chat(user, SPAN_WARNING("This tray is full of water already."))
return TRUE
@@ -498,17 +526,20 @@
to_chat(user, "The plant is dead.")
return
- // Create a sample.
- seed.harvest(user,yield_mod,1)
- health -= (rand(3,5)*10)
+ // Create a sample. Takes a moment.
+ user.visible_message(SPAN_WARNING("\The [user] begins to sample \the [src]."), SPAN_NOTICE("You begin sampling \the [src]."))
+ if(do_after(user, 1 SECOND))
+ playsound(src, 'sound/items/Wirecutter.ogg', 25, 1)
+ seed.harvest(user,yield_mod,1)
+ health -= (rand(3,5)*10)
- if(prob(30))
- sampled = 1
+ if(prob(30))
+ sampled = 1
- // Bookkeeping.
- check_health()
- force_update = 1
- process()
+ // Bookkeeping.
+ check_health()
+ force_update = 1
+ process()
return
@@ -565,14 +596,33 @@
else if (istype(attacking_item, /obj/item/material/minihoe)) // The minihoe
if(weedlevel > 0)
- user.visible_message(SPAN_DANGER("[user] starts uprooting the weeds."),
- SPAN_DANGER("You remove the weeds from the [src]."))
+ user.visible_message(SPAN_DANGER("[user] starts uprooting the weeds from \the [src]."),
+ SPAN_DANGER("You begin to remove the weeds from \the [src]."))
- weedlevel = 0
- update_icon()
+ if(do_after(user, 1 SECOND))
+ playsound(src, /singleton/sound_category/shovel_sound, 25, 1)
+ user.visible_message(SPAN_DANGER("[user] uproots the weeds from \the [src]."),
+ SPAN_DANGER("You successfully remove the weeds from \the [src]."))
+ weedlevel = 0
+ update_icon()
else
to_chat(user, SPAN_DANGER("This plot is completely devoid of weeds. It doesn't need uprooting."))
+ // Hatchets can uproot the contents of trays to kill the plant with one click.
+ else if (istype(attacking_item, /obj/item/material/hatchet))
+ if(health > 0)
+ user.visible_message(SPAN_DANGER("[user] begins uprooting the contents of \the [src]."),
+ SPAN_DANGER("You begin to uproot the contents of \the [src]."))
+
+ if(do_after(user, 2 SECOND))
+ playsound(src, /singleton/sound_category/shovel_sound, 25, 1)
+ user.visible_message(SPAN_DANGER("[user] uproots the contents of \the [src]!"),
+ SPAN_DANGER("You successfully uproot the contents of \the [src]."))
+ health = 0
+ check_health()
+ else
+ to_chat(user, SPAN_DANGER("There is nothing in this plot for you to uproot!"))
+
else if (istype(attacking_item, /obj/item/storage/bag/plants))
attack_hand(user)
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drink/food_drink_species_skrell.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drink/food_drink_species_skrell.dm
index a54e7935aac..0cdf2891484 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drink/food_drink_species_skrell.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drink/food_drink_species_skrell.dm
@@ -126,7 +126,7 @@
condiment_name = "dyn juice"
condiment_desc = "Juice from a Skrell medicinal herb. It's supposed to be diluted."
condiment_icon = 'icons/obj/item/reagent_containers/food/drinks/carton.dmi'
- condiment_icon_state = "dynjuice"
+ condiment_icon_state = "dyncarton"
/singleton/reagent/drink/dynjuice/hot
name = "Dyn Tea"
diff --git a/html/changelogs/hazelmouse-bloodreturn.yml b/html/changelogs/hazelmouse-bloodreturn.yml
new file mode 100644
index 00000000000..92ae610610c
--- /dev/null
+++ b/html/changelogs/hazelmouse-bloodreturn.yml
@@ -0,0 +1,64 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# - (fixes bugs)
+# wip
+# - (work in progress)
+# qol
+# - (quality of life)
+# soundadd
+# - (adds a sound)
+# sounddel
+# - (removes a sound)
+# rscadd
+# - (adds a feature)
+# rscdel
+# - (removes a feature)
+# imageadd
+# - (adds an image or sprite)
+# imagedel
+# - (removes an image or sprite)
+# spellcheck
+# - (fixes spelling or grammar)
+# experiment
+# - (experimental change)
+# balance
+# - (balance changes)
+# code_imp
+# - (misc internal code change)
+# refactor
+# - (refactors code)
+# config
+# - (makes a change to the config files)
+# admin
+# - (makes changes to administrator tools)
+# server
+# - (miscellaneous changes to server)
+#################################
+
+# Your name.
+author: hazelmouse
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
+# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Added a few new items to the biogenerator, including synthetic blood, wooden planks, a mop, an empty first-aid kit, cigarette filters, and cigarette papers."
+ - rscadd: "Hydroponics trays now produce sounds when watered, sampled, and weeded. Sampling and weeding both now have a one second timer for completion."
+ - rscadd: "Hatchets can now uproot plants growing in soil or in hydroponics trays with a single click."
+ - bugfix: "Dyn cartons are no longer invisible after being produced from a Condimaster."
+ - bugfix: "Horticultural magazines no longer have broken sprites."
+ - imageadd: "Introduced in-hand sprites for horticultural magazines."
+ - code_imp: "Transitioned some documentation in hydroponics tray code to DMDocs."
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index 6aebf935f2cfb9577fe8255747901750f13f8797..46db7314468950517583761a017cf9e4eebba84f 100644
GIT binary patch
delta 8340
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
delta 7730
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