diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm
index 299d7f64f8b..4d5914c970a 100644
--- a/code/_onclick/observer.dm
+++ b/code/_onclick/observer.dm
@@ -48,7 +48,9 @@
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND)
return TRUE
if(user.client)
- if(IsAdminGhost(user))
+ if(user.gas_scan && atmosanalyzer_scan(user, src))
+ return TRUE
+ else if(IsAdminGhost(user))
attack_ai(user)
else if(user.client.prefs.inquisitive_ghost)
user.examinate(src)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 1a752d862b3..611616e341a 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -205,6 +205,9 @@
else
return null
+/atom/proc/return_analyzable_air()
+ return null
+
/atom/proc/check_eye(mob/user)
return
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 8983119e371..d2767f9f8a6 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -836,6 +836,9 @@
return cabin_air
return ..()
+/obj/mecha/return_analyzable_air()
+ return cabin_air
+
/obj/mecha/proc/return_pressure()
var/datum/gas_mixture/t_air = return_air()
if(t_air)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index c29fa7d6dff..14c648719c7 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -532,9 +532,14 @@ GENE SCANNER
amount += inaccurate
return DisplayTimeText(max(1,amount))
-/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src)
+/proc/atmosanalyzer_scan(mob/user, atom/target, silent=FALSE)
+ var/mixture = target.return_analyzable_air()
+ if(!mixture)
+ return FALSE
+
var/icon = target
- user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "You use the analyzer on [icon2html(icon, user)] [target].")
+ if(!silent && isliving(user))
+ user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [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)
@@ -570,7 +575,7 @@ GENE SCANNER
var/instability = round(cached_scan_results["fusion"], 0.01)
to_chat(user, "Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.")
to_chat(user, "Instability of the last fusion reaction: [instability].")
- return
+ return TRUE
//slime scanner
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index 271cf475a77..0cf26d3414a 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -129,10 +129,11 @@
else
return ..()
-/obj/item/flamethrower/analyzer_act(mob/living/user, obj/item/I)
+/obj/item/flamethrower/return_analyzable_air()
if(ptank)
- ptank.analyzer_act(user, I)
-
+ return ptank.return_analyzable_air()
+ else
+ return null
/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 4ee885b8dd5..adbf024195a 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -112,9 +112,6 @@
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)
@@ -208,6 +205,9 @@
/obj/item/tank/return_air()
return air_contents
+/obj/item/tank/return_analyzable_air()
+ return air_contents
+
/obj/item/tank/assume_air(datum/gas_mixture/giver)
air_contents.merge(giver)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 3b7fc7fb7d4..a10c9a7f361 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -247,3 +247,8 @@
current_skin = choice
icon_state = unique_reskin[choice]
to_chat(M, "[src] is now skinned as '[choice].'")
+
+/obj/analyzer_act(mob/living/user, obj/item/I)
+ if(atmosanalyzer_scan(user, src))
+ return TRUE
+ return ..()
diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm
index b94da08322b..55020db69ab 100644
--- a/code/game/objects/structures/crates_lockers/crates/critter.dm
+++ b/code/game/objects/structures/crates_lockers/crates/critter.dm
@@ -35,4 +35,10 @@
if(tank)
return tank.air_contents
else
- return loc.return_air()
\ No newline at end of file
+ return loc.return_air()
+
+/obj/structure/closet/crate/critter/return_analyzable_air()
+ if(tank)
+ return tank.return_analyzable_air()
+ else
+ return null
\ No newline at end of file
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index 2143ff5f6dc..0b59d4177b1 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -153,6 +153,9 @@
/obj/structure/transit_tube_pod/return_air()
return air_contents
+/obj/structure/transit_tube_pod/return_analyzable_air()
+ return air_contents
+
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 3b48439e81e..762d66a5cfc 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -232,7 +232,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
var/turf/T = get_turf(mob)
if(!isturf(T))
return
- show_air_status_to(T, usr)
+ atmosanalyzer_scan(usr, T, TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Air Status In Location") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_robotize(mob/M in GLOB.mob_list)
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index 5a1c2c3500e..01472ae1ed8 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -1,27 +1,10 @@
-/proc/show_air_status_to(turf/target, mob/user)
- var/datum/gas_mixture/env = target.return_air()
- var/list/env_gases = env.gases
- var/burning = FALSE
- if(isopenturf(target))
- var/turf/open/T = target
- if(T.active_hotspot)
- burning = TRUE
-
- var/list/lines = list("[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", burning"):(null)]")
- for(var/id in env_gases)
- var/gas = env_gases[id]
- var/moles = gas[MOLES]
- if (moles >= 0.00001)
- lines += "[gas[GAS_META][META_GAS_NAME]]: [moles] mol"
- to_chat(usr, lines.Join("\n"))
-
/client/proc/air_status(turf/target)
set category = "Debug"
set name = "Display Air Status"
if(!isturf(target))
return
- show_air_status_to(target, usr)
+ atmosanalyzer_scan(usr, target, TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Air Status") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/fix_next_move()
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index dae92f53b9c..9f06dfbe45d 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -56,10 +56,6 @@
add_fingerprint(user)
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)
@@ -200,3 +196,9 @@
return
T.assume_air(removed)
air_update_turf()
+
+/obj/item/onetankbomb/return_analyzable_air()
+ if(bombtank)
+ return bombtank.return_analyzable_air()
+ else
+ return null
diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
index 667dca7fb9e..d33fac81bb0 100644
--- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
+++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
@@ -79,6 +79,9 @@
/turf/open/return_air()
return air
+/turf/open/return_analyzable_air()
+ return return_air()
+
/turf/temperature_expose()
if(temperature > heat_capacity)
to_be_destroyed = TRUE
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index f18ee0c2ff7..7f40fcfc703 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -164,5 +164,5 @@
// Tool acts
-/obj/machinery/atmospherics/components/analyzer_act(mob/living/user, obj/item/I)
- atmosanalyzer_scan(airs, user, src)
+/obj/machinery/atmospherics/components/return_analyzable_air()
+ return airs
\ No newline at end of file
diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm
index 1e513b846c5..628da9ad3da 100644
--- a/code/modules/atmospherics/machinery/pipes/pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/pipes.dm
@@ -51,6 +51,9 @@
/obj/machinery/atmospherics/pipe/return_air()
return parent.air
+/obj/machinery/atmospherics/pipe/return_analyzable_air()
+ return parent.air
+
/obj/machinery/atmospherics/pipe/remove_air(amount)
return parent.air.remove(amount)
@@ -62,9 +65,6 @@
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 bd8dd18b6a6..94b6ac58473 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -52,6 +52,9 @@
/obj/machinery/portable_atmospherics/return_air()
return air_contents
+/obj/machinery/portable_atmospherics/return_analyzable_air()
+ return air_contents
+
/obj/machinery/portable_atmospherics/proc/connect(obj/machinery/atmospherics/components/unary/portables_connector/new_port)
//Make sure not already connected to something else
if(connected_port || !new_port || new_port.connected_device)
@@ -154,9 +157,6 @@
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/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 4b112079b75..194ec9e122a 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -32,6 +32,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/ghost_hud_enabled = 1 //did this ghost disable the on-screen HUD?
var/data_huds_on = 0 //Are data HUDs currently enabled?
var/health_scan = FALSE //Are health scans currently enabled?
+ var/gas_scan = FALSE //Are gas scans currently enabled?
var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED) //list of data HUDs shown to ghosts.
var/ghost_orbit = GHOST_ORBIT_CIRCLE
@@ -61,7 +62,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
verbs += list(
/mob/dead/observer/proc/dead_tele,
/mob/dead/observer/proc/open_spawners_menu,
- /mob/dead/observer/proc/view_gas,
/mob/dead/observer/proc/tray_view)
if(icon_state in GLOB.ghost_forms_with_directions_list)
@@ -408,14 +408,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
usr.forceMove(pick(L))
update_parallax_contents()
-/mob/dead/observer/proc/view_gas()
- set category = "Ghost"
- set name = "View Gases"
- set desc= "View the atmospheric conditions in a location"
-
- var/turf/loc = get_turf(src)
- show_air_status_to(loc, usr)
-
/mob/dead/observer/verb/follow()
set category = "Ghost"
set name = "Orbit" // "Haunt"
@@ -721,6 +713,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "Health scan enabled.")
health_scan = TRUE
+/mob/dead/observer/verb/toggle_gas_scan()
+ set name = "Toggle Gas Scan"
+ set desc = "Toggles whether you analyze gas contents on click"
+ set category = "Ghost"
+
+ if(gas_scan)
+ to_chat(src, "Gas scan disabled.")
+ gas_scan = FALSE
+ else
+ to_chat(src, "Gas scan enabled.")
+ gas_scan = TRUE
+
/mob/dead/observer/verb/restore_ghost_appearance()
set name = "Restore Ghost Character"
set desc = "Sets your deadchat name and ghost appearance to your \
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 28aa94a42f4..71575b1a98d 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -169,9 +169,11 @@
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)
+/obj/machinery/power/rad_collector/return_analyzable_air()
if(loaded_tank)
- loaded_tank.analyzer_act(user, I)
+ return loaded_tank.return_analyzable_air()
+ else
+ return null
/obj/machinery/power/rad_collector/examine(mob/user)
. = ..()