Buffs atmospheric analyzers to show mole count, volume and higher degrees of precision (#37631)
add: Analyzers can now scan all kinds of atmospheric machinery - unary, binary, ternary, quaternary, you name it. This means stuff like gas pumps, gas mixers, vents and so forth can be analyzed. tweak: Analyzers now show temperature in kelvin as well as celsius. tweak: Analyzers now show total mole count, volume, and mole count of all gases. tweak: Analyzers show everything at slightly higher degrees of precision. More accurate and advanced analyzers have been something that I think atmos and toxins mains have been wanting for a while now (including myself). It's always a pain to have to manually add 273.15 to every celsius temperature, or have to use outside tools or VV (which isnt usable in actual games) to calculate mole count for a gas mixture. Not to mention, the ability to analyze things like volume pumps and gas filters makes it easier to manage larger atmos setups. This is just a QoL change for people in any of those jobs. In fact, most players probably don't even know what the fuck is a mole is so adding mole readout to analyzers is a good way to get people to understand atmospherics better.
This commit is contained in:
@@ -827,12 +827,12 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
if(istype(C))
|
||||
switch(scanmode)
|
||||
|
||||
if(1)
|
||||
if(PDA_SCANNER_MEDICAL)
|
||||
C.visible_message("<span class='alert'>[user] has analyzed [C]'s vitals!</span>")
|
||||
healthscan(user, C, 1)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(4)
|
||||
if(PDA_SCANNER_HALOGEN)
|
||||
C.visible_message("<span class='warning'>[user] has analyzed [C]'s radiation levels!</span>")
|
||||
|
||||
user.show_message("<span class='notice'>Analyzing Results for [C]:</span>")
|
||||
@@ -845,8 +845,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
if(!proximity)
|
||||
return
|
||||
switch(scanmode)
|
||||
|
||||
if(3)
|
||||
if(PDA_SCANNER_REAGENT)
|
||||
if(!isnull(A.reagents))
|
||||
if(A.reagents.reagent_list.len > 0)
|
||||
var/reagents_length = A.reagents.reagent_list.len
|
||||
@@ -858,27 +857,8 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>No significant chemical agents found in [A].</span>")
|
||||
|
||||
if(5)
|
||||
if (istype(A, /obj/item/tank))
|
||||
var/obj/item/tank/T = A
|
||||
atmosanalyzer_scan(T.air_contents, user, T)
|
||||
else if (istype(A, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/PA = A
|
||||
atmosanalyzer_scan(PA.air_contents, user, PA)
|
||||
else if (istype(A, /obj/machinery/atmospherics/pipe))
|
||||
var/obj/machinery/atmospherics/pipe/P = A
|
||||
atmosanalyzer_scan(P.parent.air, user, P)
|
||||
else if (istype(A, /obj/machinery/atmospherics/components/unary))
|
||||
var/obj/machinery/atmospherics/components/unary/U = A
|
||||
atmosanalyzer_scan(U.airs[1], user, U)
|
||||
else if (istype(A, /obj/machinery/power/rad_collector))
|
||||
var/obj/machinery/power/rad_collector/RC = A
|
||||
if(RC.loaded_tank)
|
||||
atmosanalyzer_scan(RC.loaded_tank.air_contents, user, RC)
|
||||
else if (istype(A, /obj/item/flamethrower))
|
||||
var/obj/item/flamethrower/F = A
|
||||
if(F.ptank)
|
||||
atmosanalyzer_scan(F.ptank.air_contents, user, F)
|
||||
if(PDA_SCANNER_GAS)
|
||||
A.analyzer_act(user, src)
|
||||
|
||||
if (!scanmode && istype(A, /obj/item/paper) && owner)
|
||||
var/obj/item/paper/PP = A
|
||||
@@ -1015,6 +995,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
#undef PDA_SCANNER_NONE
|
||||
#undef PDA_SCANNER_MEDICAL
|
||||
#undef PDA_SCANNER_FORENSICS
|
||||
#undef PDA_SCANNER_REAGENT
|
||||
#undef PDA_SCANNER_HALOGEN
|
||||
#undef PDA_SCANNER_GAS
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
|
||||
/*
|
||||
|
||||
CONTAINS:
|
||||
T-RAY
|
||||
HEALTH ANALYZER
|
||||
GAS ANALYZER
|
||||
SLIME SCANNER
|
||||
|
||||
*/
|
||||
/obj/item/t_scanner
|
||||
@@ -341,7 +343,7 @@ GAS ANALYZER
|
||||
desc = "A hand-held environmental scanner which reports current gas levels. Alt-Click to use the built in barometer function."
|
||||
name = "analyzer"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "atmos"
|
||||
icon_state = "analyzer"
|
||||
item_state = "analyzer"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
@@ -351,6 +353,7 @@ GAS ANALYZER
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
tool_behaviour = TOOL_ANALYZER
|
||||
materials = list(MAT_METAL=30, MAT_GLASS=20)
|
||||
grind_results = list("mercury" = 5, "iron" = 5, "silicon" = 5)
|
||||
var/cooldown = FALSE
|
||||
@@ -362,7 +365,6 @@ GAS ANALYZER
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/analyzer/attack_self(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if (user.stat || user.eye_blind)
|
||||
@@ -379,9 +381,9 @@ GAS ANALYZER
|
||||
|
||||
to_chat(user, "<span class='info'><B>Results:</B></span>")
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
to_chat(user, "<span class='info'>Pressure: [round(pressure, 0.01)] kPa</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
|
||||
if(total_moles)
|
||||
var/list/env_gases = environment.gases
|
||||
|
||||
@@ -390,35 +392,35 @@ GAS ANALYZER
|
||||
var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles
|
||||
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles
|
||||
var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles
|
||||
environment.garbage_collect()
|
||||
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)</span>")
|
||||
|
||||
if(abs(o2_concentration - O2STANDARD) < 2)
|
||||
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)</span>")
|
||||
|
||||
if(co2_concentration > 0.01)
|
||||
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)</span>")
|
||||
|
||||
if(plasma_concentration > 0.005)
|
||||
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)</span>")
|
||||
|
||||
environment.garbage_collect()
|
||||
|
||||
for(var/id in env_gases)
|
||||
if(id in GLOB.hardcoded_gases)
|
||||
continue
|
||||
var/gas_concentration = env_gases[id][MOLES]/total_moles
|
||||
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] °C ([round(environment.temperature)]K)</span>")
|
||||
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id][MOLES], 0.01)] mol)</span>")
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C, 0.01)] °C ([round(environment.temperature, 0.01)] K)</span>")
|
||||
|
||||
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
|
||||
..()
|
||||
@@ -465,7 +467,6 @@ GAS ANALYZER
|
||||
cooldown = TRUE
|
||||
addtimer(CALLBACK(src,/obj/item/analyzer/proc/ping), cooldown_time)
|
||||
|
||||
|
||||
/obj/item/analyzer/proc/ping()
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
@@ -484,6 +485,42 @@ GAS ANALYZER
|
||||
amount += inaccurate
|
||||
return DisplayTimeText(max(1,amount))
|
||||
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src)
|
||||
var/icon = target
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(src))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Results of analysis of [icon2html(icon, user)] [target].</span>")
|
||||
|
||||
var/list/airs = islist(mixture) ? mixture : list(mixture)
|
||||
for(var/g in airs)
|
||||
if(airs.len > 1) //not a unary gas mixture
|
||||
to_chat(user, "<span class='boldnotice'>Node [airs.Find(g)]</span>")
|
||||
var/datum/gas_mixture/air_contents = g
|
||||
|
||||
var/total_moles = air_contents.total_moles()
|
||||
var/pressure = air_contents.return_pressure()
|
||||
var/volume = air_contents.return_volume() //could just do mixture.volume... but safety, I guess?
|
||||
var/temperature = air_contents.temperature
|
||||
|
||||
if(total_moles > 0)
|
||||
to_chat(user, "<span class='notice'>Moles: [round(total_moles, 0.01)] mol</span>")
|
||||
to_chat(user, "<span class='notice'>Volume: [volume] L</span>")
|
||||
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.01)] kPa</span>")
|
||||
|
||||
var/list/cached_gases = air_contents.gases
|
||||
for(var/id in cached_gases)
|
||||
var/gas_concentration = cached_gases[id][MOLES]/total_moles
|
||||
to_chat(user, "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id][MOLES], 0.01)] mol)</span>")
|
||||
to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] °C ([round(temperature, 0.01)] K)</span>")
|
||||
|
||||
else
|
||||
if(airs.len > 1)
|
||||
to_chat(user, "<span class='notice'>This node is empty!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[target] is empty!</span>")
|
||||
return
|
||||
|
||||
//slime scanner
|
||||
|
||||
/obj/item/slime_scanner
|
||||
name = "slime scanner"
|
||||
desc = "A device that analyzes a slime's internal composition and measures its stats."
|
||||
|
||||
@@ -125,11 +125,13 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/analyzer) && ptank)
|
||||
atmosanalyzer_scan(ptank.air_contents, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/flamethrower/analyzer_act(mob/living/user, obj/item/I)
|
||||
if(ptank)
|
||||
ptank.analyzer_act(user, I)
|
||||
|
||||
|
||||
/obj/item/flamethrower/attack_self(mob/user)
|
||||
toggle_igniter(user)
|
||||
|
||||
@@ -107,6 +107,9 @@
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/item/tank/analyzer_act(mob/living/user, obj/item/I)
|
||||
atmosanalyzer_scan(air_contents, user, src)
|
||||
|
||||
/obj/item/tank/deconstruct(disassembled = TRUE)
|
||||
if(!disassembled)
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -138,10 +141,7 @@
|
||||
|
||||
/obj/item/tank/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if((istype(W, /obj/item/analyzer)) && get_dist(user, src) <= 1)
|
||||
atmosanalyzer_scan(air_contents, user)
|
||||
|
||||
else if(istype(W, /obj/item/assembly_holder))
|
||||
if(istype(W, /obj/item/assembly_holder))
|
||||
bomb_assemble(W,user)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user