diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index d945d49116..ed9b371a7c 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -33131,6 +33131,7 @@
/obj/item/screwdriver{
pixel_y = 10
},
+/obj/item/analyzer,
/turf/open/floor/plasteel/white,
/area/science/mixing)
"bGA" = (
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 02529a8c6b..f36112effa 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -87913,6 +87913,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 6
},
+/obj/item/analyzer,
/turf/open/floor/plasteel,
/area/science/mixing)
"dFK" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index e6ef58c9af..a4883676a4 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -62062,6 +62062,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 5
},
+/obj/item/analyzer,
/turf/open/floor/plasteel,
/area/science/mixing)
"cBw" = (
diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm
index 202008a212..878d35608d 100644
--- a/code/__DEFINES/tools.dm
+++ b/code/__DEFINES/tools.dm
@@ -5,6 +5,7 @@
#define TOOL_WIRECUTTER "wirecutter"
#define TOOL_WRENCH "wrench"
#define TOOL_WELDER "welder"
+#define TOOL_ANALYZER "analyzer"
#define TOOL_MINING "mining"
#define TOOL_SHOVEL "shovel"
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index e1a41f1d49..1dd64ea4af 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -882,28 +882,6 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
/proc/format_text(text)
return replacetext(replacetext(text,"\proper ",""),"\improper ","")
-/obj/proc/atmosanalyzer_scan(datum/gas_mixture/air_contents, mob/user, obj/target = src)
- var/obj/icon = target
- user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(src))] [target].", "You use the analyzer on [icon2html(icon, user)] [target].")
- var/pressure = air_contents.return_pressure()
- var/total_moles = air_contents.total_moles()
-
- to_chat(user, "Results of analysis of [icon2html(icon, user)] [target].")
- if(total_moles>0)
- to_chat(user, "Pressure: [round(pressure,0.1)] kPa")
-
- var/list/cached_gases = air_contents.gases
-
- for(var/id in cached_gases)
- var/gas_concentration = cached_gases[id][MOLES]/total_moles
- if((id in GLOB.hardcoded_gases) || gas_concentration > 0.001) //ensures the four primary gases are always shown.
- to_chat(user, "[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %")
-
- to_chat(user, "Temperature: [round(air_contents.temperature-T0C)] °C")
- else
- to_chat(user, "[target] is empty!")
- return
-
/proc/check_target_facings(mob/living/initator, mob/living/target)
/*This can be used to add additional effects on interactions between mobs depending on how the mobs are facing each other, such as adding a crit damage to blows to the back of a guy's head.
Given how click code currently works (Nov '13), the initiating mob will be facing the target mob most of the time
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index c308aec45f..3b58c3ead1 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -566,6 +566,8 @@
return wirecutter_act(user, I)
if(TOOL_WELDER)
return welder_act(user, I)
+ if(TOOL_ANALYZER)
+ return analyzer_act(user, I)
// Tool-specific behavior procs. To be overridden in subtypes.
/atom/proc/crowbar_act(mob/living/user, obj/item/I)
@@ -586,5 +588,8 @@
/atom/proc/welder_act(mob/living/user, obj/item/I)
return
+/atom/proc/analyzer_act(mob/living/user, obj/item/I)
+ return
+
/atom/proc/GenerateTag()
return
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 093ee1c4b7..d747aa360a 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -827,12 +827,12 @@ GLOBAL_LIST_EMPTY(PDAs)
if(istype(C))
switch(scanmode)
- if(1)
+ if(PDA_SCANNER_MEDICAL)
C.visible_message("[user] has analyzed [C]'s vitals!")
healthscan(user, C, 1)
add_fingerprint(user)
- if(4)
+ if(PDA_SCANNER_HALOGEN)
C.visible_message("[user] has analyzed [C]'s radiation levels!")
user.show_message("Analyzing Results for [C]:")
@@ -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, "No significant chemical agents found in [A].")
- 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
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 332b73c688..327af15f43 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -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, "Results:")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
- to_chat(user, "Pressure: [round(pressure,0.1)] kPa")
+ to_chat(user, "Pressure: [round(pressure, 0.01)] kPa")
else
- to_chat(user, "Pressure: [round(pressure,0.1)] kPa")
+ to_chat(user, "Pressure: [round(pressure, 0.01)] kPa")
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, "Nitrogen: [round(n2_concentration*100, 0.01)] %")
+ to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)")
else
- to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %")
+ to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 0.01)] mol)")
if(abs(o2_concentration - O2STANDARD) < 2)
- to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %")
+ to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)")
else
- to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %")
+ to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 0.01)] mol)")
if(co2_concentration > 0.01)
- to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %")
+ to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)")
else
- to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %")
+ to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 0.01)] mol)")
if(plasma_concentration > 0.005)
- to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %")
+ to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)")
else
- to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %")
+ to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 0.01)] mol)")
+ 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, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %")
- to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C ([round(environment.temperature)]K)")
+ to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id][MOLES], 0.01)] mol)")
+ to_chat(user, "Temperature: [round(environment.temperature-T0C, 0.01)] °C ([round(environment.temperature, 0.01)] K)")
/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].", "You use the analyzer on [icon2html(icon, user)] [target].")
+ to_chat(user, "Results of analysis of [icon2html(icon, user)] [target].")
+
+ 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, "Node [airs.Find(g)]")
+ 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, "Moles: [round(total_moles, 0.01)] mol")
+ to_chat(user, "Volume: [volume] L")
+ to_chat(user, "Pressure: [round(pressure,0.01)] kPa")
+
+ 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, "[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id][MOLES], 0.01)] mol)")
+ to_chat(user, "Temperature: [round(temperature - T0C,0.01)] °C ([round(temperature, 0.01)] K)")
+
+ else
+ if(airs.len > 1)
+ to_chat(user, "This node is empty!")
+ else
+ to_chat(user, "[target] is empty!")
+ return
+
+//slime scanner
+
/obj/item/slime_scanner
name = "slime scanner"
desc = "A device that analyzes a slime's internal composition and measures its stats."
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index a3d2e519a0..375b6336b5 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -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)
diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm
index 91058528e6..447a83422b 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -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
. = ..()
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index ca85255bf0..25a0e804a4 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -29,13 +29,6 @@
copy_overlays(bombassembly)
add_overlay("bomb_assembly")
-/obj/item/onetankbomb/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/analyzer))
- bombtank.attackby(W, user)
- return
- add_fingerprint(user)
- ..()
-
/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "You disassemble [src]!")
if(bombassembly)
@@ -65,6 +58,9 @@
return TRUE
+/obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I)
+ bombtank.analyzer_act(user, I)
+
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, TRUE)
add_fingerprint(user)
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index 5dcf95f3cf..c333651f5a 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -152,3 +152,10 @@ UI Stuff
return ..()
to_chat(user, "Access denied.")
return UI_CLOSE
+
+/*
+Tool acts
+*/
+
+/obj/machinery/atmospherics/components/analyzer_act(mob/living/user, obj/item/I)
+ atmosanalyzer_scan(airs, user, src)
\ No newline at end of file
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
index b4af871f76..40c2f0f5a8 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
@@ -19,12 +19,6 @@
update_icon()
..(intact)
-/obj/machinery/atmospherics/components/unary/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/analyzer))
- atmosanalyzer_scan(airs[1], user)
- else
- return ..()
-
/obj/machinery/atmospherics/components/unary/proc/assign_uid_vents()
uid = num2text(gl_uid++)
return uid
diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm
index 73317c05ef..0879b30b13 100644
--- a/code/modules/atmospherics/machinery/pipes/pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/pipes.dm
@@ -63,8 +63,6 @@
return parent.air.remove(amount)
/obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/analyzer))
- atmosanalyzer_scan(parent.air, user)
if(istype(W, /obj/item/pipe_meter))
var/obj/item/pipe_meter/meter = W
user.dropItemToGround(meter)
@@ -72,6 +70,9 @@
else
return ..()
+/obj/machinery/atmospherics/pipe/analyzer_act(mob/living/user, obj/item/I)
+ atmosanalyzer_scan(parent.air, user, src)
+
/obj/machinery/atmospherics/pipe/returnPipenet()
return parent
diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
index 5bf9f5b8c0..68223d85a2 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -138,11 +138,12 @@
"You fasten [src] to the port.", \
"You hear a ratchet.")
update_icon()
- else if(istype(W, /obj/item/analyzer) && Adjacent(user))
- atmosanalyzer_scan(air_contents, user)
else
return ..()
+/obj/machinery/portable_atmospherics/analyzer_act(mob/living/user, obj/item/I)
+ atmosanalyzer_scan(air_contents, user, src)
+
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user)
if(I.force < 10 && !(stat & BROKEN))
take_damage(0)
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 7898cd6a2e..e837805fa6 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -104,9 +104,7 @@
disconnect_from_network()
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/analyzer) && loaded_tank)
- atmosanalyzer_scan(loaded_tank.air_contents, user)
- else if(istype(W, /obj/item/tank/internals/plasma))
+ if(istype(W, /obj/item/tank/internals/plasma))
if(!anchored)
to_chat(user, "[src] needs to be secured to the floor first!")
return TRUE
@@ -170,6 +168,10 @@
to_chat(user, "You [bitcoinmining ? "enable":"disable"] the research point production feature of [src].")
return TRUE
+/obj/machinery/power/rad_collector/analyzer_act(mob/living/user, obj/item/I)
+ if(loaded_tank)
+ loaded_tank.analyzer_act(user, I)
+
/obj/machinery/power/rad_collector/examine(mob/user)
. = ..()
if(active)
diff --git a/code/modules/vending/engivend.dm b/code/modules/vending/engivend.dm
index 0e2b31037f..53106c09a6 100644
--- a/code/modules/vending/engivend.dm
+++ b/code/modules/vending/engivend.dm
@@ -4,14 +4,14 @@
icon_state = "engivend"
icon_deny = "engivend-deny"
req_access_txt = "11" //Engineering Equipment access
- products = list(/obj/item/clothing/glasses/meson/engine = 2,
+ products = list(/obj/item/clothing/glasses/meson/engine = 2,
/obj/item/clothing/glasses/welding = 3,
- /obj/item/multitool = 4,
- /obj/item/construction/rcd/loaded = 3,
+ /obj/item/multitool = 4,
+ /obj/item/construction/rcd/loaded = 3,
/obj/item/grenade/chem_grenade/smart_metal_foam = 10,
- /obj/item/geiger_counter = 5,
+ /obj/item/geiger_counter = 5,
/obj/item/stock_parts/cell/high = 10,
- /obj/item/electronics/airlock = 10,
+ /obj/item/electronics/airlock = 10,
/obj/item/electronics/apc = 10,
/obj/item/electronics/airalarm = 10,
/obj/item/electronics/firealarm = 10,
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index a515b9ea9b..8c29cec09e 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ