Collapsed space vines, glowshrooms and biomass into one spreading-plant system.

This commit is contained in:
Zuhayr
2015-01-31 14:34:41 +10:30
parent 43802dceb7
commit 09e4be2b1b
25 changed files with 266 additions and 870 deletions

View File

@@ -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"

View File

@@ -1378,3 +1378,15 @@ var/list/WALLITEMS = list(
if(istype(arglist,/list))
arglist = list2params(arglist)
return "<a href='?src=\ref[D];[arglist]'>[content]</a>"
/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

View File

@@ -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

View File

@@ -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,

View File

@@ -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])")

View File

@@ -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])")

View File

@@ -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

View File

@@ -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 , i<continueChance , i++)
possibleDirs += direction
if(possibleDirsInt & turn(direction,90))
possibleDirs += turn(direction,90)
if(possibleDirsInt & turn(direction,-90))
possibleDirs += turn(direction,-90)
if(!possibleDirs.len)
return
direction = pick(possibleDirs)
var/obj/effect/biomass/newBiomass = new /obj/effect/biomass(get_step(src,direction))
newBiomass.curDistance = curDistance + 1
newBiomass.maxDistance = maxDistance
newBiomass.set_dir(direction)
newBiomass.originalRift = originalRift
newBiomass.icon_state = "[originalRift.newicon]" //DEBUG
originalRift.linkedBiomass += newBiomass
if(!(curDistance%newSpreadDistance))
var/obj/effect/rift/newrift = new /obj/effect/rift(loc)
if(originalRift.newicon <= 3)
newrift.newicon = originalRift.newicon + 1
// NewSpread()
/obj/effect/biomass/proc/NewSpread(maxDistance = 15)
set background = 1
for(var/turf/T in orange(1,src))
if(!IsValidBiomassLoc(T,src))
continue
var/obj/effect/biomass/starting = new /obj/effect/biomass(T)
starting.set_dir(get_dir(src,starting))
starting.maxDistance = maxDistance
/proc/IsValidBiomassLoc(turf/location,obj/effect/biomass/source = null)
set background = 1
for(var/obj/effect/biomass/biomass in location)
if(biomass != source)
return 0
if(istype(location,/turf/space))
return 0
if(location.density)
return 0
return 1
*/

View File

@@ -42,7 +42,7 @@ var/global/list/image/splatter_cache=list()
dry()
/obj/effect/decal/cleanable/blood/update_icon()
if(basecolor == "rainbow") basecolor = "#[pick(rainbow)]"
if(basecolor == "rainbow") basecolor = "#[get_random_colour(1)]"
color = basecolor
/obj/effect/decal/cleanable/blood/Crossed(mob/living/carbon/human/perp)
@@ -165,11 +165,11 @@ var/global/list/image/splatter_cache=list()
var/image/giblets = new(base_icon, "[icon_state]_flesh", dir)
if(!fleshcolor || fleshcolor == "rainbow")
fleshcolor = "#[pick(rainbow)]"
fleshcolor = "#[get_random_colour(1)]"
giblets.color = fleshcolor
var/icon/blood = new(base_icon,"[icon_state]",dir)
if(basecolor == "rainbow") basecolor = "#[pick(rainbow)]"
if(basecolor == "rainbow") basecolor = "#[get_random_colour(1)]"
blood.Blend(basecolor,ICON_MULTIPLY)
icon = blood

View File

@@ -254,9 +254,6 @@ var/static/list/scarySounds = list(
// Bomb cap!
var/max_explosion_range = 14
// A list of colours comprising the rainbow.
var/list/rainbow = list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF")
// 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.

View File

@@ -2432,11 +2432,6 @@
var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No")
if(show_log == "Yes")
command_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", new_sound = 'sound/AI/ionstorm.ogg')
if("spacevines")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","K")
new /datum/event/spacevine
message_admins("[key_name_admin(usr)] has spawned spacevines", 1)
if("onlyone")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","OO")

View File

@@ -1,9 +1,5 @@
/var/global/spacevines_spawned = 0
/datum/event/spacevine/start()
//biomass is basically just a resprited version of space vines
if(prob(50))
spacevine_infestation()
else
biomass_infestation()
spacevine_infestation()
spacevines_spawned = 1

View File

@@ -4,8 +4,8 @@
#define GENE_ENVIRONMENT "environment"
#define GENE_RESISTANCE "resistance"
#define GENE_VIGOUR "vigour"
#define GENE_FLOWERS "flowers"
#define ALL_TRAITS list(GENE_PRODUCTS,GENE_CONSUMPTION,GENE_ENVIRONMENT,GENE_RESISTANCE,GENE_VIGOUR,GENE_FLOWERS)
#define GENE_PIGMENT "appearance"
#define ALL_GENES list(GENE_PRODUCTS,GENE_CONSUMPTION,GENE_ENVIRONMENT,GENE_RESISTANCE,GENE_VIGOUR,GENE_PIGMENT)
//Definitions for traits (individual descriptors)
#define TRAIT_PRODUCTS 1
@@ -46,7 +46,4 @@
#define TRAIT_PRODUCT_COLOUR 36
#define TRAIT_BIOLUM 37
#define TRAIT_BIOLUM_COLOUR 38
#define TRAIT_FLOWERS 39
#define TRAIT_FLOWER_ICON 40
#define TRAIT_FLOWER_COLOUR 41
#define TRAIT_IMMUTABLE 42
#define TRAIT_IMMUTABLE 39

View File

@@ -152,8 +152,6 @@
if(grown_seed.get_trait(TRAIT_BIOLUM))
dat += "<br>It is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "<font color='[grown_seed.get_trait(TRAIT_BIOLUM_COLOUR)]'>bio-luminescent</font>" : "bio-luminescent"]."
if(grown_seed.get_trait(TRAIT_FLOWERS))
dat += "<br>It has [grown_seed.get_trait(TRAIT_FLOWER_COLOUR) ? "<font color='[grown_seed.get_trait(TRAIT_FLOWER_COLOUR)]'>flowers</font>" : "flowers"]."
if(grown_seed.get_trait(TRAIT_PRODUCES_POWER))
dat += "<br>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

View File

@@ -139,6 +139,9 @@
nymph.visible_message("<font color='blue'><b>[nymph]</b> rolls around in [src] for a bit.</font>","<font color='blue'>You roll around in [src] for a bit.</font>")
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,6 +835,9 @@
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)
@@ -847,3 +845,11 @@
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()
..()

View File

@@ -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<total_mutations;i++)
switch(rand(0,12))
switch(rand(0,11))
if(0) //Plant cancer!
set_trait(TRAIT_ENDURANCE,get_trait(TRAIT_ENDURANCE)-rand(10,20),null,0)
source_turf.visible_message("<span class='danger'>\The [display_name] withers rapidly!</span>")
@@ -550,21 +584,11 @@ proc/populate_seed_list()
if(get_trait(TRAIT_BIOLUM))
source_turf.visible_message("<span class='notice'>\The [display_name] begins to glow!</span>")
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("<span class='notice'>\The [display_name]'s glow </span><font color='[get_trait(TRAIT_BIOLUM_COLOUR)]'>changes colour</font>!")
else
source_turf.visible_message("<span class='notice'>\The [display_name]'s glow dims...</span>")
if(11)
if(prob(degree*2))
set_trait(TRAIT_FLOWERS,!get_trait(TRAIT_FLOWERS))
if(get_trait(TRAIT_FLOWERS))
source_turf.visible_message("<span class='notice'>\The [display_name] sprouts a bevy of flowers!</span>")
if(prob(degree*2))
set_trait(TRAIT_FLOWER_COLOUR,"#[pick(rainbow)]")
source_turf.visible_message("<span class='notice'>\The [display_name]'s flowers </span><font=[get_trait(TRAIT_FLOWER_COLOUR)]>changes colour</font>!")
else
source_turf.visible_message("<span class='notice'>\The [display_name]'s flowers wither and fall off.</span>")
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

View File

@@ -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

View File

@@ -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("<span class='notice'>Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])</span>")
/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)
die_off()

View File

@@ -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(\
"<span class='notice'>[user.name] frees [buckled_mob.name] from [src].</span>",\
"<span class='notice'>[user.name] frees you from [src].</span>",\
"<span class='warning'>You hear shredding and ripping.</span>")
else
buckled_mob.visible_message(\
"<span class='notice'>[buckled_mob.name] struggles free of [src].</span>",\
"<span class='notice'>You untangle [src] from around yourself.</span>",\
"<span class='warning'>You hear shredding and ripping.</span>")
unbuckle()
else
var/text = pick("rips","tears","pulls")
user.visible_message(\
"<span class='notice'>[user.name] [text] at [src].</span>",\
"<span class='notice'>You [text] at [src].</span>",\
"<span class='warning'>You hear shredding and ripping.</span>")
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 << "<span class='danger'>The vines [pick("wind", "tangle", "tighten")] around you!</span>"
// 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

View File

@@ -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

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB