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