Better Gas Scans (Chatbox and Colored!) (#24975)

* feat: Better Gas Analyzer AND TGUI!
https://github.com/ss220-space/Paradise/pull/2333
https://github.com/ss220-space/Paradise/pull/2461
https://github.com/ss220-space/Paradise/pull/2522

* rename atmos helpers

* remove tgui

* more fixes

* better act self

* now scanner finally works again

* what if we want turf beneath the target?

* fix chatbox

* color code the gases

* unnecessary stuff removal

* ghosts can now scan portable atmospherics

* better code

* do we really need to know that?

* change colors

* add a space to separate gases from other info

* update tgui bundle

* update dark-theme CO2 color
This commit is contained in:
larentoun
2024-04-28 03:01:16 +00:00
committed by GitHub
parent 1d4d95a10b
commit 36f7c43c9c
20 changed files with 177 additions and 211 deletions
-34
View File
@@ -262,40 +262,6 @@
/proc/format_frequency(f)
return "[round(f / 10)].[f % 10]"
/obj/proc/atmosanalyzer_scan(datum/gas_mixture/air_contents, mob/user, obj/target = src)
var/obj/icon = target
if(isliving(user))
user.visible_message("<span class='notice'>[user] uses the analyzer on [target].</span>", "<span class='notice'>You use the analyzer on [target].</span>")
var/pressure = air_contents.return_pressure()
var/total_moles = air_contents.total_moles()
var/volume = air_contents.return_volume()
user.show_message("<span class='notice'>Results of analysis of [bicon(icon)] [target].</span>", 1)
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/plasma_concentration = air_contents.toxins/total_moles
var/n2o_concentration = air_contents.sleeping_agent/total_moles
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration+n2o_concentration)
user.show_message("<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>", 1)
user.show_message("<span class='notice'>Nitrogen: [round(n2_concentration*100)] % ([round(air_contents.nitrogen,0.01)] moles)</span>", 1)
user.show_message("<span class='notice'>Oxygen: [round(o2_concentration*100)] % ([round(air_contents.oxygen,0.01)] moles)</span>", 1)
user.show_message("<span class='notice'>CO2: [round(co2_concentration*100)] % ([round(air_contents.carbon_dioxide,0.01)] moles)</span>", 1)
user.show_message("<span class='notice'>Plasma: [round(plasma_concentration*100)] % ([round(air_contents.toxins,0.01)] moles)</span>", 1)
user.show_message("<span class='notice'>Nitrous Oxide: [round(n2o_concentration*100)] % ([round(air_contents.sleeping_agent,0.01)] moles)</span>", 1)
if(unknown_concentration>0.01)
user.show_message("<span class='danger'>Unknown: [round(unknown_concentration*100)] % ([round(unknown_concentration*total_moles,0.01)] moles)</span>", 1)
user.show_message("<span class='notice'>Total: [round(total_moles,0.01)] moles</span>", 1)
user.show_message("<span class='notice'>Temperature: [round(air_contents.temperature-T0C)] &deg;C</span>", 1)
user.show_message("<span class='notice'>Volume: [round(volume)] Liters</span>", 1)
else
user.show_message("<span class='notice'>[target] is empty!</span>", 1)
user.show_message("<span class='notice'>Volume: [round(volume)] Liters</span>", 1)
return
//Picks a string of symbols to display as the law number for hacked or ion laws
/proc/ionnum()
return "[pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")]"
+4 -12
View File
@@ -77,9 +77,12 @@
/mob/dead/observer/MiddleShiftControlClickOn(atom/A)
return
/atom/proc/attack_ghost(mob/user)
/atom/proc/attack_ghost(mob/dead/observer/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
if(user.client)
if(user.gas_scan && atmos_scan(user=user, target=src, silent=TRUE))
return TRUE
// health + machine analyzer for ghosts
/mob/living/attack_ghost(mob/dead/observer/user)
@@ -106,14 +109,3 @@
/obj/effect/portal/attack_ghost(mob/user as mob)
if(target)
user.forceMove(get_turf(target))
/obj/machinery/atmospherics/attack_ghost(mob/dead/observer/user)
if(!istype(user)) // Make sure user is actually an observer. Revenents also use attack_ghost, but do not have the toggle gas analyzer var.
return
if(user.gas_analyzer)
if(istype(src, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/T = src
atmosanalyzer_scan(T.parent.air, user, T)
else if(istype(src, /obj/machinery/atmospherics/unary))
var/obj/machinery/atmospherics/unary/T = src
atmosanalyzer_scan(T.air_contents, user, T)
+4
View File
@@ -288,6 +288,10 @@
else
return null
///Return the air if we can analyze it
/atom/proc/return_analyzable_air()
return null
/atom/proc/check_eye(mob/user)
return
+5
View File
@@ -1046,6 +1046,11 @@
return cabin_air
return get_turf_air()
/obj/mecha/return_analyzable_air()
if(use_internal_tank)
return cabin_air
return null
/obj/mecha/proc/return_pressure()
var/datum/gas_mixture/t_air = return_air()
if(t_air)
+67 -44
View File
@@ -520,50 +520,7 @@ SLIME SCANNER
if(!isturf(location))
return
var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
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>")
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
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/plasma_concentration = environment.toxins/total_moles
var/n2o_concentration = environment.sleeping_agent/total_moles
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration+n2o_concentration)
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100)] %</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100)] %</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100)] %</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100)] %</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100)] %</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100)] %</span>")
if(plasma_concentration > 0.01)
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100)] %</span>")
if(n2o_concentration > 0.01)
to_chat(user, "<span class='info'>Nitrous Oxide: [round(n2o_concentration*100)] %</span>")
if(unknown_concentration > 0.01)
to_chat(user, "<span class='alert'>Unknown: [round(unknown_concentration*100)] %</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] &deg;C</span>")
atmos_scan(user, location)
add_fingerprint(user)
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
@@ -629,6 +586,72 @@ SLIME SCANNER
amount += inaccurate
return DisplayTimeText(max(1, amount))
/obj/item/analyzer/afterattack(atom/target, mob/user, proximity, params)
. = ..()
if(!can_see(user, target, 1))
return
if(target.return_analyzable_air())
atmos_scan(user, target)
else
atmos_scan(user, get_turf(target))
/**
* Outputs a message to the user describing the target's gasmixes.
* Used in chat-based gas scans.
*/
/proc/atmos_scan(mob/user, atom/target, silent = FALSE, print = TRUE)
var/mixture = target.return_analyzable_air()
if(!mixture)
return FALSE
var/list/message = list()
if(!silent && isliving(user))
user.visible_message("<span class='notice'>[user] uses the analyzer on [target].</span>", "<span class='notice'>You use the analyzer on [target].</span>")
message += "<span class='boldnotice'>Results of analysis of [bicon(target)] [target].</span>"
if(!print)
return TRUE
var/list/airs = islist(mixture) ? mixture : list(mixture)
for(var/datum/gas_mixture/air as anything in airs)
var/mix_name = capitalize(lowertext(target.name))
if(length(air) > 1) //not a unary gas mixture
var/mix_number = airs.Find(air)
message += "<span class='boldnotice'>Node [mix_number]</span>"
mix_name += " - Node [mix_number]"
var/total_moles = air.total_moles()
var/pressure = air.return_pressure()
var/volume = air.return_volume() //could just do mixture.volume... but safety, I guess?
var/heat_capacity = air.heat_capacity()
var/thermal_energy = air.thermal_energy()
if(total_moles)
message += "<span class='info'>Total: [round(total_moles, 0.01)] moles</span>"
if(air.oxygen && air.oxygen / total_moles > 0.01)
message += " <span class='oxygen'>Oxygen: [round(air.oxygen, 0.01)] moles ([round(air.oxygen / total_moles * 100, 0.01)] %)</span>"
if(air.nitrogen && air.nitrogen / total_moles > 0.01)
message += " <span class='nitrogen'>Nitrogen: [round(air.nitrogen, 0.01)] moles ([round(air.nitrogen / total_moles * 100, 0.01)] %)</span>"
if(air.carbon_dioxide && air.carbon_dioxide / total_moles > 0.01)
message += " <span class='carbon_dioxide'>Carbon Dioxide: [round(air.carbon_dioxide, 0.01)] moles ([round(air.carbon_dioxide / total_moles * 100, 0.01)] %)</span>"
if(air.toxins && air.toxins / total_moles > 0.01)
message += " <span class='plasma'>Plasma: [round(air.toxins, 0.01)] moles ([round(air.toxins / total_moles * 100, 0.01)] %)</span>"
if(air.sleeping_agent && air.sleeping_agent / total_moles > 0.01)
message += " <span class='sleeping_agent'>Nitrous Oxide: [round(air.sleeping_agent, 0.01)] moles ([round(air.sleeping_agent / total_moles * 100, 0.01)] %)</span>"
if(air.agent_b && air.agent_b / total_moles > 0.01)
message += " <span class='agent_b'>Agent B: [round(air.agent_b, 0.01)] moles ([round(air.agent_b / total_moles * 100, 0.01)] %)</span>"
message += "<span class='info'>Temperature: [round(air.temperature-T0C)] &deg;C ([round(air.temperature)] K)</span>"
message += "<span class='info'>Volume: [round(volume)] Liters</span>"
message += "<span class='info'>Pressure: [round(pressure, 0.1)] kPa</span>"
message += "<span class='info'>Heat Capacity: [DisplayJoules(heat_capacity)] / K</span>"
message += "<span class='info'>Thermal Energy: [DisplayJoules(thermal_energy)]</span>"
else
message += length(airs) > 1 ? "<span class='info'>This node is empty!</span>" : "<span class='info'>[target] is empty!</span>"
message += "<span class='info'>Volume: [round(volume)] Liters</span>" // don't want to change the order volume appears in, suck it
to_chat(user, chat_box_examine(message.Join("\n")))
return TRUE
/******************************/
/*** REAGENT SCANNERS ***/
/******************************/
@@ -122,8 +122,6 @@
update_icon()
return
else if(istype(I, /obj/item/analyzer) && ptank)
atmosanalyzer_scan(ptank.air_contents, user)
else
return ..()
@@ -156,6 +154,11 @@
to_chat(user, "<span class='notice'>[igniter] is now [status ? "secured" : "unsecured"]!</span>")
update_icon()
/obj/item/flamethrower/return_analyzable_air()
if(ptank)
return ptank.return_analyzable_air()
return null
/obj/item/flamethrower/attack_self(mob/user)
toggle_igniter(user)
@@ -145,9 +145,6 @@
if(istype(loc, /obj/item/assembly))
icon = loc
if((istype(W, /obj/item/analyzer)) && get_dist(user, src) <= 1)
atmosanalyzer_scan(air_contents, user)
if(istype(W, /obj/item/assembly_holder))
bomb_assemble(W,user)
@@ -215,6 +212,9 @@
RETURN_TYPE(/datum/gas_mixture)
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)
@@ -18,6 +18,9 @@
return GM
/turf/return_analyzable_air()
return return_air()
/turf/remove_air(amount)
var/datum/gas_mixture/GM = new
@@ -7,7 +7,7 @@
max_integrity = 800
density = TRUE
/// in liters, 1 meters by 1 meters by 2 meters
var/volume = 10000
var/volume = 10000
/obj/machinery/atmospherics/unary/tank/update_underlays()
if(..())
@@ -17,12 +17,8 @@
return
add_underlay(T, node, dir)
/obj/machinery/atmospherics/unary/tank/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/analyzer))
atmosanalyzer_scan(air_contents, user)
return
return ..()
/obj/machinery/atmospherics/unary/tank/return_analyzable_air()
return air_contents
/obj/machinery/atmospherics/unary/tank/air
name = "Pressure Tank (Air)"
@@ -46,12 +46,6 @@
. = ..()
. += "<span class='notice'>This pipe can be disconnected from a pipenet using a wrench. If the pipe's pressure is too high, you'll end up flying.</span>"
/obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/analyzer))
atmosanalyzer_scan(parent.air, user)
return
return ..()
/obj/machinery/atmospherics/proc/pipeline_expansion()
return null
@@ -67,6 +61,11 @@
return 0
return parent.air
/obj/machinery/atmospherics/pipe/return_analyzable_air()
if(!parent)
return null
return parent.air
/obj/machinery/atmospherics/pipe/build_network(remove_deferral = FALSE)
if(!parent)
parent = new /datum/pipeline()
@@ -302,6 +302,8 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
return attack_hand(user)
/obj/machinery/atmospherics/portable/canister/attack_ghost(mob/user)
if(..())
return
return ui_interact(user)
/obj/machinery/atmospherics/portable/canister/attack_hand(mob/user)
@@ -103,6 +103,9 @@
if(holding_tank)
. += "<span class='notice'>\The [src] contains [holding_tank]. Alt-click [src] to remove it.</span>"
/obj/machinery/atmospherics/portable/return_analyzable_air()
return air_contents
/obj/machinery/atmospherics/portable/proc/replace_tank(mob/living/user, close_valve, obj/item/tank/new_tank)
if(holding_tank)
holding_tank.forceMove(drop_location())
@@ -129,9 +132,6 @@
holding_tank = T
update_icon()
return
if((istype(W, /obj/item/analyzer)) && get_dist(user, src) <= 1)
atmosanalyzer_scan(air_contents, user)
return
return ..()
/obj/machinery/atmospherics/portable/wrench_act(mob/user, obj/item/I)
@@ -114,6 +114,8 @@
return attack_hand(user)
/obj/machinery/atmospherics/portable/pump/attack_ghost(mob/user)
if(..())
return
return attack_hand(user)
/obj/machinery/atmospherics/portable/pump/attack_hand(mob/user)
@@ -108,6 +108,8 @@
return attack_hand(user)
/obj/machinery/atmospherics/portable/scrubber/attack_ghost(mob/user)
if(..())
return
return attack_hand(user)
/obj/machinery/atmospherics/portable/scrubber/attack_hand(mob/user)
@@ -189,12 +191,6 @@
/obj/machinery/atmospherics/portable/scrubber/huge/update_icon_state()
icon_state = "scrubber:[on]"
/obj/machinery/atmospherics/portable/scrubber/huge/attackby(obj/item/W, mob/user, params)
if((istype(W, /obj/item/analyzer)) && get_dist(user, src) <= 1)
atmosanalyzer_scan(air_contents, user)
return
return ..()
/obj/machinery/atmospherics/portable/scrubber/huge/wrench_act(mob/user, obj/item/I)
. = TRUE
if(stationary)
@@ -35,7 +35,7 @@ GLOBAL_DATUM_INIT(ghost_crew_monitor, /datum/ui_module/crew_monitor/ghost, new)
var/ghost_orbit = GHOST_ORBIT_CIRCLE
var/health_scan = FALSE //does the ghost have health scanner mode on? by default it should be off
///toggle for ghost gas analyzer
var/gas_analyzer = FALSE
var/gas_scan = FALSE
///toggle for ghost plant analyzer
var/plant_analyzer = FALSE
var/datum/orbit_menu/orbit_menu
@@ -575,17 +575,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='notice'>Health scan enabled.</span>")
health_scan = TRUE
/mob/dead/observer/verb/toggle_gas_anaylzer()
set name = "Toggle Gas Analyzer"
set desc = "Toggles wether you can anaylze gas contents on click"
/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_analyzer)
to_chat(src, "<span class='notice'>Gas Analyzer disabled.</span>")
gas_analyzer = FALSE
gas_scan = !gas_scan
if(gas_scan)
to_chat(src, "<span class='notice'>Gas scan enabled.</span>")
else
to_chat(src, "<span class='notice'>Gas Analyzer enabled. Click on a pipe to analyze.</span>")
gas_analyzer = TRUE
to_chat(src, "<span class='notice'>Gas scan disabled.</span>")
/mob/dead/observer/verb/toggle_plant_anaylzer()
set name = "Toggle Plant Analyzer"
@@ -599,62 +598,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='notice'>Plant Analyzer enabled. Click on a plant or seed to analyze.</span>")
plant_analyzer = TRUE
/mob/dead/observer/verb/analyze_air()
set name = "Analyze Air"
set category = "Ghost"
if(!isobserver(usr))
return
// Shamelessly copied from the Gas Analyzers
if(!isturf(usr.loc))
return
var/datum/gas_mixture/environment = usr.loc.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
to_chat(src, "<span class='boldnotice'>Results:</span>")
if(abs(pressure - ONE_ATMOSPHERE) < 10)
to_chat(src, "<span class='notice'>Pressure: [round(pressure, 0.1)] kPa</span>")
else
to_chat(src, "<span class='warning'>Pressure: [round(pressure, 0.1)] kPa</span>")
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/plasma_concentration = environment.toxins / total_moles
var/n2o_concentration = environment.sleeping_agent / total_moles
var/unknown_concentration = 1 - (o2_concentration + n2_concentration + co2_concentration + plasma_concentration + n2o_concentration)
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(src, "<span class='notice'>Nitrogen: [round(n2_concentration * 100)]% ([round(environment.nitrogen, 0.01)] moles)</span>")
else
to_chat(src, "<span class='warning'>Nitrogen: [round(n2_concentration * 100)]% ([round(environment.nitrogen, 0.01)] moles)</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(src, "<span class='notice'>Oxygen: [round(o2_concentration * 100)]% ([round(environment.oxygen, 0.01)] moles)</span>")
else
to_chat(src, "<span class='warning'>Oxygen: [round(o2_concentration * 100)]% ([round(environment.oxygen, 0.01)] moles)</span>")
if(co2_concentration > 0.01)
to_chat(src, "<span class='warning'>CO2: [round(co2_concentration * 100)]% ([round(environment.carbon_dioxide, 0.01)] moles)</span>")
else
to_chat(src, "<span class='notice'>CO2: [round(co2_concentration * 100)]% ([round(environment.carbon_dioxide, 0.01)] moles)</span>")
if(plasma_concentration > 0.01)
to_chat(src, "<span class='warning'>Plasma: [round(plasma_concentration * 100)]% ([round(environment.toxins, 0.01)] moles)</span>")
if(n2o_concentration > 0.01)
to_chat(src, "<span class='warning'>N2O: [round(n2o_concentration * 100)]% ([round(environment.sleeping_agent, 0.01)] moles)</span>")
if(unknown_concentration > 0.01)
to_chat(src, "<span class='warning'>Unknown: [round(unknown_concentration * 100)]% ([round(unknown_concentration * total_moles, 0.01)] moles)</span>")
to_chat(src, "<span class='notice'>Temperature: [round(environment.temperature - T0C, 0.1)]&deg;C</span>")
to_chat(src, "<span class='notice'>Heat Capacity: [round(environment.heat_capacity(), 0.1)]</span>")
/mob/dead/observer/verb/view_manifest()
set name = "View Crew Manifest"
set category = "Ghost"
+2 -25
View File
@@ -126,28 +126,5 @@
base_name = "Gas Scanner"
icon = "tachometer-alt"
/datum/data/pda/utility/scanmode/gas/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob)
if(istype(A, /obj/item/tank))
var/obj/item/tank/T = A
pda.atmosanalyzer_scan(T.air_contents, user, T)
else if(istype(A, /obj/machinery/atmospherics/portable))
var/obj/machinery/atmospherics/portable/T = A
pda.atmosanalyzer_scan(T.air_contents, user, T)
else if(istype(A, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/T = A
pda.atmosanalyzer_scan(T.parent.air, user, T)
else if(istype(A, /obj/machinery/power/rad_collector))
var/obj/machinery/power/rad_collector/T = A
if(T.loaded_tank)
pda.atmosanalyzer_scan(T.loaded_tank.air_contents, user, T)
else if(istype(A, /obj/item/flamethrower))
var/obj/item/flamethrower/T = A
if(T.ptank)
pda.atmosanalyzer_scan(T.ptank.air_contents, user, T)
else if(istype(A, /obj/machinery/atmospherics/portable/scrubber/huge))
var/obj/machinery/atmospherics/portable/scrubber/huge/T = A
pda.atmosanalyzer_scan(T.air_contents, user, T)
else if(istype(A, /obj/machinery/atmospherics/unary/tank))
var/obj/machinery/atmospherics/unary/tank/T = A
pda.atmosanalyzer_scan(T.air_contents, user, T)
/datum/data/pda/utility/scanmode/gas/scan_atom(atom/A, mob/user)
atmos_scan(user=user, target=A, silent=FALSE, print=TRUE)
@@ -49,9 +49,7 @@
/obj/machinery/power/rad_collector/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/analyzer) && loaded_tank)
atmosanalyzer_scan(loaded_tank.air_contents, user)
else if(istype(I, /obj/item/tank/internals/plasma))
if(istype(I, /obj/item/tank/internals/plasma))
if(!anchored)
to_chat(user, "<span class='warning'>[src] needs to be secured to the floor first.</span>")
return TRUE
@@ -96,6 +94,11 @@
else
return ..()
/obj/machinery/power/rad_collector/return_analyzable_air()
if(loaded_tank)
return loaded_tank.return_analyzable_air()
return null
/obj/machinery/power/rad_collector/examine(mob/user)
. = ..()
if(active)
@@ -1062,3 +1062,29 @@ span.body .coderesponses {
.boxed_message.thick_border {
border-width: thick;
}
/* GASES */
.oxygen {
color: #449dff;
}
.nitrogen {
color: #f94541;
}
.carbon_dioxide {
color: #cccccc;
}
.plasma {
color: #eb6b00;
}
.sleeping_agent {
color: #f28b89;
}
.agent_b {
color: teal;
}
@@ -1080,3 +1080,29 @@ span.body .coderesponses {
.boxed_message.thick_border {
border-width: thick;
}
/* GASES */
.oxygen {
color: #006adb;
}
.nitrogen {
color: #d00a06;
}
.carbon_dioxide {
color: #1f1f1f;
}
.plasma {
color: #853c00;
}
.sleeping_agent {
color: #e82f2c;
}
.agent_b {
color: #004d4d;
}
File diff suppressed because one or more lines are too long