diff --git a/baystation12.dme b/baystation12.dme
index 0b0ee50ef9..4bcf9eb187 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -960,6 +960,7 @@
#include "code\modules\hydroponics\grown.dm"
#include "code\modules\hydroponics\grown_inedible.dm"
#include "code\modules\hydroponics\seed.dm"
+#include "code\modules\hydroponics\seed_controller.dm"
#include "code\modules\hydroponics\seed_datums.dm"
#include "code\modules\hydroponics\seed_machines.dm"
#include "code\modules\hydroponics\seed_mobs.dm"
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index 263a91769b..3f1a105f53 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -48,7 +48,7 @@
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
return
-/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event"))
+/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -106,5 +106,8 @@
if("Event")
debug_variables(event_manager)
feedback_add_details("admin_verb", "DEvent")
+ if("Plants")
+ debug_variables(plant_controller)
+ feedback_add_details("admin_verb", "DPlants")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm
index a1132ae08a..4778ac13ea 100644
--- a/code/game/machinery/seed_extractor.dm
+++ b/code/game/machinery/seed_extractor.dm
@@ -16,10 +16,10 @@ obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob
var/datum/seed/new_seed_type
if(istype(O, /obj/item/weapon/grown))
var/obj/item/weapon/grown/F = O
- new_seed_type = seed_types[F.plantname]
+ new_seed_type = plant_controller.seeds[F.plantname]
else
var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O
- new_seed_type = seed_types[F.plantname]
+ new_seed_type = plant_controller.seeds[F.plantname]
if(new_seed_type)
user << "You extract some seeds from [O]."
diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm
index 8d8328bc9f..dd786ddc0d 100644
--- a/code/game/objects/effects/decals/remains.dm
+++ b/code/game/objects/effects/decals/remains.dm
@@ -17,6 +17,14 @@
icon = 'icons/mob/robots.dmi'
icon_state = "remainsrobot"
+/obj/effect/decal/remains/mouse
+ desc = "They look like the remains of a small rodent."
+ icon_state = "mouse"
+
+/obj/effect/decal/remains/lizard
+ desc = "They look like the remains of a small rodent."
+ icon_state = "lizard"
+
/obj/effect/decal/remains/attack_hand(mob/user as mob)
user << "[src] sinks together into a pile of ash."
var/turf/simulated/floor/F = get_turf(src)
diff --git a/code/global.dm b/code/global.dm
index 55c63433cb..c5fd821f79 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -254,11 +254,5 @@ var/static/list/scarySounds = list(
// Bomb cap!
var/max_explosion_range = 14
-// Several cache lists for plants/hydroponics.
-var/global/list/seed_types = list() // A list of all seed data.
-var/global/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
-var/global/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds.
-
// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it.
var/global/obj/item/device/radio/intercom/global_announcer = new(null)
-
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 6030a8be1d..19fd023678 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -1001,10 +1001,10 @@ var/global/floorIsLava = 0
if(!check_rights(R_SPAWN)) return
- var/seedtype = input("Select a seed type", "Spawn Fruit") as null|anything in seed_types
- if(!seedtype || !seed_types[seedtype])
+ var/seedtype = input("Select a seed type", "Spawn Fruit") as null|anything in plant_controller.seeds
+ if(!seedtype || !plant_controller.seeds[seedtype])
return
- var/datum/seed/S = seed_types[seedtype]
+ var/datum/seed/S = plant_controller.seeds[seedtype]
S.harvest(usr,0,0,1)
/datum/admins/proc/spawn_plant()
@@ -1014,10 +1014,10 @@ var/global/floorIsLava = 0
if(!check_rights(R_SPAWN)) return
- var/seedtype = input("Select a seed type", "Spawn Plant") as null|anything in seed_types
- if(!seedtype || !seed_types[seedtype])
+ var/seedtype = input("Select a seed type", "Spawn Plant") as null|anything in plant_controller.seeds
+ if(!seedtype || !plant_controller.seeds[seedtype])
return
- new /obj/effect/plant(get_turf(usr), seed_types[seedtype])
+ new /obj/effect/plant(get_turf(usr), plant_controller.seeds[seedtype])
/datum/admins/proc/spawn_atom(var/object as text)
set category = "Debug"
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 2b607f0509..ee2c7c66ff 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -24,7 +24,15 @@
if(!plantname)
return
- seed = seed_types[plantname]
+ if(!plant_controller)
+ sleep(250) // ugly hack, should mean roundstart plants are fine.
+ if(!plant_controller)
+ world << "Plant controller does not exist and [src] requires it. Aborting."
+ del(src)
+ return
+
+ seed = plant_controller.seeds[plantname]
+
if(!seed)
return
diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm
index 991fecc88b..a0802ee0f1 100644
--- a/code/modules/hydroponics/grown_inedible.dm
+++ b/code/modules/hydroponics/grown_inedible.dm
@@ -19,7 +19,7 @@
//Handle some post-spawn var stuff.
if(planttype)
plantname = planttype
- var/datum/seed/S = seed_types[plantname]
+ var/datum/seed/S = plant_controller.seeds[plantname]
if(!S || !S.chems)
return
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index ee8c9612be..3b99746ad0 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -1,96 +1,3 @@
-// Sprite lists.
-var/global/list/plant_sprites = list() // List of all harvested product sprites.
-var/global/list/plant_product_sprites = list() // List of all growth sprites plus number of growth stages.
-
-// Proc for creating a random seed type.
-/proc/create_random_seed(var/survive_on_station)
- var/datum/seed/seed = new()
- seed.randomize()
- seed.uid = seed_types.len + 1
- seed.name = "[seed.uid]"
- seed_types[seed.name] = seed
-
- if(survive_on_station)
- if(seed.consume_gasses)
- seed.consume_gasses["phoron"] = null
- seed.consume_gasses["carbon_dioxide"] = null
- seed.set_trait(TRAIT_IDEAL_HEAT,293)
- seed.set_trait(TRAIT_HEAT_TOLERANCE,20)
- seed.set_trait(TRAIT_IDEAL_LIGHT,8)
- seed.set_trait(TRAIT_LIGHT_TOLERANCE,5)
- seed.set_trait(TRAIT_LOWKPA_TOLERANCE,25)
- seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200)
-
- return seed
-
-// Debug for testing seed genes.
-/client/proc/show_plant_genes()
- set category = "Debug"
- set name = "Show Plant Genes"
- set desc = "Prints the round's plant gene masks."
-
- if(!holder) return
-
- if(!gene_tag_masks)
- usr << "Gene masks not set."
- return
-
- for(var/mask in gene_tag_masks)
- usr << "[mask]: [gene_tag_masks[mask]]"
-
-// Predefined/roundstart varieties use a string key to make it
-// easier to grab the new variety when mutating. Post-roundstart
-// and mutant varieties use their uid converted to a string instead.
-// Looks like shit but it's sort of necessary.
-
-proc/populate_seed_list()
-
- // Build the icon lists.
- for(var/icostate in icon_states('icons/obj/hydroponics_growing.dmi'))
- var/split = findtext(icostate,"-")
- if(!split)
- // invalid icon_state
- continue
-
- var/ikey = copytext(icostate,(split+1))
- if(ikey == "dead")
- // don't count dead icons
- continue
- ikey = text2num(ikey)
- var/base = copytext(icostate,1,split)
-
- if(!(plant_sprites[base]) || (plant_sprites[base] spread_distance)))
- return
+ if(buckled_mob)
+ seed.do_sting(buckled_mob,src)
+ if(seed.get_trait(TRAIT_CARNIVOROUS))
+ // Todo: refactor to be less hardcoded.
+ if(istype(buckled_mob, /mob/living/simple_animal/mouse))
+ new /obj/effect/decal/remains/mouse(get_turf(src))
+ del(buckled_mob)
+ buckled_mob = null
+ return
+ else if(istype(buckled_mob, /mob/living/simple_animal/lizard))
+ new /obj/effect/decal/remains/lizard(get_turf(src))
+ del(buckled_mob)
+ buckled_mob = null
+ return
+ seed.do_thorns(buckled_mob,src)
+ var/failed_growth
// Count our neighbors and possible locations for spreading.
var/list/possible_locs = list()
- var/count = 0
+ var/plant_count = 0
for(var/turf/simulated/floor/floor in view(1,src))
if((locate(/obj/effect/dead_plant) in floor.contents) || !floor.Enter(src) || floor.density)
continue
if(locate(/obj/effect/plant) in floor.contents)
- count++
+ plant_count++
continue
possible_locs |= floor
- //Entirely surrounded, try to spawn an actual plant.
- if(count>=8)
- if(!(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in T.contents))
- var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/new_plant = new(T,seed)
- new_plant.age = seed.get_trait(TRAIT_MATURATION)-1
- new_plant.update_icon()
- if(growth_type==0) //Vines do not become invisible.
- invisibility = INVISIBILITY_MAXIMUM
- else
- new_plant.layer = 4.1
+ if(health == max_health && plant_count >= 4 && !plant)
+ plant = new(T,seed)
+ plant.age = seed.get_trait(TRAIT_MATURATION)-1
+ plant.update_icon()
+ if(growth_type==0) //Vines do not become invisible.
+ invisibility = INVISIBILITY_MAXIMUM
+ else
+ plant.layer = layer + 0.1
if(prob(spread_chance))
for(var/i=1,i<=seed.get_trait(TRAIT_YIELD),i++)
if(!possible_locs.len)
- hibernating = 1
- world << "[src] at [x],[y] is hibernating"
+ failed_growth = 1
break
if(prob(spread_into_adjacent))
var/turf/target_turf = pick(possible_locs)
@@ -53,11 +63,14 @@
child.parent = get_root()
child.parent.children |= child
+ if(health != max_health || !failed_growth || (plant_count > 4 && !plant))
+ plant_controller.add_plant(src)
+
/obj/effect/plant/proc/die_off(var/no_remains, var/no_del)
// Remove ourselves from our parent.
if(parent && parent.children)
parent.children -= src
- // Kill off any of our children (and add an added bonus, other plants in this area)
+ // Kill off any of our children (and as an added bonus, other plants in this area)
for(var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant in get_turf(src))
plant.dead = 1
plant.update_icon()
@@ -66,7 +79,8 @@
for(var/obj/effect/plant/child in children)
child.die_off()
for(var/obj/effect/plant/neighbor in view(1,src))
- neighbor.hibernating = 0
+ plant_controller.add_plant(neighbor)
+
if(!no_remains && !(locate(/obj/effect/dead_plant) in get_turf(src)))
var/obj/effect/dead_plant/plant_remains = new(get_turf(src))
plant_remains.icon = src.icon
diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm
index 1d30c0bbf2..cb696f34af 100644
--- a/code/modules/hydroponics/spreading/spreading_response.dm
+++ b/code/modules/hydroponics/spreading/spreading_response.dm
@@ -1,7 +1,6 @@
/obj/effect/plant/HasProximity(var/atom/movable/AM)
- hibernating = 0
-
+ plant_controller.add_plant(src)
if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2)
return
@@ -9,16 +8,15 @@
if(!istype(M))
return
- if(!buckled_mob && !M.buckled && !M.anchored && prob(round(seed.get_trait(TRAIT_POTENCY)/2)))
+ if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/2))))
entangle(M)
/obj/effect/plant/attack_hand(mob/user as mob)
- hibernating = 0
+ plant_controller.add_plant(src)
manual_unbuckle(user)
/obj/effect/plant/proc/trodden_on(var/mob/living/victim)
- hibernating = 0
- world << "Blah."
+ plant_controller.add_plant(src)
if(!is_mature())
return
var/mob/living/carbon/human/H = victim
diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm
index 9ec31f6fe8..acb501b850 100644
--- a/code/modules/hydroponics/trays/tray.dm
+++ b/code/modules/hydroponics/trays/tray.dm
@@ -299,7 +299,7 @@
//Remove the seed if something is already planted.
if(seed) seed = null
- seed = seed_types[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))]
+ seed = plant_controller.seeds[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))]
if(!seed) return //Weed does not exist, someone fucked up.
dead = 0
@@ -329,7 +329,7 @@
// We need to make sure we're not modifying one of the global seed datums.
// If it's not in the global list, then no products of the line have been
// harvested yet and it's safe to assume it's restricted to this tray.
- if(!isnull(seed_types[seed.name]))
+ if(!isnull(plant_controller.seeds[seed.name]))
seed = seed.diverge()
seed.mutate(severity,get_turf(src))
@@ -370,8 +370,8 @@
var/previous_plant = seed.display_name
var/newseed = seed.get_mutant_variant()
- if(newseed in seed_types)
- seed = seed_types[newseed]
+ if(newseed in plant_controller.seeds)
+ seed = plant_controller.seeds[newseed]
else
return
@@ -528,12 +528,10 @@
return
/obj/machinery/portable_atmospherics/hydroponics/attack_tk(mob/user as mob)
-
- if(harvest)
- harvest(user)
-
- else if(dead)
+ if(dead)
remove_dead(user)
+ else if(harvest)
+ harvest(user)
/obj/machinery/portable_atmospherics/hydroponics/attack_hand(mob/user as mob)
diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm
index 404abb707c..cd7d0daf9a 100644
--- a/code/modules/hydroponics/trays/tray_tools.dm
+++ b/code/modules/hydroponics/trays/tray_tools.dm
@@ -53,13 +53,13 @@
else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown))
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target
- grown_seed = seed_types[G.plantname]
+ grown_seed = plant_controller.seeds[G.plantname]
grown_reagents = G.reagents
else if(istype(target,/obj/item/weapon/grown))
var/obj/item/weapon/grown/G = target
- grown_seed = seed_types[G.plantname]
+ grown_seed = plant_controller.seeds[G.plantname]
grown_reagents = G.reagents
else if(istype(target,/obj/item/seeds))
diff --git a/code/modules/hydroponics/trays/tray_update_icons.dm b/code/modules/hydroponics/trays/tray_update_icons.dm
index de66f4297e..e13bf644f0 100644
--- a/code/modules/hydroponics/trays/tray_update_icons.dm
+++ b/code/modules/hydroponics/trays/tray_update_icons.dm
@@ -21,7 +21,7 @@
if(dead)
var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-dead"
- var/image/dead_overlay = plant_icon_cache["[ikey]"]
+ var/image/dead_overlay = plant_controller.plant_icon_cache["[ikey]"]
if(!dead_overlay)
dead_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]")
dead_overlay.color = DEAD_PLANT_COLOUR
@@ -39,20 +39,20 @@
overlay_stage = max(1,round(seed.get_trait(TRAIT_MATURATION) / seed.growth_stages))
var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-[overlay_stage]"
- var/image/plant_overlay = plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
+ var/image/plant_overlay = plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
if(!plant_overlay)
plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]")
plant_overlay.color = seed.get_trait(TRAIT_PLANT_COLOUR)
- plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay
+ plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay
overlays |= plant_overlay
if(harvest && overlay_stage == seed.growth_stages)
ikey = "[seed.get_trait(TRAIT_PRODUCT_ICON)]"
- var/image/harvest_overlay = plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
+ var/image/harvest_overlay = plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
if(!harvest_overlay)
harvest_overlay = image('icons/obj/hydroponics_products.dmi', "[ikey]")
harvest_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
- plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay
+ plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay
overlays |= harvest_overlay
//Draw the cover.
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm
index 0024865acf..4a36d23659 100644
--- a/code/modules/organs/organ_alien.dm
+++ b/code/modules/organs/organ_alien.dm
@@ -48,7 +48,7 @@
H.death()
//This is a terrible hack and I should be ashamed.
- var/datum/seed/diona = seed_types["diona"]
+ var/datum/seed/diona = plant_controller.seeds["diona"]
if(!diona)
del(src)
diff --git a/code/world.dm b/code/world.dm
index 3897c24729..2fd24cf9f5 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -55,7 +55,7 @@ var/global/datum/global_init/init = new ()
// Set up roundstart seed list. This is here because vendors were
// bugging out and not populating with the correct packet names
// due to this list not being instantiated.
- populate_seed_list()
+ plant_controller = new()
// Create autolathe recipes, as above.
populate_lathe_recipes()
diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi
index 9820bb1f8a..8b70722fd9 100644
Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ