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