From 4ad00d93a57d1629d2dc969826e1cb67bcd94f0d Mon Sep 17 00:00:00 2001 From: FalseIncarnate Date: Sat, 23 May 2015 07:43:31 -0400 Subject: [PATCH] Botany Atmospheric Interactions Re-enables botany's interactions with atmospheric conditions and gases. Seeds can now consume and exude gases as part of their growth process. Most seeds do not have this functionality, however it can be found on random seeds. Random seeds will occasionally require a gas to grow, or will produce a gas while planted. Possible gases are Oxygen (O2), Nitrogen (N2), Carbon Dioxide (CO2), or Plasma gas. If a plant that affects a gas is planted, it will attempt to interact with the environment differently depending on conditions as detailed below: - Tray lid down: Will always utilize the air of it's tile for atmos interaction. - Tray lid up, nothing connected/inserted: Will utilize the air of it's tile for atmos interaction. - Tray lid up, tray connected to a connector port pipe: Will attempt to utilize the air of the pipe network the connector is part of, allowing you to utilize canisters or direct feeds into the station's piping. If there are no gases at all (0 total moles) in the network, it will create an empty gas_mixture at 20C (standard room temp) in the network before attempting atmos interactions. - Tray lid up, tank inserted into tray: Will attempt to utilize the contents of the inserted tank for atmos interaction. If the tank is completely empty (0 total moles), it will create a new empty gas_mixture at 20C before attempting atmos interactions. - Tray lid up, tank inserted AND connector port: Will attempt to utilize the contents of the inserted tank for atmos interaction. If the tank is completely empty (0 total moles), it will create a new empty gas_mixture at 20C before attempting atmos interactions. (Pretty much just ignores the connector port) In case it wasn't apparent from the above mentions, you can now insert any portable tank (emergency oxygen, plasma tank, pretty much any tank that could be hooked up to internals) into a hydroponics tray. You can remove them with the previously added eject internal tank verb. There is currently no visual indication of whether or not there is a tank inserted (the tray icons are already cluttered with the sheer number of overlays, and I didn't want to sprite another monstrosity like my past spriting attempts yielded) When utilizing an inserted tank for the plant's atmos interactions, it will attempt to use distribution pressure set on the tank for the atmospheric pressure inside the closed lid. If the tank's internal pressure drops lower than the distribution pressure, it will use the tank's internal pressure instead. The alter temperature trait is now functional, and will heat/cool the air used for the plant's atmos interactions. This means it can heat/cool the surrounding air, inserted tanks, or the contents of a connected pipe network. Plant analyzers have had their readouts updated to report what (if any) gases the plant consumes or produces during it's life. Also edited the alter temperature trait's message on the plant analyzer to not incorrectly refer to the change in "degrees Kelvin". There may be a bit of wonkiness with open-air atmos interaction and gas redistribution, which would be an issue with LINDA's processing and not the changes in this PR. Also, a major reminder that atmos grief is a bannable offense, and releasing plasma-producing vines into the halls will be considered equal to causing an atmos flood from atmospherics and dealt with accordingly. --- code/modules/hydroponics/seed.dm | 81 ++++++++++++++----- code/modules/hydroponics/seed_datums.dm | 18 +++++ code/modules/hydroponics/seed_packets.dm | 3 + .../hydroponics/spreading/spreading_growth.dm | 2 +- code/modules/hydroponics/trays/tray.dm | 10 +++ .../modules/hydroponics/trays/tray_process.dm | 6 +- code/modules/hydroponics/trays/tray_tools.dm | 14 +++- 7 files changed, 110 insertions(+), 24 deletions(-) diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index c11d46154f2..9d023c52c48 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -243,39 +243,49 @@ origin_turf.visible_message("The [thrown.name] splatters against [target]!") del(thrown) -/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only) +/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/obj/item/weapon/tank/holding, var/check_only) var/health_change = 0 - /* - // Handle gas consumption. - if(consume_gasses && consume_gasses.len) - var/missing_gas = 0 - for(var/gas in consume_gasses) - if(environment && environment.gas && environment.gas[gas] && \ - environment.gas[gas] >= consume_gasses[gas]) - if(!check_only) - environment.adjust_gas(gas,-consume_gasses[gas],1) - else - missing_gas++ - if(missing_gas > 0) - health_change += missing_gas * HYDRO_SPEED_MULTIPLIER - */ + if(!environment) //Someone called this without passing an environment. Punish their plant. + return -100 // Process it. - var/pressure = environment.return_pressure() + var/pressure + if(holding) //Check if we are running from an internal source (portable tank) + //Use the tank's distribution pressure or it's internal pressure (whichever is lower) for pressure checks + pressure = min(environment.return_pressure(), holding.distribute_pressure) + else //Not using an internal source + pressure = environment.return_pressure() if(pressure < get_trait(TRAIT_LOWKPA_TOLERANCE)|| pressure > get_trait(TRAIT_HIGHKPA_TOLERANCE)) health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER if(abs(environment.temperature - get_trait(TRAIT_IDEAL_HEAT)) > get_trait(TRAIT_HEAT_TOLERANCE)) health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER - /* + // Handle gas consumption. + if(consume_gasses && consume_gasses.len) + var/missing_gas = 0 + for(var/gas in consume_gasses) + if(environment && environment.vars[gas] && environment.vars[gas] >= consume_gasses[gas]) + if(!check_only) + environment = adjust_gas(environment, gas,-consume_gasses[gas]) + else + missing_gas++ + + if(missing_gas > 0) + health_change += missing_gas * HYDRO_SPEED_MULTIPLIER + // Handle gas production. if(exude_gasses && exude_gasses.len && !check_only) for(var/gas in exude_gasses) - environment.adjust_gas(gas, max(1,round((exude_gasses[gas]*(get_trait(TRAIT_POTENCY)/5))/exude_gasses.len))) - */ + environment = adjust_gas(environment, gas, max(1,round((exude_gasses[gas]*(get_trait(TRAIT_POTENCY)/5))/exude_gasses.len))) + + //Handle heat adjustment + if(get_trait(TRAIT_ALTER_TEMP)) + environment.temperature += get_trait(TRAIT_ALTER_TEMP) + if(environment.temperature < 0) //Make sure we didn't drop below absolute zero + environment.temperature = 0 //Set temperature back to zero if we did // Handle light requirements. if(!light_supplied) @@ -291,6 +301,35 @@ return health_change +//Screw it, making a new proc for this for the sake of readability or something. --FalseIncarnate +/datum/seed/proc/adjust_gas(var/datum/gas_mixture/environment, var/gas, var/amount = 0) + if(!environment || !gas) //no gas_mixture or gas defined to adjust + return + + var/transfer_moles = environment.total_moles() + var/datum/gas_mixture/temp_holding + if(transfer_moles <= 0) //Check if the transfer_moles is an unacceptable value for the remove proc + //The environment is empty (or somehow has negative moles), create a new gas_mixture for temp_holding + temp_holding = new /datum/gas_mixture() + temp_holding.temperature = T20C + else + //The environment is acceptable, transfer it's contents into temp_holding + temp_holding = environment.remove(transfer_moles) + + if(!temp_holding) return //Just in case temp_holding has somehow avoided being set + + switch(gas) + if("oxygen") + temp_holding.oxygen += amount + if("nitrogen") + temp_holding.nitrogen += amount + if("carbon_dioxide") + temp_holding.carbon_dioxide += amount + if("toxins") + temp_holding.toxins += amount + + return environment.merge(temp_holding) + /datum/seed/proc/apply_special_effect(var/mob/living/target,var/obj/item/thrown) var/impact = 1 @@ -361,12 +400,12 @@ if(prob(5)) consume_gasses = list() - var/gas = pick("oxygen","nitrogen","plasma","carbon_dioxide") + var/gas = pick("oxygen","nitrogen","toxins","carbon_dioxide") consume_gasses[gas] = rand(3,9) if(prob(5)) exude_gasses = list() - var/gas = pick("oxygen","nitrogen","plasma","carbon_dioxide") + var/gas = pick("oxygen","nitrogen","toxins","carbon_dioxide") exude_gasses[gas] = rand(3,9) chems = list() diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index d39d315bdb3..e1eb5c8681b 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -1236,6 +1236,7 @@ seed_name = "test" display_name = "test trees" chems = list("omnizine" = list(1,20)) + consume_gasses = list("oxygen" = 5) /datum/seed/test/New() ..() @@ -1249,3 +1250,20 @@ set_trait(TRAIT_PRODUCT_COLOUR,"#BB6AC4") set_trait(TRAIT_PLANT_ICON,"tree") set_trait(TRAIT_EXPLOSIVE, 1) + +/datum/seed/test2 + name = "test2" + seed_name = "test2" + display_name = "test2 trees" + exude_gasses = list("toxins" = 5) + +/datum/seed/test2/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,1) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,15) + set_trait(TRAIT_PRODUCT_ICON,"treefruit") + set_trait(TRAIT_PRODUCT_COLOUR,"#BB6AC4") + set_trait(TRAIT_PLANT_ICON,"tree") diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm index 3a2afb74f2a..687bb7fbb78 100644 --- a/code/modules/hydroponics/seed_packets.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -287,6 +287,9 @@ var/global/list/plant_seed_sprites = list() /obj/item/seeds/test seed_type = "test" +/obj/item/seeds/test2 + seed_type = "test2" + /obj/item/seeds/stobaccoseed seed_type = "stobacco" diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm index 6b589427b2e..c360ba5c0e1 100644 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -45,7 +45,7 @@ // Handle life. var/turf/simulated/T = get_turf(src) if(istype(T)) - health -= seed.handle_environment(T,T.return_air(),null,1) + health -= seed.handle_environment(T,T.return_air(),null,null,1) if(health < max_health) health += rand(3,5) refresh_icon() diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 2dae36c58d0..9e727f62bcb 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -740,6 +740,16 @@ A.icon_state = src.icon_state A.hydrotray_type = src.type del(src) + else if ((istype(O, /obj/item/weapon/tank) && !( src.destroyed ))) + if (src.holding) + user << "\blue There is alreadu a tank loaded into the [src]." + return + var/obj/item/weapon/tank/T = O + user.drop_item() + T.loc = src + src.holding = T + update_icon() + return else if(O && O.force && seed) user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [O]!") if(!dead) diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm index d16ca75cc97..cf8087ae6bd 100644 --- a/code/modules/hydroponics/trays/tray_process.dm +++ b/code/modules/hydroponics/trays/tray_process.dm @@ -62,6 +62,8 @@ var/datum/gas_mixture/environment // If we're closed, take from our internal sources. if(closed_system && (connected_port || holding)) + if(holding) + air_contents = holding.air_contents environment = air_contents // If atmos input is not there, grab from turf. if(!environment && istype(T)) environment = T.return_air() @@ -69,10 +71,12 @@ // Seed datum handles gasses, light and pressure. if(mechanical && closed_system) - health -= seed.handle_environment(T,environment,tray_light) + health -= seed.handle_environment(T,environment,tray_light, holding) else health -= seed.handle_environment(T,environment) + T.air_update_turf() + // If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses if (closed_system && connected_port) update_connected_network() diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 7d69104e2b0..d3db34ec060 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -166,6 +166,18 @@ dat += "It thrives in a temperature of [grown_seed.get_trait(TRAIT_IDEAL_HEAT)] Kelvin." + if(grown_seed.consume_gasses && grown_seed.consume_gasses.len) + for(var/gas in grown_seed.consume_gasses) + if(gas == "carbon_dioxide") gas = "carbon dioxide" + if(gas == "toxins") gas = "plasma" + dat += "
It requires an environment rich in [gas] gas to thrive." + + if(grown_seed.exude_gasses && grown_seed.exude_gasses.len) + for(var/gas in grown_seed.exude_gasses) + if(gas == "carbon_dioxide") gas = "carbon dioxide" + if(gas == "toxins") gas = "plasma" + dat += "
It releases [gas] gas as a byproduct of it's growth." + if(grown_seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) dat += "
It is well adapted to low pressure levels." if(grown_seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) @@ -213,7 +225,7 @@ if(grown_seed.get_trait(TRAIT_PARASITE)) dat += "
It is capable of parisitizing and gaining sustenance from tray weeds." if(grown_seed.get_trait(TRAIT_ALTER_TEMP)) - dat += "
It will periodically alter the local temperature by [grown_seed.get_trait(TRAIT_ALTER_TEMP)] degrees Kelvin." + dat += "
It will periodically alter the local temperature by [grown_seed.get_trait(TRAIT_ALTER_TEMP)] Kelvin." if(grown_seed.get_trait(TRAIT_BIOLUM)) dat += "
It is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]."