diff --git a/baystation12.dme b/baystation12.dme
index fe79d1a4e1..265b12f047 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -237,14 +237,12 @@
#include "code\game\gamemodes\cult\ritual.dm"
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\talisman.dm"
-#include "code\game\gamemodes\events\biomass.dm"
#include "code\game\gamemodes\events\black_hole.dm"
#include "code\game\gamemodes\events\clang.dm"
#include "code\game\gamemodes\events\dust.dm"
#include "code\game\gamemodes\events\miniblob.dm"
#include "code\game\gamemodes\events\power_failure.dm"
#include "code\game\gamemodes\events\space_ninja.dm"
-#include "code\game\gamemodes\events\spacevines.dm"
#include "code\game\gamemodes\events\wormholes.dm"
#include "code\game\gamemodes\events\holidays\Christmas.dm"
#include "code\game\gamemodes\events\holidays\Holidays.dm"
@@ -971,7 +969,6 @@
#include "code\modules\hydroponics\seed_storage.dm"
#include "code\modules\hydroponics\seeds.dm"
#include "code\modules\hydroponics\spread_plant.dm"
-#include "code\modules\hydroponics\spread_vine.dm"
#include "code\modules\library\lib_items.dm"
#include "code\modules\library\lib_machines.dm"
#include "code\modules\library\lib_readme.dm"
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index d78f3e7a9d..e0de9b857f 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1378,3 +1378,15 @@ var/list/WALLITEMS = list(
if(istype(arglist,/list))
arglist = list2params(arglist)
return "[content]"
+
+/proc/get_random_colour(var/simple, var/lower, var/upper)
+ var/colour
+ if(simple)
+ colour = pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))
+ else
+ for(var/i=1;i<=3;i++)
+ var/temp_col = "[num2hex(rand(lower,upper))]"
+ if(length(temp_col )<2)
+ temp_col = "0[temp_col]"
+ colour += temp_col
+ return colour
\ No newline at end of file
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 0045dabec9..2e3d2cc544 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -51,7 +51,6 @@
assignment = "Unassigned"
var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh*
-
var/icon/front = new(get_id_photo(H), dir = SOUTH)
var/icon/side = new(get_id_photo(H), dir = WEST)
//General Record
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index e029b524a7..14a86aed13 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -257,6 +257,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/hydroponics // -- Skie
name = "Hydroponics Supply Crate"
contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone,
+ /obj/item/weapon/reagent_containers/spray/plantbgone,
+ /obj/item/weapon/reagent_containers/spray/plantbgone,
/obj/item/weapon/reagent_containers/spray/plantbgone,
/obj/item/weapon/reagent_containers/glass/bottle/ammonia,
/obj/item/weapon/reagent_containers/glass/bottle/ammonia,
diff --git a/code/game/gamemodes/events/biomass.dm b/code/game/gamemodes/events/biomass.dm
deleted file mode 100644
index b758c85019..0000000000
--- a/code/game/gamemodes/events/biomass.dm
+++ /dev/null
@@ -1,176 +0,0 @@
-// BIOMASS (Note that this code is very similar to Space Vine code)
-/obj/effect/biomass
- name = "biomass"
- desc = "Space barf from another dimension. It just keeps spreading!"
- icon = 'icons/obj/biomass.dmi'
- icon_state = "stage1"
- anchored = 1
- density = 0
- layer = 5
- pass_flags = PASSTABLE | PASSGRILLE
- var/energy = 0
- var/obj/effect/biomass_controller/master = null
-
- New()
- return
-
- Del()
- if(master)
- master.vines -= src
- master.growth_queue -= src
- ..()
-
-/obj/effect/biomass/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (!W || !user || !W.type) return
- switch(W.type)
- if(/obj/item/weapon/circular_saw) del src
- if(/obj/item/weapon/kitchen/utensil/knife) del src
- if(/obj/item/weapon/scalpel) del src
- if(/obj/item/weapon/twohanded/fireaxe) del src
- if(/obj/item/weapon/hatchet) del src
- if(/obj/item/weapon/melee/energy) del src
- if(/obj/item/weapon/pickaxe/plasmacutter) del src
-
- //less effective weapons
- if(/obj/item/weapon/wirecutters)
- if(prob(25)) del src
- if(/obj/item/weapon/shard)
- if(prob(25)) del src
-
- else //weapons with subtypes
- if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
- else if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
- if(WT.remove_fuel(0, user)) del src
- else
- return
- ..()
-
-/obj/effect/biomass_controller
- var/list/obj/effect/biomass/vines = list()
- var/list/growth_queue = list()
- var/reached_collapse_size
- var/reached_slowdown_size
- //What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
- //meaning if you get the biomasssss..s' size to something less than 20 plots, it won't grow anymore.
-
- New()
- if(!istype(src.loc,/turf/simulated/floor))
- del(src)
-
- spawn_biomass_piece(src.loc)
- processing_objects.Add(src)
-
- Del()
- processing_objects.Remove(src)
- ..()
-
- proc/spawn_biomass_piece(var/turf/location)
- var/obj/effect/biomass/BM = new(location)
- growth_queue += BM
- vines += BM
- BM.master = src
-
- process()
- if(!vines)
- del(src) //space vines exterminated. Remove the controller
- return
- if(!growth_queue)
- del(src) //Sanity check
- return
- if(vines.len >= 250 && !reached_collapse_size)
- reached_collapse_size = 1
- if(vines.len >= 30 && !reached_slowdown_size )
- reached_slowdown_size = 1
-
- var/maxgrowth = 0
- if(reached_collapse_size)
- maxgrowth = 0
- else if(reached_slowdown_size)
- if(prob(25))
- maxgrowth = 1
- else
- maxgrowth = 0
- else
- maxgrowth = 4
- var/length = min( 30 , vines.len / 5 )
- var/i = 0
- var/growth = 0
- var/list/obj/effect/biomass/queue_end = list()
-
- for( var/obj/effect/biomass/BM in growth_queue )
- i++
- queue_end += BM
- growth_queue -= BM
- if(BM.energy < 2) //If tile isn't fully grown
- if(prob(20))
- BM.grow()
-
- if(BM.spread())
- growth++
- if(growth >= maxgrowth)
- break
- if(i >= length)
- break
-
- growth_queue = growth_queue + queue_end
-
-/obj/effect/biomass/proc/grow()
- if(!energy)
- src.icon_state = "stage2"
- energy = 1
- src.opacity = 0
- src.density = 0
- layer = 5
- else
- src.icon_state = "stage3"
- src.opacity = 0
- src.density = 1
- energy = 2
-
-/obj/effect/biomass/proc/spread()
- var/direction = pick(cardinal)
- var/step = get_step(src,direction)
- if(istype(step,/turf/simulated/floor))
- var/turf/simulated/floor/F = step
- if(!locate(/obj/effect/biomass,F))
- if(F.Enter(src))
- if(master)
- master.spawn_biomass_piece( F )
- return 1
- return 0
-
-/obj/effect/biomass/ex_act(severity)
- switch(severity)
- if(1.0)
- del(src)
- return
- if(2.0)
- if (prob(90))
- del(src)
- return
- if(3.0)
- if (prob(50))
- del(src)
- return
- return
-
-/obj/effect/biomass/fire_act(null, temp, volume) //hotspots kill biomass
- del src
-
-
-/proc/biomass_infestation()
-
- spawn() //to stop the secrets panel hanging
- var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
- for(var/areapath in typesof(/area/hallway))
- var/area/A = locate(areapath)
- for(var/area/B in A.related)
- for(var/turf/simulated/floor/F in B.contents)
- if(!F.contents.len)
- turfs += F
-
- if(turfs.len) //Pick a turf to spawn at if we can
- var/turf/simulated/floor/T = pick(turfs)
- new/obj/effect/biomass_controller(T) //spawn a controller at turf
- message_admins("\blue Event: Biomass spawned at [T.loc.loc] ([T.x],[T.y],[T.z])")
diff --git a/code/game/gamemodes/events/spacevines.dm b/code/game/gamemodes/events/spacevines.dm
deleted file mode 100644
index d095f19d56..0000000000
--- a/code/game/gamemodes/events/spacevines.dm
+++ /dev/null
@@ -1,16 +0,0 @@
-//Carn: Spacevines random event.
-/proc/spacevine_infestation()
-
- spawn() //to stop the secrets panel hanging
- var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
- for(var/areapath in typesof(/area/hallway))
- var/area/A = locate(areapath)
- for(var/area/B in A.related)
- for(var/turf/simulated/floor/F in B.contents)
- if(!F.contents.len)
- turfs += F
-
- if(turfs.len) //Pick a turf to spawn at if we can
- var/turf/simulated/floor/T = pick(turfs)
- new/obj/effect/plant_controller(T) //spawn a controller at turf
- message_admins("\blue Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
diff --git a/code/game/gamemodes/wizard/artifact.dm b/code/game/gamemodes/wizard/artifact.dm
index 15ac80ced4..8c1cff5fcc 100644
--- a/code/game/gamemodes/wizard/artifact.dm
+++ b/code/game/gamemodes/wizard/artifact.dm
@@ -15,7 +15,7 @@
/obj/effect/rend
name = "Tear in the fabric of reality"
desc = "You should run now"
- icon = 'icons/obj/biomass.dmi'
+ icon = 'icons/obj/wizard.dmi'
icon_state = "rift"
density = 1
unacidable = 1
diff --git a/code/game/objects/effects/biomass_rift.dm b/code/game/objects/effects/biomass_rift.dm
deleted file mode 100644
index c619ccb1e7..0000000000
--- a/code/game/objects/effects/biomass_rift.dm
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-/obj/effect/biomass
- icon = 'icons/obj/biomass.dmi'
- icon_state = "stage1"
- opacity = 0
- density = 0
- anchored = 1
- layer = 20 //DEBUG
- var/health = 10
- var/stage = 1
- var/obj/effect/rift/originalRift = null //the originating rift of that biomass
- var/maxDistance = 15 //the maximum length of a thread
- var/newSpreadDistance = 10 //the length of a thread at which new ones are created
- var/curDistance = 1 //the current length of a thread
- var/continueChance = 3 //weighed chance of continuing in the same direction. turning left or right has 1 weight both
- var/spreadDelay = 1 //will change to something bigger later, but right now I want it to spread as fast as possible for testing
-
-/obj/effect/rift
- icon = 'icons/obj/biomass.dmi'
- icon_state = "rift"
- var/list/obj/effect/biomass/linkedBiomass = list() //all the biomass patches that have spread from it
- var/newicon = 1 //DEBUG
-
-/obj/effect/rift/New()
- set background = 1
-
- ..()
-
- for(var/turf/T in orange(1,src))
- if(!IsValidBiomassLoc(T))
- continue
- var/obj/effect/biomass/starting = new /obj/effect/biomass(T)
- starting.set_dir(get_dir(src,starting))
- starting.originalRift = src
- linkedBiomass += starting
- spawn(1) //DEBUG
- starting.icon_state = "[newicon]"
-
-/obj/effect/rift/Del()
- for(var/obj/effect/biomass/biomass in linkedBiomass)
- del(biomass)
- ..()
-
-/obj/effect/biomass/New()
- set background = 1
-
- ..()
- if(!IsValidBiomassLoc(loc,src))
- del(src)
- return
- spawn(1) //so that the dir and stuff can be set by the source first
- if(curDistance >= maxDistance)
- return
- switch(dir)
- if(NORTHWEST)
- set_dir(NORTH)
- if(NORTHEAST)
- set_dir(EAST)
- if(SOUTHWEST)
- set_dir(WEST)
- if(SOUTHEAST)
- set_dir(SOUTH)
- sleep(spreadDelay)
- Spread()
-
-/obj/effect/biomass/proc/Spread(var/direction = dir)
- set background = 1
- var/possibleDirsInt = 0
-
- for(var/newDirection in cardinal)
- if(newDirection == turn(direction,180)) //can't go backwards
- continue
- var/turf/T = get_step(loc,newDirection)
- if(!IsValidBiomassLoc(T,src))
- continue
- possibleDirsInt |= newDirection
-
- var/list/possibleDirs = list()
-
- if(possibleDirsInt & direction)
- for(var/i=0 , iIt is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]."
- if(grown_seed.get_trait(TRAIT_FLOWERS))
- dat += "
It has [grown_seed.get_trait(TRAIT_FLOWER_COLOUR) ? "flowers" : "flowers"]."
if(grown_seed.get_trait(TRAIT_PRODUCES_POWER))
dat += "
The fruit will function as a battery if prepared appropriately."
@@ -366,8 +364,8 @@
/obj/item/weapon/scythe/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity) return
- if(istype(A, /obj/effect/plantsegment))
- for(var/obj/effect/plantsegment/B in orange(A,1))
+ if(istype(A, /obj/effect/plant))
+ for(var/obj/effect/plant/B in orange(A,1))
if(prob(80))
- del B
+ B.die_off(1)
del A
\ No newline at end of file
diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/hydro_tray.dm
index 78b12378e0..e8414b59da 100644
--- a/code/modules/hydroponics/hydro_tray.dm
+++ b/code/modules/hydroponics/hydro_tray.dm
@@ -139,6 +139,9 @@
nymph.visible_message("[nymph] rolls around in [src] for a bit.","You roll around in [src] for a bit.")
return
+/obj/machinery/portable_atmospherics/hydroponics/proc/can_label()
+ return 1
+
/obj/machinery/portable_atmospherics/hydroponics/New()
..()
temp_chem_holder = new()
@@ -629,20 +632,12 @@
return
user << "You plant the [S.seed.seed_name] [S.seed.seed_noun]."
-
- if(S.seed.get_trait(TRAIT_SPREAD) == 2)
- msg_admin_attack("[key_name(user)] has planted a spreading vine packet.")
- var/obj/effect/plant_controller/PC = new(get_turf(src))
- if(PC)
- PC.seed = S.seed
- else
- seed = S.seed //Grab the seed datum.
- dead = 0
- age = 1
- //Snowflakey, maybe move this to the seed datum
- health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE))
-
- lastcycle = world.time
+ seed = S.seed //Grab the seed datum.
+ dead = 0
+ age = 1
+ //Snowflakey, maybe move this to the seed datum
+ health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE))
+ lastcycle = world.time
del(O)
@@ -798,10 +793,7 @@
mechanical = 0
/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/shovel))
- user << "You clear up [src]!"
- del(src)
- else if(istype(O,/obj/item/weapon/shovel) || istype(O,/obj/item/weapon/tank))
+ if(istype(O,/obj/item/weapon/tank))
return
else
..()
@@ -810,6 +802,9 @@
..()
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid
+/obj/machinery/portable_atmospherics/hydroponics/soil/can_label()
+ return 0
+
/obj/machinery/portable_atmospherics/hydroponics/soil/CanPass()
return 1
@@ -840,10 +835,21 @@
if(!seed)
del(src)
+/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/die()
+ del(src)
+
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/process()
if(!seed)
del(src)
return
else if(name=="plant")
name = seed.display_name
+ ..()
+
+/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/Del()
+ // Check if we're masking a decal that needs to be visible again.
+ for(var/obj/effect/plant/plant in get_turf(src))
+ if(plant.invisibility == INVISIBILITY_MAXIMUM)
+ plant.invisibility = initial(plant.invisibility)
+ plant.die_off()
..()
\ No newline at end of file
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index b0fe9784f1..fd453f7f22 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -2,6 +2,27 @@
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"
@@ -58,7 +79,7 @@ proc/populate_seed_list()
//Might as well mask the gene types while we're at it.
var/list/used_masks = list()
- var/list/plant_traits = ALL_TRAITS
+ var/list/plant_traits = ALL_GENES
while(plant_traits && plant_traits.len)
var/gene_tag = pick(plant_traits)
var/gene_mask = "[num2hex(rand(0,255))]"
@@ -94,6 +115,48 @@ proc/populate_seed_list()
var/list/exude_gasses // The plant will exude these gasses during its life.
var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal.
+/datum/seed/New()
+
+ set_trait(TRAIT_IMMUTABLE, 0) // If set, plant will never mutate. If -1, plant is highly mutable.
+ set_trait(TRAIT_HARVEST_REPEAT, 0) // If 1, this plant will fruit repeatedly.
+ set_trait(TRAIT_PRODUCES_POWER, 0) // Can be used to make a battery.
+ set_trait(TRAIT_JUICY, 0) // When thrown, causes a splatter decal.
+ set_trait(TRAIT_EXPLOSIVE, 0) // When thrown, acts as a grenade.
+ set_trait(TRAIT_CARNIVOROUS, 0) // 0 = none, 1 = eat pests in tray, 2 = eat living things (when a vine).
+ set_trait(TRAIT_PARASITE, 0) // 0 = no, 1 = gain health from weed level.
+ set_trait(TRAIT_STINGS, 0) // Can cause damage/inject reagents when thrown or handled.
+ set_trait(TRAIT_YIELD, 0) // Amount of product.
+ set_trait(TRAIT_SPREAD, 0) // 0 limits plant to tray, 1 = creepers, 2 = vines.
+ set_trait(TRAIT_MATURATION, 0) // Time taken before the plant is mature.
+ set_trait(TRAIT_PRODUCTION, 0) // Time before harvesting can be undertaken again.
+ set_trait(TRAIT_TELEPORTING, 0) // Uses the bluespace tomato effect.
+ set_trait(TRAIT_BIOLUM, 0) // Plant is bioluminescent.
+ set_trait(TRAIT_ALTER_TEMP, 0) // If set, the plant will periodically alter local temp by this amount.
+ set_trait(TRAIT_PRODUCT_ICON, 0) // Icon to use for fruit coming from this plant.
+ set_trait(TRAIT_PLANT_ICON, 0) // Icon to use for the plant growing in the tray.
+ set_trait(TRAIT_PRODUCT_COLOUR, 0) // Colour to apply to product icon.
+ set_trait(TRAIT_BIOLUM_COLOUR, 0) // The colour of the plant's radiance.
+ set_trait(TRAIT_POTENCY, 1) // General purpose plant strength value.
+ set_trait(TRAIT_REQUIRES_NUTRIENTS, 1) // The plant can starve.
+ set_trait(TRAIT_REQUIRES_WATER, 1) // The plant can become dehydrated.
+ set_trait(TRAIT_WATER_CONSUMPTION, 3) // Plant drinks this much per tick.
+ set_trait(TRAIT_LIGHT_TOLERANCE, 5) // Departure from ideal that is survivable.
+ set_trait(TRAIT_TOXINS_TOLERANCE, 5) // Resistance to poison.
+ set_trait(TRAIT_PEST_TOLERANCE, 5) // Threshold for pests to impact health.
+ set_trait(TRAIT_WEED_TOLERANCE, 5) // Threshold for weeds to impact health.
+ set_trait(TRAIT_IDEAL_LIGHT, 8) // Preferred light level in luminosity.
+ set_trait(TRAIT_HEAT_TOLERANCE, 20) // Departure from ideal that is survivable.
+ set_trait(TRAIT_LOWKPA_TOLERANCE, 25) // Low pressure capacity.
+ set_trait(TRAIT_ENDURANCE, 100) // Maximum plant HP when growing.
+ set_trait(TRAIT_HIGHKPA_TOLERANCE, 200) // High pressure capacity.
+ set_trait(TRAIT_IDEAL_HEAT, 293) // Preferred temperature in Kelvin.
+ set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) // Plant eats this much per tick.
+ set_trait(TRAIT_PLANT_COLOUR, "#6EF86A") // Colour of the plant icon.
+
+ spawn(5)
+ sleep(-1)
+ update_growth_stages()
+
/datum/seed/proc/get_trait(var/trait)
return traits["[trait]"]
@@ -198,43 +261,14 @@ proc/populate_seed_list()
continue
// Check for windows.
var/no_los
+ var/turf/last_turf = origin_turf
for(var/turf/target_turf in getline(origin_turf,neighbor))
- if(target_turf.density)
+ if(!last_turf.Enter(target_turf) || target_turf.density)
no_los = 1
break
-
- if(!no_los)
- var/los_dir = get_dir(neighbor,origin_turf)
- var/list/blocked = list()
- for(var/obj/machinery/door/D in neighbor.contents)
- if(istype(D,/obj/machinery/door/window))
- blocked |= D.dir
- else
- if(D.density)
- no_los = 1
- break
- for(var/obj/structure/window/W in neighbor.contents)
- if(W.is_fulltile())
- no_los = 1
- break
- blocked |= W.dir
- if(!no_los)
- switch(los_dir)
- if(NORTHEAST)
- if((NORTH in blocked) && (EAST in blocked))
- no_los = 1
- if(SOUTHEAST)
- if((SOUTH in blocked) && (EAST in blocked))
- no_los = 1
- if(NORTHWEST)
- if((NORTH in blocked) && (WEST in blocked))
- no_los = 1
- if(SOUTHWEST)
- if((SOUTH in blocked) && (WEST in blocked))
- no_los = 1
- else
- if(los_dir in blocked)
- no_los = 1
+ last_turf = target_turf
+ if(!no_los && !origin_turf.Enter(neighbor))
+ no_los = 1
if(no_los)
closed_turfs |= neighbor
continue
@@ -348,8 +382,8 @@ proc/populate_seed_list()
set_trait(TRAIT_POTENCY,rand(5,30),200,0)
set_trait(TRAIT_PRODUCT_ICON,pick(plant_product_sprites))
set_trait(TRAIT_PLANT_ICON,pick(plant_sprites))
- set_trait(TRAIT_PLANT_COLOUR,"#[pick(rainbow)]")
- set_trait(TRAIT_PRODUCT_COLOUR,"#[pick(rainbow)]")
+ set_trait(TRAIT_PLANT_COLOUR,"#[get_random_colour(0,75,190)]")
+ set_trait(TRAIT_PRODUCT_COLOUR,"#[get_random_colour(0,75,190)]")
update_growth_stages()
if(prob(20))
@@ -478,7 +512,7 @@ proc/populate_seed_list()
if(prob(5))
set_trait(TRAIT_BIOLUM,1)
- set_trait(TRAIT_BIOLUM_COLOUR,"#[pick(rainbow)]")
+ set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]")
set_trait(TRAIT_ENDURANCE,rand(60,100))
set_trait(TRAIT_YIELD,rand(3,15))
@@ -500,7 +534,7 @@ proc/populate_seed_list()
//This looks like shit, but it's a lot easier to read/change this way.
var/total_mutations = rand(1,1+degree)
for(var/i = 0;i\The [display_name] withers rapidly!")
@@ -550,21 +584,11 @@ proc/populate_seed_list()
if(get_trait(TRAIT_BIOLUM))
source_turf.visible_message("\The [display_name] begins to glow!")
if(prob(degree*2))
- set_trait(TRAIT_BIOLUM_COLOUR,"#[pick(rainbow)]")
+ set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]")
source_turf.visible_message("\The [display_name]'s glow changes colour!")
else
source_turf.visible_message("\The [display_name]'s glow dims...")
if(11)
- if(prob(degree*2))
- set_trait(TRAIT_FLOWERS,!get_trait(TRAIT_FLOWERS))
- if(get_trait(TRAIT_FLOWERS))
- source_turf.visible_message("\The [display_name] sprouts a bevy of flowers!")
- if(prob(degree*2))
- set_trait(TRAIT_FLOWER_COLOUR,"#[pick(rainbow)]")
- source_turf.visible_message("\The [display_name]'s flowers changes colour!")
- else
- source_turf.visible_message("\The [display_name]'s flowers wither and fall off.")
- if(12)
set_trait(TRAIT_TELEPORTING,1)
return
@@ -640,8 +664,8 @@ proc/populate_seed_list()
traits_to_copy = list(TRAIT_TOXINS_TOLERANCE,TRAIT_PEST_TOLERANCE,TRAIT_WEED_TOLERANCE)
if(GENE_VIGOUR)
traits_to_copy = list(TRAIT_ENDURANCE,TRAIT_YIELD,TRAIT_SPREAD,TRAIT_MATURATION,TRAIT_PRODUCTION,TRAIT_TELEPORTING)
- if(GENE_FLOWERS)
- traits_to_copy = list(TRAIT_PLANT_COLOUR,TRAIT_PRODUCT_COLOUR,TRAIT_BIOLUM,TRAIT_BIOLUM_COLOUR,TRAIT_FLOWERS,TRAIT_FLOWER_ICON,TRAIT_FLOWER_COLOUR)
+ if(GENE_PIGMENT)
+ traits_to_copy = list(TRAIT_PLANT_COLOUR,TRAIT_PRODUCT_COLOUR,TRAIT_BIOLUM,TRAIT_BIOLUM_COLOUR)
for(var/trait in traits_to_copy)
P.values["[trait]"] = get_trait(trait)
@@ -748,52 +772,6 @@ proc/populate_seed_list()
else
growth_stages = 0
-/datum/seed/New()
-
- set_trait(TRAIT_IMMUTABLE, 0) // If set, plant will never mutate. If -1, plant is highly mutable.
- set_trait(TRAIT_HARVEST_REPEAT, 0) // If 1, this plant will fruit repeatedly.
- set_trait(TRAIT_PRODUCES_POWER, 0) // Can be used to make a battery.
- set_trait(TRAIT_JUICY, 0) // When thrown, causes a splatter decal.
- set_trait(TRAIT_EXPLOSIVE, 0) // When thrown, acts as a grenade.
- set_trait(TRAIT_CARNIVOROUS, 0) // 0 = none, 1 = eat pests in tray, 2 = eat living things (when a vine).
- set_trait(TRAIT_PARASITE, 0) // 0 = no, 1 = gain health from weed level.
- set_trait(TRAIT_STINGS, 0) // Can cause damage/inject reagents when thrown or handled.
- set_trait(TRAIT_YIELD, 0) // Amount of product.
- set_trait(TRAIT_SPREAD, 0) // 0 limits plant to tray, 1 = creepers, 2 = vines.
- set_trait(TRAIT_MATURATION, 0) // Time taken before the plant is mature.
- set_trait(TRAIT_PRODUCTION, 0) // Time before harvesting can be undertaken again.
- set_trait(TRAIT_TELEPORTING, 0) // Uses the bluespace tomato effect.
- set_trait(TRAIT_BIOLUM, 0) // Plant is bioluminescent.
- set_trait(TRAIT_FLOWERS, 0) // Plant has a flower overlay.
- set_trait(TRAIT_ALTER_TEMP, 0) // If set, the plant will periodically alter local temp by this amount.
- set_trait(TRAIT_PRODUCT_ICON, 0) // Icon to use for fruit coming from this plant.
- set_trait(TRAIT_PLANT_ICON, 0) // Icon to use for the plant growing in the tray.
- set_trait(TRAIT_PRODUCT_COLOUR, 0) // Colour to apply to product icon.
- set_trait(TRAIT_BIOLUM_COLOUR, 0) // The colour of the plant's radiance.
- set_trait(TRAIT_FLOWER_COLOUR, 0) // Which colour to use.
- set_trait(TRAIT_POTENCY, 1) // General purpose plant strength value.
- set_trait(TRAIT_REQUIRES_NUTRIENTS, 1) // The plant can starve.
- set_trait(TRAIT_REQUIRES_WATER, 1) // The plant can become dehydrated.
- set_trait(TRAIT_WATER_CONSUMPTION, 3) // Plant drinks this much per tick.
- set_trait(TRAIT_LIGHT_TOLERANCE, 5) // Departure from ideal that is survivable.
- set_trait(TRAIT_TOXINS_TOLERANCE, 5) // Resistance to poison.
- set_trait(TRAIT_PEST_TOLERANCE, 5) // Threshold for pests to impact health.
- set_trait(TRAIT_WEED_TOLERANCE, 5) // Threshold for weeds to impact health.
- set_trait(TRAIT_IDEAL_LIGHT, 8) // Preferred light level in luminosity.
- set_trait(TRAIT_HEAT_TOLERANCE, 20) // Departure from ideal that is survivable.
- set_trait(TRAIT_LOWKPA_TOLERANCE, 25) // Low pressure capacity.
- set_trait(TRAIT_ENDURANCE, 100) // Maximum plant HP when growing.
- set_trait(TRAIT_HIGHKPA_TOLERANCE, 200) // High pressure capacity.
- set_trait(TRAIT_IDEAL_HEAT, 293) // Preferred temperature in Kelvin.
- set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) // Plant eats this much per tick.
- set_trait(TRAIT_PLANT_COLOUR, "#6EF86A") // Colour of the plant icon.
- set_trait(TRAIT_FLOWER_ICON, "vine_fruit") // Which overlay to use.
-
- spawn(5)
- sleep(-1)
- update_growth_stages()
-
-
// Actual roundstart seed types after this point.
// Chili plants/variants.
/datum/seed/chili
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index 2194bf97db..c8c1f7ee37 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -74,13 +74,8 @@ var/global/list/plant_seed_sprites = list()
seed_type = null
/obj/item/seeds/random/New()
- seed = new()
- seed.randomize()
-
- seed.uid = seed_types.len + 1
- seed.name = "[seed.uid]"
- seed_types[seed.name] = seed
-
+ seed = create_random_seed()
+ seed_type = seed.name
update_seed()
/obj/item/seeds/replicapod
diff --git a/code/modules/hydroponics/spread_plant.dm b/code/modules/hydroponics/spread_plant.dm
index fdecb335aa..9130726789 100644
--- a/code/modules/hydroponics/spread_plant.dm
+++ b/code/modules/hydroponics/spread_plant.dm
@@ -1,4 +1,34 @@
#define DEFAULT_SEED "glowshroom"
+#define VINE_GROWTH_STAGES 4
+
+/proc/spacevine_infestation()
+ spawn() //to stop the secrets panel hanging
+ var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
+ for(var/areapath in typesof(/area/hallway))
+ var/area/A = locate(areapath)
+ for(var/area/B in A.related)
+ for(var/turf/simulated/floor/F in B.contents)
+ if(!F.contents.len)
+ turfs += F
+
+ if(turfs.len) //Pick a turf to spawn at if we can
+ var/turf/simulated/floor/T = pick(turfs)
+ var/datum/seed/seed = create_random_seed(1)
+ seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines.
+ seed.set_trait(TRAIT_POTENCY,rand(40,50)) // Guarantee a wide spread and powerful effects.
+ new /obj/effect/plant(T,seed)
+ message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
+
+/obj/effect/dead_plant
+ anchored = 1
+ opacity = 0
+ density = 0
+
+/obj/effect/dead_plant/attackby()
+ ..()
+ for(var/obj/effect/plant/neighbor in view(1,src))
+ neighbor.hibernating = 0
+ del(src)
/obj/effect/plant
name = "plant"
@@ -7,16 +37,21 @@
density = 0
icon = 'icons/obj/hydroponics_growing.dmi'
icon_state = "bush4-1"
- layer = 2.1
+ layer = 2
- var/health = 100
+ var/health = 10
var/max_health = 100
+ var/growth_threshold = 0
+ var/growth_type = 0
+ var/max_growth = 0
+ var/list/children = list()
var/obj/effect/plant/parent
var/datum/seed/seed
var/floor = 0
- var/spread_chance = 100 //40
- var/spread_into_adjacent = 100 //60
+ var/spread_chance = 40
+ var/spread_distance = 3
+ var/spread_into_adjacent = 60
var/evolve_chance = 2
var/last_tick = 0
var/hibernating = 0
@@ -33,9 +68,31 @@
del(src)
return
+ layer = rand(3,4) // Will display over pipes/machines at all times and mobs half the time.
name = seed.display_name
max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2)
- health = max_health
+ if(seed.get_trait(TRAIT_SPREAD)==2)
+ max_growth = VINE_GROWTH_STAGES
+ growth_threshold = round(max_health/VINE_GROWTH_STAGES)
+ icon = 'icons/obj/hydroponics_vines.dmi'
+ growth_type = 2 // Vines by default.
+ if(seed.get_trait(TRAIT_CARNIVOROUS) == 2)
+ growth_type = 1 // WOOOORMS.
+ else if(!(seed.seed_noun in list("seeds","pits")))
+ if(seed.seed_noun == "nodes")
+ growth_type = 3 // Biomass
+ else
+ growth_type = 4 // Mold
+ else
+ max_growth = seed.growth_stages
+ growth_threshold = round(max_health/seed.growth_stages)
+
+ if(max_growth > 2 && prob(50))
+ max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky.
+
+ spread_into_adjacent = round(seed.get_trait(TRAIT_POTENCY)/2)
+ spread_distance = ((growth_type>0) ? round(spread_into_adjacent/2) : round(spread_into_adjacent/15))
+ spread_chance = round(spread_into_adjacent/2)
set_dir(calc_dir())
update_icon()
@@ -44,14 +101,11 @@
/obj/effect/plant/update_icon()
- // TODO: convert this to an icon cache.
- icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[rand(1,max(1,seed.growth_stages-1))]"
- color = seed.get_trait(TRAIT_PLANT_COLOUR)
- if(!floor)
- // This should make the plant grow flush against the wall it's meant to be growing from.
- pixel_y = -(rand(8,12))
+ refresh_icon()
+ if(growth_type == 0 && !floor)
src.transform = null
var/matrix/M = matrix()
+ M.Translate(0,-(rand(12,14))) // should make the plant flush against the wall it's meant to be growing from.
switch(dir)
if(WEST)
M.Turn(90)
@@ -60,10 +114,12 @@
if(EAST)
M.Turn(270)
src.transform = M
-
+ var/icon_colour = seed.get_trait(TRAIT_PLANT_COLOUR)
+ if(icon_colour)
+ color = icon_colour
// Apply colour and light from seed datum.
if(seed.get_trait(TRAIT_BIOLUM))
- SetLuminosity(1+round(seed.get_trait(TRAIT_POTENCY)/10))
+ SetLuminosity(1+round(seed.get_trait(TRAIT_POTENCY)/20))
if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR)
else
@@ -72,26 +128,54 @@
else
SetLuminosity(0)
+/obj/effect/plant/proc/refresh_icon()
+ var/growth = min(max_growth,max(1,round(health/growth_threshold)))
+ if(growth_type > 0)
+ switch(growth_type)
+ if(1)
+ icon_state = "worms"
+ if(2)
+ icon_state = "vines-[growth]"
+ if(3)
+ icon_state = "mass-[growth]"
+ if(4)
+ icon_state = "mold-[growth]"
+ else
+ icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]"
+
/obj/effect/plant/Del()
processing_objects -= src
..()
-/obj/effect/plant/examine()
- ..()
- usr << "Max dist from parent is [round(seed.get_trait(TRAIT_POTENCY)/15)]."
- usr << "Current dist is [get_dist(get_root(),src)]."
-/obj/effect/plant/proc/die_off()
+/obj/effect/plant/proc/die_off(var/no_remains)
+ // 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)
for(var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant in get_turf(src))
plant.dead = 1
plant.update_icon()
// Cause the plants around us to update.
+ if(children && children.len)
+ for(var/obj/effect/plant/child in children)
+ child.die_off()
for(var/obj/effect/plant/neighbor in view(1,src))
neighbor.hibernating = 0
+ 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
+ plant_remains.icon_state = src.icon_state
del(src)
+/obj/effect/plant/proc/get_dist_to_parent(var/current_count)
+ if(!parent)
+ return current_count
+ current_count++
+ return parent.get_dist_to_parent(current_count)
+
/obj/effect/plant/process()
+ // Something is very wrong, kill ourselves.
if(!seed)
die_off()
@@ -99,27 +183,35 @@
var/turf/simulated/T = get_turf(src)
if(istype(T))
health -= seed.handle_environment(T, T.return_air(),1)
+ if(health < max_health)
+ health += rand(3,5)
+ if(health > max_health)
+ health = max_health
+ refresh_icon()
- // Hibernating or too far from parent, no chance of spreading.
- if(hibernating || (parent && (get_dist(get_root(),src) > round(seed.get_trait(TRAIT_POTENCY)/15))))
+ // Damaged, young hibernating or too far from parent, no chance of spreading.
+ if(health < (max_health/2) || hibernating || (parent && (get_dist_to_parent(0) > spread_distance)))
return
// Count our neighbors and possible locations for spreading.
var/list/possible_locs = list()
var/count = 0
for(var/turf/simulated/floor/floor in view(1,src))
- if(!floor.Adjacent(src) || floor.density || (locate(/obj/effect/plant) in floor.contents))
+ if((locate(/obj/effect/dead_plant) in floor.contents) || !floor.Enter(src) || floor.density)
+ continue
+ if(locate(/obj/effect/plant) in floor.contents)
count++
continue
possible_locs |= floor
- //Entirely surrounded, spawn an actual plant.
- if(count>=8)
- hibernating = 1 // Suspend processing for now.
+ //Entirely surrounded, try to spawn an actual plant.
+ if(count>=8 && prob(5))
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)
+ new_plant.age = seed.get_trait(TRAIT_MATURATION)-5
new_plant.update_icon()
+ if(growth_type==0) //Vines do not become invisible.
+ invisibility = INVISIBILITY_MAXIMUM
if(prob(spread_chance))
for(var/i=1,i<=seed.get_trait(TRAIT_YIELD),i++)
@@ -130,6 +222,14 @@
possible_locs -= target_turf
var/obj/effect/plant/child = new(target_turf, seed)
child.parent = get_root()
+ child.parent.children |= child
+
+ /*
+ var/need_hibernate = 0
+ if(need_hibernate)
+ hibernating = 1
+ world << "[src] at [x],[y] is hibernating"
+ */
/obj/effect/plant/proc/get_root()
if(parent)
@@ -188,19 +288,19 @@
/obj/effect/plant/ex_act(severity)
switch(severity)
if(1.0)
- del(src)
+ die_off()
return
if(2.0)
if (prob(50))
- del(src)
+ die_off()
return
if(3.0)
if (prob(5))
- del(src)
+ die_off()
return
else
return
/obj/effect/plant/proc/check_health()
if(health <= 0)
- del(src)
\ No newline at end of file
+ die_off()
\ No newline at end of file
diff --git a/code/modules/hydroponics/spread_vine.dm b/code/modules/hydroponics/spread_vine.dm
deleted file mode 100644
index c06ca4fba5..0000000000
--- a/code/modules/hydroponics/spread_vine.dm
+++ /dev/null
@@ -1,355 +0,0 @@
-// SPACE VINES (Note that this code is very similar to Biomass code)
-/obj/effect/plantsegment
- name = "space vines"
- desc = "An extremely expansionistic species of vine."
- icon = 'icons/effects/spacevines.dmi'
- icon_state = "Light1"
- anchored = 1
- density = 0
- layer = 5
- pass_flags = PASSTABLE | PASSGRILLE
-
- // Vars used by vines with seed data.
- var/age = 0
- var/lastproduce = 0
- var/harvest = 0
- var/list/chems
- var/plant_damage_noun = "Thorns"
- var/limited_growth = 0
-
- // Life vars/
- var/energy = 0
- var/obj/effect/plant_controller/master = null
- var/mob/living/buckled_mob
- var/datum/seed/seed
-
-/obj/effect/plantsegment/New()
- return
-
-/obj/effect/plantsegment/Del()
- if(master)
- master.vines -= src
- master.growth_queue -= src
- ..()
-
-/obj/effect/plantsegment/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (!W || !user || !W.type) return
- switch(W.type)
- if(/obj/item/weapon/circular_saw) del src
- if(/obj/item/weapon/kitchen/utensil/knife) del src
- if(/obj/item/weapon/scalpel) del src
- if(/obj/item/weapon/twohanded/fireaxe) del src
- if(/obj/item/weapon/hatchet) del src
- if(/obj/item/weapon/melee/energy) del src
- if(/obj/item/weapon/pickaxe/plasmacutter) del src
-
- // Less effective weapons
- if(/obj/item/weapon/wirecutters)
- if(prob(25)) del src
- if(/obj/item/weapon/shard)
- if(prob(25)) del src
-
- // Weapons with subtypes
- else
- if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
- else if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
- if(WT.remove_fuel(0, user)) del src
- else
- manual_unbuckle(user)
- return
- // Plant-b-gone damage is handled in its entry in chemistry-reagents.dm
- ..()
-
-
-/obj/effect/plantsegment/attack_hand(mob/user as mob)
-
- if(user.a_intent == "help" && seed && harvest)
- seed.harvest(user,1)
- harvest = 0
- lastproduce = age
- update()
- return
-
- manual_unbuckle(user)
-
-/obj/effect/plantsegment/proc/unbuckle()
- if(buckled_mob)
- if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt
- buckled_mob.buckled = null
- buckled_mob.anchored = initial(buckled_mob.anchored)
- buckled_mob.update_canmove()
- buckled_mob = null
- return
-
-/obj/effect/plantsegment/proc/manual_unbuckle(mob/user as mob)
- if(buckled_mob)
- if(prob(seed ? min(max(0,100 - seed.get_trait(TRAIT_POTENCY)),100) : 50))
- if(buckled_mob.buckled == src)
- if(buckled_mob != user)
- buckled_mob.visible_message(\
- "[user.name] frees [buckled_mob.name] from [src].",\
- "[user.name] frees you from [src].",\
- "You hear shredding and ripping.")
- else
- buckled_mob.visible_message(\
- "[buckled_mob.name] struggles free of [src].",\
- "You untangle [src] from around yourself.",\
- "You hear shredding and ripping.")
- unbuckle()
- else
- var/text = pick("rips","tears","pulls")
- user.visible_message(\
- "[user.name] [text] at [src].",\
- "You [text] at [src].",\
- "You hear shredding and ripping.")
- return
-
-/obj/effect/plantsegment/proc/grow()
-
- if(!energy)
- src.icon_state = pick("Med1", "Med2", "Med3")
- energy = 1
-
- //Low-lying creepers do not block vision or grow thickly.
- if(limited_growth)
- energy = 2
- return
-
- src.opacity = 1
- layer = 5
- else if(!limited_growth)
- src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
- energy = 2
-
-/obj/effect/plantsegment/proc/entangle_mob()
-
- if(limited_growth)
- return
-
- if(prob(seed ? seed.get_trait(TRAIT_POTENCY) : 25))
-
- if(!buckled_mob)
- var/mob/living/carbon/V = locate() in src.loc
- if(V && (V.stat != DEAD) && (V.buckled != src)) // If mob exists and is not dead or captured.
- V.buckled = src
- V.loc = src.loc
- V.update_canmove()
- src.buckled_mob = V
- V << "The vines [pick("wind", "tangle", "tighten")] around you!"
-
- // FEED ME, SEYMOUR.
- if(buckled_mob && seed && (buckled_mob.stat != DEAD)) //Don't bother with a dead mob.
- seed.do_thorns(buckled_mob,src)
- seed.do_sting(buckled_mob,src)
-
-/obj/effect/plantsegment/proc/update()
- if(!seed) return
-
- // Update bioluminescence.
- if(seed.get_trait(TRAIT_BIOLUM))
- SetLuminosity(1+round(seed.get_trait(TRAIT_POTENCY)/10))
- if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
- l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR)
- else
- l_color = null
- return
- else
- SetLuminosity(0)
-
- // Update flower/product overlay.
- overlays.Cut()
- if(age >= seed.get_trait(TRAIT_MATURATION))
- if(prob(20) && seed.products && seed.products.len && !harvest && ((age-lastproduce) > seed.get_trait(TRAIT_PRODUCTION)))
- harvest = 1
- lastproduce = age
-
- if(harvest)
- var/image/fruit_overlay = image('icons/obj/hydroponics_vines.dmi',"")
- if(seed.get_trait(TRAIT_PRODUCT_COLOUR))
- fruit_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
- overlays += fruit_overlay
-
- if(seed.get_trait(TRAIT_FLOWERS))
- var/image/flower_overlay = image('icons/obj/hydroponics_vines.dmi',"[seed.get_trait(TRAIT_FLOWER_ICON)]")
- if(seed.get_trait(TRAIT_FLOWER_COLOUR))
- flower_overlay.color = seed.get_trait(TRAIT_FLOWER_COLOUR)
- overlays += flower_overlay
-
-/obj/effect/plantsegment/proc/spread()
- var/direction = pick(cardinal)
- var/step = get_step(src,direction)
- if(istype(step,/turf/simulated/floor))
- var/turf/simulated/floor/F = step
- if(!locate(/obj/effect/plantsegment,F))
- if(F.Enter(src))
- if(master)
- master.spawn_piece( F )
-
-// Explosion damage.
-/obj/effect/plantsegment/ex_act(severity)
- switch(severity)
- if(1.0)
- die()
- return
- if(2.0)
- if (prob(90))
- die()
- return
- if(3.0)
- if (prob(50))
- die()
- return
- return
-
-// Hotspots kill vines.
-/obj/effect/plantsegment/fire_act(null, temp, volume)
- del src
-
-/obj/effect/plantsegment/proc/die()
- if(seed && harvest && rand(5))
- seed.harvest(src,1)
- del(src)
-
-/obj/effect/plantsegment/proc/life()
-
- if(!seed)
- return
-
- if(prob(30))
- age++
-
- var/turf/T = loc
- var/datum/gas_mixture/environment
- if(T) environment = T.return_air()
-
- if(!environment)
- return
-
- var/pressure = environment.return_pressure()
- if(pressure < seed.get_trait(TRAIT_LOWKPA_TOLERANCE) || pressure > seed.get_trait(TRAIT_HIGHKPA_TOLERANCE))
- die()
- return
-
- if(abs(environment.temperature - seed.get_trait(TRAIT_IDEAL_HEAT)) > seed.get_trait(TRAIT_HEAT_TOLERANCE))
- die()
- return
-
- var/area/A = T.loc
- if(A)
- var/light_available
- if(A.lighting_use_dynamic)
- light_available = max(0,min(10,T.lighting_lumcount)-5)
- else
- light_available = 5
- if(abs(light_available - seed.get_trait(TRAIT_IDEAL_LIGHT)) > seed.get_trait(TRAIT_LIGHT_TOLERANCE))
- die()
- return
-
-/obj/effect/plant_controller
-
- //What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
- //meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore.
-
- var/list/obj/effect/plantsegment/vines = list()
- var/list/growth_queue = list()
- var/reached_collapse_size
- var/reached_slowdown_size
- var/datum/seed/seed
-
- var/collapse_limit = 250
- var/slowdown_limit = 30
- var/limited_growth = 0
-
-/obj/effect/plant_controller/creeper
- collapse_limit = 6
- slowdown_limit = 3
- limited_growth = 1
-
-/obj/effect/plant_controller/New()
- if(!istype(src.loc,/turf/simulated/floor))
- del(src)
-
- spawn(0)
- spawn_piece(src.loc)
-
- processing_objects.Add(src)
-
-/obj/effect/plant_controller/Del()
- processing_objects.Remove(src)
- ..()
-
-/obj/effect/plant_controller/proc/spawn_piece(var/turf/location)
- var/obj/effect/plantsegment/SV = new(location)
- SV.limited_growth = src.limited_growth
- growth_queue += SV
- vines += SV
- SV.master = src
- if(seed)
- SV.seed = seed
- SV.name = "[seed.seed_name] vines"
- SV.update()
-
-/obj/effect/plant_controller/process()
-
- // Space vines exterminated. Remove the controller
- if(!vines)
- del(src)
- return
-
- // Sanity check.
- if(!growth_queue)
- del(src)
- return
-
- // Check if we're too big for our own good.
- if(vines.len >= (seed?seed.get_trait(TRAIT_POTENCY)*collapse_limit : 250)&&!reached_collapse_size)
- reached_collapse_size = 1
- if(vines.len >= (seed?seed.get_trait(TRAIT_POTENCY)*slowdown_limit : 30)&&!reached_slowdown_size)
- reached_slowdown_size = 1
-
- var/length = 0
- if(reached_collapse_size)
- length = 0
- else if(reached_slowdown_size)
- if(prob(seed ? seed.get_trait(TRAIT_POTENCY) : 25))
- length = 1
- else
- length = 0
- else
- length = 1
-
- length = min(30, max(length, vines.len/5))
-
- // Update as many pieces of vine as we're allowed to.
- // Append updated vines to the end of the growth queue.
- var/i = 0
- var/list/obj/effect/plantsegment/queue_end = list()
- for(var/obj/effect/plantsegment/SV in growth_queue)
- i++
- queue_end += SV
- growth_queue -= SV
-
- SV.life()
-
- if(!SV) continue
-
- if(SV.energy < 2) //If tile isn't fully grown
- var/chance
- if(seed)
- chance = limited_growth ? round(seed.get_trait(TRAIT_POTENCY)/2,1) : seed.get_trait(TRAIT_POTENCY)
- else
- chance = 20
-
- if(prob(chance))
- SV.grow()
-
- else if(!seed || !limited_growth) //If tile is fully grown and not just a creeper.
- SV.entangle_mob()
-
- SV.update()
- SV.spread()
- if(i >= length)
- break
-
- growth_queue = growth_queue + queue_end
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index b40e6fb819..4442e8caf0 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -45,17 +45,15 @@
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
- if(locate(/obj/effect/plantsegment) in loc)
- var/obj/effect/plantsegment/SV = locate(/obj/effect/plantsegment) in loc
- del(SV)
- if(prob(10))
- say("Nom")
+ if(locate(/obj/effect/plant) in loc)
+ var/obj/effect/plant/SV = locate() in loc
+ SV.die_off(1)
if(!pulledby)
for(var/direction in shuffle(list(1,2,4,8,5,6,9,10)))
var/step = get_step(src, direction)
if(step)
- if(locate(/obj/effect/plantsegment) in step)
+ if(locate(/obj/effect/plant) in step)
Move(step)
/mob/living/simple_animal/hostile/retaliate/goat/Retaliate()
@@ -65,11 +63,8 @@
/mob/living/simple_animal/hostile/retaliate/goat/Move()
..()
if(!stat)
- if(locate(/obj/effect/plantsegment) in loc)
- var/obj/effect/plantsegment/SV = locate(/obj/effect/plantsegment) in loc
- del(SV)
- if(prob(10))
- say("Nom")
+ for(var/obj/effect/plant/SV in loc)
+ SV.die_off(1)
/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 4f2135be98..a34d6e4d7c 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -1846,8 +1846,10 @@ datum
alien_weeds.healthcheck()
else if(istype(O,/obj/effect/plant)) //even a small amount is enough to kill it
del(O)
- else if(istype(O,/obj/effect/plantsegment))
- if(prob(50)) del(O) //Kills kudzu too.
+ else if(istype(O,/obj/effect/plant))
+ if(prob(50))
+ var/obj/effect/plant/plant = O
+ plant.die_off()
else if(istype(O,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/tray = O
diff --git a/icons/obj/biomass.dmi b/icons/obj/biomass.dmi
deleted file mode 100644
index ffb133f768..0000000000
Binary files a/icons/obj/biomass.dmi and /dev/null differ
diff --git a/icons/obj/hydroponics_vines.dmi b/icons/obj/hydroponics_vines.dmi
index 00175f5a57..2bad94b350 100644
Binary files a/icons/obj/hydroponics_vines.dmi and b/icons/obj/hydroponics_vines.dmi differ
diff --git a/icons/obj/magic.dmi b/icons/obj/magic.dmi
index 141b2df3f8..f92243d6bc 100644
Binary files a/icons/obj/magic.dmi and b/icons/obj/magic.dmi differ
diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi
index b659bdc23e..1d6bad4c50 100644
Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ