Hydroponics Overhaul: the Atmos Update (#21059)

### What does this achieve?

This overhauls hydroponics to integrate atmospherics mechanics more
heavily, with the hope of establishing the foundations of much more
significant mechanical depth to what has been a very shallow job for a
very long time.

Currently, this is limited to the preferences and tolerances system -
hydroponics is now comprised of five 'reservoirs' of segmented portions
of the pipe system connected to trays, with a gas heater and cooler to
change temperature across the entire system, and you can cut off each
reservoir with valves to separate it from the rest and maintain its
current temperature.

Five tiers, each with a trait, have been implemented for the different
heat ideals of different plants. Plants from Adhomai and Moghes are the
most environmentally extreme, and cannot be grown outside of drastically
low and high temperatures respectively, limiting them to hydroponics
proper, whereas colder and warmer terrestrial plants can be grown at
room temperature but will grow much slower than if they were within
their preferences. **This means there will be plants that outright
cannot be grown in the garden.**

With this, hydroponics becomes an atmos puzzle. If you need to grow
nothing but mushrooms you'll probably send every tray cold, but if you
need a diversity of different temperature ranges you'll have to
fine-tune your setup and routine to have everything within their
preferences. Once you're done growing mushrooms off one reservoir, you
may turn the heat in it up so you can grow citrus, etc etc.

This also solves several bugs and makes a lot of QoL changes, the full
changelog will list everything.

<img width="608" height="320" alt="image"
src="https://github.com/user-attachments/assets/12e53224-d9be-4e69-9c48-6185d3303a14"
/>

<img width="384" height="608" alt="image"
src="https://github.com/user-attachments/assets/1a0c2b0c-8ad6-4f5c-b992-2e78035ab52d"
/>

<img width="640" height="512" alt="image"
src="https://github.com/user-attachments/assets/1cf837d1-3db5-440a-a465-071841febaea"
/>


### What about the mapping?

Atmos has been integrated into every hydroponics tray in the mapping
changes, rather than only on D1 like at present, to support the new
mechanics. I've moved as much stuff up to D2 as I could fit, in the
interest of getting players to the more visible and socially viable spot
rather than hiding in their basement. D1 is now exclusively intended as
a storage area, laboratory, and now has an expanded Hazardous Specimens
unit.

### To-do before review

- [x] Ensure that chefs can still do alien-specific menus without a
hydroponicist, now that they can't necessarily grow their stuff in the
garden - loadout produce box, maybe?
- [x] Remap xenobotany
- [x] Review whether every alien crop can still grow on its respective
in-game exoplanet - Adhomai might be okay? (Adhomai is essentially fine,
Moghes will need work before we go back into the sector)
- [x] Make sure the yield_mod interactions aren't explosive.

### Known issues

1. Yes, the examine on hydroponics trays is huge. In the long-term, IMO
this should probably be a TGUI.
2. The TGUI on seed storage units is clunky, this is also on the to-do
list for the future.
3. The logic for calculating growth is bad, it's very RNG-skewed.
Another thing for later.
4. Atmos mechanics like these can be pretty opaque to players, so this
will certainly require a wiki update shortly after merge describing
exactly what steps you should take to operate the new atmos equipment.
This commit is contained in:
hazelrat
2025-08-02 19:58:04 +00:00
committed by GitHub
parent f8a791e92a
commit d8c991674f
36 changed files with 5928 additions and 5366 deletions
@@ -202,7 +202,6 @@
name = "\improper Drying Rack"
desc = "A machine for drying plants."
icon_state = "drying_rack"
opacity = TRUE
accepted_items = list(/obj/item/reagent_containers/food/snacks)
contents_path = null
@@ -5,6 +5,10 @@
icon_state = "bee_pack"
var/full = TRUE
/obj/item/bee_pack/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Insert this into a beehive with an open lid to populate it with bees."
/obj/item/bee_pack/Initialize()
. = ..()
AddOverlays("bee_pack-full")
@@ -4,6 +4,10 @@
icon = 'icons/obj/beekeeping.dmi'
icon_state = "beehive_assembly"
/obj/item/beehive_assembly/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this on any unoccupied turf to place a beehive where you are standing."
/obj/item/beehive_assembly/attack_self(var/mob/user)
to_chat(user, SPAN_NOTICE("You start assembling \the [src]..."))
if(do_after(user, 30))
@@ -14,6 +18,7 @@
/obj/machinery/beehive
name = "beehive"
desc = "They make honey in these, allegedly."
icon = 'icons/obj/beekeeping.dmi'
icon_state = "beehive"
density = TRUE
@@ -28,6 +33,17 @@
var/list/owned_bee_swarms = list()
/obj/machinery/beehive/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use a <b>crowbar</b> to open a beehive, and then retrieve the frames from inside with an open hand."
. += "You can populate a beehive using a <b>bee pack</b>, and review the status of the hive inside with a <b>plant analyzer</b>."
. += "While occupied by bees and within several turfs of a growing plant, bees will increase the health of the adjacent plant. This can be particularly \
useful if you're low on fertiliser and need to keep your crops alive!"
/obj/machinery/beehive/disassembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "This can be dismantled with a <b>screwdriver</b>."
/obj/machinery/beehive/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
. += SPAN_NOTICE("\The [src] is holding <b>[frames]/[maxFrames]</b> frames.")
@@ -14,6 +14,11 @@
. += SPAN_NOTICE("It's holding \the <b>[contained_frame]</b>.")
. += SPAN_NOTICE("It contains <b>[honey]</b> units of honey for collection.")
/obj/machinery/honey_extractor/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Once filled honeycombs have been obtained, insert them into this device to process them into wax and honey. The honey can be retrieved from \
the extractor with any reagent container."
/obj/machinery/honey_extractor/attackby(obj/item/attacking_item, mob/user)
if(contained_frame)
to_chat(user, SPAN_WARNING("\The [src] is currently spinning, wait until it's finished."))
@@ -6,6 +6,10 @@
w_class = WEIGHT_CLASS_SMALL
var/honey = 0
/obj/item/honey_frame/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
. += SPAN_NOTICE("This contains <b>[honey] units</b> of honey.")
/obj/item/honey_frame/filled
name = "filled beehive frame"
desc = "A frame for the beehive that has been filled with honeycombs."
@@ -8,6 +8,10 @@
var/caught_bees = 0
var/feralbees
/obj/item/bee_net/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "This can be used to contain rogue bees, although beware overcrowding the net! If you do, the contained bees may all break out at once."
/obj/item/bee_net/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(caught_bees)
@@ -8,6 +8,10 @@
w_class = WEIGHT_CLASS_BULKY
var/max_fuel = 60
/obj/item/bee_smoker/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Use this to pacify bees before extracting frames from a hive!"
/obj/item/bee_smoker/antagonist_hints(mob/user, distance, is_adjacent)
. += ..()
. += "This device can be used to blind people in short range."
+67 -8
View File
@@ -49,6 +49,13 @@
/// If set, overrides the extended scription of the product (Useful to describe the 'lore')
var/product_desc_extended
/// The base percentage chance the plant will grow per each process().
var/base_growth_speed = 10
/// The boost to the base growth speed applied to the plant if within temperature preferences.
var/temperature_growth_boost = 20
/// The boost to the base growth speed applied to the plant if within light preferences.
var/light_growth_boost = 5
var/force_layer
var/hydrotray_only
@@ -80,21 +87,21 @@
set_trait(TRAIT_REQUIRES_NUTRIENTS, 1)
set_trait(TRAIT_REQUIRES_WATER, 1)
set_trait(TRAIT_WATER_CONSUMPTION, 3)
set_trait(TRAIT_LIGHT_TOLERANCE, 3) // Plants will begin to die if the light levels are three or more lumens from their ideal.
set_trait(TRAIT_LIGHT_TOLERANCE, 2.5) // Plants will begin to die if the light levels are 2.5 or more lumens from their ideal.
set_trait(TRAIT_TOXINS_TOLERANCE, 5)
set_trait(TRAIT_PEST_TOLERANCE, 5)
set_trait(TRAIT_WEED_TOLERANCE, 5)
set_trait(TRAIT_IDEAL_LIGHT, 5)
set_trait(TRAIT_HEAT_TOLERANCE, 20) // Plants will begin to die if they're twenty or more degrees from their ideal temperature.
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_TEMPERATE)
set_trait(TRAIT_HEAT_TOLERANCE, 12) // Plants will begin to die if they're twelve or more degrees from their ideal temperature.
set_trait(TRAIT_LOWKPA_TOLERANCE, 25) // Plants survive all the way down to a quarter of an atmosphere!
set_trait(TRAIT_ENDURANCE, 100)
set_trait(TRAIT_HIGHKPA_TOLERANCE, 200)
set_trait(TRAIT_IDEAL_HEAT, 293)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TEMPERATE)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25)
set_trait(TRAIT_PLANT_COLOUR, "#46B543")
set_trait(TRAIT_LARGE, 0)
set_trait(TRAIT_HEAT_PREFERENCE, 5) // By default, plants grow faster in a temperature within five degrees of their ideal.
set_trait(TRAIT_LIGHT_PREFERENCE, 2) // Similarly, they grow faster under lumens within two of their ideal.
set_trait(TRAIT_LIGHT_PREFERENCE, 1.5) // Similarly, they grow faster under lumens within 1.5 of their ideal.
setup_traits()
@@ -333,7 +340,7 @@
// We take the absolute value of the environment's temperature minus the ideal heat - closer to 0 is better, in this case.
// If that value is greater than the heat tolerance, we apply some damage to the plant.
if(abs(environment.temperature - get_trait(TRAIT_IDEAL_HEAT)) > get_trait(TRAIT_HEAT_TOLERANCE))
if(check_heat_tolerances(environment))
health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER
// Handle gas production.
@@ -349,11 +356,59 @@
light_supplied = 5
if(light_supplied)
if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) > get_trait(TRAIT_LIGHT_TOLERANCE))
if(check_light_tolerances(light_supplied))
health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER
return health_change
/// Returns true if a plant is outside their light tolerances, otherwise false.
/datum/seed/proc/check_light_tolerances(var/light_supplied)
if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) > get_trait(TRAIT_LIGHT_TOLERANCE))
return TRUE
return FALSE
/// Returns true if a plant is outside their heat tolerances, otherwise false.
/datum/seed/proc/check_heat_tolerances(var/datum/gas_mixture/environment)
if(abs(environment.temperature - get_trait(TRAIT_IDEAL_HEAT)) > get_trait(TRAIT_HEAT_TOLERANCE))
return TRUE
return FALSE
/// Returns true if a plant is in their light preferences, otherwise false.
/datum/seed/proc/check_light_preferences(var/light_supplied)
if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) < get_trait(TRAIT_LIGHT_PREFERENCE))
return TRUE
return FALSE
/// Returns true if a plant is in their heat preferences, otherwise false.
/datum/seed/proc/check_heat_preferences(var/datum/gas_mixture/environment)
if(abs(environment.temperature - get_trait(TRAIT_IDEAL_HEAT)) < get_trait(TRAIT_HEAT_PREFERENCE))
return TRUE
return FALSE
/// Checks the preferences of the seed, and returns the percentage chance for growth to occur. Called in tray_process.
/datum/seed/proc/get_probability_of_growth(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only)
// By standard, the probability of growth is only the base. This rises if growing conditions are within their preferences.
// This is intended to motivate the use of atmospheric equipment to more viably grow plants with irregular preferences.
// You *can* grow plants outside of their preferences without them dying so long as it's within their tolerance, but it'll be pretty slow.
var/return_probability = base_growth_speed
// Handle light requirements.
if(!light_supplied)
if (TURF_IS_DYNAMICALLY_LIT(current_turf))
light_supplied = current_turf.get_lumcount(0, 3) * 10
else
light_supplied = 5
// Are we within the preference zone for temperature? If so, add to the chance of growth.
if(check_heat_preferences(environment))
return_probability += temperature_growth_boost
// Same for light!
if(check_light_preferences(light_supplied))
return_probability += light_growth_boost
return return_probability
/datum/seed/proc/apply_special_effect(var/mob/living/target,var/obj/item/thrown)
var/impact = 1
@@ -736,7 +791,7 @@
return (P ? P : 0)
/// Place the plant products at the feet of the user.
/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount)
/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount,var/stunted_status = FALSE)
if(!user)
return
@@ -769,6 +824,10 @@
total_yield = get_trait(TRAIT_YIELD) + rand(yield_mod)
total_yield = max(1,total_yield)
// If the plant is stunted, you get half the yield.
if(stunted_status)
total_yield *= 0.5
for(var/i = 0;i<total_yield;i++)
spawn_seed(get_turf(user))
@@ -20,7 +20,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#378C61")
set_trait(TRAIT_PLANT_COLOUR,"#378C61")
set_trait(TRAIT_PLANT_ICON,"tree5")
set_trait(TRAIT_IDEAL_HEAT, 278)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_ADHOMAI)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
/obj/item/seeds/shandseed
@@ -45,7 +46,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#4CC5C7")
set_trait(TRAIT_PLANT_COLOUR,"#4CC789")
set_trait(TRAIT_PLANT_ICON,"bush7")
set_trait(TRAIT_IDEAL_HEAT, 278)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_ADHOMAI)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
/obj/item/seeds/mtearseed
@@ -70,7 +72,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#87CEEB")
set_trait(TRAIT_PLANT_COLOUR,"#4D8F53")
set_trait(TRAIT_PLANT_ICON,"alien2")
set_trait(TRAIT_IDEAL_HEAT, 278)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_ADHOMAI)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
set_trait(TRAIT_WATER_CONSUMPTION, 8)
/obj/item/seeds/earthenroot
@@ -97,9 +100,10 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#C4AE7A")
set_trait(TRAIT_PLANT_COLOUR,"#4D8F53")
set_trait(TRAIT_PLANT_ICON,"bush4")
set_trait(TRAIT_IDEAL_HEAT, 278)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_ADHOMAI)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
/obj/item/seeds/dirtberries
seed_type = "dirtberries"
@@ -127,8 +131,8 @@
set_trait(TRAIT_PLANT_COLOUR,"#31331c")
set_trait(TRAIT_PLANT_ICON,"nfrihi")
set_trait(TRAIT_WATER_CONSUMPTION, 4)
set_trait(TRAIT_IDEAL_LIGHT, 3)
set_trait(TRAIT_IDEAL_HEAT, 253)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_ADHOMAI)
/obj/item/seeds/blizzard
seed_type = "nfrihi"
@@ -154,9 +158,9 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#fffdf7")
set_trait(TRAIT_PLANT_COLOUR,"#31331c")
set_trait(TRAIT_PLANT_ICON,"nmshaan")
set_trait(TRAIT_IDEAL_HEAT, 253)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_ADHOMAI)
set_trait(TRAIT_WATER_CONSUMPTION, 4)
set_trait(TRAIT_IDEAL_LIGHT, 3)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
/obj/item/seeds/sugartree
seed_type = "sugar tree"
@@ -15,8 +15,8 @@
set_trait(TRAIT_PRODUCT_ICON, "mollusc")
set_trait(TRAIT_PLANT_ICON, "mollusc")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_IDEAL_HEAT, 284)
set_trait(TRAIT_LIGHT_TOLERANCE, 6)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_COLD)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
set_trait(TRAIT_PRODUCT_COLOUR, "#aaabba")
set_trait(TRAIT_PLANT_COLOUR, "#aaabba")
@@ -64,3 +64,19 @@
/obj/item/seeds/clam/rasval
seed_type = "rasval clam"
/datum/seed/grass/sea
name = "seaweed"
seed_name = "seaweed"
display_name = "seaweed"
kitchen_tag = "seaweed"
/datum/seed/grass/sea/setup_traits()
..()
set_trait(TRAIT_PRODUCT_COLOUR, "#0F6E56")
set_trait(TRAIT_PLANT_COLOUR, "#0D4836")
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_COLD)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_DIM)
/obj/item/seeds/seaweed
seed_type = "seaweed"
@@ -35,7 +35,6 @@
set_trait(TRAIT_PRODUCT_ICON,"flower3")
set_trait(TRAIT_PRODUCT_COLOUR,"#B33715")
set_trait(TRAIT_PLANT_ICON,"flower3")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_WATER_CONSUMPTION, 0.5)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
@@ -53,7 +52,7 @@
set_trait(TRAIT_PRODUCT_ICON,"flower2")
set_trait(TRAIT_PRODUCT_COLOUR,"#FFF700")
set_trait(TRAIT_PLANT_ICON,"flower2")
set_trait(TRAIT_IDEAL_LIGHT, 7)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
+14 -11
View File
@@ -20,7 +20,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#3AF026")
set_trait(TRAIT_PLANT_ICON,"tree")
set_trait(TRAIT_FLESH_COLOUR,"#3AF026")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/limeseed
seed_type = "lime"
@@ -37,7 +38,6 @@
set_trait(TRAIT_PRODUCES_POWER,1)
set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226")
set_trait(TRAIT_FLESH_COLOUR,"#F0E226")
set_trait(TRAIT_IDEAL_LIGHT, 6)
/obj/item/seeds/lemonseed
seed_type = "lemon"
@@ -78,7 +78,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#BB6AC4")
set_trait(TRAIT_PLANT_COLOUR,"#378F2E")
set_trait(TRAIT_PLANT_ICON,"vine")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
/obj/item/seeds/grapeseed
@@ -294,7 +295,6 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#FF540A")
set_trait(TRAIT_PLANT_ICON,"tree2")
set_trait(TRAIT_FLESH_COLOUR,"#E8E39B")
set_trait(TRAIT_IDEAL_LIGHT, 4)
/obj/item/seeds/appleseed
seed_type = "apple"
@@ -348,7 +348,8 @@
set_trait(TRAIT_PRODUCT_ICON,"treefruit")
set_trait(TRAIT_PRODUCT_COLOUR,"#CCA935")
set_trait(TRAIT_PLANT_ICON,"tree2")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
/datum/seed/banana
@@ -369,8 +370,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#FFEC1F")
set_trait(TRAIT_PLANT_COLOUR,"#69AD50")
set_trait(TRAIT_PLANT_ICON,"tree4")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, 7)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
/obj/item/seeds/bananaseed
@@ -420,8 +421,8 @@
set_trait(TRAIT_PLANT_COLOUR,"#49be45")
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_FLESH_COLOUR,"#ff5858")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
/obj/item/seeds/watermelonseed
@@ -469,7 +470,8 @@
set_trait(TRAIT_PRODUCT_ICON,"bean2")
set_trait(TRAIT_PRODUCT_COLOUR,"#be9109")
set_trait(TRAIT_PLANT_ICON,"bush2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/coffeeseed
seed_type = "coffee"
@@ -491,7 +493,8 @@
set_trait(TRAIT_PRODUCT_ICON,"bean2")
set_trait(TRAIT_PRODUCT_COLOUR,"#be9109")
set_trait(TRAIT_PLANT_ICON,"bush2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/richcoffeeseed
seed_type = "richcoffee"
@@ -15,7 +15,6 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#DBD37D")
set_trait(TRAIT_PLANT_COLOUR,"#BFAF82")
set_trait(TRAIT_PLANT_ICON,"stalk2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
/obj/item/seeds/wheatseed
@@ -39,8 +38,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#FFF23B")
set_trait(TRAIT_PLANT_COLOUR,"#87C969")
set_trait(TRAIT_PLANT_ICON,"corn")
set_trait(TRAIT_IDEAL_HEAT, 298)
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
/obj/item/seeds/cornseed
@@ -64,6 +63,8 @@
set_trait(TRAIT_PLANT_COLOUR,"#8ED17D")
set_trait(TRAIT_PLANT_ICON,"stalk2")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
/obj/item/seeds/riceseed
@@ -16,12 +16,11 @@
set_trait(TRAIT_PRODUCT_ICON,"herb")
set_trait(TRAIT_PRODUCT_COLOUR,"#4dd298")
set_trait(TRAIT_PLANT_ICON,"herb")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/mintseed
seed_type = "mint"
/datum/seed/tea
name = "tea"
seed_name = "tea leaf"
@@ -38,7 +37,7 @@
set_trait(TRAIT_PRODUCT_ICON,"herb")
set_trait(TRAIT_PRODUCT_COLOUR,"#4fd24d")
set_trait(TRAIT_PLANT_ICON,"herb")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/teaseed
seed_type = "tea"
@@ -58,7 +57,7 @@
set_trait(TRAIT_PRODUCT_ICON,"herb")
set_trait(TRAIT_PRODUCT_COLOUR,"#0E1F0E")
set_trait(TRAIT_PLANT_ICON,"herb")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/sencha
seed_type = "sencha"
@@ -78,7 +77,7 @@
set_trait(TRAIT_PRODUCT_ICON,"herb")
set_trait(TRAIT_PRODUCT_COLOUR,"#5C6447")
set_trait(TRAIT_PLANT_ICON,"herb")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/tieguanyin
seed_type = "tieguanyin"
@@ -98,7 +97,7 @@
set_trait(TRAIT_PRODUCT_ICON,"herb")
set_trait(TRAIT_PRODUCT_COLOUR,"#534337")
set_trait(TRAIT_PLANT_ICON,"herb")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/jaekseol
seed_type = "jaekseol"
@@ -119,7 +118,7 @@
set_trait(TRAIT_PRODUCT_ICON, "herb")
set_trait(TRAIT_PRODUCT_COLOUR, "#056608")
set_trait(TRAIT_PLANT_ICON, "herb")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/cocaseed
seed_type = "coca"
+4 -17
View File
@@ -35,7 +35,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#B4D6BD")
set_trait(TRAIT_PLANT_COLOUR,"#6BBD68")
set_trait(TRAIT_PLANT_ICON,"stalk3")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/sugarcaneseed
seed_type = "sugarcane"
@@ -64,21 +65,6 @@
/obj/item/seeds/grassseed
seed_type = "grass"
/datum/seed/grass/sea
name = "seaweed"
seed_name = "seaweed"
display_name = "seaweed"
kitchen_tag = "seaweed"
/datum/seed/grass/sea/setup_traits()
..()
set_trait(TRAIT_PRODUCT_COLOUR, "#0F6E56")
set_trait(TRAIT_PLANT_COLOUR, "#0D4836")
set_trait(TRAIT_IDEAL_HEAT, 284) // To fit with molluscs.
/obj/item/seeds/seaweed
seed_type = "seaweed"
/datum/seed/grass/moss
name = "moss"
seed_name = "moss"
@@ -110,7 +96,8 @@
set_trait(TRAIT_PRODUCT_ICON,"nuts")
set_trait(TRAIT_PRODUCT_COLOUR,"#4d4d4d")
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/peppercornseed
seed_type = "peppercorn"
@@ -25,8 +25,7 @@
set_trait(TRAIT_PLANT_COLOUR,"#D9C94E")
set_trait(TRAIT_PLANT_ICON,"mushroom")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_IDEAL_HEAT, 282)
set_trait(TRAIT_LIGHT_TOLERANCE, 6)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_COLD)
/datum/seed/koisspore
name = "koisspore"
@@ -49,7 +48,6 @@
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_POTENCY,60)
set_trait(TRAIT_BIOLUM,1)
set_trait(TRAIT_IDEAL_LIGHT,5)
set_trait(TRAIT_REQUIRES_NUTRIENTS,0)
set_trait(TRAIT_REQUIRES_WATER,0)
set_trait(TRAIT_LIGHT_TOLERANCE,10)
@@ -75,7 +73,6 @@
set_trait(TRAIT_BIOLUM_PWR,-1.5)
set_trait(TRAIT_POTENCY,80)
set_trait(TRAIT_ENDURANCE,75)
set_trait(TRAIT_IDEAL_LIGHT,0)
set_trait(TRAIT_BIOLUM_COLOUR,"#FFFFFF")
set_trait(TRAIT_PRODUCT_COLOUR,"#31004A")
set_trait(TRAIT_PLANT_COLOUR,"#31004A")
@@ -17,6 +17,7 @@
set_trait(TRAIT_PRODUCT_ICON,"leaves")
set_trait(TRAIT_PRODUCT_COLOUR,"#00e0e0")
set_trait(TRAIT_PLANT_ICON,"bush8")
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/dynseed
seed_type = "dyn"
@@ -38,6 +39,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#61E2EC")
set_trait(TRAIT_PLANT_ICON,"wumpavines")
set_trait(TRAIT_WATER_CONSUMPTION, 10)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/wulumunushaseed
seed_type = "wulumunusha"
@@ -61,6 +63,7 @@
set_trait(TRAIT_FLESH_COLOUR, "#9FE4B0")
set_trait(TRAIT_PLANT_ICON,"mushroom9")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/qlortseed
seed_type = "qlort"
@@ -86,6 +89,7 @@
set_trait(TRAIT_PLANT_COLOUR,"#4790DA")
set_trait(TRAIT_PLANT_ICON,"alien1")
set_trait(TRAIT_WATER_CONSUMPTION, 10)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/guamiseed
seed_type = "guami"
@@ -135,6 +139,7 @@
set_trait(TRAIT_PLANT_ICON,"bush")
set_trait(TRAIT_WATER_CONSUMPTION, 10)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/ylpha
seed_type = "ylpha"
@@ -161,6 +166,7 @@
set_trait(TRAIT_BIOLUM_COLOUR,"#990033")
set_trait(TRAIT_SPREAD,1)
set_trait(TRAIT_WATER_CONSUMPTION, 10)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/fjylozyn
seed_type = "fjylozyn"
@@ -17,8 +17,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#749733")
set_trait(TRAIT_PLANT_COLOUR,"#749733")
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, 7)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
@@ -83,7 +83,8 @@
set_trait(TRAIT_PRODUCT_ICON,"ambrosia")
set_trait(TRAIT_PRODUCT_COLOUR,"#9FAD55")
set_trait(TRAIT_PLANT_ICON,"ambrosia")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/ambrosiavulgarisseed
seed_type = "ambrosia"
@@ -125,7 +126,8 @@
set_trait(TRAIT_PRODUCT_COLOUR, "#ad5555")
set_trait(TRAIT_PLANT_COLOUR, "#ffa2a2")
set_trait(TRAIT_PLANT_ICON, "flower")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/oracleseed
seed_type = "oracle"
@@ -20,7 +20,6 @@
set_trait(TRAIT_PRODUCT_ICON,"tomato")
set_trait(TRAIT_PRODUCT_COLOUR,"#D10000")
set_trait(TRAIT_PLANT_ICON,"bush3")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25)
+12 -1
View File
@@ -19,6 +19,8 @@
set_trait(TRAIT_PLANT_COLOUR,"#4D8F53")
set_trait(TRAIT_PLANT_ICON,"tree3")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_MOGHES)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/xuiziseed
seed_type = "xuizi"
@@ -44,6 +46,8 @@
set_trait(TRAIT_PLANT_ICON,"bush")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_MOGHES)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/sarezhiseed
seed_type = "sarezhi"
@@ -68,7 +72,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#e93e1c")
set_trait(TRAIT_PLANT_COLOUR,"#6d9c6b")
set_trait(TRAIT_PLANT_ICON,"algae")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_MOGHES)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
@@ -92,6 +97,8 @@
set_trait(TRAIT_PRODUCT_ICON,"nuts")
set_trait(TRAIT_PRODUCT_COLOUR,"#866523")
set_trait(TRAIT_PLANT_ICON,"tree")
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_MOGHES)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/aghrasshseed
seed_type = "aghrassh"
@@ -116,6 +123,8 @@
set_trait(TRAIT_PLANT_ICON,"bush")
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_MOGHES)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/sthberryseed
seed_type = "sthberry"
@@ -134,6 +143,8 @@
set_trait(TRAIT_IDEAL_LIGHT, 7)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_MOGHES)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
/obj/item/seeds/serkiflowerseed
seed_type = "serkiflower"
@@ -19,8 +19,8 @@
set_trait(TRAIT_PRODUCT_ICON,"chili")
set_trait(TRAIT_PRODUCT_COLOUR,"#ED3300")
set_trait(TRAIT_PLANT_ICON,"bush2")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, 7)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/chiliseed
seed_type = "chili"
@@ -61,8 +61,8 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#ff922d")
set_trait(TRAIT_PLANT_COLOUR,"#35d65d")
set_trait(TRAIT_PLANT_ICON,"bush2")
set_trait(TRAIT_IDEAL_HEAT, 293)
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
set_trait(TRAIT_WATER_CONSUMPTION, 5)
/obj/item/seeds/bellpepperseed
@@ -133,8 +133,8 @@
set_trait(TRAIT_PRODUCT_ICON,"eggplant")
set_trait(TRAIT_PRODUCT_COLOUR,"#892694")
set_trait(TRAIT_PLANT_ICON,"bush4")
set_trait(TRAIT_IDEAL_HEAT, 304)
set_trait(TRAIT_IDEAL_LIGHT, 7)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/eggplantseed
seed_type = "eggplant"
@@ -179,7 +179,8 @@
set_trait(TRAIT_PRODUCT_ICON,"nuts")
set_trait(TRAIT_PRODUCT_COLOUR,"#F2B369")
set_trait(TRAIT_PLANT_ICON,"bush2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/peanutseed
seed_type = "peanut"
@@ -201,6 +202,8 @@
set_trait(TRAIT_PRODUCT_ICON,"bean")
set_trait(TRAIT_PRODUCT_COLOUR,"#EBE7C0")
set_trait(TRAIT_PLANT_ICON,"stalk")
set_trait(TRAIT_IDEAL_LIGHT, IDEAL_LIGHT_HIGH)
set_trait(TRAIT_IDEAL_HEAT, IDEAL_HEAT_TROPICAL)
/obj/item/seeds/soyaseed
seed_type = "soybean"
@@ -245,7 +248,6 @@
set_trait(TRAIT_PRODUCT_ICON, "bean")
set_trait(TRAIT_PRODUCT_COLOUR, "#70b74a")
set_trait(TRAIT_PLANT_ICON, "bush2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
/obj/item/seeds/peaseed
seed_type = "peas"
@@ -272,7 +274,6 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#84BD82")
set_trait(TRAIT_PLANT_COLOUR,"#6D9C6B")
set_trait(TRAIT_PLANT_ICON,"vine2")
set_trait(TRAIT_IDEAL_LIGHT, 6)
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15)
+24 -2
View File
@@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY(plant_seed_sprites)
/obj/item/seeds
name = "packet of seeds"
icon = 'icons/obj/seeds.dmi'
icon_state = "blank"
icon_state = "random"
w_class = WEIGHT_CLASS_SMALL
storage_slot_sort_by_name = TRUE
@@ -27,6 +27,10 @@ GLOBAL_LIST_EMPTY(plant_seed_sprites)
if(!seed)
return
// This is very hacky, but we clear the icon state here because the ingame packets
// are all pure overlays, but we still want seeds to show up in StrongDMM.
icon_state = "blank"
// Update icon.
ClearOverlays()
var/is_seeds = ((seed.seed_noun in list(SEED_NOUN_SEEDS, SEED_NOUN_PITS, SEED_NOUN_NODES)) ? 1 : 0)
@@ -70,11 +74,29 @@ GLOBAL_LIST_EMPTY(plant_seed_sprites)
sm.Blend(so, ICON_OVERLAY)
return sm
/obj/item/seeds/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "All plants have preferential heat and light values. They will grow faster if close to these values. Plants also have tolerance values, \
and will stop growing and begin to take damage when outside of their tolerances. Use hydroponics trays to get plants within their optimal values!"
. += "Plants can be mutated with any mutagen, altering their genes in a random way. Do this with caution as the results may be hazardous!"
/obj/item/seeds/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(seed && !seed.roundstart)
. += "It's tagged as variety #[seed.uid]."
. += "This has an ideal temperature of <b>[seed.get_trait(TRAIT_IDEAL_HEAT)] kelvin</b> and light level of <b>[seed.get_trait(TRAIT_IDEAL_LIGHT)] lumens.</b>"
var/lower_heat_preference = seed.get_trait(TRAIT_IDEAL_HEAT) - seed.get_trait(TRAIT_HEAT_PREFERENCE)
var/higher_heat_preference = seed.get_trait(TRAIT_IDEAL_HEAT) + seed.get_trait(TRAIT_HEAT_PREFERENCE)
var/lower_light_preference = seed.get_trait(TRAIT_IDEAL_LIGHT) - seed.get_trait(TRAIT_LIGHT_PREFERENCE)
var/higher_light_preference = seed.get_trait(TRAIT_IDEAL_LIGHT) + seed.get_trait(TRAIT_LIGHT_PREFERENCE)
var/lower_heat_tolerance = seed.get_trait(TRAIT_IDEAL_HEAT) - seed.get_trait(TRAIT_HEAT_TOLERANCE)
var/higher_heat_tolerance = seed.get_trait(TRAIT_IDEAL_HEAT) + seed.get_trait(TRAIT_HEAT_TOLERANCE)
var/lower_light_tolerance = seed.get_trait(TRAIT_IDEAL_LIGHT) - seed.get_trait(TRAIT_LIGHT_TOLERANCE)
var/higher_light_tolerance = seed.get_trait(TRAIT_IDEAL_LIGHT) + seed.get_trait(TRAIT_LIGHT_TOLERANCE)
. += SPAN_NOTICE("This grows optimally between <b>[lower_heat_preference] and [higher_heat_preference] kelvin</b>, and between <b>[lower_light_preference] and [higher_light_preference] lumens.</b> It is capable of any growth at all between <b>[lower_heat_tolerance] and [higher_heat_tolerance] kelvin</b>, and between <b>[lower_light_tolerance] and [higher_light_tolerance] lumens.</b>")
/obj/item/seeds/cutting
name = SEED_NOUN_CUTTINGS
+103 -58
View File
@@ -3,8 +3,8 @@
desc = "A mechanical basin designed to nurture plants and other aquatic life. It has various useful sensors."
icon = 'icons/obj/hydroponics_machines.dmi'
icon_state = "hydrotray3"
density = 1
anchored = 1
density = TRUE
anchored = TRUE
atom_flags = ATOM_FLAG_OPEN_CONTAINER
volume = 100
@@ -35,9 +35,9 @@
// --- Tray state vars. ---
/// Is it dead?
var/dead = 0
var/dead = FALSE
/// Is it ready to harvest?
var/harvest = 0
var/harvest = FALSE
/// Current plant age
var/age = 0
/// Have we taken a sample?
@@ -70,6 +70,8 @@
var/closed_system
/// Whether this tray is under stasis, freezing all functions. It won't grow, but it won't die.
var/stasis = FALSE
/// Is this harvest stunted? If so, the yield of that harvest is halfed.
var/stunted = FALSE
/// Set this to bypass the cycle time check.
var/force_update
/// Something to hold reagents during process_reagents()
@@ -168,6 +170,20 @@
/singleton/reagent/mutagen = 15
)
/obj/machinery/portable_atmospherics/hydroponics/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
if(mechanical)
. += "You can lower or raise the lid of a hydroponics tray using <b>Alt + Left Click</b> with an open hand."
. += "Improper lighting can be lethal to plants! If your surrounding lighting is inappropriate, you can lower the lid and set a tray light level \
using <b>Control + Left Click</b> with an open hand."
. += "When the lid is lowered, and if wrenched to a connector, hydroponics trays adopt the temperature of the gas inside the connector. Use this to \
change the temperature at which a tray is growing to conform to a plant's heat preferences. Note that if you do this while the connector contains \
vacuum, it will cause the temperature of the interior of the tray to reduce drastically in temperature and kill whatever is growing there."
else
. += "This is a soil plot, and therefore lacks many of the features of hydroponics trays. You will need to ensure that the surrounding atmosphere \
lighting of the plot matches the preferences of the plant you are trying to grow, or else it may grow slowly or not at all."
. += "If a plant matures while not within within both its heat and light preferences, its yield will be reduced."
/obj/machinery/portable_atmospherics/hydroponics/AltClick()
if (istype(usr, /mob/living/carbon/alien/diona))//A diona alt+clicking feeds the plant
if(!Adjacent(usr))
@@ -282,9 +298,10 @@
/// Call this to kill a plant. Don't modify the dead variable directly.
/obj/machinery/portable_atmospherics/hydroponics/proc/die()
dead = 1
dead = TRUE
mutation_level = 0
harvest = 0
stunted = FALSE
harvest = FALSE
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
pestlevel = 0
if(prob(min(25,max(1,seed.get_trait(TRAIT_POTENCY/2)))))
@@ -353,14 +370,15 @@
return
if(user)
seed.harvest(user,yield_mod)
seed.harvest(user,yield_mod,stunted_status = stunted)
else
seed.harvest(get_turf(src),yield_mod)
seed.harvest(get_turf(src),yield_mod, stunted_status = stunted)
// Reset values.
if(seed.get_trait(TRAIT_SPOROUS))
seed.create_spores(get_turf(src))
visible_message(SPAN_DANGER("\The [src] releases its spores!"))
harvest = 0
harvest = FALSE
stunted = FALSE
lastproduce = age
if(!seed.get_trait(TRAIT_HARVEST_REPEAT))
@@ -384,7 +402,7 @@
return
seed = null
dead = 0
dead = FALSE
sampled = 0
age = 0
yield_mod = 0
@@ -402,11 +420,12 @@
seed = SSplants.seeds[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))]
if(!seed) return //Weed does not exist, someone fucked up.
dead = 0
dead = FALSE
age = 0
health = seed.get_trait(TRAIT_ENDURANCE)
lastcycle = world.time
harvest = 0
stunted = FALSE
harvest = FALSE
weedlevel = 0
pestlevel = 0
sampled = 0
@@ -462,7 +481,7 @@
health = max(0,min(seed.get_trait(TRAIT_ENDURANCE),health))
else
health = 0
dead = 0
dead = FALSE
mutation_level = max(0,min(mutation_level,100))
nutrilevel = max(0,min(nutrilevel,10))
@@ -479,12 +498,12 @@
else
return
dead = 0
dead = FALSE
mutate(1)
age = 0
health = seed.get_trait(TRAIT_ENDURANCE)
lastcycle = world.time
harvest = 0
harvest = FALSE
weedlevel = 0
update_icon()
@@ -576,6 +595,7 @@
return
to_chat(user, "You plant the [S.seed.seed_name] [S.seed.seed_noun].")
playsound(src, 'sound/items/pickup/herb.ogg', 50, 1)
lastproduce = 0
seed = S.seed //Grab the seed datum.
dead = 0
@@ -592,7 +612,6 @@
to_chat(user, SPAN_DANGER("\The [src] already has seeds in it!"))
else if (istype(attacking_item, /obj/item/material/minihoe)) // The minihoe
if(weedlevel > 0)
user.visible_message(SPAN_DANGER("[user] starts uprooting the weeds from \the [src]."),
SPAN_DANGER("You begin to remove the weeds from \the [src]."))
@@ -695,74 +714,100 @@
else if(dead)
remove_dead(user)
/obj/machinery/portable_atmospherics/hydroponics/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/machinery/portable_atmospherics/hydroponics/get_examine_text(mob/user, distance, is_adjacent)
. = ..()
if(!seed)
. += "[src] is empty."
return
. += SPAN_NOTICE("[seed.display_name] are growing here.")
if(seed)
. += SPAN_NOTICE("[seed.display_name] are growing here.")
if(!is_adjacent)
return
. += "The water gauge displays [round(waterlevel,0.1)]/100."
. += "The nutrient gauge displays [round(nutrilevel,0.1)]/10."
. += "The water gauge displays <b>[round(waterlevel,0.1)]/100</b>."
. += "The nutrient gauge displays <b>[round(nutrilevel,0.1)]/10</b>."
if(weedlevel >= 5)
. += "\The [src] is <span class='danger'>infested with weeds</span>!"
if(pestlevel >= 5)
. += "\The [src] is <span class='danger'>infested with tiny worms</span>!"
if(dead)
. += SPAN_DANGER("The plant is dead.")
else if(health <= (seed.get_trait(TRAIT_ENDURANCE)/ 2))
. += "The plant looks <span class='danger'>unhealthy</span>."
// What's the current atmosphere?
var/turf/T = loc
var/datum/gas_mixture/environment
if(closed_system && (connected_port || holding) && mechanical)
environment = air_contents
if(!environment)
if(istype(T))
environment = T.return_air()
// We're in a crate or nullspace, bail out.
if(!environment)
return
// What's the current light level?
var/light_available
if(closed_system && mechanical)
light_available = tray_light
else
if(TURF_IS_DYNAMICALLY_LIT(T))
light_available = T.get_lumcount(0, 3) * 10
else
light_available = 5
// If it's a mechanical tray, provide precise information to the user about the plant's conditions.
if(mechanical)
var/turf/T = loc
var/datum/gas_mixture/environment
var/heat_status
var/light_status
if(closed_system && (connected_port || holding))
environment = air_contents
if(!environment)
if(istype(T))
environment = T.return_air()
if(!environment) //We're in a crate or nullspace, bail out.
return
var/light_string
if(closed_system && mechanical)
light_string = "that the internal lights are set to [tray_light] lumens"
else
var/light_available
if(TURF_IS_DYNAMICALLY_LIT(T))
light_available = T.get_lumcount(0, 3) * 10
if(seed && !dead)
if(seed.check_heat_tolerances(environment))
heat_status = SPAN_BAD(", placing it outside its heat tolerances, totally preventing growth")
else if(seed.check_heat_preferences(environment))
heat_status = SPAN_GOOD(", placing it within its heat preferences, accelerating growth")
else
light_available = 5
heat_status = SPAN_NOTICE(", placing it outside its heat preferences, slowing growth and reducing yield")
light_string = "a light level of [light_available] lumens"
if(seed.check_light_tolerances(light_available))
light_status = SPAN_BAD(", placing it outside its light tolerances, totally preventing growth")
else if(seed.check_light_preferences(light_available))
light_status = SPAN_GOOD(", placing it within its light preferences, accelerating growth")
else
light_status = SPAN_NOTICE(", placing it outside its light preferences, slowing growth and reducing yield")
. += "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K."
. += "The tray thermometer displays a temperature of <b>[environment.temperature]K</b>[heat_status]."
. += "The tray light meter displays a light level of <b>[light_available] lumens</b>[light_status]."
var/stasis_string
// Are we under stasis?
if(stasis)
stasis_string = "Stasis is enabled, freezing metabolic functions."
. += SPAN_NOTICE("Stasis is enabled, freezing metabolic functions.")
else
stasis_string = "Stasis is disabled."
. += SPAN_NOTICE(stasis_string)
. += SPAN_NOTICE("Stasis is disabled.")
// Provide a vaguer description of what's going on if it's a soil plot.
if(!mechanical && seed && !dead)
if(seed.check_heat_tolerances(environment) || seed.check_light_tolerances(light_available))
. += SPAN_BAD("This plot is unable to grow whatsoever under its current conditions!")
else if(seed.check_heat_preferences(environment) && seed.check_light_preferences(light_available))
. += SPAN_GOOD("This plot is thriving under its current conditions!")
else
. += SPAN_NOTICE("This plot is struggling to grow under its current conditions.")
if(seed)
if(dead)
. += SPAN_DANGER("The plant is dead.")
else if(health <= (seed.get_trait(TRAIT_ENDURANCE)/ 2))
. += SPAN_BAD("The plant looks unhealthy.")
if(stunted)
. += SPAN_BAD("This harvest is stunted due to improper growing conditions, reducing yield.")
else if(harvest)
. += SPAN_GOOD("This is ready to harvest!")
/// Opens and closes the lid.
/obj/machinery/portable_atmospherics/hydroponics/proc/close_lid(var/mob/living/user)
if(closed_system)
stasis = FALSE
density = FALSE
update_use_power(POWER_USE_IDLE)
else
density = TRUE
closed_system = !closed_system
playsound(src, 'sound/items/pickup/device.ogg', 50, TRUE)
to_chat(user, "You [closed_system ? "close" : "open"] the tray's lid.")
+22 -29
View File
@@ -83,12 +83,16 @@
// This carries the product of the handle_enviroment proc, so we can use it for multiple things.
var/environmental_damage
// This determines the probability of growth, for use with the get_probability_of_growth proc.
var/probability_of_growth
// Seed datum handles gasses, light and pressure relevant to whether the plant should be damaged.
// Seed datum handles gasses, light and pressure relevant to whether the plant should be damaged, and what the probability of growth should be.
if(mechanical && closed_system)
environmental_damage = seed.handle_environment(T,environment,tray_light)
probability_of_growth = seed.get_probability_of_growth(T,environment,tray_light)
else
environmental_damage = seed.handle_environment(T,environment)
probability_of_growth = seed.get_probability_of_growth(T,environment)
// Reduce health by however much handle_environent returned.
health -= environmental_damage
@@ -97,35 +101,19 @@
if (closed_system && connected_port)
update_connected_network()
// We only let the plant grow if they're within their light, heat, and pressure tolerances - i.e. they've taken no damage in this process.
// We calculate this off the environmental_damage variable. If it's greater than 0, the plant has taken damage and shouldn't grow.
if(environmental_damage == 0)
// By standard, the probability of growth is only 15%. This rises if growing conditions are within their preferences.
// This is intended to motivate the use of atmospheric equipment to more viably grow plants with irregular preferences.
// You *can* grow plants outside of their preferences without them dying so long as it's within their tolerance, but it'll be pretty slow.
var/probability_of_growth = 15
// Are we within the preference zone for temperature? If so, add 15% to the chance of growth.
if(abs(environment.temperature - seed.get_trait(TRAIT_IDEAL_HEAT)) < seed.get_trait(TRAIT_HEAT_PREFERENCE))
probability_of_growth += 15
// The light value we'll be using here.
var/actual_light
// What kind of lighting are we under? If the lid isn't on and the turf isn't dynamically lit, default to 5 lumens.
if(closed_system && mechanical)
actual_light = tray_light
else if(TURF_IS_DYNAMICALLY_LIT(T))
actual_light = T.get_lumcount(0, 3) * 10
// Handle light requirements for upcoming logic.
var/light_supplied
if(!closed_system)
if (TURF_IS_DYNAMICALLY_LIT(T))
light_supplied = T.get_lumcount(0, 3) * 10
else
actual_light = 5
light_supplied = 5
else
light_supplied = tray_light
// If we're within the preference zone for light, add another 5% to the chance for growth.
if(abs(actual_light - seed.get_trait(TRAIT_IDEAL_LIGHT)) < seed.get_trait(TRAIT_LIGHT_PREFERENCE))
probability_of_growth += 5
// Roll the dice on advancing plant age, per a probability defined by the previous two checks. At minimum, 15% - at maximum, 35%.
// TODO: Move to seed datum?
// We only let the plant grow if they're within their light and heat tolerances.
if(!seed.check_light_tolerances(light_supplied) && !seed.check_heat_tolerances(environment))
// Roll the dice on advancing plant age.
if(prob(probability_of_growth)) age += 1 * HYDRO_SPEED_MULTIPLIER
// Toxin levels beyond the plant's tolerance cause damage, but
@@ -159,7 +147,12 @@
// If enough time (in cycles, not ticks) has passed since the plant was harvested, we're ready to harvest again.
if((age > seed.get_trait(TRAIT_MATURATION)) && ((age - lastproduce) > seed.get_trait(TRAIT_PRODUCTION)) && (!harvest && !dead))
harvest = 1
// If the plant matures while not at either its light or heat preference, it becomes stunted, reducing its yield on harvest.
// Better grow your plants better next time.
if(!seed.check_light_preferences(light_supplied) || !seed.check_heat_preferences(environment))
stunted = TRUE
harvest = TRUE
lastproduce = age
if(seed.get_trait(TRAIT_SPOROUS) && !closed_system)
seed.create_spores(get_turf(src))
+2 -2
View File
@@ -2,9 +2,9 @@
name = "soil"
desc = "A mound of earth. You could plant some seeds here."
icon_state = "soil"
density = 0
density = FALSE
use_power = POWER_USE_OFF
mechanical = 0
mechanical = FALSE
tray_light = 0
/// Water level begins at zero.
waterlevel = 0
@@ -69,11 +69,14 @@
if(stasis)
AddOverlays("stasis")
// Apply density and opacity if a large plant is growing in the plot. Exempt mechanical trays from density alterations, since they're always dense.
if(seed && seed.get_trait(TRAIT_LARGE))
density = TRUE
if(!mechanical)
density = TRUE
opacity = TRUE
else
density = FALSE
if(!mechanical)
density = FALSE
opacity = FALSE
// Update bioluminescence.