diff --git a/baystation12.dme b/baystation12.dme index e3de1ac51f4..02b48247b33 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -335,7 +335,6 @@ #include "code\game\machinery\atmoalter\portable_atmospherics.dm" #include "code\game\machinery\atmoalter\pump.dm" #include "code\game\machinery\atmoalter\scrubber.dm" -#include "code\game\machinery\atmoalter\zvent.dm" #include "code\game\machinery\bots\bots.dm" #include "code\game\machinery\bots\cleanbot.dm" #include "code\game\machinery\bots\ed209bot.dm" @@ -1426,7 +1425,8 @@ #include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm" #include "code\WorkInProgress\Wrongnumber\weldbackpack.dm" #include "code\ZAS\_docs.dm" -#include "code\ZAS\_gas_mixture.dm" +#include "code\ZAS\_gas_mixture_xgm.dm" +#include "code\ZAS\_xgm_gas_data.dm" #include "code\ZAS\Airflow.dm" #include "code\ZAS\Atom.dm" #include "code\ZAS\Connection.dm" @@ -1436,6 +1436,7 @@ #include "code\ZAS\Debug.dm" #include "code\ZAS\Diagnostic.dm" #include "code\ZAS\Fire.dm" +#include "code\ZAS\Gas.dm" #include "code\ZAS\Phoron.dm" #include "code\ZAS\Turf.dm" #include "code\ZAS\Variable Settings.dm" diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 4766883a645..4e2fcbc2638 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -44,7 +44,7 @@ return 1 //Calculate necessary moles to transfer using PV = nRT - if((air1.total_moles() > 0) && (air1.temperature>0)) + if((air1.total_moles > 0) && (air1.temperature>0)) var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2) //Can not have a pressure delta that would cause output_pressure > input_pressure @@ -172,4 +172,4 @@ "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) \ No newline at end of file + del(src) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 944ed53de16..acacb2e3def 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -69,7 +69,7 @@ Thus, the two variables affect pump operation are set in New(): return 1 //Calculate necessary moles to transfer using PV=nRT - if((air1.total_moles() > 0) && (air1.temperature>0)) + if((air1.total_moles > 0) && (air1.temperature>0)) var/pressure_delta = target_pressure - output_starting_pressure var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) @@ -204,4 +204,4 @@ Thus, the two variables affect pump operation are set in New(): "\blue You have unfastened \the [src].", \ "You hear ratchet.") new /obj/item/pipe(loc, make_from=src) - del(src) \ No newline at end of file + del(src) diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 1d1d335cb8a..9f4abcb8d0f 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -46,7 +46,7 @@ ..() if(!on) return 0 - + if(!input || !output) return @@ -54,7 +54,7 @@ var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug* var/output_pressure = output_air.return_pressure() - + if(output_pressure >= target_pressure) return for(var/datum/omni_port/P in filters) @@ -63,49 +63,46 @@ var/pressure_delta = target_pressure - output_pressure - if(input_air.return_temperature() > 0) - input.transfer_moles = pressure_delta * output_air.volume / (input_air.return_temperature() * R_IDEAL_GAS_EQUATION) + if(input_air.temperature > 0) + input.transfer_moles = pressure_delta * output_air.volume / (input_air.temperature * R_IDEAL_GAS_EQUATION) if(input.transfer_moles > 0) var/datum/gas_mixture/removed = input_air.remove(input.transfer_moles) - + if(!removed) return - + for(var/datum/omni_port/P in filters) var/datum/gas_mixture/filtered_out = new - filtered_out.temperature = removed.return_temperature() - + filtered_out.temperature = removed.temperature + switch(P.mode) if(ATM_O2) - filtered_out.oxygen = removed.oxygen - removed.oxygen = 0 + filtered_out.gas["oxygen"] = removed.gas["oxygen"] + removed.gas["oxygen"] = null if(ATM_N2) - filtered_out.nitrogen = removed.nitrogen - removed.nitrogen = 0 + filtered_out.gas["nitrogen"] = removed.gas["nitrogen"] + removed.gas["nitrogen"] = null if(ATM_CO2) - filtered_out.carbon_dioxide = removed.carbon_dioxide - removed.carbon_dioxide = 0 + filtered_out.gas["carbon_dioxide"] = removed.gas["carbon_dioxide"] + removed.gas["carbon_dioxide"] = null if(ATM_P) - filtered_out.phoron = removed.phoron - removed.phoron = 0 + filtered_out.gas["phoron"] = removed.gas["phoron"] + removed.gas["phoron"] = null if(ATM_N2O) - if(removed.trace_gases.len>0) - for(var/datum/gas/sleeping_agent/trace_gas in removed.trace_gases) - if(istype(trace_gas)) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas + filtered_out.gas["sleeping_agent"] = removed.gas["sleeping_agent"] + removed.gas["sleeping_agent"] = null else filtered_out = null - + P.air.merge(filtered_out) if(P.network) P.network.update = 1 - + output_air.merge(removed) if(output.network) output.network.update = 1 - + input.transfer_moles = 0 if(input.network) input.network.update = 1 diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 3b5dd1780fe..666825c1cd6 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -9,7 +9,7 @@ var/datum/omni_port/output //setup tags for initial concentration values (must be decimal) - var/tag_north_con + var/tag_north_con var/tag_south_con var/tag_east_con var/tag_west_con @@ -101,22 +101,22 @@ var/pressure_delta = target_pressure - output_pressure for(var/datum/omni_port/P in inputs) - if(P.air.return_temperature() > 0) - P.transfer_moles = (P.concentration * pressure_delta) * output_air.return_volume() / (P.air.return_temperature() * R_IDEAL_GAS_EQUATION) + if(P.air.temperature > 0) + P.transfer_moles = (P.concentration * pressure_delta) * output_air.volume / (P.air.temperature * R_IDEAL_GAS_EQUATION) var/ratio_check = null for(var/datum/omni_port/P in inputs) if(!P.transfer_moles) return - if(P.air.total_moles() < P.transfer_moles) + if(P.air.total_moles < P.transfer_moles) ratio_check = 1 continue if(ratio_check) var/list/ratio_list = new() for(var/datum/omni_port/P in inputs) - ratio_list.Add(P.air.total_moles() / P.transfer_moles) + ratio_list.Add(P.air.total_moles / P.transfer_moles) var/ratio = min(ratio_list) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 594190bdb8a..ff27f2becf3 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -41,7 +41,7 @@ Filter types: icon_state = "m" else icon_state = "" - + if(!powered()) icon_state += "off" else if(node2 && node3 && node1) @@ -106,38 +106,31 @@ Filter types: switch(filter_type) if(0) //removing hydrocarbons - filtered_out.phoron = removed.phoron - removed.phoron = 0 + filtered_out.gas["phoron"] = removed.gas["phoron"] + removed.gas["phoron"] = 0 - if(removed.trace_gases.len>0) - for(var/datum/gas/trace_gas in removed.trace_gases) - if(istype(trace_gas, /datum/gas/oxygen_agent_b)) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas + filtered_out.gas["oxygen_agent_b"] = removed.gas["oxygen_agent_b"] + removed.gas["oxygen_agent_b"] = 0 if(1) //removing O2 - filtered_out.oxygen = removed.oxygen - removed.oxygen = 0 + filtered_out.gas["oxygen"] = removed.gas["oxygen"] + removed.gas["oxygen"] = 0 if(2) //removing N2 - filtered_out.nitrogen = removed.nitrogen - removed.nitrogen = 0 + filtered_out.gas["nitrogen"] = removed.gas["nitrogen"] + removed.gas["nitrogen"] = 0 if(3) //removing CO2 - filtered_out.carbon_dioxide = removed.carbon_dioxide - removed.carbon_dioxide = 0 + filtered_out.gas["carbon_dioxide"] = removed.gas["carbon_dioxide"] + removed.gas["carbon_dioxide"] = 0 if(4)//removing N2O - if(removed.trace_gases.len>0) - for(var/datum/gas/trace_gas in removed.trace_gases) - if(istype(trace_gas, /datum/gas/sleeping_agent)) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas + filtered_out.gas["sleeping_agent"] = removed.gas["sleeping_agent"] + removed.gas["sleeping_agent"] = 0 else filtered_out = null - air2.merge(filtered_out) air3.merge(removed) @@ -272,7 +265,7 @@ obj/machinery/atmospherics/trinary/filter/m_filter/New() /obj/machinery/atmospherics/trinary/filter/m_filter/initialize() set_frequency(frequency) - + if(node1 && node2 && node3) return var/node1_connect = turn(dir, -180) @@ -295,4 +288,4 @@ obj/machinery/atmospherics/trinary/filter/m_filter/New() break update_icon() - update_underlays() \ No newline at end of file + update_underlays() diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 228be72020d..3dbfd1fb51c 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -19,7 +19,7 @@ icon_state = "t" else icon_state = "" - + if(!powered()) icon_state += "off" else if(node2 && node3 && node1) @@ -83,8 +83,8 @@ if(air2.temperature > 0) transfer_moles2 = (node2_concentration*pressure_delta)*air3.volume/(air2.temperature * R_IDEAL_GAS_EQUATION) - var/air1_moles = air1.total_moles() - var/air2_moles = air2.total_moles() + var/air1_moles = air1.total_moles + var/air2_moles = air2.total_moles if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2)) if(!transfer_moles1 || !transfer_moles2) return @@ -271,4 +271,4 @@ obj/machinery/atmospherics/trinary/mixer/m_mixer/initialize() break update_icon() - update_underlays() \ No newline at end of file + update_underlays() diff --git a/code/ATMOSPHERICS/components/unary/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary/oxygen_generator.dm index 9a58be7c302..14bbb46bbaa 100644 --- a/code/ATMOSPHERICS/components/unary/oxygen_generator.dm +++ b/code/ATMOSPHERICS/components/unary/oxygen_generator.dm @@ -33,7 +33,7 @@ obj/machinery/atmospherics/unary/oxygen_generator if(!on) return 0 - var/total_moles = air_contents.total_moles() + var/total_moles = air_contents.total_moles if(total_moles < oxygen_content) var/current_heat_capacity = air_contents.heat_capacity() @@ -41,7 +41,7 @@ obj/machinery/atmospherics/unary/oxygen_generator var/added_oxygen = oxygen_content - total_moles air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen) - air_contents.oxygen += added_oxygen + air_contents.adjust_gas("oxygen", added_oxygen) if(network) network.update = 1 diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 64514b3ebf7..9506da2459c 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -45,7 +45,7 @@ return overlays.Cut() - + var/scrubber_icon = "scrubber" var/turf/T = get_turf(src) @@ -125,8 +125,8 @@ var/datum/gas_mixture/environment = loc.return_air() if(scrubbing) - if((environment.phoron>0.001) || (environment.carbon_dioxide>0.001) || (environment.trace_gases.len>0)) - var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() + if((environment.gas["phoron"]>0.001) || (environment.gas["carbon_dioxide"]>0.001) || (environment.gas["oxygen_agent_b"]>0.001) || (environment.gas["sleeping_agent"]>0.001)) + var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles //Take a gas sample var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) @@ -137,21 +137,17 @@ var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature if(scrub_Toxins) - filtered_out.phoron = removed.phoron - removed.phoron = 0 + filtered_out.gas["phoron"] = removed.gas["phoron"] + removed.gas["phoron"] = 0 if(scrub_CO2) - filtered_out.carbon_dioxide = removed.carbon_dioxide - removed.carbon_dioxide = 0 - - if(removed.trace_gases.len>0) - for(var/datum/gas/trace_gas in removed.trace_gases) - if(istype(trace_gas, /datum/gas/oxygen_agent_b)) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas - else if(istype(trace_gas, /datum/gas/sleeping_agent) && scrub_N2O) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas - + filtered_out.gas["carbon_dioxide"] = removed.gas["carbon_dioxide"] + removed.gas["carbon_dioxide"] = 0 + if(scrub_N2O) + filtered_out.gas["sleeping_agent"] = removed.gas["sleeping_agent"] + removed.gas["sleeping_agent"] = 0 + if(removed.gas["oxygen_agent_b"]) + filtered_out.gas["oxygen_agent_b"] = removed.gas["oxygen_agent_b"] + removed.gas["oxygen_agent_b"] = 0 //Remix the resulting gases air_contents.merge(filtered_out) @@ -165,7 +161,7 @@ if (air_contents.return_pressure()>=50*ONE_ATMOSPHERE) return - var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) + var/transfer_moles = environment.total_moles*(volume_rate/environment.volume) var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm index 168e5521b6e..0728ff1f4a3 100644 --- a/code/ATMOSPHERICS/datum_pipe_network.dm +++ b/code/ATMOSPHERICS/datum_pipe_network.dm @@ -8,10 +8,10 @@ datum/pipe_network //membership roster to go through for updates and what not var/update = 1 - var/datum/gas_mixture/air_transient = null + //var/datum/gas_mixture/air_transient = null New() - air_transient = new() + //air_transient = new() ..() @@ -70,135 +70,4 @@ datum/pipe_network gases += line_member.air proc/reconcile_air() - //Perfectly equalize all gases members instantly - - //Calculate totals from individual components - var/total_thermal_energy = 0 - var/total_heat_capacity = 0 - - air_transient.volume = 0 - - air_transient.oxygen = 0 - air_transient.nitrogen = 0 - air_transient.phoron = 0 - air_transient.carbon_dioxide = 0 - - - air_transient.trace_gases = list() - - for(var/datum/gas_mixture/gas in gases) - air_transient.volume += gas.volume - var/temp_heatcap = gas.heat_capacity() - total_thermal_energy += gas.temperature*temp_heatcap - total_heat_capacity += temp_heatcap - - air_transient.oxygen += gas.oxygen - air_transient.nitrogen += gas.nitrogen - air_transient.phoron += gas.phoron - air_transient.carbon_dioxide += gas.carbon_dioxide - - if(gas.trace_gases.len) - for(var/datum/gas/trace_gas in gas.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in air_transient.trace_gases - if(!corresponding) - corresponding = new trace_gas.type() - air_transient.trace_gases += corresponding - - corresponding.moles += trace_gas.moles - - if(air_transient.volume > 0) - - if(total_heat_capacity > 0) - air_transient.temperature = total_thermal_energy/total_heat_capacity - - //Allow air mixture to react - if(air_transient.react()) - update = 1 - - else - air_transient.temperature = 0 - - //Update individual gas_mixtures by volume ratio - for(var/datum/gas_mixture/gas in gases) - gas.oxygen = air_transient.oxygen*gas.volume/air_transient.volume - gas.nitrogen = air_transient.nitrogen*gas.volume/air_transient.volume - gas.phoron = air_transient.phoron*gas.volume/air_transient.volume - gas.carbon_dioxide = air_transient.carbon_dioxide*gas.volume/air_transient.volume - - gas.temperature = air_transient.temperature - - if(air_transient.trace_gases.len) - for(var/datum/gas/trace_gas in air_transient.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in gas.trace_gases - if(!corresponding) - corresponding = new trace_gas.type() - gas.trace_gases += corresponding - - corresponding.moles = trace_gas.moles*gas.volume/air_transient.volume - gas.update_values() - air_transient.update_values() - return 1 - -proc/equalize_gases(datum/gas_mixture/list/gases) - //Perfectly equalize all gases members instantly - - //Calculate totals from individual components - var/total_volume = 0 - var/total_thermal_energy = 0 - var/total_heat_capacity = 0 - - var/total_oxygen = 0 - var/total_nitrogen = 0 - var/total_phoron = 0 - var/total_carbon_dioxide = 0 - - var/list/total_trace_gases = list() - - for(var/datum/gas_mixture/gas in gases) - total_volume += gas.volume - var/temp_heatcap = gas.heat_capacity() - total_thermal_energy += gas.temperature*temp_heatcap - total_heat_capacity += temp_heatcap - - total_oxygen += gas.oxygen - total_nitrogen += gas.nitrogen - total_phoron += gas.phoron - total_carbon_dioxide += gas.carbon_dioxide - - if(gas.trace_gases.len) - for(var/datum/gas/trace_gas in gas.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in total_trace_gases - if(!corresponding) - corresponding = new trace_gas.type() - total_trace_gases += corresponding - - corresponding.moles += trace_gas.moles - - if(total_volume > 0) - - //Calculate temperature - var/temperature = 0 - - if(total_heat_capacity > 0) - temperature = total_thermal_energy/total_heat_capacity - - //Update individual gas_mixtures by volume ratio - for(var/datum/gas_mixture/gas in gases) - gas.oxygen = total_oxygen*gas.volume/total_volume - gas.nitrogen = total_nitrogen*gas.volume/total_volume - gas.phoron = total_phoron*gas.volume/total_volume - gas.carbon_dioxide = total_carbon_dioxide*gas.volume/total_volume - - gas.temperature = temperature - - if(total_trace_gases.len) - for(var/datum/gas/trace_gas in total_trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in gas.trace_gases - if(!corresponding) - corresponding = new trace_gas.type() - gas.trace_gases += corresponding - - corresponding.moles = trace_gas.moles*gas.volume/total_volume - gas.update_values() - - return 1 \ No newline at end of file + equalize_gases(gases) diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index b7444d00df8..4c3b191617e 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -37,22 +37,9 @@ datum/pipeline for(var/obj/machinery/atmospherics/pipe/member in members) member.air_temporary = new + member.air_temporary.copy_from(air) member.air_temporary.volume = member.volume - - member.air_temporary.oxygen = air.oxygen*member.volume/air.volume - member.air_temporary.nitrogen = air.nitrogen*member.volume/air.volume - member.air_temporary.phoron = air.phoron*member.volume/air.volume - member.air_temporary.carbon_dioxide = air.carbon_dioxide*member.volume/air.volume - - member.air_temporary.temperature = air.temperature - - if(air.trace_gases.len) - for(var/datum/gas/trace_gas in air.trace_gases) - var/datum/gas/corresponding = new trace_gas.type() - member.air_temporary.trace_gases += corresponding - - corresponding.moles = trace_gas.moles*member.volume/air.volume - member.air_temporary.update_values() + member.air_temporary.multiply(member.volume / air.volume) proc/build_pipeline(obj/machinery/atmospherics/pipe/base) air = new @@ -213,7 +200,7 @@ datum/pipeline air.temperature -= heat/total_heat_capacity if(network) network.update = 1 - + proc/radiate_heat(surface, thermal_conductivity) var/total_heat_capacity = air.heat_capacity() var/heat = STEFAN_BOLTZMANN_CONSTANT * surface * air.temperature ** 4 * thermal_conductivity diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index 7ee65162d76..6fca9cc2ca5 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -106,7 +106,7 @@ update_icon() /obj/machinery/atmospherics/pipe/add_underlay(var/obj/machinery/atmospherics/node, var/direction) - if(istype(src, /obj/machinery/atmospherics/pipe/tank)) //todo: move tanks to unary devices + if(istype(src, /obj/machinery/atmospherics/pipe/tank)) //todo: move tanks to unary devices return ..() if(node) @@ -157,7 +157,7 @@ /obj/machinery/atmospherics/pipe/simple/New() ..() - + // Pipe colors and icon states are handled by an image cache - so color and icon should // be null. For mapping purposes color is defined in the object definitions. icon = null @@ -473,7 +473,7 @@ overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core") overlays += icon_manager.get_atmos_icon("manifold", , , "clamps") underlays.Cut() - + var/list/directions = list(NORTH, SOUTH, EAST, WEST) directions -= dir @@ -678,7 +678,7 @@ overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way") overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way") underlays.Cut() - + var/list/directions = list(NORTH, SOUTH, EAST, WEST) directions -= add_underlay(node1) @@ -931,24 +931,13 @@ O << "\red [user] has used the analyzer on \icon[icon]" var/pressure = parent.air.return_pressure() - var/total_moles = parent.air.total_moles() + var/total_moles = parent.air.total_moles user << "\blue Results of analysis of \icon[icon]" if (total_moles>0) - var/o2_concentration = parent.air.oxygen/total_moles - var/n2_concentration = parent.air.nitrogen/total_moles - var/co2_concentration = parent.air.carbon_dioxide/total_moles - var/phoron_concentration = parent.air.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - user << "\blue Pressure: [round(pressure,0.1)] kPa" - user << "\blue Nitrogen: [round(n2_concentration*100)]%" - user << "\blue Oxygen: [round(o2_concentration*100)]%" - user << "\blue CO2: [round(co2_concentration*100)]%" - user << "\blue Phoron: [round(phoron_concentration*100)]%" - if(unknown_concentration>0.01) - user << "\red Unknown: [round(unknown_concentration*100)]%" + for(var/g in parent.air.gas) + user << "\blue [gas_data.name[g]]: [round((parent.air.gas[g] / total_moles) * 100)]%" user << "\blue Temperature: [round(parent.air.temperature-T0C)]°C" else user << "\blue Tank is empty!" @@ -962,10 +951,11 @@ air_temporary.volume = volume air_temporary.temperature = T20C - air_temporary.oxygen = (25*ONE_ATMOSPHERE*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) - air_temporary.nitrogen = (25*ONE_ATMOSPHERE*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + air_temporary.adjust_multi("oxygen", (25*ONE_ATMOSPHERE*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ + "nitrogen",(25*ONE_ATMOSPHERE*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - ..() + + ..() icon_state = "air" /obj/machinery/atmospherics/pipe/tank/oxygen @@ -977,7 +967,7 @@ air_temporary.volume = volume air_temporary.temperature = T20C - air_temporary.oxygen = (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + air_temporary.adjust_gas("oxygen", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) ..() icon_state = "o2" @@ -991,7 +981,7 @@ air_temporary.volume = volume air_temporary.temperature = T20C - air_temporary.nitrogen = (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + air_temporary.adjust_gas("nitrogen", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) ..() icon_state = "n2" @@ -1005,7 +995,7 @@ air_temporary.volume = volume air_temporary.temperature = T20C - air_temporary.carbon_dioxide = (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + air_temporary.adjust_gas("carbon_dioxide", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) ..() icon_state = "co2" @@ -1019,7 +1009,7 @@ air_temporary.volume = volume air_temporary.temperature = T20C - air_temporary.phoron = (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) + air_temporary.adjust_gas("phoron", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) ..() icon_state = "phoron" @@ -1033,10 +1023,7 @@ air_temporary.volume = volume air_temporary.temperature = T0C - var/datum/gas/sleeping_agent/trace_gas = new - trace_gas.moles = (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature) - - air_temporary.trace_gases += trace_gas + air_temporary.adjust_gas("sleeping_agent", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) ..() icon_state = "n2o" diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm b/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm index c31d6138dff..cd397e10958 100644 --- a/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm +++ b/code/WorkInProgress/Cael_Aislinn/Rust/core_field.dm @@ -140,20 +140,19 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //the amount of phoron pulled in each update is relative to the field strength, with 50T (max field strength) = 100% of area covered by the field //at minimum strength, 0.25% of the field volume is pulled in per update (?) //have a max of 1000 moles suspended - if(held_phoron.phoron < transfer_ratio * 1000) + if(held_phoron.gas["phoron"] < transfer_ratio * 1000) var/moles_covered = environment.return_pressure()*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION) //world << "\blue moles_covered: [moles_covered]" // var/datum/gas_mixture/gas_covered = environment.remove(moles_covered) var/datum/gas_mixture/phoron_captured = new /datum/gas_mixture() // - phoron_captured.phoron = round(gas_covered.phoron * transfer_ratio) + phoron_captured.gas["phoron"] = round(gas_covered.gas["phoron"] * transfer_ratio) //world << "\blue[phoron_captured.phoron] moles of phoron captured" phoron_captured.temperature = gas_covered.temperature phoron_captured.update_values() // - gas_covered.phoron -= phoron_captured.phoron - gas_covered.update_values() + gas_covered.adjust_gas("phoron", -phoron_captured.gas["phoron"]) // held_phoron.merge(phoron_captured) // @@ -171,7 +170,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //change held phoron temp according to energy levels //SPECIFIC_HEAT_TOXIN - if(mega_energy > 0 && held_phoron.phoron) + if(mega_energy > 0 && held_phoron.gas["phoron"]) var/heat_capacity = held_phoron.heat_capacity()//200 * number of phoron moles if(heat_capacity > 0.0003) //formerly MINIMUM_HEAT_CAPACITY held_phoron.temperature = (heat_capacity + mega_energy * 35000)/heat_capacity @@ -179,7 +178,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //if there is too much phoron in the field, lose some /*if( held_phoron.phoron > (MOLES_CELLSTANDARD * 7) * (50 / field_strength) ) LosePhoron()*/ - if(held_phoron.phoron > 1) + if(held_phoron.gas["phoron"] > 1) //lose a random amount of phoron back into the air, increased by the field strength (want to switch this over to frequency eventually) var/loss_ratio = rand() * (0.05 + (0.05 * 50 / field_strength)) //world << "lost [loss_ratio*100]% of held phoron" @@ -187,16 +186,16 @@ Deuterium-tritium fusion: 4.5 x 10^7 K var/datum/gas_mixture/phoron_lost = new phoron_lost.temperature = held_phoron.temperature // - phoron_lost.phoron = held_phoron.phoron * loss_ratio + phoron_lost.gas["phoron"] = held_phoron.gas["phoron"] * loss_ratio //phoron_lost.update_values() - held_phoron.phoron -= held_phoron.phoron * loss_ratio + held_phoron.gas["phoron"] -= held_phoron.gas["phoron"] * loss_ratio //held_phoron.update_values() // environment.merge(phoron_lost) radiation += loss_ratio * mega_energy * 0.1 mega_energy -= loss_ratio * mega_energy * 0.1 else - held_phoron.phoron = 0 + held_phoron.gas["phoron"] = null //held_phoron.update_values() //handle some reactants formatting diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index 481492e7e29..7fab5e94adc 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -86,7 +86,8 @@ Class Procs: /connection_edge/proc/tick() /connection_edge/proc/flow(list/movable, differential, repelled) - for(var/atom/movable/M in movable) + for(var/i = 1; i <= movable.len; i++) + var/atom/movable/M = movable[i] //If they're already being tossed, don't do it again. if(M.last_airflow > world.time - vsc.airflow_delay) continue @@ -156,7 +157,7 @@ Class Procs: return //air_master.equalize(A, B) - ShareRatio(A.air,B.air,coefficient) + A.air.share_ratio(B.air, coefficient) air_master.mark_zone_update(A) air_master.mark_zone_update(B) //world << "equalized." @@ -215,7 +216,7 @@ Class Procs: return //world << "[id]: Tick [air_master.current_cycle]: To [B]!" //A.air.mimic(B, coefficient) - ShareSpace(A.air,air,dbg_out) + A.air.share_space(air, dbg_out) air_master.mark_zone_update(A) var/differential = A.air.return_pressure() - air.return_pressure() @@ -224,196 +225,6 @@ Class Procs: var/list/attracted = A.movables() flow(attracted, abs(differential), differential < 0) -var/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66) - -proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) - //Shares a specific ratio of gas between mixtures using simple weighted averages. - var - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - ratio = sharing_lookup_table[6] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - size = max(1,A.group_multiplier) - share_size = max(1,B.group_multiplier) - - full_oxy = A.oxygen * size - full_nitro = A.nitrogen * size - full_co2 = A.carbon_dioxide * size - full_phoron = A.phoron * size - - full_heat_capacity = A.heat_capacity() * size - - s_full_oxy = B.oxygen * share_size - s_full_nitro = B.nitrogen * share_size - s_full_co2 = B.carbon_dioxide * share_size - s_full_phoron = B.phoron * share_size - - s_full_heat_capacity = B.heat_capacity() * share_size - - oxy_avg = (full_oxy + s_full_oxy) / (size + share_size) - nit_avg = (full_nitro + s_full_nitro) / (size + share_size) - co2_avg = (full_co2 + s_full_co2) / (size + share_size) - phoron_avg = (full_phoron + s_full_phoron) / (size + share_size) - - temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) - - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[connecting_tiles] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) - A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg ) - A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) - A.phoron = max(0, (A.phoron - phoron_avg) * (1-ratio) + phoron_avg ) - - A.temperature = max(0, (A.temperature - temp_avg) * (1-ratio) + temp_avg ) - - B.oxygen = max(0, (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) - B.nitrogen = max(0, (B.nitrogen - nit_avg) * (1-ratio) + nit_avg ) - B.carbon_dioxide = max(0, (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) - B.phoron = max(0, (B.phoron - phoron_avg) * (1-ratio) + phoron_avg ) - - B.temperature = max(0, (B.temperature - temp_avg) * (1-ratio) + temp_avg ) - - for(var/datum/gas/G in A.trace_gases) - var/datum/gas/H = locate(G.type) in B.trace_gases - if(H) - var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - else - H = new G.type - B.trace_gases += H - var/G_avg = (G.moles*size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - - for(var/datum/gas/G in B.trace_gases) - var/datum/gas/H = locate(G.type) in A.trace_gases - if(!H) - H = new G.type - A.trace_gases += H - var/G_avg = (G.moles*size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - - A.update_values() - B.update_values() - - if(A.compare(B)) return 1 - else return 0 - -proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) - //A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room. - if(!unsimulated_tiles) - return 0 - - var - unsim_oxygen = 0 - unsim_nitrogen = 0 - unsim_co2 = 0 - unsim_phoron = 0 - unsim_heat_capacity = 0 - unsim_temperature = 0 - - size = max(1,A.group_multiplier) - - var/tileslen - var/share_size - - if(istype(unsimulated_tiles, /datum/gas_mixture)) - var/datum/gas_mixture/avg_unsim = unsimulated_tiles - unsim_oxygen = avg_unsim.oxygen - unsim_co2 = avg_unsim.carbon_dioxide - unsim_nitrogen = avg_unsim.nitrogen - unsim_phoron = avg_unsim.phoron - unsim_temperature = avg_unsim.temperature - share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier) - tileslen = avg_unsim.group_multiplier - - if(dbg_output) - world << "O2: [unsim_oxygen] N2: [unsim_nitrogen] Size: [share_size] Tiles: [tileslen]" - - else if(istype(unsimulated_tiles, /list)) - if(!unsimulated_tiles.len) - return 0 - // We use the same size for the potentially single space tile - // as we use for the entire room. Why is this? - // Short answer: We do not want larger rooms to depressurize more - // slowly than small rooms, preserving our good old "hollywood-style" - // oh-shit effect when large rooms get breached, but still having small - // rooms remain pressurized for long enough to make escape possible. - share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len) - var/correction_ratio = share_size / unsimulated_tiles.len - - for(var/turf/T in unsimulated_tiles) - unsim_oxygen += T.oxygen - unsim_co2 += T.carbon_dioxide - unsim_nitrogen += T.nitrogen - unsim_phoron += T.phoron - unsim_temperature += T.temperature/unsimulated_tiles.len - - //These values require adjustment in order to properly represent a room of the specified size. - unsim_oxygen *= correction_ratio - unsim_co2 *= correction_ratio - unsim_nitrogen *= correction_ratio - unsim_phoron *= correction_ratio - tileslen = unsimulated_tiles.len - - else //invalid input type - return 0 - - unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_phoron) - - var - ratio = sharing_lookup_table[6] - - old_pressure = A.return_pressure() - - full_oxy = A.oxygen * size - full_nitro = A.nitrogen * size - full_co2 = A.carbon_dioxide * size - full_phoron = A.phoron * size - - full_heat_capacity = A.heat_capacity() * size - - oxy_avg = (full_oxy + unsim_oxygen*share_size) / (size + share_size) - nit_avg = (full_nitro + unsim_nitrogen*share_size) / (size + share_size) - co2_avg = (full_co2 + unsim_co2*share_size) / (size + share_size) - phoron_avg = (full_phoron + unsim_phoron*share_size) / (size + share_size) - - temp_avg = 0 - - if((full_heat_capacity + unsim_heat_capacity) > 0) - temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity) - - if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[tileslen] - - if(dbg_output) - world << "Ratio: [ratio]" - world << "Avg O2: [oxy_avg] N2: [nit_avg]" - - A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) - A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) - A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg ) - A.phoron = max(0, (A.phoron - phoron_avg) * (1 - ratio) + phoron_avg ) - - A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg ) - - for(var/datum/gas/G in A.trace_gases) - var/G_avg = (G.moles * size) / (size + share_size) - G.moles = (G.moles - G_avg) * (1 - ratio) + G_avg - - A.update_values() - - if(dbg_output) world << "Result: [abs(old_pressure - A.return_pressure())] kPa" - - return abs(old_pressure - A.return_pressure()) - - proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) //This implements a simplistic version of the Stefan-Boltzmann law. var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5 diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index cef6b068a84..756887cc09c 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -73,6 +73,7 @@ Class Procs: //Geometry updates lists /datum/controller/air_system/var/list/tiles_to_update = list() /datum/controller/air_system/var/list/zones_to_update = list() +/datum/controller/air_system/var/list/active_fire_zones = list() /datum/controller/air_system/var/list/active_hotspots = list() /datum/controller/air_system/var/active_zones = 0 @@ -171,9 +172,16 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun for(var/connection_edge/edge in edges) edge.tick() - //Process fires. + //Process fire zones. if(.) - tick_progress = "processing fire" + tick_progress = "processing fire zones" + + for(var/zone/Z in active_fire_zones) + Z.process_fire() + + //Process hotspots. + if(.) + tick_progress = "processing hotspots" for(var/obj/fire/fire in active_hotspots) fire.process() diff --git a/code/ZAS/Diagnostic.dm b/code/ZAS/Diagnostic.dm index 31deb69bc52..1d4cc1a3883 100644 --- a/code/ZAS/Diagnostic.dm +++ b/code/ZAS/Diagnostic.dm @@ -19,7 +19,8 @@ client/proc/Zone_Info(turf/T as null|turf) mob << "No zone here." var/datum/gas_mixture/mix = T.return_air() mob << "[mix.return_pressure()] kPa [mix.temperature]C" - mob << "O2: [mix.oxygen] N2: [mix.nitrogen] CO2: [mix.carbon_dioxide] TX: [mix.phoron]" + for(var/g in mix.gas) + mob << "[g]: [mix.gas[g]]\n" else if(zone_debug_images) for(var/zone in zone_debug_images) diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index 2d181dc6009..d8738d5fc5e 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -10,6 +10,7 @@ Attach to transfer valve and open. BOOM. */ +/turf/var/obj/fire/fire = null //Some legacy definitions so fires can be started. atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -34,12 +35,54 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) if(air_contents.check_combustability(liquid)) igniting = 1 - if(! (locate(/obj/fire) in src)) - - new /obj/fire(src,1000) - + create_fire(1000) return igniting +/zone/proc/process_fire() + if(!air.check_combustability()) + for(var/turf/simulated/T in fire_tiles) + if(istype(T.fire)) + T.fire.RemoveFire() + T.fire = null + fire_tiles.Cut() + + if(!fire_tiles.len) + air_master.active_fire_zones.Remove(src) + return + + var/datum/gas_mixture/burn_gas = air.remove_ratio(vsc.fire_consuption_rate, fire_tiles.len) + var/gm = burn_gas.group_multiplier + + burn_gas.group_multiplier = 1 + burn_gas.zburn(force_burn = 1, no_check = 1) + burn_gas.group_multiplier = gm + + air.merge(burn_gas) + + var/firelevel = air.calculate_firelevel() + + for(var/turf/T in fire_tiles) + if(T.fire) + T.fire.firelevel = firelevel + else + fire_tiles -= T + +/turf/proc/create_fire(fl) + return 0 + +/turf/simulated/create_fire(fl) + if(fire) + fire.firelevel = max(fl, fire.firelevel) + return 1 + + if(!zone) + return 1 + + fire = new(src, fl) + zone.fire_tiles |= src + air_master.active_fire_zones |= zone + return 0 + /obj/fire //Icon for fire on turfs. @@ -58,41 +101,14 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) /obj/fire/process() . = 1 - //get location and check if it is in a proper ZAS zone - var/turf/simulated/S = loc - - if(!istype(S)) - del src - return - - if(!S.zone) - del src - return - - var/datum/gas_mixture/air_contents = S.return_air() - //get liquid fuels on the ground. - var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S - //and the volatile stuff from the air - var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases - - //since the air is processed in fractions, we need to make sure not to have any minuscle residue or - //the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour - if(air_contents.oxygen < 0.1) - air_contents.oxygen = 0 - if(air_contents.phoron < 0.1) - air_contents.phoron = 0 - if(fuel) - if(fuel.moles < 0.1) - air_contents.trace_gases.Remove(fuel) - - //check if there is something to combust - if(!air_contents.check_combustability(liquid)) - //del src + var/turf/simulated/my_tile = loc + if(!istype(my_tile) || !my_tile.zone) + if(my_tile.fire == src) + my_tile.fire = null RemoveFire() - return + return 1 - //get a firelevel and set the icon - firelevel = air_contents.calculate_firelevel(liquid) + var/datum/gas_mixture/air_contents = my_tile.return_air() if(firelevel > 6) icon_state = "3" @@ -106,21 +122,26 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) //im not sure how to implement a version that works for every creature so for now monkeys are firesafe for(var/mob/living/carbon/human/M in loc) - M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans! + M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure()) //Burn the humans! - loc.fire_act(air_contents, air_contents.temperature, air_contents.return_volume()) + loc.fire_act(air_contents, air_contents.temperature, air_contents.volume) for(var/atom/A in loc) - A.fire_act(air_contents, air_contents.temperature, air_contents.return_volume()) + A.fire_act(air_contents, air_contents.temperature, air_contents.volume) + //spread for(var/direction in cardinal) - var/turf/simulated/enemy_tile = get_step(S, direction) + var/turf/simulated/enemy_tile = get_step(my_tile, direction) if(istype(enemy_tile)) - if(S.open_directions & direction) //Grab all valid bordering tiles - var/datum/gas_mixture/acs = enemy_tile.return_air() - var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile - if(!acs) continue - if(!acs.check_combustability(liq)) continue + if(my_tile.open_directions & direction) //Grab all valid bordering tiles + if(!enemy_tile.zone || enemy_tile.fire) + continue + + if(!enemy_tile.zone.fire_tiles.len) + var/datum/gas_mixture/acs = enemy_tile.return_air() + if(!acs || !acs.check_combustability()) + continue + //If extinguisher mist passed over the turf it's trying to spread to, don't spread and //reduce firelevel. if(enemy_tile.fire_protection > world.time-30) @@ -128,26 +149,11 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) continue //Spread the fire. - if(!(locate(/obj/fire) in enemy_tile)) - if( prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0)) - new/obj/fire(enemy_tile,firelevel) + if(prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && my_tile.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, my_tile, 0,0)) + enemy_tile.create_fire(firelevel) else - enemy_tile.adjacent_fire_act(loc, air_contents, air_contents.temperature, air_contents.return_volume()) - - //seperate part of the present gas - //this is done to prevent the fire burning all gases in a single pass - var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate) -///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR /////////////////////////////////////////////// - - if(flow) - //burn baby burn! - flow.zburn(liquid,1) - //merge the air back - S.assume_air(flow) - -///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on ////////////////////////////////////////////////////////////////// - + enemy_tile.adjacent_fire_act(loc, air_contents, air_contents.temperature, air_contents.volume) /obj/fire/New(newLoc,fl) ..() @@ -171,31 +177,29 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) ..() /obj/fire/proc/RemoveFire() - if (istype(loc, /turf/simulated)) + if (istype(loc, /turf)) SetLuminosity(0) loc = null air_master.active_hotspots.Remove(src) - turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again. turf/proc/apply_fire_protection() turf/simulated/apply_fire_protection() fire_protection = world.time -datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, force_burn) - var/value = 0 - - if((temperature > PHORON_MINIMUM_BURN_TEMPERATURE || force_burn) && check_recombustability(liquid)) +datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, force_burn, no_check = 0) + . = 0 + if((temperature > PHORON_MINIMUM_BURN_TEMPERATURE || force_burn) && (no_check ||check_recombustability(liquid))) var/total_fuel = 0 - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases + var/total_oxidizers = 0 - total_fuel += phoron - - if(fuel) - //Volatile Fuel - total_fuel += fuel.moles + for(var/g in gas) + if(gas_data.flags[g] & XGM_GAS_FUEL) + total_fuel += gas[g] + if(gas_data.flags[g] & XGM_GAS_OXIDIZER) + total_oxidizers += gas[g] if(liquid) //Liquid Fuel @@ -208,36 +212,29 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, forc return 0 //Calculate the firelevel. - var/firelevel = calculate_firelevel(liquid) + var/firelevel = calculate_firelevel(liquid, total_fuel, total_oxidizers, force = 1) //get the current inner energy of the gas mix //this must be taken here to prevent the addition or deletion of energy by a changing heat capacity var/starting_energy = temperature * heat_capacity() //determine the amount of oxygen used - var/total_oxygen = min(oxygen, 2 * total_fuel) + var/used_oxidizers = min(total_oxidizers, 2 * total_fuel) //determine the amount of fuel actually used - var/used_fuel_ratio = min(oxygen / 2 , total_fuel) / total_fuel + var/used_fuel_ratio = min(total_oxidizers / 2 , total_fuel) / total_fuel total_fuel = total_fuel * used_fuel_ratio - var/total_reactants = total_fuel + total_oxygen + var/total_reactants = total_fuel + used_oxidizers //determine the amount of reactants actually reacting - var/used_reactants_ratio = min( max(total_reactants * firelevel / vsc.fire_firelevel_multiplier, 0.2), total_reactants) / total_reactants + var/used_reactants_ratio = min(max(total_reactants * firelevel / vsc.fire_firelevel_multiplier, 0.2), total_reactants) / total_reactants //remove and add gasses as calculated - oxygen -= min(oxygen, total_oxygen * used_reactants_ratio ) + remove_by_flag(XGM_GAS_OXIDIZER, used_oxidizers * used_reactants_ratio) + remove_by_flag(XGM_GAS_FUEL, total_fuel * used_reactants_ratio * 3) - phoron -= min(phoron, (phoron * used_fuel_ratio * used_reactants_ratio ) * 3) - if(phoron < 0) - phoron = 0 - - carbon_dioxide += max(2 * total_fuel, 0) - - if(fuel) - fuel.moles -= (fuel.moles * used_fuel_ratio * used_reactants_ratio) * 5 //Fuel burns 5 times as quick - if(fuel.moles <= 0) del fuel + adjust_gas("carbon_dioxide", max(2 * total_fuel, 0)) if(liquid) liquid.amount -= (liquid.amount * used_fuel_ratio * used_reactants_ratio) * 5 // liquid fuel burns 5 times as quick @@ -248,64 +245,67 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, forc temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity() update_values() - value = total_reactants * used_reactants_ratio - return value + . = total_reactants * used_reactants_ratio datum/gas_mixture/proc/check_recombustability(obj/effect/decal/cleanable/liquid_fuel/liquid) - //this is a copy proc to continue a fire after its been started. + . = 0 + for(var/g in gas) + if(gas_data.flags[g] & XGM_GAS_OXIDIZER && gas[g] >= 0.1) + . = 1 + break - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases + if(!.) + return 0 - if(oxygen && (phoron || fuel || liquid)) - if(liquid) - return 1 - if(phoron >= 0.1) - return 1 - if(fuel && fuel.moles >= 0.1) - return 1 + if(liquid) + return 1 - return 0 + . = 0 + for(var/g in gas) + if(gas_data.flags[g] & XGM_GAS_FUEL && gas[g] >= 0.1) + . = 1 + break datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid) - //this check comes up very often and is thus centralized here to ease adding stuff + . = 0 + for(var/g in gas) + if(gas_data.flags[g] & XGM_GAS_OXIDIZER && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.1) + . = 1 + break - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases + if(!.) + return 0 - if(oxygen && (phoron || fuel || liquid)) - if(liquid) - return 1 - if(QUANTIZE(phoron * vsc.fire_consuption_rate) >= 0.1) - return 1 - if(fuel && QUANTIZE(fuel.moles * vsc.fire_consuption_rate) >= 0.1) - return 1 + if(liquid) + return 1 - return 0 + . = 0 + for(var/g in gas) + if(gas_data.flags[g] & XGM_GAS_FUEL && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.1) + . = 1 + break -datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid) +datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid, total_fuel = null, total_oxidizers = null, force = 0) //Calculates the firelevel based on one equation instead of having to do this multiple times in different areas. - - var/datum/gas/volatile_fuel/fuel = locate() in trace_gases - var/total_fuel = 0 var/firelevel = 0 - if(check_recombustability(liquid)) + if(force || check_recombustability(liquid)) + if(isnull(total_fuel)) + for(var/g in gas) + if(gas_data.flags[g] & XGM_GAS_FUEL) + total_fuel += gas[g] + if(gas_data.flags[g] & XGM_GAS_OXIDIZER) + total_oxidizers += gas[g] + if(liquid) + total_fuel += liquid.amount - total_fuel += phoron - - if(liquid) - total_fuel += liquid.amount - - if(fuel) - total_fuel += fuel.moles - - var/total_combustables = (total_fuel + oxygen) - - if(total_fuel > 0 && oxygen > 0) + var/total_combustables = (total_fuel + total_oxidizers) + if(total_combustables > 0) //slows down the burning when the concentration of the reactants is low - var/dampening_multiplier = total_combustables / (total_combustables + nitrogen + carbon_dioxide) + var/dampening_multiplier = total_combustables / total_moles //calculates how close the mixture of the reactants is to the optimum - var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ** 2))) + var/mix_multiplier = 1 / (1 + (5 * ((total_oxidizers / total_combustables) ** 2))) //toss everything together firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier diff --git a/code/ZAS/Gas.dm b/code/ZAS/Gas.dm new file mode 100644 index 00000000000..66a996457a7 --- /dev/null +++ b/code/ZAS/Gas.dm @@ -0,0 +1,45 @@ +/xgm_gas/oxygen + id = "oxygen" + name = "Oxygen" + specific_heat = 20 + + flags = XGM_GAS_OXIDIZER + +/xgm_gas/nitrogen + id = "nitrogen" + name = "Nitrogen" + specific_heat = 20 + +/xgm_gas/carbon_dioxide + id = "carbon_dioxide" + name = "Carbon Dioxide" + specific_heat = 30 + +/xgm_gas/phoron + id = "phoron" + name = "Phoron" + specific_heat = 200 + + tile_overlay = "phoron" + overlay_limit = 0.7 + flags = XGM_GAS_FUEL | XGM_GAS_CONTAMINANT + +/xgm_gas/volatile_fuel + id = "volatile_fuel" + name = "Volatile Fuel" + specific_heat = 30 + + flags = XGM_GAS_FUEL + +/xgm_gas/sleeping_agent + id = "sleeping_agent" + name = "Sleeping Agent" + specific_heat = 40 + + tile_overlay = "sleeping_agent" + overlay_limit = 1 + +/xgm_gas/oxygen_agent_b + id = "oxygen_agent_b" + name = "Oxygen Agent-B" + specific_heat = 300 diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index f96e47c188d..98ab1278257 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -111,7 +111,7 @@ obj/var/contaminated = 0 if(vsc.plc.GENETIC_CORRUPTION) if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION) randmutb(src) - src << "\red High levels of phoron cause you to spontaneously mutate." + src << "\red High levels of toxins cause you to spontaneously mutate." domutcheck(src,null) @@ -155,10 +155,11 @@ obj/var/contaminated = 0 turf/Entered(obj/item/I) . = ..() //Items that are in phoron, but not on a mob, can still be contaminated. - if(istype(I) && vsc.plc.CLOTH_CONTAMINATION) + if(istype(I) && vsc.plc.CLOTH_CONTAMINATION && I.can_contaminate()) var/datum/gas_mixture/env = return_air(1) if(!env) return - if(env.phoron > MOLES_PHORON_VISIBLE + 1) - if(I.can_contaminate()) - I.contaminate() \ No newline at end of file + for(var/g in env.gas) + if(gas_data.flags[g] & XGM_GAS_CONTAMINANT && env.gas[g] > gas_data.overlay_limit[g] + 1) + I.contaminate() + break diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index 35dc8f684eb..4e70e3b627f 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -6,12 +6,10 @@ /turf/var/datum/gas_mixture/air /turf/simulated/proc/set_graphic(new_graphic) - if(isnum(new_graphic)) - if(new_graphic == 1) new_graphic = plmaster - else if(new_graphic == 2) new_graphic = slmaster - if(gas_graphic) overlays -= gas_graphic - if(new_graphic) overlays += new_graphic gas_graphic = new_graphic + overlays.Cut() + for(var/i in gas_graphic) + overlays += i /turf/proc/update_air_properties() var/block = c_airblock(src) @@ -185,17 +183,15 @@ /turf/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air return 0 +/turf/proc/assume_gas(gasid, moles, temp = 0) + return 0 + /turf/return_air() //Create gas mixture to hold data for passing var/datum/gas_mixture/GM = new - GM.oxygen = oxygen - GM.carbon_dioxide = carbon_dioxide - GM.nitrogen = nitrogen - GM.phoron = phoron - + GM.adjust_multi("oxygen", oxygen, "carbon_dioxide", carbon_dioxide, "nitrogen", nitrogen, "phoron", phoron) GM.temperature = temperature - GM.update_values() return GM @@ -204,10 +200,10 @@ var/sum = oxygen + carbon_dioxide + nitrogen + phoron if(sum>0) - GM.oxygen = (oxygen/sum)*amount - GM.carbon_dioxide = (carbon_dioxide/sum)*amount - GM.nitrogen = (nitrogen/sum)*amount - GM.phoron = (phoron/sum)*amount + GM.gas["oxygen"] = (oxygen/sum)*amount + GM.gas["carbon_dioxide"] = (carbon_dioxide/sum)*amount + GM.gas["nitrogen"] = (nitrogen/sum)*amount + GM.gas["phoron"] = (phoron/sum)*amount GM.temperature = temperature GM.update_values() @@ -218,6 +214,16 @@ var/datum/gas_mixture/my_air = return_air() my_air.merge(giver) +/turf/simulated/assume_gas(gasid, moles, temp = null) + var/datum/gas_mixture/my_air = return_air() + + if(isnull(temp)) + my_air.adjust_gas(gasid, moles) + else + my_air.adjust_gas_temp(gasid, moles, temp) + + return 1 + /turf/simulated/remove_air(amount as num) var/datum/gas_mixture/my_air = return_air() return my_air.remove(amount) @@ -240,11 +246,11 @@ /turf/proc/make_air() air = new/datum/gas_mixture air.temperature = temperature - air.adjust(oxygen, carbon_dioxide, nitrogen, phoron) + air.adjust_multi("oxygen", oxygen, "carbon_dioxide", carbon_dioxide, "nitrogen", nitrogen, "phoron", phoron) air.group_multiplier = 1 air.volume = CELL_VOLUME /turf/simulated/proc/c_copy_air() if(!air) air = new/datum/gas_mixture air.copy_from(zone.air) - air.group_multiplier = 1 \ No newline at end of file + air.group_multiplier = 1 diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 2d285d08f6f..40c509bbd90 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -43,6 +43,7 @@ Class Procs: /zone/var/name /zone/var/invalid = 0 /zone/var/list/contents = list() +/zone/var/list/fire_tiles = list() /zone/var/needs_update = 0 @@ -67,6 +68,9 @@ Class Procs: add_tile_air(turf_air) T.zone = src contents.Add(T) + if(T.fire) + fire_tiles.Add(T) + air_master.active_fire_zones.Add(src) T.set_graphic(air.graphic) /zone/proc/remove(turf/simulated/T) @@ -77,6 +81,7 @@ Class Procs: soft_assert(T in contents, "Lists are weird broseph") #endif contents.Remove(T) + fire_tiles.Remove(T) T.zone = null T.set_graphic(0) if(contents.len) @@ -123,16 +128,16 @@ Class Procs: air.group_multiplier = contents.len+1 /zone/proc/tick() - air.archive() if(air.check_tile_graphic()) for(var/turf/simulated/T in contents) T.set_graphic(air.graphic) /zone/proc/dbg_data(mob/M) M << name - M << "O2: [air.oxygen] N2: [air.nitrogen] CO2: [air.carbon_dioxide] P: [air.phoron]" + for(var/g in air.gas) + M << "[gas_data.name[g]]: [air.gas[g]]" M << "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)" - M << "O2 per N2: [(air.nitrogen ? air.oxygen/air.nitrogen : "N/A")] Moles: [air.total_moles]" + M << "O2 per N2: [(air.gas["nitrogen"] ? air.gas["oxygen"]/air.gas["nitrogen"] : "N/A")] Moles: [air.total_moles]" M << "Simulated: [contents.len] ([air.group_multiplier])" //M << "Unsimulated: [unsimulated_contents.len]" //M << "Edges: [edges.len]" diff --git a/code/ZAS/_gas_mixture_xgm.dm b/code/ZAS/_gas_mixture_xgm.dm new file mode 100644 index 00000000000..a60fc0bc09d --- /dev/null +++ b/code/ZAS/_gas_mixture_xgm.dm @@ -0,0 +1,367 @@ +#define QUANTIZE(variable) (round(variable,0.0001)) + +/datum/gas_mixture + //Associative list of gas moles. + //Gases with 0 moles are not tracked and are pruned by update_values() + var/list/gas = list() + //Temperature in Kelvin of this gas mix. + var/temperature = 0 + + //Sum of all the gas moles in this mix. Updated by update_values() + var/total_moles = 0 + //Volume of this mix. + var/volume = CELL_VOLUME + //Size of the group this gas_mixture is representing. 1 for singletons. + var/group_multiplier = 1 + + //List of active tile overlays for this gas_mixture. Updated by check_tile_graphic() + var/list/graphic = list() + +//Takes a gas string, and the amount of moles to adjust by. Calls update_values() if update isn't 0. +/datum/gas_mixture/proc/adjust_gas(gasid, moles, update = 1) + if(moles == 0) + return + + gas[gasid] += moles + + if(update) + update_values() + +//Same as adjust_gas(), but takes a temperature which is mixed in with the gas. +/datum/gas_mixture/proc/adjust_gas_temp(gasid, moles, temp, update = 1) + if(moles == 0) + return + + if(moles > 0 && abs(temperature - temp) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity()*group_multiplier + var/giver_heat_capacity = gas_data.specific_heat[gasid] * moles + var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity + if(combined_heat_capacity != 0) + temperature = (temp * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity + + gas[gasid] += moles + + if(update) + update_values() + +//Variadic version of adjust_gas(). Takes any number of gas and mole pairs, and applies them. +/datum/gas_mixture/proc/adjust_multi() + ASSERT(!(args.len % 2)) + + for(var/i = 1; i < args.len; i += 2) + adjust_gas(args[i], args[i+1], update = 0) + + update_values() + +//Variadic version of adjust_gas_temp(). Takes any number of gas, mole, and temperature tuples, and applies them. +/datum/gas_mixture/proc/adjust_multi_temp() + ASSERT(!(args.len % 3)) + + for(var/i = 1; i < args.len; i += 3) + adjust_gas_temp(args[i], args[i + 1], args[i + 2], update = 0) + + update_values() + +//Merges all the gas from another mixture into this one. Respects group_multiplies and adjusts temperature correctly. +/datum/gas_mixture/proc/merge(datum/gas_mixture/giver) + if(!giver) + return + + if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity()*group_multiplier + var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier + var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity + if(combined_heat_capacity != 0) + temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity + + if((group_multiplier != 1)||(giver.group_multiplier != 1)) + for(var/g in giver.gas) + gas[g] += giver.gas[g] * giver.group_multiplier / group_multiplier + else + for(var/g in giver.gas) + gas[g] += giver.gas[g] + + update_values() + +//Returns the heat capacity of the gas mix based on the specific heat of the gases. +/datum/gas_mixture/proc/heat_capacity() + . = 0 + for(var/g in gas) + . += gas_data.specific_heat[g] * gas[g] + +//Updates the total_moles count and trims any empty gases. +/datum/gas_mixture/proc/update_values() + total_moles = 0 + for(var/g in gas) + if(gas[g] <= 0) + gas -= g + else + total_moles += gas[g] + +//Returns the pressure of the gas mix. Only accurate if there have been no gas modifications since update_values() has been called. +/datum/gas_mixture/proc/return_pressure() + if(volume) + return total_moles * R_IDEAL_GAS_EQUATION * temperature / volume + return 0 + +//Removes moles from the gas mixture and returns a gas_mixture containing the removed air. +/datum/gas_mixture/proc/remove(amount) + var/sum = total_moles + amount = min(amount, sum) //Can not take more air than tile has! + if(amount <= 0) + return null + + var/datum/gas_mixture/removed = new + + for(var/g in gas) + removed.gas[g] = QUANTIZE((gas[g] / sum) * amount) + gas[g] -= removed.gas[g] / group_multiplier + + removed.temperature = temperature + update_values() + removed.update_values() + + return removed + +//Removes a ratio of gas from the mixture and returns a gas_mixture containing the removed air. +/datum/gas_mixture/proc/remove_ratio(ratio, out_group_multiplier = 1) + if(ratio <= 0) + return null + out_group_multiplier = max(1, min(group_multiplier, out_group_multiplier)) + + ratio = min(ratio, 1) + + var/datum/gas_mixture/removed = new + removed.group_multiplier = out_group_multiplier + + for(var/g in gas) + removed.gas[g] = QUANTIZE(gas[g] * ratio) + gas[g] = ((gas[g] * group_multiplier) - (removed.gas[g] * out_group_multiplier)) / group_multiplier + + removed.temperature = temperature + update_values() + removed.update_values() + + return removed + +//Removes moles from the gas mixture, limited by a given flag. Returns a gax_mixture containing the removed air. +/datum/gas_mixture/proc/remove_by_flag(flag, amount) + if(!flag || amount <= 0) + return + + var/sum = 0 + for(var/g in gas) + if(gas_data.flags[g] & flag) + sum += gas[g] + + var/datum/gas_mixture/removed = new + + for(var/g in gas) + if(gas_data.flags[g] & flag) + removed.gas[g] = QUANTIZE((gas[g] / sum) * amount) + gas[g] -= removed.gas[g] / group_multiplier + + removed.temperature = temperature + update_values() + removed.update_values() + + return removed + +//Copies gas and temperature from another gas_mixture. +/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample) + gas = sample.gas.Copy() + temperature = sample.temperature + + update_values() + + return 1 + +//Checks if we are within acceptable range of another gas_mixture to suspend processing. +/datum/gas_mixture/proc/compare(datum/gas_mixture/sample) + if(!sample) return 0 + + var/list/marked = list() + for(var/g in gas) + if((abs(gas[g] - sample.gas[g]) > MINIMUM_AIR_TO_SUSPEND) && \ + ((gas[g] < (1 - MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.gas[g]) || \ + (gas[g] > (1 + MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.gas[g]))) + return 0 + marked[g] = 1 + + for(var/g in sample.gas) + if(!marked[g]) + if((abs(gas[g] - sample.gas[g]) > MINIMUM_AIR_TO_SUSPEND) && \ + ((gas[g] < (1 - MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.gas[g]) || \ + (gas[g] > (1 + MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.gas[g]))) + return 0 + + if(total_moles > MINIMUM_AIR_TO_SUSPEND) + if((abs(temperature - sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \ + ((temperature < (1 - MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || \ + (temperature > (1 + MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature))) + return 0 + + return 1 + +/datum/gas_mixture/proc/react(atom/dump_location) + zburn(null) + +//Rechecks the gas_mixture and adjusts the graphic list if needed. +/datum/gas_mixture/proc/check_tile_graphic() + //List of new overlays that weren't valid before. + var/list/graphic_add = null + //List of overlays that need to be removed now that they're not valid. + var/list/graphic_remove = null + + for(var/g in gas_data.overlay_limit) + if(graphic.Find(gas_data.tile_overlay[g])) + //Overlay is already applied for this gas, check if it's still valid. + if(gas[g] <= gas_data.overlay_limit[g]) + if(!graphic_remove) + graphic_remove = list() + graphic_remove += gas_data.tile_overlay[g] + else + //Overlay isn't applied for this gas, check if it's valid and needs to be added. + if(gas[g] > gas_data.overlay_limit[g]) + if(!graphic_add) + graphic_add = list() + graphic_add += gas_data.tile_overlay[g] + + . = 0 + //Apply changes + if(graphic_add && graphic_add.len) + graphic += graphic_add + . = 1 + if(graphic_remove && graphic_remove.len) + graphic -= graphic_remove + . = 1 + +//Simpler version of merge(), adjusts gas amounts directly and doesn't account for temperature or group_multiplier. +/datum/gas_mixture/proc/add(datum/gas_mixture/right_side) + for(var/g in right_side.gas) + gas[g] += right_side.gas[g] + + update_values() + return 1 + +//Simpler version of remove(), adjusts gas amounts directly and doesn't account for group_multiplier. +/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side) + for(var/g in right_side.gas) + gas[g] -= right_side.gas[g] + + update_values() + return 1 + +//Multiply all gas amounts by a factor. +/datum/gas_mixture/proc/multiply(factor) + for(var/g in gas) + gas[g] *= factor + + update_values() + return 1 + +//Divide all gas amounts by a factor. +/datum/gas_mixture/proc/divide(factor) + for(var/g in gas) + gas[g] /= factor + + update_values() + return 1 + +//Shares gas with another gas_mixture based on the amount of connecting tiles and a fixed lookup table. +/datum/gas_mixture/proc/share_ratio(datum/gas_mixture/other, connecting_tiles, share_size = null) + var/static/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66) + //Shares a specific ratio of gas between mixtures using simple weighted averages. + var/ratio = sharing_lookup_table[6] + + var/size = max(1, group_multiplier) + if(isnull(share_size)) share_size = max(1, other.group_multiplier) + + var/list/full_gas = list() + for(var/g in gas) + full_gas[g] = gas[g] * size + + var/full_heat_capacity = heat_capacity() * size + + var/list/s_full_gas = list() + for(var/g in other.gas) + s_full_gas[g] = other.gas[g] * share_size + + var/s_full_heat_capacity = other.heat_capacity() * share_size + + var/list/avg_gas = list() + + for(var/g in full_gas) + avg_gas[g] = (full_gas[g] + s_full_gas[g]) / (size + share_size) + + for(var/g in s_full_gas) + if(avg_gas[g] == null) + avg_gas[g] = (full_gas[g] + s_full_gas[g]) / (size + share_size) + + var/temp_avg = 0 + if(full_heat_capacity + s_full_heat_capacity) + temp_avg = (temperature * full_heat_capacity + other.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) + + //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD. + if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. + ratio = sharing_lookup_table[connecting_tiles] + //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD + + for(var/g in avg_gas) + gas[g] = max(0, (gas[g] - avg_gas[g]) * (1 - ratio) + avg_gas[g]) + other.gas[g] = max(0, (other.gas[g] - avg_gas[g]) * (1 - ratio) + avg_gas[g]) + + temperature = max(0, (temperature - temp_avg) * (1-ratio) + temp_avg) + other.temperature = max(0, (other.temperature - temp_avg) * (1-ratio) + temp_avg) + + update_values() + other.update_values() + + if(compare(other)) return 1 + else return 0 + +//A wrapper around share_ratio for spacing gas at the same rate as if it were going into a large airless room. +/datum/gas_mixture/proc/share_space(datum/gas_mixture/unsim_air) + if(!unsim_air) + return 0 + + var/old_pressure = return_pressure() + + share_ratio(unsim_air, unsim_air.group_multiplier, max(1, max(group_multiplier + 3, 1) + unsim_air.group_multiplier)) + + return abs(old_pressure - return_pressure()) + +//Equalizes a list of gas mixtures. Used for pipe networks. +/proc/equalize_gases(datum/gas_mixture/list/gases) + //Calculate totals from individual components + var/total_volume = 0 + var/total_thermal_energy = 0 + var/total_heat_capacity = 0 + + var/list/total_gas = list() + for(var/datum/gas_mixture/gasmix in gases) + total_volume += gasmix.volume + var/temp_heatcap = gasmix.heat_capacity() + total_thermal_energy += gasmix.temperature * temp_heatcap + total_heat_capacity += temp_heatcap + for(var/g in gasmix.gas) + total_gas[g] += gasmix.gas[g] + + if(total_volume > 0) + //Average out the gases + for(var/g in total_gas) + total_gas[g] /= total_volume + + //Calculate temperature + var/temperature = 0 + + if(total_heat_capacity > 0) + temperature = total_thermal_energy / total_heat_capacity + + //Update individual gas_mixtures + for(var/datum/gas_mixture/gasmix in gases) + gasmix.gas = total_gas.Copy() + gasmix.temperature = temperature + gasmix.multiply(gasmix.volume) + + return 1 diff --git a/code/ZAS/_xgm_gas_data.dm b/code/ZAS/_xgm_gas_data.dm new file mode 100644 index 00000000000..ee33a4d57f3 --- /dev/null +++ b/code/ZAS/_xgm_gas_data.dm @@ -0,0 +1,42 @@ +/var/xgm_gas_data/gas_data + +/xgm_gas_data + //Simple list of all the gas IDs. + var/list/gases = list() + //The friendly, human-readable name for the gas. + var/list/name = list() + //Specific heat of the gas. Used for calculating heat capacity. + var/list/specific_heat = list() + //Tile overlays. /images, created from references to 'icons/effects/tile_effects.dmi' + var/list/tile_overlay = list() + //Overlay limits. There must be at least this many moles for the overlay to appear. + var/list/overlay_limit = list() + //Flags. + var/list/flags = list() + +/xgm_gas + var/id = "" + var/name = "Unnamed Gas" + var/specific_heat = 20 + + var/tile_overlay = null + var/overlay_limit = null + + var/flags = 0 + +/hook/startup/proc/generateGasData() + gas_data = new + for(var/p in (typesof(/xgm_gas) - /xgm_gas)) + var/xgm_gas/gas = new p + + if(gas.id in gas_data.gases) + error("Duplicate gas id `[gas.id]` in `[p]`") + + gas_data.gases += gas.id + gas_data.name[gas.id] = gas.name + gas_data.specific_heat[gas.id] = gas.specific_heat + if(gas.tile_overlay) gas_data.tile_overlay[gas.id] = image('icons/effects/tile_effects.dmi', gas.tile_overlay, FLY_LAYER) + if(gas.overlay_limit) gas_data.overlay_limit[gas.id] = gas.overlay_limit + gas_data.flags[gas.id] = gas.flags + + return 1 diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 996ea857acf..c733d1ad35e 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -276,7 +276,7 @@ var/list/nicename = null var/list/tankcheck = null var/breathes = "oxygen" //default, we'll check later - var/list/contents = list() + var/list/contents = list() if(ishuman(C)) var/mob/living/carbon/human/H = C @@ -284,7 +284,7 @@ nicename = list ("suit", "back", "belt", "right hand", "left hand", "left pocket", "right pocket") tankcheck = list (H.s_store, C.back, H.belt, C.r_hand, C.l_hand, H.l_store, H.r_store) - else + else nicename = list("Right Hand", "Left Hand", "Back") tankcheck = list(C.r_hand, C.l_hand, C.back) @@ -295,30 +295,30 @@ if (!isnull(t.manipulated_by) && t.manipulated_by != C.real_name && findtext(t.desc,breathes)) contents.Add(t.air_contents.total_moles) //Someone messed with the tank and put unknown gasses continue //in it, so we're going to believe the tank is what it says it is - switch(breathes) + switch(breathes) //These tanks we're sure of their contents if("nitrogen") //So we're a bit more picky about them. - - if(t.air_contents.nitrogen && !t.air_contents.oxygen) - contents.Add(t.air_contents.nitrogen) + + if(t.air_contents.gas["nitrogen"] && !t.air_contents.gas["oxygen"]) + contents.Add(t.air_contents.gas["nitrogen"]) else - contents.Add(0) + contents.Add(0) if ("oxygen") - if(t.air_contents.oxygen && !t.air_contents.phoron) - contents.Add(t.air_contents.oxygen) + if(t.air_contents.gas["oxygen"] && !t.air_contents.gas["phoron"]) + contents.Add(t.air_contents.gas["oxygen"]) else contents.Add(0) // No races breath this, but never know about downstream servers. if ("carbon dioxide") - if(t.air_contents.carbon_dioxide && !t.air_contents.phoron) - contents.Add(t.air_contents.carbon_dioxide) + if(t.air_contents.gas["carbon_dioxide"] && !t.air_contents.gas["phoron"]) + contents.Add(t.air_contents.gas["carbon_dioxide"]) else contents.Add(0) - - - else + + + else //no tank so we set contents to 0 contents.Add(0) @@ -328,19 +328,19 @@ var/bestcontents = 0 for(var/i=1, i < contents.len + 1 , ++i) if(!contents[i]) - continue + continue if(contents[i] > bestcontents) best = i bestcontents = contents[i] - - + + //We've determined the best container now we set it as our internals if(best) C << "You are now running on internals from [tankcheck[best]] on your [nicename[best]]." C.internal = tankcheck[best] - - + + if(C.internal) if(C.internals) C.internals.icon_state = "internal1" diff --git a/code/controllers/lighting_controller.dm b/code/controllers/lighting_controller.dm index 3d4f859efaf..a938586e241 100644 --- a/code/controllers/lighting_controller.dm +++ b/code/controllers/lighting_controller.dm @@ -16,6 +16,8 @@ datum/controller/lighting var/list/changed_turfs = list() var/changed_turfs_workload_max = 0 + var/list/changed_areas = list() + datum/controller/lighting/New() lighting_states = max( 0, length(icon_states(LIGHTING_ICON))-1 ) if(lighting_controller != src) @@ -53,9 +55,18 @@ datum/controller/lighting/proc/process() for(var/i=1, i<=changed_turfs.len, i++) var/turf/T = changed_turfs[i] if(T && T.lighting_changed) + changed_areas |= T.loc T.shift_to_subarea() changed_turfs.Cut() // reset the changed list + for(var/i = 1; i <= changed_areas.len, i++) + var/area/A = changed_areas[i] + if(A.master != A && !A.contents.len) + A.related -= A + active_areas -= A + all_areas -= A + changed_areas.Cut() + process_cost = (world.timeofday - started) sleep(processing_interval) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 0b314a25312..cf9214079dc 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -292,7 +292,8 @@ datum/controller/game_controller/proc/process_machines_power() var/area/A = active_areas[i] if(A.powerupdate && A.master == A) A.powerupdate -= 1 - for(var/area/SubArea in A.related) + for(var/j = 1; j <= A.related.len; j++) + var/area/SubArea = A.related[j] for(var/obj/machinery/M in SubArea) if(M) if(M.use_power) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index a331dab556c..b4ff1ed7ca8 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -48,7 +48,7 @@ message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") return -/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller")) +/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -100,5 +100,8 @@ if("Transfer Controller") debug_variables(transfer_controller) feedback_add_details("admin_verb","DAutovoter") + if("Gas Data") + debug_variables(gas_data) + feedback_add_details("admin_verv","DGasdata") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index fa97b27f2fb..7d6628b5733 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -164,7 +164,7 @@ icon_state = "beartrap[armed]" user << "[src] is now [armed ? "armed" : "disarmed"]" -/obj/item/weapon/legcuffs/beartrap/HasEntered(AM as mob|obj) +/obj/item/weapon/legcuffs/beartrap/Crossed(AM as mob|obj) if(armed) if(ishuman(AM)) if(isturf(src.loc)) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 05a52137cc0..630746304f5 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -70,9 +70,6 @@ /atom/proc/CheckExit() return 1 -/atom/proc/HasEntered(atom/movable/AM as mob|obj) - return - /atom/proc/HasProximity(atom/movable/AM as mob|obj) return diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 9334e0f8d63..bf2124ebb54 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -1,57 +1,57 @@ -/obj/structure/cult - density = 1 - anchored = 1 - icon = 'icons/obj/cult.dmi' - -/obj/structure/cult/talisman - name = "Altar" - desc = "A bloodstained altar dedicated to Nar-Sie" - icon_state = "talismanaltar" - - -/obj/structure/cult/forge - name = "Daemon forge" - desc = "A forge used in crafting the unholy weapons used by the armies of Nar-Sie" - icon_state = "forge" - -/obj/structure/cult/pylon - name = "Pylon" - desc = "A floating crystal that hums with an unearthly energy" - icon_state = "pylon" - luminosity = 5 - - -/obj/structure/cult/tome - name = "Desk" - desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl" - icon_state = "tomealtar" -// luminosity = 5 - -//sprites for this no longer exist -Pete -//(they were stolen from another game anyway) -/* -/obj/structure/cult/pillar - name = "Pillar" - desc = "This should not exist" - icon_state = "pillar" - icon = 'magic_pillar.dmi' -*/ - -/obj/effect/gateway - name = "gateway" - desc = "You're pretty sure that abyss is staring back" - icon = 'icons/obj/cult.dmi' - icon_state = "hole" - density = 1 - unacidable = 1 - anchored = 1.0 - -/obj/effect/gateway/Bumped(mob/M as mob|obj) - spawn(0) - return - return - -/obj/effect/gateway/HasEntered(AM as mob|obj) - spawn(0) - return +/obj/structure/cult + density = 1 + anchored = 1 + icon = 'icons/obj/cult.dmi' + +/obj/structure/cult/talisman + name = "Altar" + desc = "A bloodstained altar dedicated to Nar-Sie" + icon_state = "talismanaltar" + + +/obj/structure/cult/forge + name = "Daemon forge" + desc = "A forge used in crafting the unholy weapons used by the armies of Nar-Sie" + icon_state = "forge" + +/obj/structure/cult/pylon + name = "Pylon" + desc = "A floating crystal that hums with an unearthly energy" + icon_state = "pylon" + luminosity = 5 + + +/obj/structure/cult/tome + name = "Desk" + desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl" + icon_state = "tomealtar" +// luminosity = 5 + +//sprites for this no longer exist -Pete +//(they were stolen from another game anyway) +/* +/obj/structure/cult/pillar + name = "Pillar" + desc = "This should not exist" + icon_state = "pillar" + icon = 'magic_pillar.dmi' +*/ + +/obj/effect/gateway + name = "gateway" + desc = "You're pretty sure that abyss is staring back" + icon = 'icons/obj/cult.dmi' + icon_state = "hole" + density = 1 + unacidable = 1 + anchored = 1.0 + +/obj/effect/gateway/Bumped(mob/M as mob|obj) + spawn(0) + return + return + +/obj/effect/gateway/Crossed(AM as mob|obj) + spawn(0) + return return \ No newline at end of file diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm index 2a7d35b4a5c..51b19f131b3 100644 --- a/code/game/gamemodes/events/ninja_equipment.dm +++ b/code/game/gamemodes/events/ninja_equipment.dm @@ -315,24 +315,15 @@ ________________________________________________________________________________ var/datum/gas_mixture/environment = T.return_air() var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() + var/total_moles = environment.total_moles dat += "Air Pressure: [round(pressure,0.1)] kPa" if (total_moles) - var/o2_level = environment.oxygen/total_moles - var/n2_level = environment.nitrogen/total_moles - var/co2_level = environment.carbon_dioxide/total_moles - var/phoron_level = environment.phoron/total_moles - var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) dat += "" - if(unknown_level > 0.01) - dat += "OTHER: [round(unknown_level)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C" if(2) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 5112a51187c..3d1f8140948 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -557,7 +557,7 @@ datum/objective/steal for(var/obj/item/I in all_items) //Check for phoron tanks if(istype(I, steal_target)) - found_amount += (target_name=="28 moles of phoron (full tank)" ? (I:air_contents:phoron) : (I:amount)) + found_amount += (target_name=="28 moles of phoron (full tank)" ? (I:air_contents:gas["phoron"]) : (I:amount)) return found_amount>=target_amount if("50 coins (in bag)") diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 76139556270..2a7ef4800f3 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -198,23 +198,24 @@ gas = location.remove_air(0.25*environment.total_moles) if(gas) var/heat_capacity = gas.heat_capacity() - var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE) + if(heat_capacity) + var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE) - //Use power. Assuming that each power unit represents 1 watts.... - use_power(energy_used, ENVIRON) + //Use power. Assuming that each power unit represents 1 watts.... + use_power(energy_used, ENVIRON) - //We need to cool ourselves. - if(environment.temperature > target_temperature) - gas.temperature -= energy_used/heat_capacity - else - gas.temperature += energy_used/heat_capacity + //We need to cool ourselves. + if(environment.temperature > target_temperature) + gas.temperature -= energy_used/heat_capacity + else + gas.temperature += energy_used/heat_capacity - environment.merge(gas) + environment.merge(gas) - if(abs(environment.temperature - target_temperature) <= 0.5) - regulating_temperature = 0 - visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\ - "You hear a click as a faint electronic humming stops.") + if(abs(environment.temperature - target_temperature) <= 0.5) + regulating_temperature = 0 + visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\ + "You hear a click as a faint electronic humming stops.") var/old_level = danger_level var/old_pressurelevel = pressure_dangerlevel @@ -256,23 +257,23 @@ var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume var/environment_pressure = environment.return_pressure() - var/other_moles = 0.0 - for(var/datum/gas/G in environment.trace_gases) - other_moles+=G.moles + //var/other_moles = 0.0 + ////for(var/datum/gas/G in environment.trace_gases) + // other_moles+=G.moles pressure_dangerlevel = get_danger_level(environment_pressure, TLV["pressure"]) - oxygen_dangerlevel = get_danger_level(environment.oxygen*partial_pressure, TLV["oxygen"]) - co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, TLV["carbon dioxide"]) - phoron_dangerlevel = get_danger_level(environment.phoron*partial_pressure, TLV["phoron"]) + oxygen_dangerlevel = get_danger_level(environment.gas["oxygen"]*partial_pressure, TLV["oxygen"]) + co2_dangerlevel = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, TLV["carbon dioxide"]) + phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, TLV["phoron"]) temperature_dangerlevel = get_danger_level(environment.temperature, TLV["temperature"]) - other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"]) + //other_dangerlevel = get_danger_level(other_moles*partial_pressure, TLV["other"]) return max( pressure_dangerlevel, oxygen_dangerlevel, co2_dangerlevel, phoron_dangerlevel, - other_dangerlevel, + //other_dangerlevel, temperature_dangerlevel ) @@ -661,7 +662,7 @@ /obj/machinery/alarm/proc/return_status() var/turf/location = get_turf(src) var/datum/gas_mixture/environment = location.return_air() - var/total = environment.oxygen + environment.carbon_dioxide + environment.phoron + environment.nitrogen + var/total = environment.total_moles var/output = "Air Status:
" if(total == 0) @@ -683,22 +684,22 @@ var/pressure_dangerlevel = get_danger_level(environment_pressure, current_settings) current_settings = TLV["oxygen"] - var/oxygen_dangerlevel = get_danger_level(environment.oxygen*partial_pressure, current_settings) - var/oxygen_percent = round(environment.oxygen / total * 100, 2) + var/oxygen_dangerlevel = get_danger_level(environment.gas["oxygen"]*partial_pressure, current_settings) + var/oxygen_percent = round(environment.gas["oxygen"] / total * 100, 2) current_settings = TLV["carbon dioxide"] - var/co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, current_settings) - var/co2_percent = round(environment.carbon_dioxide / total * 100, 2) + var/co2_dangerlevel = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, current_settings) + var/co2_percent = round(environment.gas["carbon_dioxide"] / total * 100, 2) current_settings = TLV["phoron"] - var/phoron_dangerlevel = get_danger_level(environment.phoron*partial_pressure, current_settings) - var/phoron_percent = round(environment.phoron / total * 100, 2) + var/phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, current_settings) + var/phoron_percent = round(environment.gas["phoron"] / total * 100, 2) - current_settings = TLV["other"] - var/other_moles = 0.0 - for(var/datum/gas/G in environment.trace_gases) - other_moles+=G.moles - var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, current_settings) + //current_settings = TLV["other"] + //var/other_moles = 0.0 + //for(var/datum/gas/G in environment.trace_gases) + // other_moles+=G.moles + //var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, current_settings) current_settings = TLV["temperature"] var/temperature_dangerlevel = get_danger_level(environment.temperature, current_settings) @@ -709,10 +710,10 @@ Oxygen: [oxygen_percent]%
Carbon dioxide: [co2_percent]%
Toxins: [phoron_percent]%
"} - if (other_dangerlevel==2) - output += "Notice: High Concentration of Unknown Particles Detected
" - else if (other_dangerlevel==1) - output += "Notice: Low Concentration of Unknown Particles Detected
" + //if (other_dangerlevel==2) + // output += "Notice: High Concentration of Unknown Particles Detected
" + //else if (other_dangerlevel==1) + // output += "Notice: Low Concentration of Unknown Particles Detected
" output += "Temperature: [environment.temperature]K ([round(environment.temperature - T0C, 0.1)]C)
" diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index d803f49657a..a1ca9bc4293 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -40,16 +40,16 @@ obj/machinery/air_sensor signal.data["temperature"] = round(air_sample.temperature,0.1) if(output>4) - var/total_moles = air_sample.total_moles() + var/total_moles = air_sample.total_moles if(total_moles > 0) if(output&4) - signal.data["oxygen"] = round(100*air_sample.oxygen/total_moles,0.1) + signal.data["oxygen"] = round(100*air_sample.gas["oxygen"]/total_moles,0.1) if(output&8) - signal.data["phoron"] = round(100*air_sample.phoron/total_moles,0.1) + signal.data["phoron"] = round(100*air_sample.gas["phoron"]/total_moles,0.1) if(output&16) - signal.data["nitrogen"] = round(100*air_sample.nitrogen/total_moles,0.1) + signal.data["nitrogen"] = round(100*air_sample.gas["nitrogen"]/total_moles,0.1) if(output&32) - signal.data["carbon_dioxide"] = round(100*air_sample.carbon_dioxide/total_moles,0.1) + signal.data["carbon_dioxide"] = round(100*air_sample.gas["carbon_dioxide"]/total_moles,0.1) else signal.data["oxygen"] = 0 signal.data["phoron"] = 0 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 96152823cab..6f8911810f1 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -88,9 +88,9 @@ update_flag src.overlays = 0 src.icon_state = text("[]-1", src.canister_color) - if(icon_state != "[canister_color]") + if(icon_state != "[canister_color]") icon_state = "[canister_color]" - + if(check_change()) //Returns 1 if no change needed to icons. return @@ -227,10 +227,10 @@ update_flag return ..() - + nanomanager.update_uis(src) // Update all NanoUIs attached to src - - + + /obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob) return src.attack_hand(user) @@ -255,8 +255,8 @@ update_flag data["minReleasePressure"] = round(ONE_ATMOSPHERE/10) data["maxReleasePressure"] = round(10*ONE_ATMOSPHERE) data["valveOpen"] = valve_open ? 1 : 0 - - data["hasHoldingTank"] = holding ? 1 : 0 + + data["hasHoldingTank"] = holding ? 1 : 0 if (holding) data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure())) @@ -330,18 +330,17 @@ update_flag src.canister_color = colors[label] src.icon_state = colors[label] src.name = "Canister: [label]" - + src.add_fingerprint(usr) update_icon() - + return 1 /obj/machinery/portable_atmospherics/canister/phoron/New() ..() - src.air_contents.phoron = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.update_values() + src.air_contents.adjust_gas("phoron", (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) src.update_icon() return 1 @@ -350,8 +349,7 @@ update_flag ..() - src.air_contents.oxygen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.update_values() + src.air_contents.adjust_gas("oxygen", (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) src.update_icon() return 1 @@ -359,10 +357,7 @@ update_flag ..() - var/datum/gas/sleeping_agent/trace_gas = new - air_contents.trace_gases += trace_gas - trace_gas.moles = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.update_values() + air_contents.adjust_gas("sleeping_agent", (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) src.update_icon() return 1 @@ -370,8 +365,7 @@ update_flag //Dirty way to fill room with gas. However it is a bit easier to do than creating some floor/engine/n2o -rastaf0 /obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller/New() ..() - var/datum/gas/sleeping_agent/trace_gas = air_contents.trace_gases[1] - trace_gas.moles = 9*4000 + air_contents.gas["sleeping_agent"] = 9*4000 spawn(10) var/turf/simulated/location = src.loc if (istype(src.loc)) @@ -385,8 +379,7 @@ update_flag ..() - src.air_contents.nitrogen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.update_values() + src.air_contents.adjust_gas("nitrogen", (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) src.update_icon() return 1 @@ -394,19 +387,14 @@ update_flag /obj/machinery/portable_atmospherics/canister/carbon_dioxide/New() ..() - src.air_contents.carbon_dioxide = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.update_values() - - src.update_icon() + src.air_contents.adjust_gas("carbon_dioxide", (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) return 1 /obj/machinery/portable_atmospherics/canister/air/New() ..() - src.air_contents.oxygen = (O2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - src.air_contents.nitrogen = (N2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.update_values() + src.air_contents.adjust_multi("oxygen", (O2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature), "nitrogen", (N2STANDARD*src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) src.update_icon() return 1 diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 43f836f3017..8fbbece0b2f 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -26,7 +26,7 @@ if(port) connect(port) update_icon() - + process() if(!connected_port) //only react when pipe_network will ont it do it for you //Allow for reactions @@ -118,24 +118,13 @@ visible_message("\red [user] has used [W] on \icon[icon]") if(air_contents) var/pressure = air_contents.return_pressure() - var/total_moles = air_contents.total_moles() + var/total_moles = air_contents.total_moles user << "\blue Results of analysis of \icon[icon]" if (total_moles>0) - var/o2_concentration = air_contents.oxygen/total_moles - var/n2_concentration = air_contents.nitrogen/total_moles - var/co2_concentration = air_contents.carbon_dioxide/total_moles - var/phoron_concentration = air_contents.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - user << "\blue Pressure: [round(pressure,0.1)] kPa" - user << "\blue Nitrogen: [round(n2_concentration*100)]%" - user << "\blue Oxygen: [round(o2_concentration*100)]%" - user << "\blue CO2: [round(co2_concentration*100)]%" - user << "\blue Phoron: [round(phoron_concentration*100)]%" - if(unknown_concentration>0.01) - user << "\red Unknown: [round(unknown_concentration*100)]%" + for(var/g in air_contents.gas) + user << "\blue [gas_data.name[g]]: [round((air_contents.gas[g] / total_moles) * 100)]%" user << "\blue Temperature: [round(air_contents.temperature-T0C)]°C" else user << "\blue Tank is empty!" diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index cb92e4096a8..fa1fac9980b 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -98,7 +98,7 @@ environment = holding.air_contents else environment = loc.return_air() - var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() + var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles //Take a gas sample var/datum/gas_mixture/removed @@ -114,23 +114,17 @@ filtered_out.temperature = removed.temperature - filtered_out.phoron = removed.phoron - removed.phoron = 0 + filtered_out.gas["phoron"] = removed.gas["phoron"] + removed.gas["phoron"] = 0 - filtered_out.carbon_dioxide = removed.carbon_dioxide - removed.carbon_dioxide = 0 + filtered_out.gas["carbon_dioxide"] = removed.gas["carbon_dioxide"] + removed.gas["carbon_dioxide"] = 0 - if(removed.trace_gases.len>0) - for(var/datum/gas/trace_gas in removed.trace_gases) - if(istype(trace_gas, /datum/gas/sleeping_agent)) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas + filtered_out.gas["sleeping_agent"] = removed.gas["sleeping_agent"] + removed.gas["sleeping_agent"] = 0 - if(removed.trace_gases.len>0) - for(var/datum/gas/trace_gas in removed.trace_gases) - if(istype(trace_gas, /datum/gas/oxygen_agent_b)) - removed.trace_gases -= trace_gas - filtered_out.trace_gases += trace_gas + filtered_out.gas["oxygen_agent_b"] = removed.gas["oxygen_agent_b"] + removed.gas["oxygen_agent_b"] = 0 //Remix the resulting gases air_contents.merge(filtered_out) diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 68d9888d5ed..37d2bc37a5b 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -789,7 +789,7 @@ return get_turf(src) -// called from mob/living/carbon/human/HasEntered() +// called from mob/living/carbon/human/Crossed() // when mulebot is in the same loc /obj/machinery/bot/mulebot/proc/RunOver(var/mob/living/carbon/human/H) src.visible_message("\red [src] drives over [H]!") diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index a82828311cb..9cde4c6c7f0 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -121,13 +121,13 @@ data["beakerVolume"] += R.volume // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 410) // when the ui is first opened this is the data it will use - ui.set_initial_data(data) + ui.set_initial_data(data) // open the new ui window ui.open() // auto update every Master Controller tick @@ -194,7 +194,7 @@ icon_state = "cell-off" /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() - if(air_contents.total_moles() < 10) + if(air_contents.total_moles < 10) return if(occupant) if(occupant.stat == 2) @@ -205,7 +205,7 @@ if(occupant.bodytemperature < T0C) occupant.sleeping = max(5, (1/occupant.bodytemperature)*2000) occupant.Paralyse(max(5, (1/occupant.bodytemperature)*3000)) - if(air_contents.oxygen > 2) + if(air_contents.gas["oxygen"] > 2) if(occupant.getOxyLoss()) occupant.adjustOxyLoss(-1) else occupant.adjustOxyLoss(-1) @@ -224,7 +224,7 @@ beaker.reagents.reaction(occupant) /obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents() - if(air_contents.total_moles() < 1) + if(air_contents.total_moles < 1) return var/air_heat_capacity = air_contents.heat_capacity() var/combined_heat_capacity = current_heat_capacity + air_heat_capacity @@ -233,7 +233,7 @@ air_contents.temperature = combined_energy/combined_heat_capacity /obj/machinery/atmospherics/unary/cryo_cell/proc/expel_gas() - if(air_contents.total_moles() < 1) + if(air_contents.total_moles < 1) return // var/datum/gas_mixture/expel_gas = new // var/remove_amount = air_contents.total_moles()/50 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index bb3fdbaa233..d666c707131 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -288,13 +288,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. /obj/machinery/door/airlock/phoron/proc/PhoronBurn(temperature) for(var/turf/simulated/floor/target_tile in range(2,loc)) -// if(target_tile.parent && target_tile.parent.group_processing) // THESE PROBABLY DO SOMETHING IMPORTANT BUT I DON'T KNOW HOW TO FIX IT - Erthilo -// target_tile.parent.suspend_group_processing() - var/datum/gas_mixture/napalm = new - var/phoronToDeduce = 35 - napalm.phoron = phoronToDeduce - napalm.temperature = 400+T0C - target_tile.assume_air(napalm) + target_tile.assume_gas("phoron", 35, 400+T0C) spawn (0) target_tile.hotspot_expose(temperature, 400) for(var/obj/structure/falsewall/phoron/F in range(3,src))//Hackish as fuck, but until temperature_expose works, there is nothing I can do -Sieve var/turf/T = get_turf(F) diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 35954c0c8b6..de67e7cea10 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -210,7 +210,7 @@ if("/turf/simulated/floor", "/turf/simulated/floor/engine") var/datum/gas_mixture/environment = T.return_air() - var/turf_total = environment.total_moles() + var/turf_total = environment.total_moles var/t1 = turf_total / MOLES_CELLSTANDARD * 175 if(t1<=100) diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index c8b6962458a..4b166354c5f 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -128,7 +128,7 @@ /* //Allow you to push disposal pipes into it (for those with density 1) -/obj/machinery/pipedispenser/disposal/HasEntered(var/obj/structure/disposalconstruct/pipe as obj) +/obj/machinery/pipedispenser/disposal/Crossed(var/obj/structure/disposalconstruct/pipe as obj) if(istype(pipe) && !pipe.anchored) del(pipe) diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 9a6849dcdf4..122cac0f8a9 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -1,202 +1,202 @@ -/obj/machinery/space_heater - anchored = 0 - density = 1 - icon = 'icons/obj/atmos.dmi' - icon_state = "sheater0" - name = "space heater" - desc = "Made by Space Amish using traditional space techniques, this heater is guaranteed not to set the station on fire." - var/obj/item/weapon/cell/cell - var/on = 0 - var/open = 0 - var/set_temperature = 50 // in celcius, add T0C for kelvin - var/heating_power = 40000 - - flags = FPRINT - - - New() - ..() - cell = new(src) - cell.charge = 1000 - cell.maxcharge = 1000 - update_icon() - return - - update_icon() - overlays.Cut() - icon_state = "sheater[on]" - if(open) - overlays += "sheater-open" - return - - examine() - set src in oview(12) - if (!( usr )) - return - usr << "This is \icon[src] \an [src.name]." - usr << src.desc - - usr << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]." - if(open) - usr << "The power cell is [cell ? "installed" : "missing"]." - else - usr << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" - return - - emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - if(cell) - cell.emp_act(severity) - ..(severity) - - attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/weapon/cell)) - if(open) - if(cell) - user << "There is already a power cell inside." - return - else - // insert cell - var/obj/item/weapon/cell/C = usr.get_active_hand() - if(istype(C)) - user.drop_item() - cell = C - C.loc = src - C.add_fingerprint(usr) - - user.visible_message("\blue [user] inserts a power cell into [src].", "\blue You insert the power cell into [src].") - else - user << "The hatch must be open to insert a power cell." - return - else if(istype(I, /obj/item/weapon/screwdriver)) - open = !open - user.visible_message("\blue [user] [open ? "opens" : "closes"] the hatch on the [src].", "\blue You [open ? "open" : "close"] the hatch on the [src].") - update_icon() - if(!open && user.machine == src) - user << browse(null, "window=spaceheater") - user.unset_machine() - else - ..() - return - - attack_hand(mob/user as mob) - src.add_fingerprint(user) - interact(user) - - interact(mob/user as mob) - - if(open) - - var/dat - dat = "Power cell: " - if(cell) - dat += "Installed
" - else - dat += "Removed
" - - dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%

" - - dat += "Set Temperature: " - - dat += "-" - - dat += " [set_temperature]°C " - dat += "+
" - - user.set_machine(src) - user << browse("Space Heater Control Panel[dat]", "window=spaceheater") - onclose(user, "spaceheater") - - - - - else - on = !on - user.visible_message("\blue [user] switches [on ? "on" : "off"] the [src].","\blue You switch [on ? "on" : "off"] the [src].") - update_icon() - return - - - Topic(href, href_list) - if (usr.stat) - return - if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - - switch(href_list["op"]) - - if("temp") - var/value = text2num(href_list["val"]) - - // limit to 20-90 degC - set_temperature = dd_range(0, 90, set_temperature + value) - - if("cellremove") - if(open && cell && !usr.get_active_hand()) - cell.updateicon() - usr.put_in_hands(cell) - cell.add_fingerprint(usr) - cell = null - usr.visible_message("\blue [usr] removes the power cell from \the [src].", "\blue You remove the power cell from \the [src].") - - - if("cellinstall") - if(open && !cell) - var/obj/item/weapon/cell/C = usr.get_active_hand() - if(istype(C)) - usr.drop_item() - cell = C - C.loc = src - C.add_fingerprint(usr) - - usr.visible_message("\blue [usr] inserts a power cell into \the [src].", "\blue You insert the power cell into \the [src].") - - updateDialog() - else - usr << browse(null, "window=spaceheater") - usr.unset_machine() - return - - - - process() - if(on) - if(cell && cell.charge > 0) - - var/turf/simulated/L = loc - if(istype(L)) - var/datum/gas_mixture/env = L.return_air() - if(env.temperature != set_temperature + T0C) - - var/transfer_moles = 0.25 * env.total_moles() - - var/datum/gas_mixture/removed = env.remove(transfer_moles) - - //world << "got [transfer_moles] moles at [removed.temperature]" - - if(removed) - - var/heat_capacity = removed.heat_capacity() - //world << "heating ([heat_capacity])" - if(heat_capacity) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE - if(removed.temperature < set_temperature + T0C) - removed.temperature = min(removed.temperature + heating_power/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE - else - removed.temperature = max(removed.temperature - heating_power/heat_capacity, TCMB) - cell.use(heating_power/20000) - - //world << "now at [removed.temperature]" - - env.merge(removed) - - //world << "turf now at [env.temperature]" - - - else - on = 0 - update_icon() - - +/obj/machinery/space_heater + anchored = 0 + density = 1 + icon = 'icons/obj/atmos.dmi' + icon_state = "sheater0" + name = "space heater" + desc = "Made by Space Amish using traditional space techniques, this heater is guaranteed not to set the station on fire." + var/obj/item/weapon/cell/cell + var/on = 0 + var/open = 0 + var/set_temperature = 50 // in celcius, add T0C for kelvin + var/heating_power = 40000 + + flags = FPRINT + + + New() + ..() + cell = new(src) + cell.charge = 1000 + cell.maxcharge = 1000 + update_icon() + return + + update_icon() + overlays.Cut() + icon_state = "sheater[on]" + if(open) + overlays += "sheater-open" + return + + examine() + set src in oview(12) + if (!( usr )) + return + usr << "This is \icon[src] \an [src.name]." + usr << src.desc + + usr << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]." + if(open) + usr << "The power cell is [cell ? "installed" : "missing"]." + else + usr << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" + return + + emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + ..(severity) + return + if(cell) + cell.emp_act(severity) + ..(severity) + + attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/cell)) + if(open) + if(cell) + user << "There is already a power cell inside." + return + else + // insert cell + var/obj/item/weapon/cell/C = usr.get_active_hand() + if(istype(C)) + user.drop_item() + cell = C + C.loc = src + C.add_fingerprint(usr) + + user.visible_message("\blue [user] inserts a power cell into [src].", "\blue You insert the power cell into [src].") + else + user << "The hatch must be open to insert a power cell." + return + else if(istype(I, /obj/item/weapon/screwdriver)) + open = !open + user.visible_message("\blue [user] [open ? "opens" : "closes"] the hatch on the [src].", "\blue You [open ? "open" : "close"] the hatch on the [src].") + update_icon() + if(!open && user.machine == src) + user << browse(null, "window=spaceheater") + user.unset_machine() + else + ..() + return + + attack_hand(mob/user as mob) + src.add_fingerprint(user) + interact(user) + + interact(mob/user as mob) + + if(open) + + var/dat + dat = "Power cell: " + if(cell) + dat += "Installed
" + else + dat += "Removed
" + + dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%

" + + dat += "Set Temperature: " + + dat += "-" + + dat += " [set_temperature]°C " + dat += "+
" + + user.set_machine(src) + user << browse("Space Heater Control Panel[dat]", "window=spaceheater") + onclose(user, "spaceheater") + + + + + else + on = !on + user.visible_message("\blue [user] switches [on ? "on" : "off"] the [src].","\blue You switch [on ? "on" : "off"] the [src].") + update_icon() + return + + + Topic(href, href_list) + if (usr.stat) + return + if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + + switch(href_list["op"]) + + if("temp") + var/value = text2num(href_list["val"]) + + // limit to 20-90 degC + set_temperature = dd_range(0, 90, set_temperature + value) + + if("cellremove") + if(open && cell && !usr.get_active_hand()) + cell.updateicon() + usr.put_in_hands(cell) + cell.add_fingerprint(usr) + cell = null + usr.visible_message("\blue [usr] removes the power cell from \the [src].", "\blue You remove the power cell from \the [src].") + + + if("cellinstall") + if(open && !cell) + var/obj/item/weapon/cell/C = usr.get_active_hand() + if(istype(C)) + usr.drop_item() + cell = C + C.loc = src + C.add_fingerprint(usr) + + usr.visible_message("\blue [usr] inserts a power cell into \the [src].", "\blue You insert the power cell into \the [src].") + + updateDialog() + else + usr << browse(null, "window=spaceheater") + usr.unset_machine() + return + + + + process() + if(on) + if(cell && cell.charge > 0) + + var/turf/simulated/L = loc + if(istype(L)) + var/datum/gas_mixture/env = L.return_air() + if(env.temperature != set_temperature + T0C) + + var/transfer_moles = 0.25 * env.total_moles + + var/datum/gas_mixture/removed = env.remove(transfer_moles) + + //world << "got [transfer_moles] moles at [removed.temperature]" + + if(removed) + + var/heat_capacity = removed.heat_capacity() + //world << "heating ([heat_capacity])" + if(heat_capacity) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE + if(removed.temperature < set_temperature + T0C) + removed.temperature = min(removed.temperature + heating_power/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE + else + removed.temperature = max(removed.temperature - heating_power/heat_capacity, TCMB) + cell.use(heating_power/20000) + + //world << "now at [removed.temperature]" + + env.merge(removed) + + //world << "turf now at [env.temperature]" + + + else + on = 0 + update_icon() + + return \ No newline at end of file diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 1d03618de16..edc90ed8256 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -246,7 +246,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() var/datum/gas_mixture/env = L.return_air() if(env.temperature < (heat_amt+T0C)) - var/transfer_moles = 0.25 * env.total_moles() + var/transfer_moles = 0.25 * env.total_moles var/datum/gas_mixture/removed = env.remove(transfer_moles) diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 629e3b9d7de..ddfa9fa3284 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -924,13 +924,11 @@ return var/datum/gas_mixture/GM = new if(prob(10)) - GM.phoron += 100 - GM.temperature = 1500+T0C //should be enough to start a fire + T.assume_gas("phoron", 100, 1500+T0C) T.visible_message("The [src] suddenly disgorges a cloud of heated phoron.") destroy() else - GM.phoron += 5 - GM.temperature = istype(T) ? T.air.temperature : T20C + T.assume_gas("phoron", 5, istype(T) ? T.air.temperature : T20C) T.visible_message("The [src] suddenly disgorges a cloud of phoron.") T.assume_air(GM) return diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 0cb89ee683d..3c877d3908a 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -123,8 +123,7 @@ cabin_air = new cabin_air.temperature = T20C cabin_air.volume = 200 - cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) - cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.adjust_multi("oxygen", O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature), "nitrogen", N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)) return cabin_air /obj/mecha/proc/add_radio() @@ -332,7 +331,7 @@ var/obj/O = obstacle if(istype(O, /obj/effect/portal)) //derpfix src.anchored = 0 - O.HasEntered(src) + O.Crossed(src) spawn(0)//countering portal teleport spawn(0), hurr src.anchored = 1 else if(!O.anchored) @@ -855,11 +854,11 @@ /obj/mecha/proc/return_temperature() . = 0 if(use_internal_tank) - . = cabin_air.return_temperature() + . = cabin_air.temperature else var/datum/gas_mixture/t_air = get_turf_air() if(t_air) - . = t_air.return_temperature() + . = t_air.temperature return /obj/mecha/proc/connect(obj/machinery/atmospherics/portables_connector/new_port) @@ -1705,7 +1704,7 @@ delay = 20 process(var/obj/mecha/mecha) - if(mecha.cabin_air && mecha.cabin_air.return_volume() > 0) + if(mecha.cabin_air && mecha.cabin_air.volume > 0) var/delta = mecha.cabin_air.temperature - T20C mecha.cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) return @@ -1723,8 +1722,8 @@ var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) var/transfer_moles = 0 if(pressure_delta > 0) //cabin pressure lower than release pressure - if(tank_air.return_temperature() > 0) - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + if(tank_air.temperature > 0) + transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) cabin_air.merge(removed) else if(pressure_delta < 0) //cabin pressure higher than release pressure @@ -1733,7 +1732,7 @@ if(t_air) pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) if(pressure_delta > 0) //if location pressure is lower than cabin pressure - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles) if(t_air) t_air.merge(removed) @@ -1766,12 +1765,12 @@ if(mecha.internal_tank.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH))) mecha.setInternalDamage(MECHA_INT_TANK_BREACH) var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air() - if(int_tank_air && int_tank_air.return_volume()>0) //heat the air_contents + if(int_tank_air && int_tank_air.volume>0) //heat the air_contents int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15)) - if(mecha.cabin_air && mecha.cabin_air.return_volume()>0) - mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.return_temperature()+rand(10,15)) - if(mecha.cabin_air.return_temperature()>mecha.max_temperature/2) - mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.return_temperature(),0.1),"fire") + if(mecha.cabin_air && mecha.cabin_air.volume>0) + mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.temperature+rand(10,15)) + if(mecha.cabin_air.temperature>mecha.max_temperature/2) + mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.temperature,0.1),"fire") if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum mecha.pr_int_temp_processor.stop() if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 17bcaba4280..d348a351a1e 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -45,7 +45,7 @@ var/global/list/image/splatter_cache=list() if(basecolor == "rainbow") basecolor = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]" color = basecolor -/obj/effect/decal/cleanable/blood/HasEntered(mob/living/carbon/human/perp) +/obj/effect/decal/cleanable/blood/Crossed(mob/living/carbon/human/perp) if (!istype(perp)) return if(amount < 1) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 59e516a7147..0da251e1eed 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -216,7 +216,7 @@ steam.start() -- spawns the effect delete() return -/obj/effect/effect/smoke/HasEntered(mob/living/carbon/M as mob ) +/obj/effect/effect/smoke/Crossed(mob/living/carbon/M as mob ) ..() if(istype(M)) affect(M) @@ -549,7 +549,7 @@ steam.start() -- spawns the effect delete() -/obj/effect/effect/foam/HasEntered(var/atom/movable/AM) +/obj/effect/effect/foam/Crossed(var/atom/movable/AM) if(metal) return diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 25711498511..de356849917 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -12,7 +12,7 @@ /obj/effect/mine/New() icon_state = "uglyminearmed" -/obj/effect/mine/HasEntered(AM as mob|obj) +/obj/effect/mine/Crossed(AM as mob|obj) Bumped(AM) /obj/effect/mine/Bumped(mob/M as mob|obj) @@ -51,14 +51,7 @@ for (var/turf/simulated/floor/target in range(1,src)) if(!target.blocks_air) - - var/datum/gas_mixture/payload = new - var/datum/gas/sleeping_agent/trace_gas = new - - trace_gas.moles = 30 - payload += trace_gas - - target.zone.air.merge(payload) + target.assume_gas("sleeping_agent", 30) spawn(0) del(src) @@ -66,12 +59,7 @@ /obj/effect/mine/proc/triggerphoron(obj) for (var/turf/simulated/floor/target in range(1,src)) if(!target.blocks_air) - - var/datum/gas_mixture/payload = new - - payload.phoron = 30 - - target.zone.air.merge(payload) + target.assume_gas("phoron", 30) target.hotspot_expose(1000, CELL_VOLUME) diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index ae174260e38..b6fcb88b4f1 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -16,7 +16,7 @@ return return -/obj/effect/portal/HasEntered(AM as mob|obj) +/obj/effect/portal/Crossed(AM as mob|obj) spawn(0) src.teleport(AM) return diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm index 6540b5f3bb5..3f694a8b49a 100644 --- a/code/game/objects/effects/spawners/bombspawner.dm +++ b/code/game/objects/effects/spawners/bombspawner.dm @@ -137,13 +137,10 @@ OT.master = V PT.air_contents.temperature = PHORON_FLASHPOINT - PT.air_contents.phoron = 12 - PT.air_contents.carbon_dioxide = 8 - PT.air_contents.update_values() + PT.air_contents.adjust_multi("phoron", 12, "carbon_dioxide", 8) OT.air_contents.temperature = PHORON_FLASHPOINT - OT.air_contents.oxygen = 20 - OT.air_contents.update_values() + OT.air_contents.adjust_gas("oxygen", 20) var/obj/item/device/assembly/S diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm index 3acecd04b2d..cd9142bdc0b 100644 --- a/code/game/objects/effects/step_triggers.dm +++ b/code/game/objects/effects/step_triggers.dm @@ -1,117 +1,117 @@ -/* Simple object type, calls a proc when "stepped" on by something */ - -/obj/effect/step_trigger - var/affect_ghosts = 0 - var/stopper = 1 // stops throwers - invisibility = 101 // nope cant see this shit - anchored = 1 - -/obj/effect/step_trigger/proc/Trigger(var/atom/movable/A) - return 0 - -/obj/effect/step_trigger/HasEntered(H as mob|obj) - ..() - if(!H) - return - if(istype(H, /mob/dead/observer) && !affect_ghosts) - return - Trigger(H) - - - -/* Tosses things in a certain direction */ - -/obj/effect/step_trigger/thrower - var/direction = SOUTH // the direction of throw - var/tiles = 3 // if 0: forever until atom hits a stopper - var/immobilize = 1 // if nonzero: prevents mobs from moving while they're being flung - var/speed = 1 // delay of movement - var/facedir = 0 // if 1: atom faces the direction of movement - var/nostop = 0 // if 1: will only be stopped by teleporters - var/list/affecting = list() - - Trigger(var/atom/A) - if(!A || !istype(A, /atom/movable)) - return - var/atom/movable/AM = A - var/curtiles = 0 - var/stopthrow = 0 - for(var/obj/effect/step_trigger/thrower/T in orange(2, src)) - if(AM in T.affecting) - return - - if(ismob(AM)) - var/mob/M = AM - if(immobilize) - M.canmove = 0 - - affecting.Add(AM) - while(AM && !stopthrow) - if(tiles) - if(curtiles >= tiles) - break - if(AM.z != src.z) - break - - curtiles++ - - sleep(speed) - - // Calculate if we should stop the process - if(!nostop) - for(var/obj/effect/step_trigger/T in get_step(AM, direction)) - if(T.stopper && T != src) - stopthrow = 1 - else - for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction)) - if(T.stopper) - stopthrow = 1 - - if(AM) - var/predir = AM.dir - step(AM, direction) - if(!facedir) - AM.dir = predir - - - - affecting.Remove(AM) - - if(ismob(AM)) - var/mob/M = AM - if(immobilize) - M.canmove = 1 - -/* Stops things thrown by a thrower, doesn't do anything */ - -/obj/effect/step_trigger/stopper - -/* Instant teleporter */ - -/obj/effect/step_trigger/teleporter - var/teleport_x = 0 // teleportation coordinates (if one is null, then no teleport!) - var/teleport_y = 0 - var/teleport_z = 0 - - Trigger(var/atom/movable/A) - if(teleport_x && teleport_y && teleport_z) - - A.x = teleport_x - A.y = teleport_y - A.z = teleport_z - -/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */ - -/obj/effect/step_trigger/teleporter/random - var/teleport_x_offset = 0 - var/teleport_y_offset = 0 - var/teleport_z_offset = 0 - - Trigger(var/atom/movable/A) - if(teleport_x && teleport_y && teleport_z) - if(teleport_x_offset && teleport_y_offset && teleport_z_offset) - - A.x = rand(teleport_x, teleport_x_offset) - A.y = rand(teleport_y, teleport_y_offset) - A.z = rand(teleport_z, teleport_z_offset) - +/* Simple object type, calls a proc when "stepped" on by something */ + +/obj/effect/step_trigger + var/affect_ghosts = 0 + var/stopper = 1 // stops throwers + invisibility = 101 // nope cant see this shit + anchored = 1 + +/obj/effect/step_trigger/proc/Trigger(var/atom/movable/A) + return 0 + +/obj/effect/step_trigger/Crossed(H as mob|obj) + ..() + if(!H) + return + if(istype(H, /mob/dead/observer) && !affect_ghosts) + return + Trigger(H) + + + +/* Tosses things in a certain direction */ + +/obj/effect/step_trigger/thrower + var/direction = SOUTH // the direction of throw + var/tiles = 3 // if 0: forever until atom hits a stopper + var/immobilize = 1 // if nonzero: prevents mobs from moving while they're being flung + var/speed = 1 // delay of movement + var/facedir = 0 // if 1: atom faces the direction of movement + var/nostop = 0 // if 1: will only be stopped by teleporters + var/list/affecting = list() + + Trigger(var/atom/A) + if(!A || !istype(A, /atom/movable)) + return + var/atom/movable/AM = A + var/curtiles = 0 + var/stopthrow = 0 + for(var/obj/effect/step_trigger/thrower/T in orange(2, src)) + if(AM in T.affecting) + return + + if(ismob(AM)) + var/mob/M = AM + if(immobilize) + M.canmove = 0 + + affecting.Add(AM) + while(AM && !stopthrow) + if(tiles) + if(curtiles >= tiles) + break + if(AM.z != src.z) + break + + curtiles++ + + sleep(speed) + + // Calculate if we should stop the process + if(!nostop) + for(var/obj/effect/step_trigger/T in get_step(AM, direction)) + if(T.stopper && T != src) + stopthrow = 1 + else + for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction)) + if(T.stopper) + stopthrow = 1 + + if(AM) + var/predir = AM.dir + step(AM, direction) + if(!facedir) + AM.dir = predir + + + + affecting.Remove(AM) + + if(ismob(AM)) + var/mob/M = AM + if(immobilize) + M.canmove = 1 + +/* Stops things thrown by a thrower, doesn't do anything */ + +/obj/effect/step_trigger/stopper + +/* Instant teleporter */ + +/obj/effect/step_trigger/teleporter + var/teleport_x = 0 // teleportation coordinates (if one is null, then no teleport!) + var/teleport_y = 0 + var/teleport_z = 0 + + Trigger(var/atom/movable/A) + if(teleport_x && teleport_y && teleport_z) + + A.x = teleport_x + A.y = teleport_y + A.z = teleport_z + +/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */ + +/obj/effect/step_trigger/teleporter/random + var/teleport_x_offset = 0 + var/teleport_y_offset = 0 + var/teleport_z_offset = 0 + + Trigger(var/atom/movable/A) + if(teleport_x && teleport_y && teleport_z) + if(teleport_x_offset && teleport_y_offset && teleport_z_offset) + + A.x = rand(teleport_x, teleport_x_offset) + A.y = rand(teleport_y, teleport_y_offset) + A.z = rand(teleport_z, teleport_z_offset) + diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index d4879eff363..2bd77901c0b 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -440,13 +440,13 @@ var/global/list/obj/item/device/pda/PDAs = list() var/datum/gas_mixture/environment = T.return_air() var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() + var/total_moles = environment.total_moles if (total_moles) - var/o2_level = environment.oxygen/total_moles - var/n2_level = environment.nitrogen/total_moles - var/co2_level = environment.carbon_dioxide/total_moles - var/phoron_level = environment.phoron/total_moles + var/o2_level = environment.gas["oxygen"]/total_moles + var/n2_level = environment.gas["nitrogen"]/total_moles + var/co2_level = environment.gas["carbon_dioxide"]/total_moles + var/phoron_level = environment.gas["phoron"]/total_moles var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) data["aircontents"] = list(\ "pressure" = "[round(pressure,0.1)]",\ @@ -1162,24 +1162,13 @@ var/global/list/obj/item/device/pda/PDAs = list() O << "\red [user] has used [src] on \icon[icon] [A]" var/pressure = A:air_contents.return_pressure() - var/total_moles = A:air_contents.total_moles() + var/total_moles = A:air_contents.total_moles user << "\blue Results of analysis of \icon[icon]" if (total_moles>0) - var/o2_concentration = A:air_contents.oxygen/total_moles - var/n2_concentration = A:air_contents.nitrogen/total_moles - var/co2_concentration = A:air_contents.carbon_dioxide/total_moles - var/phoron_concentration = A:air_contents.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - user << "\blue Pressure: [round(pressure,0.1)] kPa" - user << "\blue Nitrogen: [round(n2_concentration*100)]%" - user << "\blue Oxygen: [round(o2_concentration*100)]%" - user << "\blue CO2: [round(co2_concentration*100)]%" - user << "\blue Phoron: [round(phoron_concentration*100)]%" - if(unknown_concentration>0.01) - user << "\red Unknown: [round(unknown_concentration*100)]%" + for(var/g in A:air_contents.gas) + user << "\blue [gas_data.name[g]]: [round((A:air_contents.gas[g] / total_moles) * 100)]%" user << "\blue Temperature: [round(A:air_contents.temperature-T0C)]°C" else user << "\blue Tank is empty!" @@ -1191,24 +1180,13 @@ var/global/list/obj/item/device/pda/PDAs = list() var/obj/machinery/atmospherics/pipe/tank/T = A var/pressure = T.parent.air.return_pressure() - var/total_moles = T.parent.air.total_moles() + var/total_moles = T.parent.air.total_moles user << "\blue Results of analysis of \icon[icon]" if (total_moles>0) - var/o2_concentration = T.parent.air.oxygen/total_moles - var/n2_concentration = T.parent.air.nitrogen/total_moles - var/co2_concentration = T.parent.air.carbon_dioxide/total_moles - var/phoron_concentration = T.parent.air.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - user << "\blue Pressure: [round(pressure,0.1)] kPa" - user << "\blue Nitrogen: [round(n2_concentration*100)]%" - user << "\blue Oxygen: [round(o2_concentration*100)]%" - user << "\blue CO2: [round(co2_concentration*100)]%" - user << "\blue Phoron: [round(phoron_concentration*100)]%" - if(unknown_concentration>0.01) - user << "\red Unknown: [round(unknown_concentration*100)]%" + for(var/g in T.parent.air.gas) + user << "\blue [gas_data.name[g]]: [round((T.parent.air.gas[g] / total_moles) * 100)]%" user << "\blue Temperature: [round(T.parent.air.temperature-T0C)]°C" else user << "\blue Tank is empty!" @@ -1278,7 +1256,7 @@ var/global/list/obj/item/device/pda/PDAs = list() src.id.loc = get_turf(src.loc) ..() -/obj/item/device/pda/clown/HasEntered(AM as mob|obj) //Clown PDA is slippery. +/obj/item/device/pda/clown/Crossed(AM as mob|obj) //Clown PDA is slippery. if (istype(AM, /mob/living/carbon)) var/mob/M = AM if ((istype(M, /mob/living/carbon/human) && (istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP)) || M.m_intent == "walk") diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 2a8ec10569b..acd446238e3 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -257,7 +257,7 @@ REAGENT SCANNER var/datum/gas_mixture/environment = location.return_air() var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() + var/total_moles = environment.total_moles user.show_message("\blue Results:", 1) if(abs(pressure - ONE_ATMOSPHERE) < 10) @@ -265,32 +265,8 @@ REAGENT SCANNER else user.show_message("\red Pressure: [round(pressure,0.1)] kPa", 1) if(total_moles) - var/o2_concentration = environment.oxygen/total_moles - var/n2_concentration = environment.nitrogen/total_moles - var/co2_concentration = environment.carbon_dioxide/total_moles - var/phoron_concentration = environment.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - if(abs(n2_concentration - N2STANDARD) < 20) - user.show_message("\blue Nitrogen: [round(n2_concentration*100)]%", 1) - else - user.show_message("\red Nitrogen: [round(n2_concentration*100)]%", 1) - - if(abs(o2_concentration - O2STANDARD) < 2) - user.show_message("\blue Oxygen: [round(o2_concentration*100)]%", 1) - else - user.show_message("\red Oxygen: [round(o2_concentration*100)]%", 1) - - if(co2_concentration > 0.01) - user.show_message("\red CO2: [round(co2_concentration*100)]%", 1) - else - user.show_message("\blue CO2: [round(co2_concentration*100)]%", 1) - - if(phoron_concentration > 0.01) - user.show_message("\red Phoron: [round(phoron_concentration*100)]%", 1) - - if(unknown_concentration > 0.01) - user.show_message("\red Unknown: [round(unknown_concentration*100)]%", 1) + for(var/g in environment.gas) + user.show_message("\blue [gas_data.name[g]]: [round((environment.gas[g] / total_moles)*100)]%", 1) user.show_message("\blue Temperature: [round(environment.temperature-T0C)]°C", 1) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 43ca3841298..843cb782468 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -284,7 +284,7 @@ return return ..() -/obj/item/weapon/shard/HasEntered(AM as mob|obj) +/obj/item/weapon/shard/Crossed(AM as mob|obj) if(ismob(AM)) var/mob/M = AM M << "\red You step in the broken glass!" diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index c89b115071d..28fa0f46dbf 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -406,7 +406,7 @@ playsound(src, 'sound/effects/snap.ogg', 50, 1) del(src) -/obj/item/toy/snappop/HasEntered(H as mob|obj) +/obj/item/toy/snappop/Crossed(H as mob|obj) if((ishuman(H))) //i guess carp and shit shouldn't set them off var/mob/living/carbon/M = H if(M.m_intent == "run") diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index e526cf1c351..3ae5094dd03 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -8,7 +8,7 @@ /* * Banana Peals */ -/obj/item/weapon/bananapeel/HasEntered(AM as mob|obj) +/obj/item/weapon/bananapeel/Crossed(AM as mob|obj) if (istype(AM, /mob/living/carbon)) var/mob/M = AM if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) @@ -23,7 +23,7 @@ /* * Soap */ -/obj/item/weapon/soap/HasEntered(AM as mob|obj) //EXACTLY the same as bananapeel for now, so it makes sense to put it in the same dm -- Urist +/obj/item/weapon/soap/Crossed(AM as mob|obj) //EXACTLY the same as bananapeel for now, so it makes sense to put it in the same dm -- Urist if (istype(AM, /mob/living/carbon)) var/mob/M = AM if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 1d107719581..e16b9dd38c1 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -116,24 +116,13 @@ var/obj/item/weapon/icon = src user.visible_message("[user] has used the analyzer on \icon[icon]") var/pressure = ptank.air_contents.return_pressure() - var/total_moles = ptank.air_contents.total_moles() + var/total_moles = ptank.air_contents.total_moles user << "\blue Results of analysis of \icon[icon]" if(total_moles>0) - var/o2_concentration = ptank.air_contents.oxygen/total_moles - var/n2_concentration = ptank.air_contents.nitrogen/total_moles - var/co2_concentration = ptank.air_contents.carbon_dioxide/total_moles - var/phoron_concentration = ptank.air_contents.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - user << "\blue Pressure: [round(pressure,0.1)] kPa" - user << "\blue Nitrogen: [round(n2_concentration*100)]%" - user << "\blue Oxygen: [round(o2_concentration*100)]%" - user << "\blue CO2: [round(co2_concentration*100)]%" - user << "\blue Phoron: [round(phoron_concentration*100)]%" - if(unknown_concentration>0.01) - user << "\red Unknown: [round(unknown_concentration*100)]%" + for(var/g in ptank.air_contents.gas) + user << "\blue [gas_data.name[g]]: [round((ptank.air_contents.gas[g] / total_moles) * 100)]%" user << "\blue Temperature: [round(ptank.air_contents.temperature-T0C)]°C" else user << "\blue Tank is empty!" @@ -163,7 +152,7 @@ usr.set_machine(src) if(href_list["light"]) if(!ptank) return - if(ptank.air_contents.phoron < 1) return + if(ptank.air_contents.gas["phoron"] < 1) return if(!status) return lit = !lit if(lit) @@ -212,8 +201,8 @@ //Transfer 5% of current tank air contents to turf var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100)) //air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE - new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.phoron,get_dir(loc,target)) - air_transfer.phoron = 0 + new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.gas["phoron"],get_dir(loc,target)) + air_transfer.gas["phoron"] = 0 target.assume_air(air_transfer) //Burn it based on transfered gas //target.hotspot_expose(part4.air_contents.temperature*2,300) diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index 3c63ac33273..953e9a010dc 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -23,7 +23,7 @@ examine() set src in usr ..() - if(air_contents.oxygen < 10) + if(air_contents.gas["oxygen"] < 10) usr << text("\red The meter on the [src.name] indicates you are almost out of air!") playsound(usr, 'sound/effects/alert.ogg', 50, 1) return @@ -55,14 +55,13 @@ proc/allow_thrust(num, mob/living/user as mob) if(!(src.on)) return 0 - if((num < 0.005 || src.air_contents.total_moles() < num)) + if((num < 0.005 || src.air_contents.total_moles < num)) src.ion_trail.stop() return 0 var/datum/gas_mixture/G = src.air_contents.remove(num) - var/allgases = G.carbon_dioxide + G.nitrogen + G.oxygen + G.phoron //fuck trace gases -Pete - if(allgases >= 0.005) + if(G.total_moles >= 0.005) return 1 del(G) @@ -80,8 +79,7 @@ New() ..() - //src.air_contents.oxygen = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - air_contents.adjust((6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + air_contents.adjust_gas("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) return /obj/item/weapon/tank/jetpack/oxygen @@ -92,8 +90,7 @@ New() ..() - //src.air_contents.oxygen = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - air_contents.adjust((6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + air_contents.adjust_gas("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) return /obj/item/weapon/tank/jetpack/carbondioxide @@ -108,13 +105,13 @@ src.ion_trail = new /datum/effect/effect/system/ion_trail_follow() src.ion_trail.set_up(src) //src.air_contents.carbon_dioxide = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - air_contents.adjust(0,(6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + air_contents.adjust_gas("carbon_dioxide", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) return examine() set src in usr ..() - if(air_contents.carbon_dioxide < 10) + if(air_contents.gas["carbon_dioxide"] < 10) usr << text("\red The meter on the [src.name] indicates you are almost out of air!") playsound(usr, 'sound/effects/alert.ogg', 50, 1) return diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index cfbe34c1a8a..336ba4aa18d 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -19,15 +19,14 @@ New() ..() - //src.air_contents.oxygen = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - air_contents.adjust((6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + air_contents.adjust_gas("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) return examine() set src in usr ..() - if(air_contents.oxygen < 10) + if(air_contents.gas["oxygen"] < 10) usr << text("\red The meter on the [src.name] indicates you are almost out of air!") //playsound(usr, 'sound/effects/alert.ogg', 50, 1) @@ -53,13 +52,8 @@ /obj/item/weapon/tank/anesthetic/New() ..() - src.air_contents.oxygen = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - - var/datum/gas/sleeping_agent/trace_gas = new() - trace_gas.moles = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD - - src.air_contents.trace_gases += trace_gas - // + air_contents.gas["oxygen"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gas["sleeping_agent"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD air_contents.update_values() return @@ -76,17 +70,14 @@ examine() set src in usr ..() - if(air_contents.oxygen < 1 && loc==usr) + if(air_contents.gas["oxygen"] < 1 && loc==usr) usr << "\red The meter on the [src.name] indicates you are almost out of air!" usr << sound('sound/effects/alert.ogg') /obj/item/weapon/tank/air/New() ..() - src.air_contents.oxygen = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - src.air_contents.nitrogen = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD - // - src.air_contents.update_values() + src.air_contents.adjust_multi("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD, "nitrogen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD) return @@ -105,9 +96,7 @@ /obj/item/weapon/tank/phoron/New() ..() - src.air_contents.phoron = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) - // - src.air_contents.update_values() + src.air_contents.adjust_gas("phoron", (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C)) return /obj/item/weapon/tank/phoron/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -139,9 +128,7 @@ New() ..() - src.air_contents.oxygen = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) - // - src.air_contents.update_values() + src.air_contents.adjust_gas("oxygen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) return @@ -149,7 +136,7 @@ examine() set src in usr ..() - if(air_contents.oxygen < 0.2 && loc==usr) + if(air_contents.gas["oxygen"] < 0.2 && loc==usr) usr << text("\red The meter on the [src.name] indicates you are almost out of air!") usr << sound('sound/effects/alert.ogg') @@ -176,14 +163,12 @@ /obj/item/weapon/tank/nitrogen/New() ..() - src.air_contents.nitrogen = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) - // - src.air_contents.update_values() + src.air_contents.adjust_gas("nitrogen", (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C)) return /obj/item/weapon/tank/nitrogen/examine() set src in usr ..() - if(air_contents.nitrogen < 10) + if(air_contents.gas["nitrogen"] < 10) usr << text("\red The meter on the [src.name] indicates you are almost out of air!") //playsound(usr, 'sound/effects/alert.ogg', 50, 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index e0a3bcb5926..d01e681c428 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -28,7 +28,7 @@ src.air_contents.volume = volume //liters src.air_contents.temperature = T20C - processing_objects.Add(src) + processing_objects.Add(src) return /obj/item/weapon/tank/Del() @@ -91,24 +91,13 @@ var/pressure = air_contents.return_pressure() manipulated_by = user.real_name //This person is aware of the contents of the tank. - var/total_moles = air_contents.total_moles() + var/total_moles = air_contents.total_moles user << "\blue Results of analysis of \icon[icon]" if (total_moles>0) - var/o2_concentration = air_contents.oxygen/total_moles - var/n2_concentration = air_contents.nitrogen/total_moles - var/co2_concentration = air_contents.carbon_dioxide/total_moles - var/phoron_concentration = air_contents.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - user << "\blue Pressure: [round(pressure,0.1)] kPa" - user << "\blue Nitrogen: [round(n2_concentration*100)]%" - user << "\blue Oxygen: [round(o2_concentration*100)]%" - user << "\blue CO2: [round(co2_concentration*100)]%" - user << "\blue Phoron: [round(phoron_concentration*100)]%" - if(unknown_concentration>0.01) - user << "\red Unknown: [round(unknown_concentration*100)]%" + for(var/g in air_contents.gas) + user << "\blue [gas_data.name[g]]: [(round(air_contents.gas[g] / total_moles) * 100)]%" user << "\blue Temperature: [round(air_contents.temperature-T0C)]°C" else user << "\blue Tank is empty!" @@ -142,8 +131,8 @@ data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE) data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) data["valveOpen"] = using_internal ? 1 : 0 - - data["maskConnected"] = 0 + + data["maskConnected"] = 0 if(istype(loc,/mob/living/carbon)) var/mob/living/carbon/location = loc if(location.internal == src || (location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 6ee0f5e05e2..29a6b39658b 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -323,12 +323,7 @@ var/datum/gas_mixture/gas = (..()) if(!gas) return null var/datum/gas_mixture/newgas = new/datum/gas_mixture() - newgas.oxygen = gas.oxygen - newgas.carbon_dioxide = gas.carbon_dioxide - newgas.nitrogen = gas.nitrogen - newgas.phoron = gas.phoron - newgas.volume = gas.volume - newgas.temperature = gas.temperature + newgas.copy_from(gas) if(newgas.temperature <= target_temp) return if((newgas.temperature - cooling_power) > target_temp) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index fdb84443705..4902b6a631d 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -206,15 +206,9 @@ proc/TemperatureAct(temperature) for(var/turf/simulated/floor/target_tile in range(2,loc)) - - var/datum/gas_mixture/napalm = new - var/phoronToDeduce = temperature/10 + target_tile.assume_gas("phoron", phoronToDeduce, 200+T0C) - napalm.phoron = phoronToDeduce - napalm.temperature = 200+T0C - - target_tile.assume_air(napalm) spawn (0) target_tile.hotspot_expose(temperature, 400) hardness -= phoronToDeduce/100 diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index 2dcc270bdb0..aed971b20d1 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -81,8 +81,7 @@ obj/structure/ex_act(severity) /obj/structure/transit_tube_pod/New(loc) ..(loc) - air_contents.oxygen = MOLES_O2STANDARD * 2 - air_contents.nitrogen = MOLES_N2STANDARD + air_contents.adjust_multi("oxygen", MOLES_O2STANDARD * 2, "nitrogen", MOLES_N2STANDARD) air_contents.temperature = T20C // Give auto tubes time to align before trying to start moving @@ -123,8 +122,8 @@ obj/structure/ex_act(severity) else if(!pod.moving && pod.dir in directions()) AM.loc = pod return - - + + /obj/structure/transit_tube/station/attack_hand(mob/user as mob) if(!pod_moving) for(var/obj/structure/transit_tube_pod/pod in loc) @@ -359,11 +358,7 @@ obj/structure/ex_act(severity) // datum, there might be problems if I don't... /obj/structure/transit_tube_pod/return_air() var/datum/gas_mixture/GM = new() - GM.oxygen = air_contents.oxygen - GM.carbon_dioxide = air_contents.carbon_dioxide - GM.nitrogen = air_contents.nitrogen - GM.phoron = air_contents.phoron - GM.temperature = air_contents.temperature + GM.copy_from(air_contents) return GM // For now, copying what I found in an unused FEA file (and almost identical in a @@ -398,8 +393,8 @@ obj/structure/ex_act(severity) var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure) var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure) - var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles() * transfer_in) - var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles() * transfer_out) + var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles * transfer_in) + var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles * transfer_out) loc.assume_air(from_int) air_contents.merge(from_env) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 41b3bec5013..5d6caee5e21 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -190,7 +190,7 @@ del(mymist) ismist = 0 -/obj/machinery/shower/HasEntered(atom/movable/O) +/obj/machinery/shower/Crossed(atom/movable/O) ..() wash(O) if(ismob(O)) diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index 932e40e8c5a..98e0f660350 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -78,14 +78,7 @@ /turf/simulated/floor/engine/n20 New() . = ..() - var/datum/gas_mixture/adding = new - var/datum/gas/sleeping_agent/trace_gas = new - - trace_gas.moles = 2000 - adding.trace_gases += trace_gas - adding.temperature = T20C - - assume_air(adding) + assume_gas("sleeping_agent", 2000) /turf/simulated/floor/engine/vacuum name = "vacuum floor" diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm index 8834a7770ba..5585de31d87 100644 --- a/code/game/turfs/simulated/walls_mineral.dm +++ b/code/game/turfs/simulated/walls_mineral.dm @@ -87,13 +87,7 @@ new /obj/structure/girder(src) src.ChangeTurf(/turf/simulated/floor) for(var/turf/simulated/floor/target_tile in range(0,src)) - /*if(target_tile.parent && target_tile.parent.group_processing) - target_tile.parent.suspend_group_processing()*/ - var/datum/gas_mixture/napalm = new - var/phoronToDeduce = 20 - napalm.phoron = phoronToDeduce - napalm.temperature = 400+T0C - target_tile.assume_air(napalm) + target_tile.assume_gas("phoron", 20, 400+T0C) spawn (0) target_tile.hotspot_expose(temperature, 400) for(var/obj/structure/falsewall/phoron/F in range(3,src))//Hackish as fuck, but until temperature_expose works, there is nothing I can do -Sieve var/turf/T = get_turf(F) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index f0d206ec710..8168a34f0c5 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -132,14 +132,6 @@ M:inertia_dir = 0 ..() var/objects = 0 - for(var/atom/A as mob|obj|turf|area in src) - if(objects > loopsanity) break - objects++ - spawn( 0 ) - if ((A && M)) - A.HasEntered(M, 1) - return - objects = 0 for(var/atom/A as mob|obj|turf|area in range(1)) if(objects > loopsanity) break objects++ @@ -222,6 +214,7 @@ ///// Z-Level Stuff var/old_lumcount = lighting_lumcount - initial(lighting_lumcount) + var/obj/fire/old_fire = fire //world << "Replacing [src.type] with [N]" @@ -250,6 +243,9 @@ W.lighting_changed = 1 lighting_controller.changed_turfs += W + if(old_fire) + fire = old_fire + if (istype(W,/turf/simulated/floor)) W.RemoveLattice() @@ -271,6 +267,9 @@ W.lighting_changed = 1 lighting_controller.changed_turfs += W + if(old_fire) + old_fire.RemoveFire() + if(air_master) air_master.mark_for_update(src) diff --git a/code/global.dm b/code/global.dm index ac068a92e33..6a9e43c3cf2 100644 --- a/code/global.dm +++ b/code/global.dm @@ -2,8 +2,6 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 var/global/obj/effect/datacore/data_core = null -var/global/obj/effect/overlay/plmaster = null -var/global/obj/effect/overlay/slmaster = null var/global/list/active_areas = list() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index bf6c5559975..fef38f3b35d 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -152,7 +152,7 @@ var/list/admin_verbs_debug = list( /client/proc/callproc, /client/proc/toggledebuglogs, /client/proc/SDQL_query, - /client/proc/SDQL2_query + /client/proc/SDQL2_query, ) var/list/admin_verbs_possess = list( /proc/possess, @@ -304,7 +304,6 @@ var/list/admin_verbs_mentor = list( /client/proc/camera_view, /client/proc/sec_camera_report, /client/proc/intercom_view, - /client/proc/air_status, /client/proc/atmosscan, /client/proc/powerdebug, /client/proc/count_objects_on_z_level, diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index d2a53f0aff1..0076cded1bd 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -131,7 +131,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/Cell() set category = "Debug" - set name = "Air Status in Location" + set name = "Cell" if(!mob) return var/turf/T = mob.loc @@ -141,11 +141,11 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/datum/gas_mixture/env = T.return_air() - var/t = "" - t+= "Nitrogen : [env.nitrogen]\n" - t+= "Oxygen : [env.oxygen]\n" - t+= "Phoron : [env.phoron]\n" - t+= "CO2: [env.carbon_dioxide]\n" + var/t = "\blue Coordinates: [T.x],[T.y],[T.z]\n" + t += "\red Temperature: [env.temperature]\n" + t += "\red Pressure: [env.return_pressure()]kPa\n" + for(var/g in env.gas) + t += "\blue [g]: [env.gas[g]] / [env.gas[g] * R_IDEAL_GAS_EQUATION * env.temperature / env.volume]kPa\n" usr.show_message(t, 1) feedback_add_details("admin_verb","ASL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -956,7 +956,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(Rad.anchored) if(!Rad.P) var/obj/item/weapon/tank/phoron/Phoron = new/obj/item/weapon/tank/phoron(Rad) - Phoron.air_contents.phoron = 70 + Phoron.air_contents.gas["phoron"] = 70 Rad.drainratio = 0 Rad.P = Phoron Phoron.loc = Rad @@ -999,7 +999,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/obj/item/weapon/tank/phoron/Phoron = new/obj/item/weapon/tank/phoron(Rad) - Phoron.air_contents.phoron = 29.1154 //This is a full tank if you filled it from a canister + Phoron.air_contents.gas["phoron"] = 29.1154 //This is a full tank if you filled it from a canister Rad.P = Phoron Phoron.loc = Rad @@ -1012,7 +1012,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/obj/machinery/atmospherics/binary/pump/Pump = M if(Pump.name == "Engine Feed" && response == "Setup Completely") found_the_pump = 1 - Pump.air2.nitrogen = 3750 //The contents of 2 canisters. + Pump.air2.gas["nitrogen"] = 3750 //The contents of 2 canisters. Pump.air2.temperature = 50 Pump.air2.update_values() Pump.on=1 @@ -1040,7 +1040,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(!found_the_pump && response == "Setup Completely") src << "\red Unable to locate air supply to fill up with coolant, adding some coolant around the supermatter" var/turf/simulated/T = SM.loc - T.zone.air.nitrogen += 450 + T.zone.air.gas["nitrogen"] += 450 T.zone.air.temperature = 50 T.zone.air.update_values() diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index ebef50f5ae1..ac27ba20a2e 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -41,27 +41,6 @@ usr << browse(output,"window=airreport") - -/client/proc/air_status(turf/target as turf) - set category = "Debug" - set name = "Display Air Status" - - /*(!isturf(target)) - return - - var/datum/gas_mixture/GM = target.return_air() - var/burning = 0 - if(istype(target, /turf/simulated)) - var/turf/simulated/T = target - if(T.active_hotspot) - burning = 1 - - usr << "\blue @[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.phoron] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]" - for(var/datum/gas/trace_gas in GM.trace_gases) - usr << "[trace_gas.type]: [trace_gas.moles]" - feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - */ - /client/proc/fix_next_move() set category = "Debug" set name = "Unfreeze Everyone" @@ -145,7 +124,7 @@ set category = "Debug" if(!check_rights(R_SERVER)) return - + message_admins("[usr] manually reloaded Mentors") world.load_mods() diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 0a7c1fe345e..6e2bd20e322 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -129,7 +129,6 @@ var/list/debug_verbs = list ( ,/client/proc/camera_view ,/client/proc/sec_camera_report ,/client/proc/intercom_view - ,/client/proc/air_status ,/client/proc/Cell ,/client/proc/atmosscan ,/client/proc/powerdebug diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 49ded54e4c5..e5b1555b0d9 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -212,12 +212,14 @@ var/list/forbidden_varedit_object_types = list( usr << "If a direction, direction is: [dir]" var/class = "text" + var/list/choices = list("text","num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])", "DELETE FROM LIST") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default", "DELETE FROM LIST") + choices += "marked datum ([holder.marked_datum.type])" + if(!isnull(default) && default != "num" && !isnull(L[variable])) + choices += "edit associated variable" + choices += "DELETE FROM LIST" + + class = input("What kind of variable?","Variable Type",default) as null|anything in choices if(!class) return @@ -264,6 +266,11 @@ var/list/forbidden_varedit_object_types = list( if("marked datum") L[L.Find(variable)] = holder.marked_datum + if("edit associated variable") + var/temp_var = mod_list_add_ass() + if(temp_var) + L[variable] = temp_var + /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) if(!check_rights(R_VAREDIT)) return diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 65a43a6468e..05dd13a7bca 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -100,7 +100,7 @@ return /obj/item/weapon/tank/proc/ignite() //This happens when a bomb is told to explode - var/fuel_moles = air_contents.phoron + air_contents.oxygen/6 + var/fuel_moles = air_contents.gas["phoron"] + air_contents.gas["oxygen"] / 6 var/strength = 1 var/turf/ground_zero = get_turf(loc) @@ -148,7 +148,7 @@ del(src) /obj/item/weapon/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. - var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles()) + var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles) var/turf/simulated/T = get_turf(src) if(!T) return diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 7d834bd0a00..477313114d2 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -104,13 +104,13 @@ special_assembly.HasProximity(AM) - HasEntered(atom/movable/AM as mob|obj) + Crossed(atom/movable/AM as mob|obj) if(a_left) - a_left.HasEntered(AM) + a_left.Crossed(AM) if(a_right) - a_right.HasEntered(AM) + a_right.Crossed(AM) if(special_assembly) - special_assembly.HasEntered(AM) + special_assembly.Crossed(AM) on_found(mob/finder as mob) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 50697f503a5..50b2c862058 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -251,7 +251,7 @@ hit() return -/obj/effect/beam/i_beam/HasEntered(atom/movable/AM as mob|obj) +/obj/effect/beam/i_beam/Crossed(atom/movable/AM as mob|obj) if(istype(AM, /obj/effect/beam)) return spawn(0) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 3c22613022c..959b2edc031 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -81,7 +81,7 @@ ..() - HasEntered(AM as mob|obj) + Crossed(AM as mob|obj) if(armed) if(ishuman(AM)) var/mob/living/carbon/H = AM diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f6681f9d22f..558bb9dcb77 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -36,9 +36,9 @@ switch(target_species) if("Human", "Skrell") //humanoid bodytypes species_restricted = list("exclude","Unathi","Tajaran","Diona","Vox") - else + else species_restricted = list(target_species) - + if (sprite_sheets_obj && (target_species in sprite_sheets_obj)) icon = sprite_sheets_obj[target_species] @@ -48,9 +48,9 @@ species_restricted = list("exclude","Unathi","Tajaran","Diona","Vox") if("Human") species_restricted = list("exclude","Skrell","Unathi","Tajaran","Diona","Vox") - else + else species_restricted = list(target_species) - + if (sprite_sheets_obj && (target_species in sprite_sheets_obj)) icon = sprite_sheets_obj[target_species] @@ -190,6 +190,8 @@ BLIND // can't see anything slot_flags = SLOT_MASK sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi') +/obj/item/clothing/mask/proc/filter_air(datum/gas_mixture/air) + //Shoes /obj/item/clothing/shoes name = "shoes" diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 2b4d2548090..841c233f559 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -10,6 +10,20 @@ permeability_coefficient = 0.01 siemens_coefficient = 0.9 var/gas_filter_strength = 1 //For gas mask filters + var/list/filtered_gases = list("phoron", "sleeping_agent") + +/obj/item/clothing/mask/gas/filter_air(datum/gas_mixture/air) + var/datum/gas_mixture/filtered = new + + for(var/g in filtered_gases) + if(air.gas[g]) + filtered.gas[g] = air.gas[g] * gas_filter_strength + air.gas[g] -= filtered.gas[g] + + air.update_values() + filtered.update_values() + + return filtered //Plague Dr suit can be found in clothing/suits/bio.dm /obj/item/clothing/mask/gas/plaguedoctor diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 7751ef478dc..8ff9c616338 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -252,7 +252,7 @@ proc/check_panel(mob/M) return - HasEntered(var/mob/M, somenumber) + Crossed(var/mob/M, somenumber) if(M == my_target) step_away(src,my_target,2) if(prob(30)) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 13cc1933e23..58949e71a9c 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -69,15 +69,15 @@ ..() - -/mob/dead/observer/Topic(href, href_list) - if (href_list["track"]) - var/mob/target = locate(href_list["track"]) in mob_list - if(target) - ManualFollow(target) - - - + +/mob/dead/observer/Topic(href, href_list) + if (href_list["track"]) + var/mob/target = locate(href_list["track"]) in mob_list + if(target) + ManualFollow(target) + + + /mob/dead/attackby(obj/item/W, mob/user) if(istype(W,/obj/item/weapon/tome)) var/mob/dead/M = src @@ -111,7 +111,7 @@ Works together with spawning an observer, noted above. for(var/image/hud in client.images) if(copytext(hud.icon_state,1,4) == "hud") client.images.Remove(hud) - + if(antagHUD) var/list/target_list = list() for(var/mob/living/target in oview(src, 14)) @@ -123,19 +123,19 @@ Works together with spawning an observer, noted above. process_medHUD(src) -/mob/dead/proc/process_medHUD(var/mob/M) - var/client/C = M.client - for(var/mob/living/carbon/human/patient in oview(M, 14)) - C.images += patient.hud_list[HEALTH_HUD] - C.images += patient.hud_list[STATUS_HUD_OOC] - -/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U) - var/client/C = U.client - for(var/mob/living/carbon/human/target in target_list) - C.images += target.hud_list[SPECIALROLE_HUD] - - -/* +/mob/dead/proc/process_medHUD(var/mob/M) + var/client/C = M.client + for(var/mob/living/carbon/human/patient in oview(M, 14)) + C.images += patient.hud_list[HEALTH_HUD] + C.images += patient.hud_list[STATUS_HUD_OOC] + +/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U) + var/client/C = U.client + for(var/mob/living/carbon/human/target in target_list) + C.images += target.hud_list[SPECIALROLE_HUD] + + +/* else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. var/mob/living/silicon/silicon_target = target if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))||silicon_target.mind.special_role=="traitor") @@ -143,9 +143,9 @@ Works together with spawning an observer, noted above. U.client.images += image(tempHud,silicon_target,"hudmalborg") else U.client.images += image(tempHud,silicon_target,"hudmalai") -*/ - return 1 - +*/ + return 1 + /mob/proc/ghostize(var/can_reenter_corpse = 1) if(key) var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc. @@ -180,7 +180,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(NewLoc) loc = NewLoc for(var/obj/effect/step_trigger/S in NewLoc) - S.HasEntered(src) + S.Crossed(src) return loc = get_turf(src) //Get out of closets and such as a ghost @@ -194,7 +194,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp x-- for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb - S.HasEntered(src) + S.Crossed(src) /mob/dead/observer/examine() if(usr) @@ -256,10 +256,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set category = "Ghost" set name = "Toggle AntagHUD" set desc = "Toggles AntagHUD allowing you to see who is the antagonist" - - if(!client) - return - var/mentor = is_mentor(usr.client) + + if(!client) + return + var/mentor = is_mentor(usr.client) if(!config.antag_hud_allowed && (!client.holder || mentor)) src << "\red Admins have disabled this for this round." return @@ -387,9 +387,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/analyze_air() set name = "Analyze Air" set category = "Ghost" - + if(!istype(usr, /mob/dead/observer)) return - + // Shamelessly copied from the Gas Analyzers if (!( istype(usr.loc, /turf) )) return @@ -397,7 +397,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/datum/gas_mixture/environment = usr.loc.return_air() var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() + var/total_moles = environment.total_moles src << "\blue Results:" if(abs(pressure - ONE_ATMOSPHERE) < 10) @@ -405,33 +405,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp else src << "\red Pressure: [round(pressure,0.1)] kPa" if(total_moles) - var/o2_concentration = environment.oxygen/total_moles - var/n2_concentration = environment.nitrogen/total_moles - var/co2_concentration = environment.carbon_dioxide/total_moles - var/phoron_concentration = environment.phoron/total_moles - - var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+phoron_concentration) - if(abs(n2_concentration - N2STANDARD) < 20) - src << "\blue Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)" - else - src << "\red Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)" - - if(abs(o2_concentration - O2STANDARD) < 2) - src << "\blue Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)" - else - src << "\red Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)" - - if(co2_concentration > 0.01) - src << "\red CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)" - else - src << "\blue CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)" - - if(phoron_concentration > 0.01) - src << "\red Phoron: [round(phoron_concentration*100)]% ([round(environment.phoron,0.01)] moles)" - - if(unknown_concentration > 0.01) - src << "\red Unknown: [round(unknown_concentration*100)]% ([round(unknown_concentration*total_moles,0.01)] moles)" - + for(var/g in environment.gas) + src << "\blue [gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]% ([round(environment.gas[g], 0.01)] moles)" src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]°C" src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]" @@ -572,4 +547,4 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp W.update_icon() W.message = message W.add_hiddenprint(src) - W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...") + W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...") diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index cd62ff9b2c4..15ff3dd7218 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -123,7 +123,7 @@ breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature) else*/ // Not enough air around, take a percentage of what's there to model this properly - breath_moles = environment.total_moles()*BREATH_PERCENTAGE + breath_moles = environment.total_moles*BREATH_PERCENTAGE breath = loc.remove_air(breath_moles) @@ -172,24 +172,24 @@ return 0 var/phoron_used = 0 - var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME + var/breath_pressure = (breath.total_moles * R_IDEAL_GAS_EQUATION * breath.temperature) / BREATH_VOLUME //Partial pressure of the phoron in our breath - var/Toxins_pp = (breath.phoron/breath.total_moles())*breath_pressure + var/Toxins_pp = (breath.gas["phoron"] / breath.total_moles) * breath_pressure if(Toxins_pp) // Detect phoron in air - adjustToxLoss(breath.phoron*250) + adjustToxLoss(breath.gas["phoron"] * 250) phoron_alert = max(phoron_alert, 1) - phoron_used = breath.phoron + phoron_used = breath.gas["phoron"] else phoron_alert = 0 //Breathe in phoron and out oxygen - breath.phoron -= phoron_used - breath.oxygen += phoron_used + breath.adjust_gas("phoron", -phoron_used) + breath.adjust_gas("oxygen", phoron_used) if(breath.temperature > (T0C+66) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :( if(prob(20)) diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 975dd29dc8c..cc9dbaea988 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -98,7 +98,7 @@ breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature) else*/ // Not enough air around, take a percentage of what's there to model this properly - breath_moles = environment.total_moles()*BREATH_PERCENTAGE + breath_moles = environment.total_moles*BREATH_PERCENTAGE breath = loc.remove_air(breath_moles) @@ -147,24 +147,24 @@ return 0 var/phoron_used = 0 - var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME + var/breath_pressure = (breath.total_moles * R_IDEAL_GAS_EQUATION * breath.temperature) / BREATH_VOLUME //Partial pressure of the phoron in our breath - var/Toxins_pp = (breath.phoron/breath.total_moles())*breath_pressure + var/Toxins_pp = (breath.gas["phoron"] / breath.total_moles) * breath_pressure if(Toxins_pp) // Detect phoron in air - adjustToxLoss(breath.phoron*250) + adjustToxLoss(breath.gas["phoron"] * 250) phoron_alert = max(phoron_alert, 1) - phoron_used = breath.phoron + phoron_used = breath.gas["phoron"] else phoron_alert = 0 //Breathe in phoron and out oxygen - breath.phoron -= phoron_used - breath.oxygen += phoron_used + breath.adjust_gas("phoron", -phoron_used) + breath.adjust_gas("oxygen", phoron_used) if(breath.temperature > (T0C+66) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :( if(prob(20)) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 48c16a99839..8c7afca770b 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -80,7 +80,7 @@ var/const/MAX_ACTIVE_TIME = 400 /obj/item/clothing/mask/facehugger/equipped(mob/M) Attach(M) -/obj/item/clothing/mask/facehugger/HasEntered(atom/target) +/obj/item/clothing/mask/facehugger/Crossed(atom/target) HasProximity(target) return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index fca5ffa0655..63117913a08 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -450,7 +450,7 @@ // called when something steps onto a human // this handles mulebots and vehicles -/mob/living/carbon/human/HasEntered(var/atom/movable/AM) +/mob/living/carbon/human/Crossed(var/atom/movable/AM) if(istype(AM, /obj/machinery/bot/mulebot)) var/obj/machinery/bot/mulebot/MB = AM MB.RunOver(src) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index f772fe58400..bfcffff42df 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -354,26 +354,15 @@ breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature) else*/ // Not enough air around, take a percentage of what's there to model this properly - breath_moles = environment.total_moles()*BREATH_PERCENTAGE + breath_moles = environment.total_moles*BREATH_PERCENTAGE breath = loc.remove_air(breath_moles) - if(istype(wear_mask, /obj/item/clothing/mask/gas) && breath) - var/obj/item/clothing/mask/gas/G = wear_mask - var/datum/gas_mixture/filtered = new - - filtered.copy_from(breath) - filtered.phoron *= G.gas_filter_strength - for(var/datum/gas/gas in filtered.trace_gases) - gas.moles *= G.gas_filter_strength - filtered.update_values() + if(istype(wear_mask, /obj/item/clothing/mask) && breath) + var/obj/item/clothing/mask/M = wear_mask + var/datum/gas_mixture/filtered = M.filter_air(breath) loc.assume_air(filtered) - breath.phoron *= 1 - G.gas_filter_strength - for(var/datum/gas/gas in breath.trace_gases) - gas.moles *= 1 - G.gas_filter_strength - breath.update_values() - if(!is_lung_ruptured()) if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5) if(prob(5)) @@ -436,7 +425,7 @@ if(status_flags & GODMODE) return - if(!breath || (breath.total_moles() == 0) || suiciding) + if(!breath || (breath.total_moles == 0) || suiciding) if(suiciding) adjustOxyLoss(2)//If you are suiciding, you should die a little bit faster failed_last_breath = 1 @@ -461,51 +450,41 @@ var/SA_sleep_min = 5 var/inhaled_gas_used = 0 - var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME + var/breath_pressure = (breath.total_moles*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/inhaling - var/exhaling var/poison + var/exhaling var/no_exhale + var/breath_type + var/poison_type + var/exhale_type + var/failed_inhale = 0 var/failed_exhale = 0 - switch(species.breath_type) - if("nitrogen") - inhaling = breath.nitrogen - if("phoron") - inhaling = breath.phoron - if("carbon_dioxide") - inhaling = breath.carbon_dioxide - else - inhaling = breath.oxygen + if(species.breath_type) + breath_type = species.breath_type + inhaling = breath.gas[breath_type] + else + inhaling = "oxygen" - switch(species.poison_type) - if("oxygen") - poison = breath.oxygen - if("nitrogen") - poison = breath.nitrogen - if("carbon_dioxide") - poison = breath.carbon_dioxide - else - poison = breath.phoron + if(species.poison_type) + poison_type = species.poison_type + poison = breath.gas[poison_type] + else + poison = "phoron" - switch(species.exhale_type) - if("carbon_dioxide") - exhaling = breath.carbon_dioxide - if("oxygen") - exhaling = breath.oxygen - if("nitrogen") - exhaling = breath.nitrogen - if("phoron") - exhaling = breath.phoron - else - no_exhale = 1 + if(species.exhale_type) + exhale_type = species.exhale_type + exhaling = breath.gas[exhale_type] + else + no_exhale = 1 - var/inhale_pp = (inhaling/breath.total_moles())*breath_pressure - var/toxins_pp = (poison/breath.total_moles())*breath_pressure - var/exhaled_pp = (exhaling/breath.total_moles())*breath_pressure + var/inhale_pp = (inhaling/breath.total_moles)*breath_pressure + var/toxins_pp = (poison/breath.total_moles)*breath_pressure + var/exhaled_pp = (exhaling/breath.total_moles)*breath_pressure // Not enough to breathe if(inhale_pp < safe_pressure_min) @@ -532,32 +511,16 @@ inhaled_gas_used = inhaling/6 oxygen_alert = 0 - switch(species.breath_type) - if("nitrogen") - breath.nitrogen -= inhaled_gas_used - if("phoron") - breath.phoron -= inhaled_gas_used - if("carbon_dioxide") - breath.carbon_dioxide-= inhaled_gas_used - else - breath.oxygen -= inhaled_gas_used + breath.adjust_gas(breath_type, -inhaled_gas_used) if(!no_exhale) - switch(species.exhale_type) - if("oxygen") - breath.oxygen += inhaled_gas_used - if("nitrogen") - breath.nitrogen += inhaled_gas_used - if("phoron") - breath.phoron += inhaled_gas_used - if("CO2") - breath.carbon_dioxide += inhaled_gas_used + breath.adjust_gas(exhale_type, inhaled_gas_used) // Too much exhaled gas in the air if(exhaled_pp > safe_exhaled_max) if (!co2_alert|| prob(15)) var/word = pick("extremely dizzy","short of breath","faint","confused") - src << "\red You feel [word]." + src << "You feel [word]." adjustOxyLoss(HUMAN_MAX_OXYLOSS) co2_alert = 1 @@ -566,7 +529,7 @@ else if(exhaled_pp > safe_exhaled_max * 0.7) if (!co2_alert || prob(1)) var/word = pick("dizzy","short of breath","faint","momentarily confused") - src << "\red You feel [word]." + src << "You feel [word]." else co2_alert = 0 @@ -594,26 +557,27 @@ else phoron_alert = 0 + + // If there's some other shit in the air lets deal with it here. - if(breath.trace_gases.len) - for(var/datum/gas/sleeping_agent/SA in breath.trace_gases) - var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure + if(breath.gas["sleeping_agent"]) + var/SA_pp = (breath.gas["sleeping_agent"] / breath.total_moles) * breath_pressure - // Enough to make us paralysed for a bit - if(SA_pp > SA_para_min) + // Enough to make us paralysed for a bit + if(SA_pp > SA_para_min) - // 3 gives them one second to wake up and run away a bit! - Paralyse(3) + // 3 gives them one second to wake up and run away a bit! + Paralyse(3) - // Enough to make us sleep as well - if(SA_pp > SA_sleep_min) - sleeping = min(sleeping+2, 10) + // Enough to make us sleep as well + if(SA_pp > SA_sleep_min) + sleeping = min(sleeping+2, 10) - // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning - else if(SA_pp > 0.15) - if(prob(20)) - spawn(0) emote(pick("giggle", "laugh")) - SA.moles = 0 + // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning + else if(SA_pp > 0.15) + if(prob(20)) + spawn(0) emote(pick("giggle", "laugh")) + breath.adjust_gas("sleeping_agent", -breath.gas["sleeping_agent"]) // Were we able to breathe? if (failed_inhale || failed_exhale) @@ -630,10 +594,10 @@ if(breath.temperature < species.cold_level_1) if(prob(20)) - src << "\red You feel your face freezing and icicles forming in your lungs!" + src << "You feel your face freezing and icicles forming in your lungs!" else if(breath.temperature > species.heat_level_1) if(prob(20)) - src << "\red You feel your face burning and a searing heat in your lungs!" + src << "You feel your face burning and a searing heat in your lungs!" switch(breath.temperature) if(-INFINITY to species.cold_level_3) @@ -662,7 +626,7 @@ else temp_adj /= (BODYTEMP_HEAT_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed - var/relative_density = breath.total_moles() / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE) + var/relative_density = breath.total_moles / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE) temp_adj *= relative_density if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX @@ -689,7 +653,7 @@ else loc_temp = environment.temperature - if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1 && environment.phoron < MOLES_PHORON_VISIBLE) + if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1) pressure_alert = 0 return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp @@ -705,7 +669,7 @@ temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR) //Use heat transfer as proportional to the gas density. However, we only care about the relative density vs standard 101 kPa/20 C air. Therefore we can use mole ratios - var/relative_density = environment.total_moles() / MOLES_CELLSTANDARD + var/relative_density = environment.total_moles / MOLES_CELLSTANDARD temp_adj *= relative_density if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX @@ -765,8 +729,10 @@ else pressure_alert = -1 - if(environment.phoron > MOLES_PHORON_VISIBLE) - pl_effects() + for(var/g in environment.gas) + if(gas_data.flags[g] & XGM_GAS_CONTAMINANT && environment.gas[g] > gas_data.overlay_limit[g] + 1) + pl_effects() + break return /* diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 19cfe316868..091c5630301 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -237,25 +237,14 @@ var/obj/location_as_object = loc breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME) else if(istype(loc, /turf/)) - var/breath_moles = environment.total_moles()*BREATH_PERCENTAGE + var/breath_moles = environment.total_moles*BREATH_PERCENTAGE breath = loc.remove_air(breath_moles) - if(istype(wear_mask, /obj/item/clothing/mask/gas)) - var/obj/item/clothing/mask/gas/G = wear_mask - var/datum/gas_mixture/filtered = new - - filtered.copy_from(breath) - filtered.phoron *= G.gas_filter_strength - for(var/datum/gas/gas in filtered.trace_gases) - gas.moles *= G.gas_filter_strength - filtered.update_values() + if(istype(wear_mask, /obj/item/clothing/mask) && breath) + var/obj/item/clothing/mask/M = wear_mask + var/datum/gas_mixture/filtered = M.filter_air(breath) loc.assume_air(filtered) - breath.phoron *= 1 - G.gas_filter_strength - for(var/datum/gas/gas in breath.trace_gases) - gas.moles *= 1 - G.gas_filter_strength - breath.update_values() - // Handle chem smoke effect -- Doohl var/block = 0 if(wear_mask) @@ -316,14 +305,14 @@ var/SA_para_min = 0.5 var/SA_sleep_min = 5 var/oxygen_used = 0 - var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME + var/breath_pressure = (breath.total_moles * R_IDEAL_GAS_EQUATION * breath.temperature) / BREATH_VOLUME //Partial pressure of the O2 in our breath - var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure + var/O2_pp = (breath.gas["oxygen"] / breath.total_moles) * breath_pressure // Same, but for the phoron - var/Toxins_pp = (breath.phoron/breath.total_moles())*breath_pressure + var/Toxins_pp = (breath.gas["phoron"] / breath.total_moles) * breath_pressure // And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun) - var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure + var/CO2_pp = (breath.gas["carbon_dioxide"] / breath.total_moles) * breath_pressure if(O2_pp < safe_oxygen_min) // Too little oxygen if(prob(20)) @@ -332,7 +321,7 @@ O2_pp = 0.01 var/ratio = safe_oxygen_min/O2_pp adjustOxyLoss(min(5*ratio, 7)) // Don't fuck them up too fast (space only does 7 after all!) - oxygen_used = breath.oxygen*ratio/6 + oxygen_used = breath.gas["oxygen"] * ratio / 6 oxygen_alert = max(oxygen_alert, 1) /*else if (O2_pp > safe_oxygen_max) // Too much oxygen (commented this out for now, I'll deal with pressure damage elsewhere I suppose) spawn(0) emote("cough") @@ -342,11 +331,11 @@ oxygen_alert = max(oxygen_alert, 1)*/ else // We're in safe limits adjustOxyLoss(-5) - oxygen_used = breath.oxygen/6 + oxygen_used = breath.gas["oxygen"] / 6 oxygen_alert = 0 - breath.oxygen -= oxygen_used - breath.carbon_dioxide += oxygen_used + breath.adjust_gas("oxygen", -oxygen_used) + breath.adjust_gas("carbon_dioxide", oxygen_used) if(CO2_pp > safe_co2_max) if(!co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so. @@ -363,7 +352,7 @@ co2overloadtime = 0 if(Toxins_pp > safe_phoron_max) // Too much phoron - var/ratio = (breath.phoron/safe_phoron_max) * 10 + var/ratio = (breath.gas["phoron"] / safe_phoron_max) * 10 //adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) //Limit amount of damage toxin exposure can do per second if(reagents) reagents.add_reagent("toxin", Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE)) @@ -371,16 +360,15 @@ else phoron_alert = 0 - if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here. - for(var/datum/gas/sleeping_agent/SA in breath.trace_gases) - var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure - if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit - Paralyse(3) // 3 gives them one second to wake up and run away a bit! - if(SA_pp > SA_sleep_min) // Enough to make us sleep as well - sleeping = max(sleeping+2, 10) - else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning - if(prob(20)) - spawn(0) emote(pick("giggle", "laugh")) + if(breath.gas["sleeping_agent"]) + var/SA_pp = (breath.gas["sleeping_agent"] / breath.total_moles) * breath_pressure + if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit + Paralyse(3) // 3 gives them one second to wake up and run away a bit! + if(SA_pp > SA_sleep_min) // Enough to make us sleep as well + sleeping = max(sleeping+2, 10) + else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning + if(prob(20)) + spawn(0) emote(pick("giggle", "laugh")) if(breath.temperature > (T0C+66)) // Hot air hurts :( @@ -403,7 +391,7 @@ var/pressure = environment.return_pressure() var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. - if(adjusted_pressure < WARNING_HIGH_PRESSURE && adjusted_pressure > WARNING_LOW_PRESSURE && abs(environment.temperature - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.phoron < MOLES_PHORON_VISIBLE) + if(adjusted_pressure < WARNING_HIGH_PRESSURE && adjusted_pressure > WARNING_LOW_PRESSURE && abs(environment.temperature - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.gas["phoron"] < gas_data.overlay_limit["phoron"]) //Hopefully should fix the walk-inside-still-pressure-warning issue. if(pressure_alert) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index e3028fc08ca..ae4dcc54fc9 100755 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -576,22 +576,13 @@ var/datum/gas_mixture/environment = T.return_air() var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() + var/total_moles = environment.total_moles dat += "Air Pressure: [round(pressure,0.1)] kPa
" - if (total_moles) - var/o2_level = environment.oxygen/total_moles - var/n2_level = environment.nitrogen/total_moles - var/co2_level = environment.carbon_dioxide/total_moles - var/phoron_level = environment.phoron/total_moles - var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) - dat += "Nitrogen: [round(n2_level*100)]%
" - dat += "Oxygen: [round(o2_level*100)]%
" - dat += "Carbon Dioxide: [round(co2_level*100)]%
" - dat += "Phoron: [round(phoron_level*100)]%
" - if(unknown_level > 0.01) - dat += "OTHER: [round(unknown_level)]%
" + if(total_moles) + for(var/g in environment.gas) + dat += "[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]%
" dat += "Temperature: [round(environment.temperature-T0C)]°C
" dat += "
Refresh Reading" return dat diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index f897d2de569..5a13dccc49b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -126,7 +126,7 @@ src << "You are too small to pull anything." return -/mob/living/simple_animal/mouse/HasEntered(AM as mob|obj) +/mob/living/simple_animal/mouse/Crossed(AM as mob|obj) if( ishuman(AM) ) if(!stat) var/mob/M = AM diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index c3c8cde75ed..628534e75b1 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -141,41 +141,41 @@ //Atmos var/atmos_suitable = 1 - var/atom/A = src.loc + var/atom/A = src.loc if(istype(A,/turf)) - var/turf/T = A - + var/turf/T = A + var/datum/gas_mixture/Environment = T.return_air() - + if(Environment) - + if( abs(Environment.temperature - bodytemperature) > 40 ) bodytemperature += ((Environment.temperature - bodytemperature) / 5) - + if(min_oxy) - if(Environment.oxygen < min_oxy) + if(Environment.gas["oxygen"] < min_oxy) atmos_suitable = 0 if(max_oxy) - if(Environment.oxygen > max_oxy) + if(Environment.gas["oxygen"] > max_oxy) atmos_suitable = 0 if(min_tox) - if(Environment.phoron < min_tox) + if(Environment.gas["phoron"] < min_tox) atmos_suitable = 0 if(max_tox) - if(Environment.phoron > max_tox) + if(Environment.gas["phoron"] > max_tox) atmos_suitable = 0 if(min_n2) - if(Environment.nitrogen < min_n2) + if(Environment.gas["nitrogen"] < min_n2) atmos_suitable = 0 if(max_n2) - if(Environment.nitrogen > max_n2) + if(Environment.gas["nitrogen"] > max_n2) atmos_suitable = 0 if(min_co2) - if(Environment.carbon_dioxide < min_co2) + if(Environment.gas["carbon_dioxide"] < min_co2) atmos_suitable = 0 if(max_co2) - if(Environment.carbon_dioxide > max_co2) + if(Environment.gas["carbon_dioxide"] > max_co2) atmos_suitable = 0 //Atmos effect diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 0177034e806..2f92ffeffb2 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -13,25 +13,6 @@ living_mob_list += src ..() -/mob/proc/Cell() - set category = "Admin" - set hidden = 1 - - if(!loc) return 0 - - var/datum/gas_mixture/environment = loc.return_air() - - var/t = "\blue Coordinates: [x],[y] \n" - t+= "\red Temperature: [environment.temperature] \n" - t+= "\blue Nitrogen: [environment.nitrogen] \n" - t+= "\blue Oxygen: [environment.oxygen] \n" - t+= "\blue Phoron : [environment.phoron] \n" - t+= "\blue Carbon Dioxide: [environment.carbon_dioxide] \n" - for(var/datum/gas/trace_gas in environment.trace_gases) - usr << "\blue [trace_gas.type]: [trace_gas.moles] \n" - - usr.show_message(t, 1) - /mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) if(!client) return diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index bba93c26bc3..be32b3d41c6 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -27,12 +27,11 @@ var/global/list/rad_collectors = list() /obj/machinery/power/rad_collector/process() if(P) - if(P.air_contents.phoron <= 0) + if(P.air_contents.gas["phoron"] == 0) investigate_log("out of fuel.","singulo") - P.air_contents.phoron = 0 eject() else - P.air_contents.adjust(tx = -0.001*drainratio) + P.air_contents.adjust_gas("phoron", -0.001*drainratio) return @@ -42,7 +41,7 @@ var/global/list/rad_collectors = list() toggle_power() user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \ "You turn the [src.name] [active? "on":"off"].") - investigate_log("turned [active?"on":"off"] by [user.key]. [P?"Fuel: [round(P.air_contents.phoron/0.29)]%":"It is empty"].","singulo") + investigate_log("turned [active?"on":"off"] by [user.key]. [P?"Fuel: [round(P.air_contents.gas["phoron"]/0.29)]%":"It is empty"].","singulo") return else user << "\red The controls are locked!" @@ -121,7 +120,7 @@ var/global/list/rad_collectors = list() /obj/machinery/power/rad_collector/proc/receive_pulse(var/pulse_strength) if(P && active) var/power_produced = 0 - power_produced = P.air_contents.phoron*pulse_strength*20 + power_produced = P.air_contents.gas["phoron"]*pulse_strength*20 add_avail(power_produced) last_power = power_produced return diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 07a93f4c60f..fd25e71df1f 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -70,7 +70,7 @@ return rpm = 0.9* rpm + 0.1 * rpmtarget var/datum/gas_mixture/environment = inturf.return_air() - var/transfer_moles = environment.total_moles()/10 + var/transfer_moles = environment.total_moles / 10 //var/transfer_moles = rpm/10000*capacity var/datum/gas_mixture/removed = inturf.remove_air(transfer_moles) gas_contained.merge(removed) @@ -129,14 +129,14 @@ lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) *TURBGENQ add_avail(lastgen) - var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles())/4 + var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles)/4 newrpm = max(0, newrpm) if(!compressor.starter || newrpm > 1000) compressor.rpmtarget = newrpm - if(compressor.gas_contained.total_moles()>0) - var/oamount = min(compressor.gas_contained.total_moles(), (compressor.rpm+100)/35000*compressor.capacity) + if(compressor.gas_contained.total_moles>0) + var/oamount = min(compressor.gas_contained.total_moles, (compressor.rpm+100)/35000*compressor.capacity) var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount) outturf.assume_air(removed) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 4d278053811..de8f974fb98 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -238,7 +238,7 @@ datum var/hotspot = (locate(/obj/fire) in T) if(hotspot && !istype(T, /turf/space)) - var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) + var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles ) lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0) lowertemp.react() T.assume_air(lowertemp) @@ -249,7 +249,7 @@ datum var/turf/T = get_turf(O) var/hotspot = (locate(/obj/fire) in T) if(hotspot && !istype(T, /turf/space)) - var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) + var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles ) lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0) lowertemp.react() T.assume_air(lowertemp) @@ -842,18 +842,18 @@ datum description = "Sterilizes wounds in preparation for surgery." reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 - + //makes you squeaky clean reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) if (method == TOUCH) M.germ_level -= min(volume*20, M.germ_level) - + reaction_obj(var/obj/O, var/volume) O.germ_level -= min(volume*20, O.germ_level) - + reaction_turf(var/turf/T, var/volume) T.germ_level -= min(volume*20, T.germ_level) - + /* reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) src = null if (method==TOUCH) @@ -1612,18 +1612,10 @@ datum egg.Hatch()*/ if((!O) || (!volume)) return 0 var/turf/the_turf = get_turf(O) - var/datum/gas_mixture/napalm = new - var/datum/gas/volatile_fuel/fuel = new - fuel.moles = volume - napalm.trace_gases += fuel - the_turf.assume_air(napalm) + the_turf.assume_gas("volatile_fuel", volume, T20C) reaction_turf(var/turf/T, var/volume) src = null - var/datum/gas_mixture/napalm = new - var/datum/gas/volatile_fuel/fuel = new - fuel.moles = volume - napalm.trace_gases += fuel - T.assume_air(napalm) + T.assume_gas("volatile_fuel", volume, T20C) return toxin/lexorin @@ -2339,7 +2331,7 @@ datum T.wet_overlay = null var/hotspot = (locate(/obj/fire) in T) if(hotspot) - var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) + var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles ) lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0) lowertemp.react() T.assume_air(lowertemp) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 2fab5c9400d..c8e317ca86f 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -406,16 +406,7 @@ datum on_reaction(var/datum/reagents/holder, var/created_volume) var/turf/location = get_turf(holder.my_atom.loc) for(var/turf/simulated/floor/target_tile in range(0,location)) - - var/datum/gas_mixture/napalm = new - var/datum/gas/volatile_fuel/fuel = new - fuel.moles = created_volume - napalm.trace_gases += fuel - - napalm.temperature = 400+T0C - napalm.update_values() - - target_tile.assume_air(napalm) + target_tile.assume_gas("volatile_fuel", created_volume, 400+T0C) spawn (0) target_tile.hotspot_expose(700, 400) holder.del_reagent("napalm") return @@ -1183,13 +1174,7 @@ datum sleep(50) var/turf/location = get_turf(holder.my_atom.loc) for(var/turf/simulated/floor/target_tile in range(0,location)) - - var/datum/gas_mixture/napalm = new - - napalm.phoron = 25 - napalm.temperature = 1400 - - target_tile.assume_air(napalm) + target_tile.assume_gas("phoron", 25, 1400) spawn (0) target_tile.hotspot_expose(700, 400) //Yellow diff --git a/code/modules/reagents/reagent_containers/food/snacks/grown.dm b/code/modules/reagents/reagent_containers/food/snacks/grown.dm index 9fb7fc2d977..d5938f3b7c4 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/grown.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/grown.dm @@ -728,7 +728,7 @@ del(src) return -/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/HasEntered(AM as mob|obj) +/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/Crossed(AM as mob|obj) if (istype(AM, /mob/living/carbon)) var/mob/M = AM if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index a22d6e03995..30058fd3571 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -107,7 +107,7 @@ var/datum/gas_mixture/env = L.return_air() if(env.temperature < (heat_amt+T0C)) - var/transfer_moles = 0.25 * env.total_moles() + var/transfer_moles = 0.25 * env.total_moles var/datum/gas_mixture/removed = env.remove(transfer_moles) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm b/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm index ae3539dbc43..30d2c6354ae 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm @@ -143,13 +143,13 @@ var/list/valid_secondary_effect_types = list(\ else if(env.temperature > 375) trigger_hot = 1 - if(env.phoron >= 10) + if(env.gas["phoron"] >= 10) trigger_phoron = 1 - if(env.oxygen >= 10) + if(env.gas["oxygen"] >= 10) trigger_oxy = 1 - if(env.carbon_dioxide >= 10) + if(env.gas["carbon_dioxide"] >= 10) trigger_co2 = 1 - if(env.nitrogen >= 10) + if(env.gas["nitrogen"] >= 10) trigger_nitro = 1 //COLD ACTIVATION diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasco2.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasco2.dm index c9cafa4e718..c486959afd9 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasco2.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasco2.dm @@ -1,26 +1,26 @@ - -/datum/artifact_effect/gasco2 - effecttype = "gasco2" - var/max_pressure - var/target_percentage - -/datum/artifact_effect/heat/New() - ..() - effect_type = pick(6,7) - -/datum/artifact_effect/gasco2/New() - ..() - effect = pick(EFFECT_TOUCH, EFFECT_AURA) - max_pressure = rand(115,1000) - -/datum/artifact_effect/gasco2/DoEffectTouch(var/mob/user) - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env) - env.carbon_dioxide += rand(2,15) - -/datum/artifact_effect/gasco2/DoEffectAura() - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env && env.total_moles < max_pressure) - env.carbon_dioxide += pick(0, 0, 0.1, rand()) + +/datum/artifact_effect/gasco2 + effecttype = "gasco2" + var/max_pressure + var/target_percentage + +/datum/artifact_effect/heat/New() + ..() + effect_type = pick(6,7) + +/datum/artifact_effect/gasco2/New() + ..() + effect = pick(EFFECT_TOUCH, EFFECT_AURA) + max_pressure = rand(115,1000) + +/datum/artifact_effect/gasco2/DoEffectTouch(var/mob/user) + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("carbon_dioxide", rand(2, 15)) + +/datum/artifact_effect/gasco2/DoEffectAura() + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("carbon_dioxide", pick(0, 0, 0.1, rand())) diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasnitro.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasnitro.dm index 527c2592aa9..6954ab3c77a 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasnitro.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasnitro.dm @@ -1,23 +1,23 @@ - -/datum/artifact_effect/gasnitro - effecttype = "gasnitro" - var/max_pressure - var/target_percentage - -/datum/artifact_effect/gasnitro/New() - ..() - effect = pick(EFFECT_TOUCH, EFFECT_AURA) - effect_type = pick(6,7) - max_pressure = rand(115,1000) - -/datum/artifact_effect/gasnitro/DoEffectTouch(var/mob/user) - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env) - env.nitrogen += rand(2,15) - -/datum/artifact_effect/gasnitro/DoEffectAura() - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env && env.total_moles < max_pressure) - env.nitrogen += pick(0, 0, 0.1, rand()) + +/datum/artifact_effect/gasnitro + effecttype = "gasnitro" + var/max_pressure + var/target_percentage + +/datum/artifact_effect/gasnitro/New() + ..() + effect = pick(EFFECT_TOUCH, EFFECT_AURA) + effect_type = pick(6,7) + max_pressure = rand(115,1000) + +/datum/artifact_effect/gasnitro/DoEffectTouch(var/mob/user) + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("nitrogen", rand(2, 15)) + +/datum/artifact_effect/gasnitro/DoEffectAura() + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("nitrogen", pick(0, 0, 0.1, rand())) diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasoxy.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasoxy.dm index d0daa6951fb..ae8d253652d 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasoxy.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasoxy.dm @@ -1,23 +1,23 @@ - -/datum/artifact_effect/gasoxy - effecttype = "gasoxy" - var/max_pressure - -/datum/artifact_effect/gasoxy/New() - ..() - effect = pick(EFFECT_TOUCH, EFFECT_AURA) - max_pressure = rand(115,1000) - effect_type = pick(6,7) - - -/datum/artifact_effect/gasoxy/DoEffectTouch(var/mob/user) - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env) - env.oxygen += rand(2,15) - -/datum/artifact_effect/gasoxy/DoEffectAura() - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env && env.total_moles < max_pressure) - env.oxygen += pick(0, 0, 0.1, rand()) + +/datum/artifact_effect/gasoxy + effecttype = "gasoxy" + var/max_pressure + +/datum/artifact_effect/gasoxy/New() + ..() + effect = pick(EFFECT_TOUCH, EFFECT_AURA) + max_pressure = rand(115,1000) + effect_type = pick(6,7) + + +/datum/artifact_effect/gasoxy/DoEffectTouch(var/mob/user) + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("oxygen", rand(2, 15)) + +/datum/artifact_effect/gasoxy/DoEffectAura() + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("oxygen", pick(0, 0, 0.1, rand())) diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasplasma.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasplasma.dm index 545d88a4a8e..d470a462b1b 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasplasma.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gasplasma.dm @@ -12,12 +12,12 @@ /datum/artifact_effect/gasphoron/DoEffectTouch(var/mob/user) if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env) - env.phoron += rand(2,15) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("oxygen", rand(2, 15)) /datum/artifact_effect/gasphoron/DoEffectAura() if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env && env.total_moles < max_pressure) - env.phoron += pick(0, 0, 0.1, rand()) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("phoron", pick(0, 0, 0.1, rand())) diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gassleeping.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gassleeping.dm index 5ce5256736c..afa1d0704c4 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gassleeping.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_gassleeping.dm @@ -1,31 +1,23 @@ - -/datum/artifact_effect/gassleeping - effecttype = "gassleeping" - var/max_pressure - var/target_percentage - -/datum/artifact_effect/gassleeping/New() - ..() - effect = pick(EFFECT_TOUCH, EFFECT_AURA) - max_pressure = rand(115,1000) - effect_type = pick(6,7) - -/datum/artifact_effect/gassleeping/DoEffectTouch(var/mob/user) - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env) - var/datum/gas/sleeping_agent/trace_gas = new - env.trace_gases += trace_gas - trace_gas.moles = rand(2,15) - env.update_values() - - -/datum/artifact_effect/gassleeping/DoEffectAura() - if(holder) - var/datum/gas_mixture/env = holder.loc.return_air() - if(env && env.total_moles < max_pressure) - var/datum/gas/sleeping_agent/trace_gas = new - env.trace_gases += trace_gas - trace_gas.moles = pick(0, 0, 0.1, rand()) - env.update_values() - + +/datum/artifact_effect/gassleeping + effecttype = "gassleeping" + var/max_pressure + var/target_percentage + +/datum/artifact_effect/gassleeping/New() + ..() + effect = pick(EFFECT_TOUCH, EFFECT_AURA) + max_pressure = rand(115,1000) + effect_type = pick(6,7) + +/datum/artifact_effect/gassleeping/DoEffectTouch(var/mob/user) + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("sleeping_agent", rand(2, 15)) + +/datum/artifact_effect/gassleeping/DoEffectAura() + if(holder) + var/turf/holder_loc = holder.loc + if(istype(holder_loc)) + holder_loc.assume_gas("sleeping_agent", pick(0, 0, 0.1, rand())) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index e7e3cc4972f..db66442df01 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -175,7 +175,7 @@ damage = max( damage + min( ( (removed.temperature - 800) / 150 ), damage_inc_limit ) , 0 ) //Ok, 100% oxygen atmosphere = best reaction //Maxes out at 100% oxygen pressure - oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) + oxygen = max(min((removed.gas["oxygen"] - (removed.gas["nitrogen"] * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) var/temp_factor = 100 @@ -212,11 +212,8 @@ removed.temperature = max(0, min(removed.temperature, 10000)) //Calculate how much gas to release - removed.phoron += max(device_energy / PHORON_RELEASE_MODIFIER, 0) - - removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) - - removed.update_values() + removed.adjust_multi("phoron", max(device_energy / PHORON_RELEASE_MODIFIER, 0), \ + "oxygen", max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0)) env.merge(removed) diff --git a/code/setup.dm b/code/setup.dm index 13974e022e7..fdf55a58382 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -16,7 +16,6 @@ #define MOLES_O2STANDARD MOLES_CELLSTANDARD*O2STANDARD // O2 standard value (21%) #define MOLES_N2STANDARD MOLES_CELLSTANDARD*N2STANDARD // N2 standard value (79%) -#define MOLES_PHORON_VISIBLE 0.7 //Moles in a standard cell after which phoron is visible #define MIN_TOXIN_DAMAGE 1 //This and MAX_TOXIN_DAMAGE are for when a mob breathes poisonous air #define MAX_TOXIN_DAMAGE 10 //This and MIN_TOXIN_DAMAGE are for when a mob breathes poisonous air @@ -135,6 +134,11 @@ #define T20C 293.15 // 20degC #define TCMB 2.7 // -270.3degC +//XGM gas flags +#define XGM_GAS_FUEL 1 +#define XGM_GAS_OXIDIZER 2 +#define XGM_GAS_CONTAMINANT 4 + //Used to be used by FEA //var/turf/space/Space_Tile = locate(/turf/space) // A space tile to reference when atmos wants to remove excess heat.