From 4c10fe270f2d0b4261e28fb941fa9ed16bfc0b32 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Tue, 10 Oct 2017 20:17:47 -0700 Subject: [PATCH 01/44] Fixes VVing associated values in lists when the value was a number. --- code/modules/admin/verbs/modifyvariables.dm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 2a0575eb28..b708e42b3c 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -433,12 +433,18 @@ GLOBAL_PROTECT(VVpixelmovement) to_chat(src, "Variable appears to be [uppertext(default)].") - to_chat(src, "Variable contains: [L[index]]") + to_chat(src, "Variable contains: [variable]") if(default == VV_NUM) var/dir_text = "" +<<<<<<< HEAD if(dir < 0 && dir < 16) if(dir & 1) +======= + var/tdir = variable + if(tdir > 0 && tdir < 16) + if(tdir & 1) +>>>>>>> 428922c... Fixes VVing associated values in lists when the value was a number. (#31511) dir_text += "NORTH" if(dir & 2) dir_text += "SOUTH" @@ -450,11 +456,8 @@ GLOBAL_PROTECT(VVpixelmovement) if(dir_text) to_chat(usr, "If a direction, direction is: [dir_text]") - var/original_var - if(assoc) - original_var = L[assoc_key] - else - original_var = L[index] + var/original_var = variable + if (O) L = L.Copy() var/class From 0b86f2befe7185b8516c27e5ad0c0649703048cc Mon Sep 17 00:00:00 2001 From: MoreRobustThanYou Date: Tue, 10 Oct 2017 23:17:10 -0400 Subject: [PATCH 02/44] Jungle Fever carriers now hear the proper antag sound (#31517) * Jungle Fever carriers now here the proper antag sound * less whitespace --- code/game/gamemodes/miniantags/monkey/monkey.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm index b0d78f57a4..34ab6c839f 100644 --- a/code/game/gamemodes/miniantags/monkey/monkey.dm +++ b/code/game/gamemodes/miniantags/monkey/monkey.dm @@ -52,6 +52,7 @@ to_chat(carrier.current, "Soon the disease will transform you into an ape. Afterwards, you will be able spread the infection to others with a bite.") to_chat(carrier.current, "While your infection strain is undetectable by scanners, any other infectees will show up on medical equipment.") to_chat(carrier.current, "Your mission will be deemed a success if any of the live infected monkeys reach CentCom.") + carrier.current.playsound_local(get_turf(carrier.current), 'sound/ambience/antag/monkey.ogg', 100, FALSE, pressure_affected = FALSE) return /datum/game_mode/monkey/post_setup() From 5be4669924bd522883a08802e2f7198d7049bf8d Mon Sep 17 00:00:00 2001 From: AnturK Date: Wed, 11 Oct 2017 12:23:26 +0200 Subject: [PATCH 04/44] Datum antag wizard. --- code/_compile_options.dm | 79 +++++ code/datums/antagonists/antag_datum.dm | 9 +- code/datums/antagonists/datum_cult.dm | 2 +- code/datums/antagonists/devil.dm | 2 +- code/datums/antagonists/wizard.dm | 273 ++++++++++++++++++ code/datums/mind.dm | 60 ++-- code/game/gamemodes/antag_hud.dm | 4 +- code/game/gamemodes/antag_spawner.dm | 82 ++---- code/game/gamemodes/wizard/spellbook.dm | 2 +- code/game/gamemodes/wizard/wizard.dm | 149 +--------- code/modules/admin/verbs/randomverbs.dm | 3 +- .../awaymissions/mission_code/Academy.dm | 23 +- code/modules/clothing/outfits/standard.dm | 14 + code/modules/events/wizard/curseditems.dm | 2 +- code/modules/events/wizard/imposter.dm | 39 +-- code/modules/events/wizard/shuffle.dm | 2 +- code/modules/mob/mob_helpers.dm | 2 +- .../spells/spell_types/rightandwrong.dm | 224 ++++++++++++++ tgstation.dme | 1 + 19 files changed, 664 insertions(+), 308 deletions(-) create mode 100644 code/datums/antagonists/wizard.dm diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 829a55150f..c7132130e4 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD #define DEBUG //Enables byond profiling and full runtime logs - note, this may also be defined in your .dme file //Enables in-depth debug messages to runtime log (used for debugging) //#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this @@ -73,3 +74,81 @@ //make sure you add an update to the schema_version stable in the db changelog #define DB_MAJOR_VERSION 3 #define DB_MINOR_VERSION 3 +======= +#define DEBUG //Enables byond profiling and full runtime logs - note, this may also be defined in your .dme file + //Enables in-depth debug messages to runtime log (used for debugging) +//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this + //uncommented, but not visible in the release version) + +#ifdef TESTING +//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing. + //Also allows for recursive reference searching of datums. + //Sets world.loop_checks to false and prevents find references from sleeping + +//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green +#endif + +#define PRELOAD_RSC 1 /*set to: + 0 to allow using external resources or on-demand behaviour; + 1 to use the default behaviour; + 2 for preloading absolutely everything; + */ + +#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary. + // 1 will enable set background. 0 will disable set background. + +//ADMIN STUFF +#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. + +#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu +#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you + +//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam +#define MAX_MESSAGE_LEN 1024 +#define MAX_NAME_LEN 42 +#define MAX_BROADCAST_LEN 512 +#define MAX_CHARTER_LEN 80 + +//MINOR TWEAKS/MISC +#define AGE_MIN 17 //youngest a character can be +#define AGE_MAX 85 //oldest a character can be +#define WIZARD_AGE_MIN 30 //youngest a wizard can be +#define APPRENTICE_AGE_MIN 29 //youngest an apprentice can be +#define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up +#define POCKET_STRIP_DELAY 40 //time taken (in deciseconds) to search somebody's pockets +#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you + +#define HUNGER_FACTOR 0.1 //factor at which mob nutrition decreases +#define REAGENTS_METABOLISM 0.4 //How many units of reagent are consumed per tick, by default. +#define REAGENTS_EFFECT_MULTIPLIER (REAGENTS_METABOLISM / 0.4) // By defining the effect multiplier this way, it'll exactly adjust all effects according to how they originally were with the 0.4 metabolism + +#define MAX_STACK_AMOUNT_METAL 50 +#define MAX_STACK_AMOUNT_GLASS 50 +#define MAX_STACK_AMOUNT_RODS 60 + +// AI Toggles +#define AI_CAMERA_LUMINOSITY 5 +#define AI_VOX 1 // Comment out if you don't want VOX to be enabled and have players download the voice sounds. + +//Additional code for the above flags. +#ifdef TESTING +#warn compiling in TESTING mode. testing() debug messages will be visible. +#endif + +#ifdef TRAVISTESTING +#define TESTING +#endif + +//Update this whenever you need to take advantage of more recent byond features +#define MIN_COMPILER_VERSION 511 +#if DM_VERSION < MIN_COMPILER_VERSION +//Don't forget to update this part +#error Your version of BYOND is too out-of-date to compile this project. Go to byond.com/download and update. +#error You need version 511 or higher +#endif + +//Update this whenever the db schema changes +//make sure you add an update to the schema_version stable in the db changelog +#define DB_MAJOR_VERSION 3 +#define DB_MINOR_VERSION 4 +>>>>>>> e8ff73e... Datum antag wizard. (#31449) diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index ad5a9d9e18..7e500c2e4a 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -1,20 +1,21 @@ +GLOBAL_LIST_EMPTY(antagonists) + /datum/antagonist var/name = "Antagonist" - var/datum/mind/owner //Mind that owns this datum - var/silent = FALSE //Silent will prevent the gain/lose texts to show - var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with - var/delete_on_death = TRUE + var/delete_on_mind_deletion = TRUE /datum/antagonist/New(datum/mind/new_owner) + GLOB.antagonists += src typecache_datum_blacklist = typecacheof(typecache_datum_blacklist) if(new_owner) owner = new_owner /datum/antagonist/Destroy() + GLOB.antagonists -= src if(owner) LAZYREMOVE(owner.antag_datums, src) owner = null diff --git a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm index 8c05c54b21..37dce88691 100644 --- a/code/datums/antagonists/datum_cult.dm +++ b/code/datums/antagonists/datum_cult.dm @@ -131,7 +131,7 @@ /datum/antagonist/cult/master/on_gain() . = ..() var/mob/living/current = owner.current - SSticker.mode.set_antag_hud(current, "cultmaster") + set_antag_hud(current, "cultmaster") /datum/antagonist/cult/master/greet() to_chat(owner.current, "You are the cult's Master. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \ diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm index f66fc5a3b2..76a9e022c6 100644 --- a/code/datums/antagonists/devil.dm +++ b/code/datums/antagonists/devil.dm @@ -86,7 +86,7 @@ GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")) /datum/antagonist/devil //Don't delete upon mind destruction, otherwise soul re-selling will break. - delete_on_death = FALSE + delete_on_mind_deletion = FALSE var/obligation var/ban var/bane diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm new file mode 100644 index 0000000000..627b3e88d7 --- /dev/null +++ b/code/datums/antagonists/wizard.dm @@ -0,0 +1,273 @@ +#define APPRENTICE_DESTRUCTION "destruction" +#define APPRENTICE_BLUESPACE "bluespace" +#define APPRENTICE_ROBELESS "robeless" +#define APPRENTICE_HEALING "healing" + +/datum/antagonist/wizard + name = "Space Wizard" + var/give_objectives = TRUE + var/strip = TRUE //strip before equipping + var/allow_rename = TRUE + var/hud_version = "wizard" + var/datum/objective_team/wizard/wiz_team //Only created if wizard summons apprentices + var/list/objectives = list() //this should be base datum antag proc and list, todo make lazy + var/move_to_lair = TRUE + var/outfit_type = /datum/outfit/wizard + var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */ + +/datum/antagonist/wizard/on_gain() + register() + if(give_objectives) + create_objectives() + equip_wizard() + if(move_to_lair) + send_to_lair() + . = ..() + if(allow_rename) + rename_wizard() + +/datum/antagonist/wizard/proc/register() + SSticker.mode.wizards |= owner + +/datum/antagonist/wizard/proc/unregister() + SSticker.mode.wizards -= src + +/datum/objective_team/wizard + name = "wizard team" + +/datum/antagonist/wizard/proc/create_wiz_team() + wiz_team = new(owner) + wiz_team.name = "[owner.current.real_name] team" + update_wiz_icons_added(owner.current) + +/datum/antagonist/wizard/proc/send_to_lair() + if(!owner || !owner.current) + return + if(!GLOB.wizardstart.len) + SSjob.SendToLateJoin(owner.current) + to_chat(owner, "HOT INSERTION, GO GO GO") + owner.current.forceMove(pick(GLOB.wizardstart)) + +/datum/antagonist/wizard/proc/create_objectives() + switch(rand(1,100)) + if(1 to 30) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = owner + kill_objective.find_target() + objectives += kill_objective + + if (!(locate(/datum/objective/escape) in owner.objectives)) + var/datum/objective/escape/escape_objective = new + escape_objective.owner = owner + objectives += escape_objective + + if(31 to 60) + var/datum/objective/steal/steal_objective = new + steal_objective.owner = owner + steal_objective.find_target() + objectives += steal_objective + + if (!(locate(/datum/objective/escape) in owner.objectives)) + var/datum/objective/escape/escape_objective = new + escape_objective.owner = owner + objectives += escape_objective + + if(61 to 85) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = owner + kill_objective.find_target() + objectives += kill_objective + + var/datum/objective/steal/steal_objective = new + steal_objective.owner = owner + steal_objective.find_target() + objectives += steal_objective + + if (!(locate(/datum/objective/survive) in owner.objectives)) + var/datum/objective/survive/survive_objective = new + survive_objective.owner = owner + objectives += survive_objective + + else + if (!(locate(/datum/objective/hijack) in owner.objectives)) + var/datum/objective/hijack/hijack_objective = new + hijack_objective.owner = owner + objectives += hijack_objective + + for(var/datum/objective/O in objectives) + owner.objectives += O + +/datum/antagonist/wizard/on_removal() + unregister() + owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff + return ..() + +/datum/antagonist/wizard/proc/equip_wizard() + if(!owner) + return + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + return + if(strip) + H.delete_equipment() + //Wizards are human by default. Use the mirror if you want something else. + H.set_species(/datum/species/human) + if(H.age < wiz_age) + H.age = wiz_age + H.equipOutfit(outfit_type) + +/datum/antagonist/wizard/greet() + to_chat(owner, "You are the Space Wizard!") + to_chat(owner, "The Space Wizards Federation has given you the following tasks:") + owner.announce_objectives() + to_chat(owner, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") + to_chat(owner, "The spellbook is bound to you, and others cannot use it.") + to_chat(owner, "In your pockets you will find a teleport scroll. Use it as needed.") + to_chat(owner,"Remember: do not forget to prepare your spells.") + +/datum/antagonist/wizard/farewell() + to_chat(owner, "You have been brainwashed! You are no longer a wizard!") + +/datum/antagonist/wizard/proc/rename_wizard() + set waitfor = FALSE + + var/wizard_name_first = pick(GLOB.wizard_first) + var/wizard_name_second = pick(GLOB.wizard_second) + var/randomname = "[wizard_name_first] [wizard_name_second]" + var/mob/living/wiz_mob = owner.current + var/newname = copytext(sanitize(input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN) + + if (!newname) + newname = randomname + + wiz_mob.fully_replace_character_name(wiz_mob.real_name, newname) + +/datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + if(wiz_team) //Don't bother with the icon if you're solo wizard + update_wiz_icons_added(M) + M.faction |= "wizard" + +/datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_wiz_icons_removed(M) + M.faction -= "wizard" + +/datum/antagonist/wizard/apprentice + name = "Wizard Apprentice" + hud_version = "apprentice" + var/datum/mind/master + var/school = APPRENTICE_DESTRUCTION + outfit_type = /datum/outfit/wizard/apprentice + wiz_age = APPRENTICE_AGE_MIN + +/datum/antagonist/wizard/apprentice/greet() + to_chat(owner, "You are [master.current.real_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.") + owner.announce_objectives() + +/datum/antagonist/wizard/apprentice/register() + SSticker.mode.apprentices |= src + +/datum/antagonist/wizard/apprentice/unregister() + SSticker.mode.apprentices -= src + +/datum/antagonist/wizard/apprentice/equip_wizard() + . = ..() + if(!owner) + return + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + return + switch(school) + if(APPRENTICE_DESTRUCTION) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null)) + to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.") + if(APPRENTICE_BLUESPACE) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) + to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.") + if(APPRENTICE_HEALING) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null)) + H.put_in_hands(new /obj/item/gun/magic/staff/healing(H)) + to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") + if(APPRENTICE_HEALING) + owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null)) + to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.") + +/datum/antagonist/wizard/apprentice/create_objectives() + var/datum/objective/protect/new_objective = new /datum/objective/protect + new_objective.owner = owner + new_objective.target = master + new_objective.explanation_text = "Protect [master.current.real_name], the wizard." + owner.objectives += new_objective + objectives += new_objective + +//Random event wizard +/datum/antagonist/wizard/apprentice/imposter + name = "Wizard Imposter" + allow_rename = FALSE + +/datum/antagonist/wizard/apprentice/imposter/greet() + to_chat(owner, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!") + owner.announce_objectives() + +/datum/antagonist/wizard/apprentice/imposter/equip_wizard() + var/mob/living/carbon/human/master_mob = master.current + var/mob/living/carbon/human/H = owner.current + if(!istype(master_mob) || !istype(H)) + return + if(master_mob.ears) + H.equip_to_slot_or_del(new master_mob.ears.type, slot_ears) + if(master_mob.w_uniform) + H.equip_to_slot_or_del(new master_mob.w_uniform.type, slot_w_uniform) + if(master_mob.shoes) + H.equip_to_slot_or_del(new master_mob.shoes.type, slot_shoes) + if(master_mob.wear_suit) + H.equip_to_slot_or_del(new master_mob.wear_suit.type, slot_wear_suit) + if(master_mob.head) + H.equip_to_slot_or_del(new master_mob.head.type, slot_head) + if(master_mob.back) + H.equip_to_slot_or_del(new master_mob.back.type, slot_back) + + //Operation: Fuck off and scare people + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) + +/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz) + var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] + wizhud.join_hud(wiz) + set_antag_hud(wiz, hud_version) + +/datum/antagonist/wizard/proc/update_wiz_icons_removed(mob/living/wiz) + var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] + wizhud.leave_hud(wiz) + set_antag_hud(wiz, null) + + +/datum/antagonist/wizard/academy + name = "Academy Teacher" + outfit_type = /datum/outfit/wizard/academy + +/datum/antagonist/wizard/academy/equip_wizard() + . = ..() + + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile) + owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball) + + var/mob/living/M = owner.current + if(!istype(M)) + return + + var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M) + Implant.implant(M) + +/datum/antagonist/wizard/academy/create_objectives() + var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders") + new_objective.owner = owner + owner.objectives += new_objective + objectives += new_objective \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 3116be2ea1..2f45067b0c 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -75,7 +75,7 @@ if(islist(antag_datums)) for(var/i in antag_datums) var/datum/antagonist/antag_datum = i - if(antag_datum.delete_on_death) + if(antag_datum.delete_on_mind_deletion) qdel(i) antag_datums = null return ..() @@ -133,10 +133,16 @@ memory = null // Datum antag mind procs -/datum/mind/proc/add_antag_datum(datum_type, team) - if(!datum_type) +/datum/mind/proc/add_antag_datum(datum_type_or_instance, team) + if(!datum_type_or_instance) return - var/datum/antagonist/A = new datum_type(src, team) + var/datum/antagonist/A + if(!ispath(datum_type_or_instance)) + A = datum_type_or_instance + if(!istype(A)) + return + else + A = new datum_type_or_instance(src, team) if(!A.can_be_owned(src)) qdel(A) return @@ -193,12 +199,12 @@ /datum/mind/proc/remove_traitor() if(src in SSticker.mode.traitors) - src.remove_antag_datum(ANTAG_DATUM_TRAITOR) + remove_antag_datum(ANTAG_DATUM_TRAITOR) SSticker.mode.update_traitor_icons_removed(src) /datum/mind/proc/remove_brother() if(src in SSticker.mode.brothers) - src.remove_antag_datum(ANTAG_DATUM_BROTHER) + remove_antag_datum(ANTAG_DATUM_BROTHER) SSticker.mode.update_brother_icons_removed(src) /datum/mind/proc/remove_nukeop() @@ -210,11 +216,8 @@ remove_antag_equip() /datum/mind/proc/remove_wizard() - if(src in SSticker.mode.wizards) - SSticker.mode.wizards -= src - RemoveAllSpells() + remove_antag_datum(/datum/antagonist/wizard) special_role = null - remove_antag_equip() /datum/mind/proc/remove_cultist() if(src in SSticker.mode.cult) @@ -254,7 +257,6 @@ remove_rev() SSticker.mode.update_changeling_icons_removed(src) SSticker.mode.update_traitor_icons_removed(src) - SSticker.mode.update_wiz_icons_removed(src) SSticker.mode.update_cult_icons_removed(src) SSticker.mode.update_rev_icons_removed(src) @@ -526,11 +528,9 @@ if (SSticker.mode.config_tag=="wizard") text = uppertext(text) text = "[text]: " - if ((src in SSticker.mode.wizards) || (src in SSticker.mode.apprentices)) + if (has_antag_datum(/datum/antagonist/wizard)) text += "YES | no" - text += "
To lair, undress, dress up, let choose name." - if (objectives.len==0) - text += "
Objectives are empty! Randomize!" + text += "
To lair, undress" else text += "yes | NO" @@ -1049,27 +1049,15 @@ switch(href_list["wizard"]) if("clear") remove_wizard() - to_chat(current, "You have been brainwashed! You are no longer a wizard!") log_admin("[key_name(usr)] has de-wizard'ed [current].") - SSticker.mode.update_wiz_icons_removed(src) if("wizard") - if(!(src in SSticker.mode.wizards)) - SSticker.mode.wizards += src + if(has_antag_datum(/datum/antagonist/wizard)) special_role = "Wizard" - //SSticker.mode.learn_basic_spells(current) - to_chat(current, "You are the Space Wizard!") + add_antag_datum(/datum/antagonist/wizard) message_admins("[key_name_admin(usr)] has wizard'ed [current].") log_admin("[key_name(usr)] has wizard'ed [current].") - SSticker.mode.update_wiz_icons_added(src) if("lair") current.forceMove(pick(GLOB.wizardstart)) - if("dressup") - SSticker.mode.equip_wizard(current) - if("name") - SSticker.mode.name_wizard(current) - if("autoobjectives") - SSticker.mode.forge_wizard_objectives(src) - to_chat(usr, "The objectives for wizard [key] have been generated. You can edit them and anounce manually.") else if (href_list["changeling"]) switch(href_list["changeling"]) @@ -1440,20 +1428,10 @@ SSticker.mode.update_changeling_icons_added(src) /datum/mind/proc/make_Wizard() - if(!(src in SSticker.mode.wizards)) - SSticker.mode.wizards += src + if(!has_antag_datum(/datum/antagonist/wizard)) special_role = "Wizard" assigned_role = "Wizard" - if(!GLOB.wizardstart.len) - SSjob.SendToLateJoin(current) - to_chat(current, "HOT INSERTION, GO GO GO") - else - current.forceMove(pick(GLOB.wizardstart)) - - SSticker.mode.equip_wizard(current) - SSticker.mode.name_wizard(current) - SSticker.mode.forge_wizard_objectives(src) - SSticker.mode.greet_wizard(src) + add_antag_datum(/datum/antagonist/wizard) /datum/mind/proc/make_Cultist() diff --git a/code/game/gamemodes/antag_hud.dm b/code/game/gamemodes/antag_hud.dm index 4fba08101c..b047ff92ea 100644 --- a/code/game/gamemodes/antag_hud.dm +++ b/code/game/gamemodes/antag_hud.dm @@ -29,7 +29,7 @@ //GAME_MODE PROCS //called to set a mob's antag icon state -/datum/game_mode/proc/set_antag_hud(mob/M, new_icon_state) +/proc/set_antag_hud(mob/M, new_icon_state) if(!istype(M)) CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!") var/image/holder = M.hud_list[ANTAG_HUD] @@ -43,7 +43,7 @@ //these are called by mind.transfer_to() /datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud) leave_all_antag_huds() - SSticker.mode.set_antag_hud(current, antag_hud_icon_state) + set_antag_hud(current, antag_hud_icon_state) if(newhud) newhud.join_hud(current) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index c529ab546d..8b33863381 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -29,13 +29,13 @@ dat += "Using this contract, you may summon an apprentice to aid you on your mission.
" dat += "If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.
" dat += "Which school of magic is your apprentice studying?:
" - dat += "Destruction
" + dat += "Destruction
" dat += "Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.
" - dat += "Bluespace Manipulation
" + dat += "Bluespace Manipulation
" dat += "Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.
" - dat += "Healing
" + dat += "Healing
" dat += "Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.
" - dat += "Robeless
" + dat += "Robeless
" dat += "Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.
" user << browse(dat, "window=radio") onclose(user, "radio") @@ -63,73 +63,31 @@ return used = 1 var/mob/dead/observer/theghost = pick(candidates) - spawn_antag(theghost.client, get_turf(src), href_list["school"]) - if(H && H.mind) - SSticker.mode.update_wiz_icons_added(H.mind) + spawn_antag(theghost.client, get_turf(src), href_list["school"],H.mind) else to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.") -/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, type = "") +/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/wizard) new /obj/effect/particle_effect/smoke(T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key - var/wizard_name = "the wizard" - if(usr) - wizard_name = usr.real_name - to_chat(M, "You are [wizard_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.") - switch(type) - if("destruction") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null)) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.") - if("bluespace") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.") - if("healing") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null)) - M.put_in_hands(new /obj/item/gun/magic/staff/healing(M), TRUE) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") - if("robeless") - M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null)) - to_chat(M, "Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.") - - equip_antag(M) - var/wizard_name_first = pick(GLOB.wizard_first) - var/wizard_name_second = pick(GLOB.wizard_second) - var/randomname = "[wizard_name_first] [wizard_name_second]" - if(usr) - var/datum/objective/protect/new_objective = new /datum/objective/protect - new_objective.owner = M.mind - new_objective.target = usr.mind - new_objective.explanation_text = "Protect [usr.real_name], the wizard." - M.mind.objectives += new_objective - SSticker.mode.apprentices += M.mind - M.mind.assigned_role = "Apprentice" - M.mind.special_role = "apprentice" - SSticker.mode.update_wiz_icons_added(M.mind) + var/datum/mind/app_mind = M.mind + var/datum/antagonist/wizard/master_antag = wizard.has_antag_datum(/datum/antagonist/wizard) + if(!master_antag.wiz_team) + master_antag.create_wiz_team() + var/datum/antagonist/wizard/apprentice/app = new(app_mind) + app.wiz_team = master_antag.wiz_team + app.master = wizard + app.school = school + master_antag.wiz_team.members += app_mind + app_mind.add_antag_datum(app) + //TODO Kill these if possible + app_mind.assigned_role = "Apprentice" + app_mind.special_role = "apprentice" + // SEND_SOUND(M, sound('sound/effects/magic.ogg')) - var/newname = copytext(sanitize(input(M, "You are [wizard_name]'s apprentice. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN) - if (!newname) - newname = randomname - M.mind.name = newname - M.real_name = newname - M.name = newname - M.age = rand(AGE_MIN, WIZARD_AGE_MIN - 1) - M.dna.update_dna_identity() -/obj/item/antag_spawner/contract/equip_antag(mob/target) - target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_ears) - target.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(target), slot_w_uniform) - target.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(target), slot_shoes) - target.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(target), slot_wear_suit) - target.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(target), slot_head) - target.equip_to_slot_or_del(new /obj/item/storage/backpack(target), slot_back) - target.equip_to_slot_or_del(new /obj/item/storage/box(target), slot_in_backpack) - target.equip_to_slot_or_del(new /obj/item/teleportation_scroll/apprentice(target), slot_r_store) ///////////BORGS AND OPERATIVES diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 5e22aaac42..0838bfeed6 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -737,7 +737,7 @@ for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list) if(knownspell.type == S.type) if(user.mind) - if(user.mind.special_role == "apprentice" || user.mind.special_role == "Wizard") + if(iswizard(user)) to_chat(user,"You're already far more versed in this spell than this flimsy how-to book can provide.") else to_chat(user,"You've already read this one.") diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index fb9fb31fff..a5bd17bc8c 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -16,160 +16,34 @@ announce_text = "There is a space wizard attacking the station!\n\ Wizard: Accomplish your objectives and cause mayhem on the station.\n\ Crew: Eliminate the wizard before they can succeed!" - var/use_huds = 0 var/finished = 0 /datum/game_mode/wizard/pre_setup() - var/datum/mind/wizard = pick(antag_candidates) wizards += wizard modePlayer += wizard wizard.assigned_role = "Wizard" wizard.special_role = "Wizard" + log_game("[wizard.key] (ckey) has been selected as a Wizard") //TODO: Move these to base antag datum if(GLOB.wizardstart.len == 0) to_chat(wizard.current, "A starting location for you could not be found, please report this bug!") return 0 for(var/datum/mind/wiz in wizards) wiz.current.forceMove(pick(GLOB.wizardstart)) - return 1 /datum/game_mode/wizard/post_setup() for(var/datum/mind/wizard in wizards) - log_game("[wizard.key] (ckey) has been selected as a Wizard") - equip_wizard(wizard.current) - forge_wizard_objectives(wizard) - if(use_huds) - update_wiz_icons_added(wizard) - greet_wizard(wizard) - name_wizard(wizard.current) - ..() - return + wizard.add_antag_datum(/datum/antagonist/wizard) + return ..() /datum/game_mode/wizard/generate_report() return "A dangerous Wizards' Federation individual by the name of [pick(GLOB.wizard_first)] [pick(GLOB.wizard_second)] has recently escaped confinement from an unlisted prison facility. This \ man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \ his execution is highly encouraged, as is the preservation of his body for later study." -/datum/game_mode/proc/forge_wizard_objectives(datum/mind/wizard) - switch(rand(1,100)) - if(1 to 30) - - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = wizard - kill_objective.find_target() - wizard.objectives += kill_objective - - if (!(locate(/datum/objective/escape) in wizard.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = wizard - wizard.objectives += escape_objective - if(31 to 60) - var/datum/objective/steal/steal_objective = new - steal_objective.owner = wizard - steal_objective.find_target() - wizard.objectives += steal_objective - - if (!(locate(/datum/objective/escape) in wizard.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = wizard - wizard.objectives += escape_objective - - if(61 to 85) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = wizard - kill_objective.find_target() - wizard.objectives += kill_objective - - var/datum/objective/steal/steal_objective = new - steal_objective.owner = wizard - steal_objective.find_target() - wizard.objectives += steal_objective - - if (!(locate(/datum/objective/survive) in wizard.objectives)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = wizard - wizard.objectives += survive_objective - - else - if (!(locate(/datum/objective/hijack) in wizard.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = wizard - wizard.objectives += hijack_objective - return - - -/datum/game_mode/proc/name_wizard(mob/living/carbon/human/wizard_mob) - //Allows the wizard to choose a custom name or go with a random one. Spawn 0 so it does not lag the round starting. - var/wizard_name_first = pick(GLOB.wizard_first) - var/wizard_name_second = pick(GLOB.wizard_second) - var/randomname = "[wizard_name_first] [wizard_name_second]" - spawn(0) - var/newname = copytext(sanitize(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - wizard_mob.fully_replace_character_name(wizard_mob.real_name, newname) - - /* Wizards by nature cannot be too young. */ - if(wizard_mob.age < WIZARD_AGE_MIN) - wizard_mob.age = WIZARD_AGE_MIN - return - - -/datum/game_mode/proc/greet_wizard(datum/mind/wizard, you_are=1) - if (you_are) - to_chat(wizard.current, "You are the Space Wizard!") - to_chat(wizard.current, "The Space Wizards Federation has given you the following tasks:") - - wizard.announce_objectives() - return - - -/datum/game_mode/proc/learn_basic_spells(mob/living/carbon/human/wizard_mob) - if(!istype(wizard_mob) || !wizard_mob.mind) - return 0 - wizard_mob.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) //Wizards get Magic Missile and Ethereal Jaunt by default - wizard_mob.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) - - -/datum/game_mode/proc/equip_wizard(mob/living/carbon/human/wizard_mob) - if (!istype(wizard_mob)) - return - - //So zards properly get their items when they are admin-made. - qdel(wizard_mob.wear_suit) - qdel(wizard_mob.head) - qdel(wizard_mob.shoes) - for(var/obj/item/I in wizard_mob.held_items) - qdel(I) - qdel(wizard_mob.r_store) - qdel(wizard_mob.l_store) - - wizard_mob.set_species(/datum/species/human) - wizard_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(wizard_mob), slot_ears) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(wizard_mob), slot_shoes) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head) - wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack(wizard_mob), slot_back) - wizard_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival(wizard_mob), slot_in_backpack) - wizard_mob.equip_to_slot_or_del(new /obj/item/teleportation_scroll(wizard_mob), slot_r_store) - var/obj/item/spellbook/spellbook = new /obj/item/spellbook(wizard_mob) - spellbook.owner = wizard_mob - wizard_mob.put_in_hands(spellbook, TRUE) - - to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") - to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.") - to_chat(wizard_mob, "In your pockets you will find a teleport scroll. Use it as needed.") - wizard_mob.mind.store_memory("Remember: do not forget to prepare your spells.") - return 1 - - /datum/game_mode/wizard/check_finished() - for(var/datum/mind/wizard in wizards) if(isliving(wizard.current) && wizard.current.stat!=DEAD) return ..() @@ -186,7 +60,6 @@ to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!") SSticker.news_report = WIZARD_KILLED - ..() return 1 @@ -247,20 +120,6 @@ to_chat(world, text) return 1 - -//OTHER PROCS - //returns whether the mob is a wizard (or apprentice) /proc/iswizard(mob/living/M) - return istype(M) && M.mind && SSticker && SSticker.mode && ((M.mind in SSticker.mode.wizards) || (M.mind in SSticker.mode.apprentices)) - - -/datum/game_mode/proc/update_wiz_icons_added(datum/mind/wiz_mind) - var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] - wizhud.join_hud(wiz_mind.current) - set_antag_hud(wiz_mind.current, ((wiz_mind in wizards) ? "wizard" : "apprentice")) - -/datum/game_mode/proc/update_wiz_icons_removed(datum/mind/wiz_mind) - var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ] - wizhud.leave_hud(wiz_mind.current) - set_antag_hud(wiz_mind.current, null) + return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index e81ab011e4..feac0eb7aa 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -382,7 +382,8 @@ Traitors and the like can also be revived with the previous role mostly intact. switch(new_character.mind.special_role) if("Wizard") new_character.forceMove(pick(GLOB.wizardstart)) - SSticker.mode.equip_wizard(new_character) + var/datum/antagonist/wizard/A = new_character.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) + A.equip_wizard() if("Syndicate") new_character.forceMove(pick(GLOB.nukeop_start)) call(/datum/game_mode/proc/equip_syndicate)(new_character) diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 87583ebea1..d01a0757ba 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -108,27 +108,12 @@ /obj/structure/academy_wizard_spawner/proc/summon_wizard() var/turf/T = src.loc - var/mob/living/carbon/human/wizbody = new(T) - wizbody.equipOutfit(/datum/outfit/wizard/academy) - var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(wizbody) - Implant.implant(wizbody) - wizbody.faction |= "wizard" - wizbody.real_name = "Academy Teacher" - wizbody.name = "Academy Teacher" - - var/datum/mind/wizmind = new /datum/mind() - wizmind.name = "Wizard Defender" + wizbody.fully_replace_character_name("Academy Teacher") + wizbody.mind_initialize() + var/datum/mind/wizmind = wizbody.mind wizmind.special_role = "Academy Defender" - var/datum/objective/O = new("Protect Wizard Academy from the intruders") - wizmind.objectives += O - wizmind.transfer_to(wizbody) - SSticker.mode.wizards |= wizmind - - wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt) - wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile) - wizmind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball) - + wizmind.add_antag_datum(/datum/antagonist/wizard/academy) current_wizard = wizbody give_control() diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index b021259d5c..0552c1b4b3 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -265,6 +265,20 @@ back = /obj/item/storage/backpack backpack_contents = list(/obj/item/storage/box=1) +/datum/outfit/wizard/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + if(visualsOnly) + return + + var/obj/item/spellbook/S = locate() in H.held_items + if(S) + S.owner = H + +/datum/outfit/wizard/apprentice + name = "Wizard Apprentice" + r_hand = null + l_hand = null + r_pocket = /obj/item/teleportation_scroll/apprentice + /datum/outfit/wizard/red name = "Red Wizard" diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index f5b6ae1cc1..30a4377839 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -40,7 +40,7 @@ for(var/mob/living/carbon/human/H in GLOB.living_mob_list) if(ruins_spaceworthiness && !(H.z in GLOB.station_z_levels) || isspaceturf(H.loc) || isplasmaman(H)) continue //#savetheminers - if(ruins_wizard_loadout && H.mind && ((H.mind in SSticker.mode.wizards) || (H.mind in SSticker.mode.apprentices))) + if(ruins_wizard_loadout && iswizard(H)) continue if(item_set == "catgirls2015") //Wizard code means never having to say you're sorry H.gender = FEMALE diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index 1ba052c4c0..54d3d8ed41 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -24,35 +24,18 @@ I.name = I.dna.real_name I.updateappearance(mutcolor_update=1) I.domutcheck() - if(W.ears) - I.equip_to_slot_or_del(new W.ears.type, slot_ears) - if(W.w_uniform) - I.equip_to_slot_or_del(new W.w_uniform.type , slot_w_uniform) - if(W.shoes) - I.equip_to_slot_or_del(new W.shoes.type, slot_shoes) - if(W.wear_suit) - I.equip_to_slot_or_del(new W.wear_suit.type, slot_wear_suit) - if(W.head) - I.equip_to_slot_or_del(new W.head.type, slot_head) - if(W.back) - I.equip_to_slot_or_del(new W.back.type, slot_back) I.key = C.key - - //Operation: Fuck off and scare people - I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) - I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null)) - I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null)) - + var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard) + if(!master.wiz_team) + master.create_wiz_team() + var/datum/antagonist/wizard/apprentice/imposter = new(I.mind) + imposter.master = M + imposter.wiz_team = master.wiz_team + master.wiz_team += imposter + I.mind.add_antag_datum(imposter) + //Remove if possible SSticker.mode.apprentices += I.mind I.mind.special_role = "imposter" - - var/datum/objective/protect/protect_objective = new /datum/objective/protect - protect_objective.owner = I.mind - protect_objective.target = W.mind - protect_objective.explanation_text = "Protect [W.real_name], the wizard." - I.mind.objectives += protect_objective - SSticker.mode.update_wiz_icons_added(I.mind) - - I.log_message("Is an imposter!", INDIVIDUAL_ATTACK_LOG) - to_chat(I, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!") + // + I.log_message("Is an imposter!", INDIVIDUAL_ATTACK_LOG) //? SEND_SOUND(I, sound('sound/effects/magic.ogg')) diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm index 568a8fbc72..2f525d2098 100644 --- a/code/modules/events/wizard/shuffle.dm +++ b/code/modules/events/wizard/shuffle.dm @@ -82,7 +82,7 @@ var/list/mobs = list() for(var/mob/living/carbon/human/H in GLOB.living_mob_list) - if(H.stat || !H.mind || (H.mind in SSticker.mode.wizards) || (H.mind in SSticker.mode.apprentices)) + if(H.stat || !H.mind || iswizard(H)) continue //the wizard(s) are spared on this one mobs += H diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 457376990e..cb086b7115 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -363,7 +363,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if(M.mind in SSticker.mode.changelings) return 2 if("wizard") - if(M.mind in SSticker.mode.wizards) + if(iswizard(M)) return 2 if("apprentice") if(M.mind in SSticker.mode.apprentices) diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index 1d657117c3..e184cd3b75 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD //In this file: Summon Magic/Summon Guns/Summon Events /proc/rightandwrong(summon_type, mob/user, survivor_probability) //0 = Summon Guns, 1 = Summon Magic @@ -217,3 +218,226 @@ SSevents.reschedule() message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.") log_game("Summon Events was increased!") +======= +//In this file: Summon Magic/Summon Guns/Summon Events + +/proc/rightandwrong(summon_type, mob/user, survivor_probability) //0 = Summon Guns, 1 = Summon Magic + var/list/gunslist = list("taser","gravgun","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","speargun","arg","uzi","alienpistol","dragnet","turret","pulsecarbine","decloner","mindflayer","hyperkinetic","advplasmacutter","wormhole","wt550","bulldog","grenadelauncher","goldenrevolver","sniper","medibeam","scatterbeam") + var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffchange", "staffhealing", "armor", "scrying","staffdoor","voodoo", "whistle", "battlemage", "immortality", "ghostsword", "special") + var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos", "necromantic", "bloodcontract") + + if(user) //in this case either someone holding a spellbook or a badmin + to_chat(user, "You summoned [summon_type ? "magic" : "guns"]!") + message_admins("[key_name_admin(user, 1)] summoned [summon_type ? "magic" : "guns"]!") + log_game("[key_name(user)] summoned [summon_type ? "magic" : "guns"]!") + for(var/mob/living/carbon/human/H in GLOB.player_list) + if(H.stat == DEAD || !(H.client)) + continue + if(H.mind) + if(iswizard(H) || H.mind.special_role == "survivalist") + continue + if(prob(survivor_probability) && !(H.mind in SSticker.mode.traitors)) + SSticker.mode.traitors += H.mind + if(!summon_type) + var/datum/objective/steal_five_of_type/summon_guns/guns = new + guns.owner = H.mind + H.mind.objectives += guns + H.mind.special_role = "survivalist" + to_chat(H, "You are the survivalist! Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way.") + else + var/datum/objective/steal_five_of_type/summon_magic/magic = new + magic.owner = H.mind + H.mind.objectives += magic + H.mind.special_role = "amateur magician" + to_chat(H, "You are the amateur magician! Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way.") + var/datum/objective/survive/survive = new + survive.owner = H.mind + H.mind.objectives += survive + H.log_message("Was made into a survivalist, and trusts no one!", INDIVIDUAL_ATTACK_LOG) + H.mind.announce_objectives() + var/randomizeguns = pick(gunslist) + var/randomizemagic = pick(magiclist) + var/randomizemagicspecial = pick(magicspeciallist) + if(!summon_type) + var/obj/item/gun/G + switch (randomizeguns) + if("taser") + G = new /obj/item/gun/energy/e_gun/advtaser(get_turf(H)) + if("egun") + G = new /obj/item/gun/energy/e_gun(get_turf(H)) + if("laser") + G = new /obj/item/gun/energy/laser(get_turf(H)) + if("revolver") + G = new /obj/item/gun/ballistic/revolver(get_turf(H)) + if("detective") + G = new /obj/item/gun/ballistic/revolver/detective(get_turf(H)) + if("deagle") + G = new /obj/item/gun/ballistic/automatic/pistol/deagle/camo(get_turf(H)) + if("gyrojet") + G = new /obj/item/gun/ballistic/automatic/gyropistol(get_turf(H)) + if("pulse") + G = new /obj/item/gun/energy/pulse(get_turf(H)) + if("suppressed") + G = new /obj/item/gun/ballistic/automatic/pistol(get_turf(H)) + new /obj/item/suppressor(get_turf(H)) + if("doublebarrel") + G = new /obj/item/gun/ballistic/revolver/doublebarrel(get_turf(H)) + if("shotgun") + G = new /obj/item/gun/ballistic/shotgun(get_turf(H)) + if("combatshotgun") + G = new /obj/item/gun/ballistic/shotgun/automatic/combat(get_turf(H)) + if("arg") + G = new /obj/item/gun/ballistic/automatic/ar(get_turf(H)) + if("mateba") + G = new /obj/item/gun/ballistic/revolver/mateba(get_turf(H)) + if("boltaction") + G = new /obj/item/gun/ballistic/shotgun/boltaction(get_turf(H)) + if("speargun") + G = new /obj/item/gun/ballistic/automatic/speargun(get_turf(H)) + if("uzi") + G = new /obj/item/gun/ballistic/automatic/mini_uzi(get_turf(H)) + if("cannon") + G = new /obj/item/gun/energy/lasercannon(get_turf(H)) + if("crossbow") + G = new /obj/item/gun/energy/kinetic_accelerator/crossbow/large(get_turf(H)) + if("nuclear") + G = new /obj/item/gun/energy/e_gun/nuclear(get_turf(H)) + if("sabr") + G = new /obj/item/gun/ballistic/automatic/proto(get_turf(H)) + if("bulldog") + G = new /obj/item/gun/ballistic/automatic/shotgun/bulldog(get_turf(H)) + if("c20r") + G = new /obj/item/gun/ballistic/automatic/c20r(get_turf(H)) + if("saw") + G = new /obj/item/gun/ballistic/automatic/l6_saw(get_turf(H)) + if("car") + G = new /obj/item/gun/ballistic/automatic/m90(get_turf(H)) + if("alienpistol") + G = new /obj/item/gun/energy/alien(get_turf(H)) + if("dragnet") + G = new /obj/item/gun/energy/e_gun/dragnet(get_turf(H)) + if("turret") + G = new /obj/item/gun/energy/e_gun/turret(get_turf(H)) + if("pulsecarbine") + G = new /obj/item/gun/energy/pulse/carbine(get_turf(H)) + if("decloner") + G = new /obj/item/gun/energy/decloner(get_turf(H)) + if("mindflayer") + G = new /obj/item/gun/energy/mindflayer(get_turf(H)) + if("hyperkinetic") + G = new /obj/item/gun/energy/kinetic_accelerator(get_turf(H)) + if("advplasmacutter") + G = new /obj/item/gun/energy/plasmacutter/adv(get_turf(H)) + if("wormhole") + G = new /obj/item/gun/energy/wormhole_projector(get_turf(H)) + if("wt550") + G = new /obj/item/gun/ballistic/automatic/wt550(get_turf(H)) + if("bulldog") + G = new /obj/item/gun/ballistic/automatic/shotgun(get_turf(H)) + if("grenadelauncher") + G = new /obj/item/gun/ballistic/revolver/grenadelauncher(get_turf(H)) + if("goldenrevolver") + G = new /obj/item/gun/ballistic/revolver/golden(get_turf(H)) + if("sniper") + G = new /obj/item/gun/ballistic/automatic/sniper_rifle(get_turf(H)) + if("medibeam") + G = new /obj/item/gun/medbeam(get_turf(H)) + if("scatterbeam") + G = new /obj/item/gun/energy/laser/scatter(get_turf(H)) + if("gravgun") + G = new /obj/item/gun/energy/gravity_gun(get_turf(H)) + G.unlock() + playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, 1) + + else + switch (randomizemagic) + if("fireball") + new /obj/item/spellbook/oneuse/fireball(get_turf(H)) + if("smoke") + new /obj/item/spellbook/oneuse/smoke(get_turf(H)) + if("blind") + new /obj/item/spellbook/oneuse/blind(get_turf(H)) + if("mindswap") + new /obj/item/spellbook/oneuse/mindswap(get_turf(H)) + if("forcewall") + new /obj/item/spellbook/oneuse/forcewall(get_turf(H)) + if("knock") + new /obj/item/spellbook/oneuse/knock(get_turf(H)) + if("horsemask") + new /obj/item/spellbook/oneuse/barnyard(get_turf(H)) + if("charge") + new /obj/item/spellbook/oneuse/charge(get_turf(H)) + if("summonitem") + new /obj/item/spellbook/oneuse/summonitem(get_turf(H)) + if("wandnothing") + new /obj/item/gun/magic/wand(get_turf(H)) + if("wanddeath") + new /obj/item/gun/magic/wand/death(get_turf(H)) + if("wandresurrection") + new /obj/item/gun/magic/wand/resurrection(get_turf(H)) + if("wandpolymorph") + new /obj/item/gun/magic/wand/polymorph(get_turf(H)) + if("wandteleport") + new /obj/item/gun/magic/wand/teleport(get_turf(H)) + if("wanddoor") + new /obj/item/gun/magic/wand/door(get_turf(H)) + if("wandfireball") + new /obj/item/gun/magic/wand/fireball(get_turf(H)) + if("staffhealing") + new /obj/item/gun/magic/staff/healing(get_turf(H)) + if("staffdoor") + new /obj/item/gun/magic/staff/door(get_turf(H)) + if("armor") + new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H)) + if("scrying") + new /obj/item/scrying(get_turf(H)) + if (!(H.dna.check_mutation(XRAY))) + H.dna.add_mutation(XRAY) + to_chat(H, "The walls suddenly disappear.") + if("voodoo") + new /obj/item/voodoo(get_turf(H)) + if("whistle") + new /obj/item/warpwhistle(get_turf(H)) + if("battlemage") + new /obj/item/clothing/suit/space/hardsuit/shielded/wizard(get_turf(H)) + if("immortality") + new /obj/item/device/immortality_talisman(get_turf(H)) + if("ghostsword") + new /obj/item/melee/ghost_sword(get_turf(H)) + if("special") + magiclist -= "special" //only one super OP item per summoning max + switch (randomizemagicspecial) + if("staffchange") + new /obj/item/gun/magic/staff/change(get_turf(H)) + if("staffanimation") + new /obj/item/gun/magic/staff/animate(get_turf(H)) + if("wandbelt") + new /obj/item/storage/belt/wands/full(get_turf(H)) + if("contract") + new /obj/item/antag_spawner/contract(get_turf(H)) + if("staffchaos") + new /obj/item/gun/magic/staff/chaos(get_turf(H)) + if("necromantic") + new /obj/item/device/necromantic_stone(get_turf(H)) + if("bloodcontract") + new /obj/item/blood_contract(get_turf(H)) + to_chat(H, "You suddenly feel lucky.") + playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, 1) + + +/proc/summonevents() + if(!SSevents.wizardmode) + SSevents.frequency_lower = 600 //1 minute lower bound + SSevents.frequency_upper = 3000 //5 minutes upper bound + SSevents.toggleWizardmode() + SSevents.reschedule() + + else //Speed it up + SSevents.frequency_upper -= 600 //The upper bound falls a minute each time, making the AVERAGE time between events lessen + if(SSevents.frequency_upper < SSevents.frequency_lower) //Sanity + SSevents.frequency_upper = SSevents.frequency_lower + + SSevents.reschedule() + message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.") + log_game("Summon Events was increased!") +>>>>>>> e8ff73e... Datum antag wizard. (#31449) diff --git a/tgstation.dme b/tgstation.dme index c63b893b69..07a801de50 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -300,6 +300,7 @@ #include "code\datums\antagonists\datum_traitor.dm" #include "code\datums\antagonists\devil.dm" #include "code\datums\antagonists\ninja.dm" +#include "code\datums\antagonists\wizard.dm" #include "code\datums\components\_component.dm" #include "code\datums\components\archaeology.dm" #include "code\datums\components\infective.dm" From bd18903e13adc78a28a8ea2cb46ab13805d4c00f Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 11 Oct 2017 18:03:58 -0400 Subject: [PATCH 05/44] eh it works --- code/citadel/cit_crewobjectives.dm | 12 +++++------ code/controllers/subsystem/ticker.dm | 21 +++++++++++++++---- .../modules/mob/dead/new_player/new_player.dm | 2 +- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/code/citadel/cit_crewobjectives.dm b/code/citadel/cit_crewobjectives.dm index 90a655b622..5a5d0b2384 100644 --- a/code/citadel/cit_crewobjectives.dm +++ b/code/citadel/cit_crewobjectives.dm @@ -1,6 +1,6 @@ /datum/controller/subsystem/ticker/proc/generate_crew_objectives() for(var/datum/mind/crewMind in SSticker.minds) - if(prob(2) && !issilicon(crewMind.current) && !jobban_isbanned(crewMind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in crewMind.current.client.prefs.be_special) + if(prob(5) && !issilicon(crewMind.current) && !jobban_isbanned(crewMind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in crewMind.current.client.prefs.be_special) generate_miscreant_objectives(crewMind) else if(CONFIG_GET(flag/allow_crew_objectives)) @@ -16,7 +16,8 @@ return if(!crewMind.assigned_role) return - var/list/validobjs = get_valid_crew_objs(ckey(crewMind.assigned_role)) + var/list/validobjs = crewobjjobs["[ckey(crewMind.assigned_role)]"] + //var/list/validobjs = get_valid_crew_objs(ckey(crewMind.assigned_role)) if(!validobjs || !validobjs.len) return var/selectedObj = pick(validobjs) @@ -28,15 +29,14 @@ to_chat(crewMind, "As a part of Nanotrasen's anti-tide efforts, you have been assigned an optional objective. It will be checked at the end of the shift. Performing traitorous acts in pursuit of your objective may result in termination of your employment.") to_chat(crewMind, "Your optional objective: [newObjective.explanation_text]") -/datum/controller/subsystem/ticker/proc/get_valid_crew_objs(var/job = "")//taken from old hippie with adjustments - var/list/objpaths = typesof(/datum/objective/crew) +/*/datum/controller/subsystem/ticker/proc/get_valid_crew_objs(var/job = "")//taken from old hippie with adjustments var/list/objlist = list() - for(var/hoorayhackyshit in objpaths) + for(var/hoorayhackyshit in crewobjlist) var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form. var/list/availableto = splittext(initial(obj.jobs),",") if(job in availableto) objlist += obj - return objlist + return objlist*/ /datum/objective/crew/ var/jobs = "" diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 02a9808f48..34e20ceee9 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -66,6 +66,11 @@ SUBSYSTEM_DEF(ticker) var/modevoted = FALSE //Have we sent a vote for the gamemode? + //Crew Objective/Miscreant stuff + var/list/crewobjlist = list() + var/list/crewobjjobs = list() + var/list/miscreantobjlist = list() + /datum/controller/subsystem/ticker/Initialize(timeofday) load_mode() @@ -87,7 +92,7 @@ SUBSYSTEM_DEF(ticker) var/list/provisional_title_music = flist("config/title_music/sounds/") var/list/music = list() var/use_rare_music = prob(1) - + for(var/S in provisional_title_music) var/lower = lowertext(S) var/list/L = splittext(lower,"+") @@ -115,12 +120,20 @@ SUBSYSTEM_DEF(ticker) if(byond_sound_formats[ext]) continue music -= S - + if(isemptylist(music)) music = world.file2list(ROUND_START_MUSIC_LIST, "\n") login_music = pick(music) + crewobjlist = typesof(/datum/objective/crew) + miscreantobjlist = typesof(/datum/objective/miscreant) + for(var/hoorayhackyshit in crewobjlist) + var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form. + var/list/availableto = splittext(initial(obj.jobs),",") + for(var/job in availableto) + crewobjjobs["[job]"] += list(obj) + if(!GLOB.syndicate_code_phrase) GLOB.syndicate_code_phrase = generate_code_phrase() if(!GLOB.syndicate_code_response) @@ -519,11 +532,11 @@ SUBSYSTEM_DEF(ticker) if(!crewMind.current || !crewMind.objectives.len) continue for(var/datum/objective/miscreant/MO in crewMind.objectives) - miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)
" + miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)" for(var/datum/objective/crew/CO in crewMind.objectives) if(CO.check_completion()) to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Success!") - successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)
" + successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)" else to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Failed.") diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index b692ab2d32..1eb4ced083 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -375,7 +375,7 @@ if(GLOB.highlander) to_chat(humanc, "THERE CAN BE ONLY ONE!!!") humanc.make_scottish() - if(prob(2) && !issilicon(humanc) && !jobban_isbanned(humanc.mind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in humanc.client.prefs.be_special) + if(prob(5) && !issilicon(humanc) && !jobban_isbanned(humanc.mind, "Syndicate") && GLOB.miscreants_allowed && ROLE_MISCREANT in humanc.client.prefs.be_special) SSticker.generate_miscreant_objectives(humanc.mind) else if(CONFIG_GET(flag/allow_crew_objectives)) From 1a3b0c6528c5627b7f5193382008d9848a709ae1 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 11 Oct 2017 18:07:08 -0400 Subject: [PATCH 06/44] applies optimizations to miscreants --- code/citadel/cit_miscreants.dm | 2 +- code/controllers/subsystem/ticker.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/citadel/cit_miscreants.dm b/code/citadel/cit_miscreants.dm index e658fad097..ec5ff0156f 100644 --- a/code/citadel/cit_miscreants.dm +++ b/code/citadel/cit_miscreants.dm @@ -11,7 +11,7 @@ return if(jobban_isbanned(crewMind, "Syndicate")) return - var/list/objectiveTypes = typesof(/datum/objective/miscreant) - /datum/objective/miscreant + var/list/objectiveTypes = miscreantobjlist if(!objectiveTypes.len) return var/selectedType = pick(objectiveTypes) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 34e20ceee9..2b3d1f9887 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -127,7 +127,7 @@ SUBSYSTEM_DEF(ticker) login_music = pick(music) crewobjlist = typesof(/datum/objective/crew) - miscreantobjlist = typesof(/datum/objective/miscreant) + miscreantobjlist = (typesof(/datum/objective/miscreant) - /datum/objective/miscreant) for(var/hoorayhackyshit in crewobjlist) var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form. var/list/availableto = splittext(initial(obj.jobs),",") From 2a46696e5547b79f50775b6b9efb8330162dede2 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 11 Oct 2017 18:26:10 -0400 Subject: [PATCH 07/44] cleans up comments --- code/citadel/cit_crewobjectives.dm | 10 ---------- code/controllers/subsystem/ticker.dm | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/code/citadel/cit_crewobjectives.dm b/code/citadel/cit_crewobjectives.dm index 5a5d0b2384..6afa92af65 100644 --- a/code/citadel/cit_crewobjectives.dm +++ b/code/citadel/cit_crewobjectives.dm @@ -17,7 +17,6 @@ if(!crewMind.assigned_role) return var/list/validobjs = crewobjjobs["[ckey(crewMind.assigned_role)]"] - //var/list/validobjs = get_valid_crew_objs(ckey(crewMind.assigned_role)) if(!validobjs || !validobjs.len) return var/selectedObj = pick(validobjs) @@ -29,15 +28,6 @@ to_chat(crewMind, "As a part of Nanotrasen's anti-tide efforts, you have been assigned an optional objective. It will be checked at the end of the shift. Performing traitorous acts in pursuit of your objective may result in termination of your employment.") to_chat(crewMind, "Your optional objective: [newObjective.explanation_text]") -/*/datum/controller/subsystem/ticker/proc/get_valid_crew_objs(var/job = "")//taken from old hippie with adjustments - var/list/objlist = list() - for(var/hoorayhackyshit in crewobjlist) - var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form. - var/list/availableto = splittext(initial(obj.jobs),",") - if(job in availableto) - objlist += obj - return objlist*/ - /datum/objective/crew/ var/jobs = "" explanation_text = "Yell on the development discussion channel on Citadels discord if this ever shows up. Something just broke here, dude" diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 2b3d1f9887..25e54aed64 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -128,7 +128,7 @@ SUBSYSTEM_DEF(ticker) crewobjlist = typesof(/datum/objective/crew) miscreantobjlist = (typesof(/datum/objective/miscreant) - /datum/objective/miscreant) - for(var/hoorayhackyshit in crewobjlist) + for(var/hoorayhackyshit in crewobjlist) //taken from old Hippie's "job2obj" proc with adjustments. var/datum/objective/crew/obj = hoorayhackyshit //dm is not a sane language in any way, shape, or form. var/list/availableto = splittext(initial(obj.jobs),",") for(var/job in availableto) From 5e90fec86535f14347ee6a8b00e6291e9c6892ed Mon Sep 17 00:00:00 2001 From: Jordie Date: Thu, 12 Oct 2017 14:08:04 +1100 Subject: [PATCH 08/44] Merge pull request #31597 from Bawhoppen/barackobama Manual changelog for smoke machine change --- .../Bawhoppen Forgot to add a Changelog.yml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 html/changelogs/Bawhoppen Forgot to add a Changelog.yml diff --git a/html/changelogs/Bawhoppen Forgot to add a Changelog.yml b/html/changelogs/Bawhoppen Forgot to add a Changelog.yml new file mode 100644 index 0000000000..9c9895e895 --- /dev/null +++ b/html/changelogs/Bawhoppen Forgot to add a Changelog.yml @@ -0,0 +1,35 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: "Bawhoppen" + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Smoke machine board has been moved to tech storage." From fa0aaa9870c01b20874529bc576f282566b0cef5 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Wed, 11 Oct 2017 22:25:39 -0400 Subject: [PATCH 10/44] Reebe cogscarabs have infinite power and can recite scripture during non-clockcult rounds (#31282) * During non-clock rounds, scarabs get more stuff * Actually, admins might want to make scarabs... * That's a thing --- code/game/gamemodes/clock_cult/clock_cult.dm | 2 ++ .../clock_items/construct_chassis.dm | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 2f877776d5..e312f51319 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -146,6 +146,8 @@ Credit where due: var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful G.initial_activation_delay = ark_time * 60 G.seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes + for(var/obj/item/clockwork/construct_chassis/cogscarab/C in GLOB.all_clockwork_objects) + C.infinite_resources = FALSE SSshuttle.registerHostileEnvironment(GLOB.ark_of_the_clockwork_justiciar) ..() return 1 diff --git a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm index 11349cb013..0b7738961a 100644 --- a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm +++ b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm @@ -34,17 +34,28 @@ . = ..() /obj/item/clockwork/construct_chassis/attack_ghost(mob/user) + if(!SSticker.mode) + to_chat(user, "You cannot use that before the game has started.") + return if(alert(user, "Become a [construct_name]? You can no longer be cloned!", construct_name, "Yes", "Cancel") == "Cancel") return if(QDELETED(src)) to_chat(user, "You were too late! Better luck next time.") return + pre_spawn() visible_message(creation_message) var/mob/living/construct = new construct_type(get_turf(src)) construct.key = user.key + post_spawn(construct) qdel(user) qdel(src) +/obj/item/clockwork/construct_chassis/proc/pre_spawn() //Some things might change before the construct spawns; override those on a subtype basis in this proc + return + +/obj/item/clockwork/construct_chassis/proc/post_spawn(mob/living/construct) //And some things might change after it + return + //Marauder armor, used to create clockwork marauders - sturdy frontline combatants that can deflect projectiles. /obj/item/clockwork/construct_chassis/clockwork_marauder @@ -67,3 +78,21 @@ creation_message = "The cogscarab clicks and whirrs as it hops up and springs to life!" construct_type = /mob/living/simple_animal/drone/cogscarab w_class = WEIGHT_CLASS_SMALL + var/infinite_resources = TRUE + +/obj/item/clockwork/construct_chassis/cogscarab/Initialize() + . = ..() + if(istype(SSticker.mode, /datum/game_mode/clockwork_cult)) + infinite_resources = FALSE //For any that are somehow spawned in late + +/obj/item/clockwork/construct_chassis/cogscarab/pre_spawn() + if(infinite_resources) + construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar //During rounds where they can't interact with the station, let them experiment with builds + +/obj/item/clockwork/construct_chassis/cogscarab/post_spawn(mob/living/construct) + if(infinite_resources) //Allow them to build stuff and recite scripture + var/list/cached_stuff = construct.GetAllContents() + for(var/obj/item/clockwork/replica_fabricator/F in cached_stuff) + F.uses_power = FALSE + for(var/obj/item/clockwork/slab/S in cached_stuff) + S.no_cost = TRUE From 1604f8b1d39d42feb7c19e32edc57dd0ac4ee723 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 11 Oct 2017 21:46:51 -0400 Subject: [PATCH 12/44] Datumizes world/Topic (#31543) * Datumizes world/Topic * active_players requires comms_key --- code/__DEFINES/misc.dm | 3 + code/datums/world_topic.dm | 168 +++++++++++++++++++++ code/game/world.dm | 95 ++---------- code/modules/admin/chat_commands.dm | 4 +- code/modules/mob/dead/observer/observer.dm | 8 - tgstation.dme | 1 + 6 files changed, 187 insertions(+), 92 deletions(-) create mode 100644 code/datums/world_topic.dm diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index bdb9ad35a9..b83fc3dd39 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -466,3 +466,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE //Dummy mob reserve slots #define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview" #define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation" + +#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round + //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored \ No newline at end of file diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm new file mode 100644 index 0000000000..02cb4e0c31 --- /dev/null +++ b/code/datums/world_topic.dm @@ -0,0 +1,168 @@ +// SETUP + +/proc/TopicHandlers() + . = list() + var/list/all_handlers = subtypesof(/datum/world_topic) + for(var/I in all_handlers) + var/datum/world_topic/WT = I + var/keyword = initial(WT.keyword) + if(!keyword) + warning("[WT] has no keyword! Ignoring...") + continue + var/existing_path = .[keyword] + if(existing_path) + warning("[existing_path] and [WT] have the same keyword! Ignoring [WT]...") + else if(keyword == "key") + warning("[WT] has keyword 'key'! Ignoring...") + else + .[keyword] = WT + +// DATUM + +/datum/world_topic + var/keyword + var/log = TRUE + var/key_valid + var/require_comms_key = FALSE + +/datum/world_topic/proc/TryRun(list/input) + key_valid = !config || CONFIG_GET(string/comms_key) != input["key"] + if(require_comms_key && !key_valid) + return "Bad Key" + input -= "key" + . = Run(input) + if(islist(.)) + . = list2params(.) + +/datum/world_topic/proc/Run(list/input) + CRASH("Run() not implemented for [type]!") + +// TOPICS + +/datum/world_topic/ping + keyword = "ping" + log = FALSE + +/datum/world_topic/ping/Run(list/input) + . = 0 + for (var/client/C in GLOB.clients) + ++. + +/datum/world_topic/playing + keyword = "playing" + log = FALSE + +/datum/world_topic/playing/Run(list/input) + return GLOB.player_list.len + +/datum/world_topic/pr_announce + keyword = "announce" + require_comms_key = TRUE + var/static/list/PRcounts = list() //PR id -> number of times announced this round + +/datum/world_topic/pr_announce/Run(list/input) + var/list/payload = json_decode(input["payload"]) + var/id = "[payload["pull_request"]["id"]]" + if(!PRcounts[id]) + PRcounts[id] = 1 + else + ++PRcounts[id] + if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND) + return + + var/final_composed = "PR: [input[keyword]]" + for(var/client/C in GLOB.clients) + C.AnnouncePR(final_composed) + +/datum/world_topic/ahelp_relay + keyword = "ahelp_relay" + require_comms_key = TRUE + +/datum/world_topic/ahelp_relay/Run(list/input) + relay_msg_admins("HELP: [input["source"]] [input["message_sender"]]: [input["message"]]") + +/datum/world_topic/comms_console + keyword = "comms_console" + require_comms_key = TRUE + +/datum/world_topic/comms_console/Run(list/input) + minor_announce(input["message"], "Incoming message from [input["message_sender"]]") + for(var/obj/machinery/computer/communications/CM in GLOB.machines) + CM.overrideCooldown() + +/datum/world_topic/news_report + keyword = "news_report" + require_comms_key = TRUE + +/datum/world_topic/news_report/Run(list/input) + minor_announce(input["message"], "Breaking Update From [input["message_sender"]]") + +/datum/world_topic/server_hop + keyword = "server_hop" + +/datum/world_topic/server_hop/Run(list/input) + var/expected_key = input[keyword] + for(var/mob/dead/observer/O in GLOB.player_list) + if(O.key == expected_key) + if(O.client) + new /obj/screen/splash(O.client, TRUE) + break + +/datum/world_topic/adminmsg + keyword = "adminmsg" + +/datum/world_topic/adminmsg/Run(list/input) + return IrcPm(input[keyword], input["msg"], input["sender"]) + +/datum/world_topic/namecheck + keyword = "namecheck" + +/datum/world_topic/namecheck/Run(list/input) + var/datum/server_tools_command/namecheck/NC = new + return NC.Run(input["sender"], input["namecheck"]) + +/datum/world_topic/adminwho + keyword = "namecheck" + +/datum/world_topic/adminwho/Run(list/input) + return ircadminwho() + +/datum/world_topic/status + keyword = "status" + +/datum/world_topic/status/Run(list/input) + . = list() + .["version"] = GLOB.game_version + .["mode"] = GLOB.master_mode + .["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE + .["enter"] = GLOB.enter_allowed + .["vote"] = CONFIG_GET(flag/allow_vote_mode) + .["ai"] = CONFIG_GET(flag/allow_ai) + .["host"] = world.host ? world.host : null + .["players"] = GLOB.clients.len + .["revision"] = GLOB.revdata.commit + .["revision_date"] = GLOB.revdata.date + + var/list/adm = get_admin_counts() + var/list/presentmins = adm["present"] + var/list/afkmins = adm["afk"] + .["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho + .["gamestate"] = SSticker.current_state + + .["map_name"] = SSmapping.config.map_name + + if(key_valid) + .["active_players"] = get_active_player_count() + if(SSticker.HasRoundStarted()) + .["real_mode"] = SSticker.mode.name + // Key-authed callers may know the truth behind the "secret" + + .["security_level"] = get_security_level() + .["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0 + // Amount of world's ticks in seconds, useful for calculating round duration + + if(SSshuttle && SSshuttle.emergency) + .["shuttle_mode"] = SSshuttle.emergency.mode + // Shuttle status, see /__DEFINES/stat.dm + .["shuttle_timer"] = SSshuttle.emergency.timeLeft() + // Shuttle timer, in seconds diff --git a/code/game/world.dm b/code/game/world.dm index bd04008ea3..5fe674cb7f 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -1,6 +1,3 @@ -#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round - //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored - GLOBAL_VAR(security_mode) GLOBAL_PROTECT(security_mode) @@ -118,91 +115,25 @@ GLOBAL_PROTECT(security_mode) warning("/tg/station 13 uses many file operations, a few shell()s, and some external call()s. Trusted mode is recommended. You can download our source code for your own browsing and compilation at https://github.com/tgstation/tgstation") /world/Topic(T, addr, master, key) + var/static/list/topic_handlers = TopicHandlers() + var/list/input = params2list(T) - - var/pinging = ("ping" in input) - var/playing = ("players" in input) - - if(!pinging && !playing && config && CONFIG_GET(flag/log_world_topic)) + var/datum/world_topic/handler + for(var/I in topic_handlers) + if(input[I]) + handler = I + break + + if((!handler || initial(handler.log)) && config && CONFIG_GET(flag/log_world_topic)) WRITE_FILE(GLOB.world_game_log, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]") SERVER_TOOLS_ON_TOPIC //redirect to server tools if necessary - var/comms_key = CONFIG_GET(string/comms_key) - var/key_valid = (comms_key && input["key"] == comms_key) + if(!handler) + return - if(pinging) - var/x = 1 - for (var/client/C in GLOB.clients) - x++ - return x - - else if(playing) - var/n = 0 - for(var/mob/M in GLOB.player_list) - if(M.client) - n++ - return n - - else if("status" in input) - var/list/s = list() - s["version"] = GLOB.game_version - s["mode"] = GLOB.master_mode - s["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE - s["enter"] = GLOB.enter_allowed - s["vote"] = CONFIG_GET(flag/allow_vote_mode) - s["ai"] = CONFIG_GET(flag/allow_ai) - s["host"] = host ? host : null - s["active_players"] = get_active_player_count() - s["players"] = GLOB.clients.len - s["revision"] = GLOB.revdata.commit - s["revision_date"] = GLOB.revdata.date - - var/list/adm = get_admin_counts() - var/list/presentmins = adm["present"] - var/list/afkmins = adm["afk"] - s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho - s["gamestate"] = SSticker.current_state - - s["map_name"] = SSmapping.config.map_name - - if(key_valid && SSticker.HasRoundStarted()) - s["real_mode"] = SSticker.mode.name - // Key-authed callers may know the truth behind the "secret" - - s["security_level"] = get_security_level() - s["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0 - // Amount of world's ticks in seconds, useful for calculating round duration - - if(SSshuttle && SSshuttle.emergency) - s["shuttle_mode"] = SSshuttle.emergency.mode - // Shuttle status, see /__DEFINES/stat.dm - s["shuttle_timer"] = SSshuttle.emergency.timeLeft() - // Shuttle timer, in seconds - - return list2params(s) - - else if("announce" in input) - if(!key_valid) - return "Bad Key" - else - AnnouncePR(input["announce"], json_decode(input["payload"])) - - else if("crossmessage" in input) - if(!key_valid) - return - else - if(input["crossmessage"] == "Ahelp") - relay_msg_admins("HELP: [input["source"]] [input["message_sender"]]: [input["message"]]") - if(input["crossmessage"] == "Comms_Console") - minor_announce(input["message"], "Incoming message from [input["message_sender"]]") - for(var/obj/machinery/computer/communications/CM in GLOB.machines) - CM.overrideCooldown() - if(input["crossmessage"] == "News_Report") - minor_announce(input["message"], "Breaking Update From [input["message_sender"]]") - - else if("server_hop" in input) - show_server_hop_transfer_screen(input["server_hop"]) + handler = new handler() + return handler.Run(input) /world/proc/AnnouncePR(announcement, list/payload) var/static/list/PRcounts = list() //PR id -> number of times announced this round diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index f24e03aabc..ec79aaca07 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -49,8 +49,8 @@ admin_only = TRUE /datum/server_tools_command/namecheck/Run(sender, params) - log_admin("IRC Name Check: [sender] on [params]") - message_admins("IRC name checking on [params] from [sender]") + log_admin("Chat Name Check: [sender] on [params]") + message_admins("Name checking [params] from [sender]") return keywords_lookup(params, 1) /datum/server_tools_command/adminwho diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 1022719805..4c6628a53b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -597,14 +597,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp target.faction = list("neutral") return 1 -/proc/show_server_hop_transfer_screen(expected_key) - //only show it to incoming ghosts - for(var/mob/dead/observer/O in GLOB.player_list) - if(O.key == expected_key) - if(O.client) - new /obj/screen/splash(O.client, TRUE) - break - //this is a mob verb instead of atom for performance reasons //see /mob/verb/examinate() in mob.dm for more info //overriden here and in /mob/living for different point span classes and sanity checks diff --git a/tgstation.dme b/tgstation.dme index c63b893b69..581c882e41 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -291,6 +291,7 @@ #include "code\datums\soullink.dm" #include "code\datums\spawners_menu.dm" #include "code\datums\verbs.dm" +#include "code\datums\world_topic.dm" #include "code\datums\antagonists\antag_datum.dm" #include "code\datums\antagonists\datum_abductor.dm" #include "code\datums\antagonists\datum_brother.dm" From 0e5605119411aa50a492d6c09d37cf50445c4e20 Mon Sep 17 00:00:00 2001 From: bawhoppen Date: Wed, 11 Oct 2017 20:36:06 -0500 Subject: [PATCH 14/44] Moves Smoke Machine boards to tech storage (#31546) --- _maps/map_files/BoxStation/BoxStation.dmm | 2 +- _maps/map_files/Deltastation/DeltaStation2.dmm | 2 +- _maps/map_files/MetaStation/MetaStation.dmm | 2 +- _maps/map_files/PubbyStation/PubbyStation.dmm | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 1db3e9697d..7878db0e5d 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -27778,7 +27778,6 @@ /obj/structure/table, /obj/item/folder/white, /obj/item/device/radio/headset/headset_med, -/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/white, /area/medical/chemistry) "boe" = ( @@ -37450,6 +37449,7 @@ /obj/item/circuitboard/machine/clonescanner, /obj/item/circuitboard/machine/clonepod, /obj/item/circuitboard/computer/scan_consolenew, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plating, /area/storage/tech) "bJl" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 95256fae4c..a29396fa14 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -39367,6 +39367,7 @@ pixel_y = -3 }, /obj/effect/turf_decal/bot, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel, /area/storage/tech) "bAP" = ( @@ -77224,7 +77225,6 @@ /obj/structure/table/glass, /obj/item/clipboard, /obj/item/toy/figure/chemist, -/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/whiteyellow/corner{ dir = 1 }, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 26bc13dde1..06e1282622 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -27681,6 +27681,7 @@ /obj/item/circuitboard/machine/clonescanner, /obj/item/circuitboard/machine/clonepod, /obj/item/circuitboard/computer/scan_consolenew, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/black, /area/storage/tech) "bbo" = ( @@ -59764,7 +59765,6 @@ dir = 1; pixel_y = -24 }, -/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/whiteyellow{ dir = 4 }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 154df34231..6bee0493d0 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -32785,7 +32785,6 @@ /obj/item/hand_labeler, /obj/item/device/radio/headset/headset_med, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/white, /area/medical/chemistry) "bwW" = ( @@ -41751,6 +41750,7 @@ /obj/structure/sign/poster/official/random{ pixel_y = 32 }, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/darkgreen, /area/storage/tech) "bQw" = ( From 976797afb36c94c20e4d0c5cd6adfe3b9a277992 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 11 Oct 2017 20:42:16 -0400 Subject: [PATCH 16/44] Adds round id to the banning panel (#31545) --- code/modules/admin/DB_ban/functions.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm index 086df300d3..7fe9904102 100644 --- a/code/modules/admin/DB_ban/functions.dm +++ b/code/modules/admin/DB_ban/functions.dm @@ -434,7 +434,7 @@ output += "OPTIONS" output += "" var/limit = " LIMIT [bansperpage * page], [bansperpage]" - var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC[limit]") + var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC[limit]") if(!query_search_bans.warn_execute()) return @@ -452,6 +452,7 @@ var/unbanckey = query_search_bans.item[11] var/unbantime = query_search_bans.item[12] var/edits = query_search_bans.item[13] + var/round_id = query_search_bans.item[14] var/lcolor = blcolor var/dcolor = bdcolor @@ -477,7 +478,7 @@ output += "" output += "[typedesc]" output += "[ckey]" - output += "[bantime]" + output += "[bantime] (Round ID: [round_id])" output += "[ackey]" output += "[(unbanned) ? "" : "Unban"]" output += "" From 17795f04c8c436c3fbbae0e92cfdfe312fd0b89e Mon Sep 17 00:00:00 2001 From: Mercenaryblue Date: Wed, 11 Oct 2017 20:41:27 -0400 Subject: [PATCH 18/44] Added Banana Peels Inhand Sprites (#31551) Added in-hand Banana Peels sprites. Default, Mime, and Bluespace. --- code/modules/hydroponics/grown/banana.dm | 5 +++++ icons/mob/inhands/misc/food_lefthand.dmi | Bin 2666 -> 2976 bytes icons/mob/inhands/misc/food_righthand.dmi | Bin 2610 -> 2907 bytes 3 files changed, 5 insertions(+) diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index 7183cac451..a78416b6cc 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -38,10 +38,13 @@ user.visible_message("[user] laughs so hard they begin to suffocate!") return (OXYLOSS) +//Banana Peel /obj/item/grown/bananapeel seed = /obj/item/seeds/banana name = "banana peel" desc = "A peel from a banana." + lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' icon_state = "banana_peel" item_state = "banana_peel" w_class = WEIGHT_CLASS_TINY @@ -81,6 +84,7 @@ name = "mimana peel" desc = "A mimana peel." icon_state = "mimana_peel" + item_state = "mimana_peel" // Bluespace Banana /obj/item/seeds/banana/bluespace @@ -100,6 +104,7 @@ seed = /obj/item/seeds/banana/bluespace name = "bluespace banana" icon_state = "banana_blue" + item_state = "bluespace_peel" trash = /obj/item/grown/bananapeel/bluespace filling_color = "#0000FF" origin_tech = "biotech=3;bluespace=5" diff --git a/icons/mob/inhands/misc/food_lefthand.dmi b/icons/mob/inhands/misc/food_lefthand.dmi index 770172cb5bec6b9279f26a13782962478a9110a4..bdcccfc08bb2a28b0d7b5cf577996a26b131f70a 100644 GIT binary patch delta 2693 zcmZ`(c{tSD8=s*l>+RY~cCuxtE`_mY-(zGqh`0!M3_^T|x@8+gmh2IdkiD_X7KR!7 z79u;twa1L{8`Ztf(;vU{$2sqLpXYp*bI$v&vSxF{aWJ9IQG-CBgi9J|5D4sAc0~vb z5SE;+9bB6-X|8lcuJ3azl34RNEL!!3HBu3{62Qi(~gGu~i_<0;%roa}V*SH}X#} zPY~!~I{HPgVe2)9P8`7$Hkrr|$jALgE9uHI5!#@ZSn0_LK?{oHc^Dbh+N!9Hb+Te`AOcR#=FM1jg*8IP$il&N9|YMpcK^x-abfNrn14UN7Kfy2oqBkmA_v z%sh(o-|LxT{@cc}Z;}@`I!yjhCwby!1ZmJNOKE8WfzF|H)Ky^*(+N}PAQm(B&Mh&R zwXwDHD>mae6IZM3dbamg*^yyqRCi3YZ}*feAC-6K)W16+PhTqQ1sdcMH3 z7k4^HGfA6w6SDo(oNZBU32M)_^$K@RJ8R4^ah!je7`~PnwmYmX%>OU!_Z0wv#?+n) zycO;bo&64+`F+OQ{Y3o+`5E9Qf5PMK$~-DSk*cj;5kKH}s{cPc2y|ik(xm_`bLnoT z&gdAr9ldtRMf0|L;&jmFYUI{F0hm09{irHPJfI&wCTcMls`Txnd1U!u%v={`Qs9&g zI+lKTYwP;s!_E%2CgqU%;4)HU7uBcn%sUt@O?qR6`}(U**5Fg0j^MWKHEWdmMy1Ay zuNa~La#X7K9QvRiC}RD^G6*D!*2z-mh|(PY2Mus3h{Bk8qz{oFQV3Aww|{1tC*JaY zSbb$zkequfjX5@aL6Fze#;+*%nG&K{>E8Y{8oY~0gae66$yfauS2EdcXloa(`TQ5nUdnV zxeL55+E;42$n9<5wpnEn?ZR5o%dIT7t1ZFlEa+{s`rJago90*bWAVDSF+;pAzEsDV zKyB+?=0O}*s7t?J=S6<}{1B|G=)=GZRSuYH-k=U55T6EIgIHoq&!;LS2)Xp>2PIZI zy{Ee}N{V*`>y85%;=oiUO8CvZJZ!sm$Zo|i#30W70E>;T0eKRmd#SLmfk;hE53mX= zyq7o0fv_EK>5L7VYUt-(bGtU1(uq@m*S|&|vcXdNazH z`=YG7Hx;6K^Yh`3+8*i9hi0c|ypf(mif%ZHL+T<{%7ylbMBMQwkv7EHdNlo2wo-hy zHQbQ2tg#qA_-jpnlq22}Gbpzpn;PeXDDdh2OPZf!-f-!~*OVv!QU2stUp`p+>VHJ) z`kbeywl|O`_n0NFA~?B}fo{0vYBJ+uaz!vN4tQ76VUo8?+}WaBJej48)K%X?k{fT7 zI~0(qrH<^hX%t98Z=mL`?_@~NsA7}-HNf!Z zzY2c(Z+^P+LqYJ#A*yJ!gnoE!w1ku5k;wk+>62AFKBt9*@cUAcj#~omdsE4cXW|xk zY)?MhlhZwLXpOS^hpngK%x4bAL;3_Lh1#Y;_=lQXjjTQJR0&i%VeJ4%Ym@jx35MTa zzJRM!2srbvlAo*fr{3_lI!G1rxrVvNdsCXUo*FR0LN!k&y$A6{&td$x;StJw{C7`N zjJl^OB>$~v?d82xqBM*Iww@peyGqRdRQ!p^<(u@`oE@fdjhtOVzmSYYdP>o?w@+SX z=N8ohMryL4b6SF%9u~-K8}>k3!yd&+0e1_sm1xKV#I_?+b}<~kR$j!ZFI7y)H*E|u za&2y?V`q%ZnJhTcOgXvS{=B_^V8T;=A!vq<@!QC2u*t4_2HaxOpfe-SxC%qnzU+;s znGQ{*x2HA}Pc(;%mo_H8*!B2lq?!bIl;mE3vN%4r=o|Oy$ zp0B73V8lnq&v?D8r#B^WhY9DURasS~3S|W5SHkoLSNEiAt62k*Zf=H2i)}Z_>XW$< z1rN#DI^CHo5@v3`H94MF)~a+%9jpfkbIuH@PLmbHz4fPvD9ff9_mOHg>8?t^g*i!l z@2zR6gyQnCehsC9IuwK6SHg-V`^hn3!j}%#TaJm9P1<;&!2kNd`(9~ILf$l!`TECH z&GOF-y0d;R51y5_OK26(GYxB}GV>lmJd~o(yF%-|X{}^zvhLosf)3k6(4Aw3$65wl ztcr)ie8y$GoqZer26~5);G|)2%Pi!&=UIt9Z$X7^9ln?+p z{*TJmzBM3jD)|itOpiaNDipnLfOpF+d~}wP$t%LLkG;$X3pAB?Zj$EwA$5U#_g!or z^OUanfw!qokGMCiG&taHa$ddK9mJ>bNHPD=4G@_*iBlp^O5IOWepH&Kd;@A)N$FHu z6CL-qoSQwti0RuU;zT$y3mJ2`RgeYf#GgEIHvhJ;loc|Rq3Y!Kc3Dhxs;Qb^Ibuxl z?1BVpUk1qDpfE0j{_70FU?y3yLJAGj5#DJ>ukn}x9rIa=y)E)7bW%qA&XHHdttul{gCeN+j4 T<(r`!a+=W5FjOy5vk&_peFzQW delta 2381 zcmZ8hc{tST7ynKpOSVK>Tv90%qcFJTZlSSzG8fS4Kf+{EgkHg;G8k3csJ`YIM3a0LKD za+A`uuC$&IiuK}17^#+c_g6V3@EFFEN9;pF&XfZAUSliVY)wJiL{s^uaCfgDULwSX3_6s6M(%Zcp}EK88tP zH?JE=amCi!jD$YEkeny%a?Pr=Ua}@9m7jO7;{3K`@?lqe&YxF{gUX+z-;;)Si7P*s z{==$5Qz5-g)ro3w-tPrx)NWN$57lyyFv=wduFgOX4Ifw;ek+5mN|G=ybpZcOCj&lgl;kX57kbDnkxg?0`;1 zBp)tXouT-j_gc&yGZ5QUX6wAc@opm??aPNk1`tI2^`Cci?z^L;{U*CHWB7l-SCujg z3>*)0mz7WV=Ox%-$MALy`=T!QwKTWY_5e22kRAQD(5xE(_&?sQ=qlR9XJb*Qy~W%5 zlYQ+UQq>RxpVW)OMLSN1+x!HAU83U&VHq*%Dd;&R&2Sr~k3xw0+a0L;dhm6Z)5Q4}9GC$UdvsA$kRvHhyiNzTZ0xqeDpq2;MF8O1X3n_c@g`6%tO zH{)jO>lH}C5U00+G|jIWE%0WLuorQE(S>4GB2N%F_C#d&E+?N#EV=n;XMNa}E3lIQjuYDh z%uKl0myb;A23Edl=${ktjv4WAc%oA<41PL~`N297+$bVzKex;?Q_DHfIG4Ry#TH?A zZG$4V)vUIfFV)LmU-t394v@5DV3XbVyUN z`uTepyS=vWuxwaQ|KXaoPIq9_$b})#+L(_4*j z20QbRig70eeh~lwp35w05`1(+yz6|t#YP(WY3#y99ZO&YuiMf zIa|wT&r;~QAH!dxpevUir^G93EdT5dS6*s!FDOqcnz#tN@7nfnk?Dp3wl^kTfghz4 zSrX7MoL;TP2X_{Nl|EQ2?RW<3n66^n*(XU8Y-b;pS25!F!uX%T$ix;_zaK7dA}&QA zsuTIhJ4#}dJRpCGi%JOdG&Zjr4N5qmD=56|*AFPJrp&8!2M=BIQnc}}LY(~I^7wiR zqG$V~>t@CMgBksUjdv%EYy8vzaNrnPK6N&EB90DsPR-69c<5zTj49r4IE^W`s!V&! zCtFb5;~V99Z!MBK<&-(mI|f&5vM)=cTE46DGAqCLd!<9tgX87VUg&Qylhi}pq}Hj0 zgA286c6Jdx>$OjrRgid4YQ+V!(O8CQK;6sF@U8|g7h)1$nv^HgywRQmrVq)z&9AIX zCwi1PI5>UTILlV7Hto=MbaYbAutkH8&Z)P<8d%eUjNS=&eE$DsqN~+A_?A&9$3-qV zDmzq%9pMItDdT9#_M+MD1w=z;wM(jU1t=`wO$wWVsF#y;{QcB%#3nI`G1@w=yJLu8 z$|_qW`;LJfGYgV~8k3NUa_CcvM*9;1yWDZ)a=KjQ&L;B|e$CJJDN=ThT&5qR>EmsE zUi?#z%C*~Cg~*k%Hqvo_-9T)o`|eAfuUDG8T=Bj zK~IvZPZFMXd)~}h$Xp#<9F_M4=2>ip6sZ>_!WI_s1IhlHPt@MC#70RTYK8Qo_9 z0LKHOOEl+>4r>~%yX_Oa{ZGfP?)#)_p}yWL^nFlQ7thPA^H{86T#Wfs zD4@TG$Ye5Ab@s7OnU9|_G2srRT7qu~qwsCUEhzKajqhL9lgC*S909jY?f|rB`dwMr zKg7Z&K*z=3$|Y)$$|fB=n}8Ceu9BfY*ntb8DEq* zOp#)WffMk}Ph>qsd9B@?(+WdQX`ehJbo3S|a3$u3r&yz?6jzP7YeLz_p>GJEw=NpG zl3-O29}5p6HP$#>Vj%XDq1MM=M~m@Oq-De3^)m$46a9^*c(it#q3DElPrJ# zUhhr5b3@u}OEvitlPjIWKo?~ZpXV1+sqzXeusbU_x453To>GL`4YfnFo3GDiH~BQR3qHKp>qX~XJD7A&YvGEN&-QD0R1svz&X4I^$CX0J8Z?0ix>E^meN;li}X}C*hEe>oQf$PQy=_#iq&z(g z9$VX#vPjy<4+OjCC(cN3u|Qopqw%q;UwwHo_m30V1dcG68-07b=3n}PEz;Bn`>aWr zM!&^=U-=8_?XNsM9a{r+n;nacLQOqP@^TH-~=K#wsuAJ%3G-Y~O=!5m?U!S9Z0~%=6Dp@MtB!tR2dV zw)ZCV|JlVfm70?{&i+OhoHxK1&|MiVS_y@Z}t4q^O{S zdT%JQa@jg5<2mY^)r!bx4|LaeNAC|X6+)T6K+IHyhRvFzcd=b|5{{DEx9QjvxwmEM zv@uy!S zj>F8KvI)TX!{Oa1sk<+ee(|z@s{nqngG8K5*>)|hnu^QVsii7e&C;bq1ycU9JJJ%& zkpE097z_nx9t=Y<}nTp!#O{G+M2v zXKEQiIq$Ojiv$WUHC9EH#xy!$>}W{_(4<RX<)aQU~(&k zWK>^oD2D#(SHNo>+=)ssnhTt_S)aYj7*}1QhTx6njM=5j+Q;e|G^MPsgo0&IK*~7E zT3#x)R&8lI<2qtdq!#5FFH*-fJW@BKHI|mMFIyQh0=~D)Go^7}B=;cEtMI*F9R5RX TsSjHLv-^PPn&=eYa*X&d?bGx> delta 2332 zcmZ8hcOaYl8jj zQG3LwYXudvHbHD^=Y*bn?&xSV?kj4zU8O|+ zrV@FevM@p0#w!a3N8LPRTa4CUHD63kS$ENu(m9ko0dWYv4o*~(UT9I#i?L`M$sWcWnr$r=Nb6%m z2YrARlKtOiJuFt#?{1exi93397?SGhFO2O^hzLn?tbtuxp)-{)SOE#KDP<~ zrJ0`ddiw55TA!Gpvc*N0)y6G)@A|@-vyX+qi3NetwxbDDUe(w}^U4uz0~=$bXL08p ze^XEPc2|Yq4|gzw>qTxCICNVMwkCkaCDDc-nw~=OHH}~S?TND394IVMG?9t# z7k5o#cgUo!00L!pWo8cup)P3?yiB~83i1PK6dJIG5a)LsqOEM!8O z>kkL|iL0cl|CjHtyJ0jQj(Vs^RyxLqM|gwILR};i*Wxlgfop&9({CR0lQJnF2ny4YI_mE1I_r*(ayB%-R#i``!wimx%rL%jN;ZJgMah-@^ z*3uf#<7{YnQa?4eg5Bb6XldcUz4o~!WWmVL($3walF3vp_9dUt*sDfHULL4`OTZzUCfbV;wf)m8+ywZisNZwO!eRgWXMe zV-Hz<>$YLCZxiOk6U8RASaE%Q!ksE51!#z2#0Y1ws?xJu(*41!hURuRESW@fi4xiO z?@QR*v$PHjw8qCv4ekF6h8iE9acdJT=G6?HU6D*K>~fBLartle~#n%37|j)hKNUqZDMF*T7R zP>I@^!qdPJ=e4n&RF*XzUrrJ=VvXr=dVzdq2;Bd<8`C@+*WwWg={WyC{mbhOgx_^Syrf2Y-o z5eUy!SI>`6lF4=cp#_nERVkgm-&2i0xv@FIFR{F}c@Hix3;%jbVi^Xvhs(czKP)J* zod5nVyl`%wp4z!PJ|I)`lPaU(rUAjcF%#@7Mt1I|l}u8a?xEBa9P^F93Em$6RdD9d zBH;0bvIZt4%TEz^FYiRZ@3$PtR7lW zzjX@SpMsMtG&<_8ewa+HRwy+G$DHy=vJfXa8W5XS*0^!)duB&htJ9X(&lHvY&xyy$ z#}M9o>#MK*50>co+7Gkvr>%mWsSJS|-!La)gboe{^Z?l=8}=vg9%L#UCa>lT<*fGT zuran9#KAbL4H<-u6A|0&xJky@E;~{^8m2gw8_Xz?!N>7kWp@7r*EO~}6GYp2{xBiw>|vj6SF)0a@HZpk$t zDb~%7eM?*HMXMA{z63liGnE63TzwRiqUL!iB~hOC_Wh5QXHagXIF zHkdxQrjKC_`LZnTHPEv;;1VZ<=&G<}3Z`#0q0qGCoMWD-6_6&h)lXNF9s--OPvG?~ z3v|2|Ny#X>=Tw4lj0gN?bNXFXddxIGYWO^5-aV}OL&#PtWDnL&n0x=c<8`%=jZB=+ zW`wU<`z~JH`Y5V+C}3r8IrytzX*K6Lw5+S0XPD>_yFV*&Tc}@{4P-p+q(VIsgNoi5YAiZtLxRU`!iq a*gosfLYfh`gImQ>Z%{gh+Ihd*2L1_lNI&ub From 33afe4f0ca53b579dc233c8909817ae26cae9c7a Mon Sep 17 00:00:00 2001 From: PKPenguin321 Date: Wed, 11 Oct 2017 17:41:04 -0700 Subject: [PATCH 20/44] Removes unwelding a singletank (#31550) Fixes #27341 --- code/modules/assembly/bomb.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index ebd2214aba..7c0875c3aa 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -51,10 +51,6 @@ GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" message_admins("[key_name_admin(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.") - else - status = FALSE - GLOB.bombers += "[key_name(user)] unwelded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" - to_chat(user, "The hole has been closed.") add_fingerprint(user) ..() From 5711f562f0f335a3e06a219ab680e101f2240a4c Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Wed, 11 Oct 2017 20:40:36 -0400 Subject: [PATCH 22/44] when cleanbot cleans a tile, it will now fully cleans the tile (#31548) As opposed to taking out one stain at a time --- code/modules/mob/living/simple_animal/bot/cleanbot.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 28de1f16e8..af4d8736b6 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -206,7 +206,8 @@ if(A && isturf(A.loc)) var/atom/movable/AM = A if(istype(AM, /obj/effect/decal/cleanable)) - qdel(AM) + for(var/obj/effect/decal/cleanable/C in A.loc) + qdel(C) anchored = FALSE target = null From 9bd56416f8e4c54038132c0cf3e0b163aa26fb7c Mon Sep 17 00:00:00 2001 From: oranges Date: Thu, 12 Oct 2017 11:09:48 +1300 Subject: [PATCH 24/44] Merge pull request #31500 from Armhulen/patch-7 sleeping carp grabs now put out a message --- code/datums/martial/sleeping_carp.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index 8fe8fcd366..ed46910148 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -112,6 +112,8 @@ D.stop_pulling() if(A.a_intent == INTENT_GRAB) add_logs(A, D, "grabbed", addition="aggressively") + D.visible_message("[A] violently grabs [D]!", \ + "[A] violently grabs you!") A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab else add_logs(A, D, "grabbed", addition="passively") From c269b062b9b7e6837d2b847f4a1eebc91ee1904e Mon Sep 17 00:00:00 2001 From: Armhulen Date: Wed, 11 Oct 2017 15:07:53 -0700 Subject: [PATCH 26/44] Mega Carp Re-Carpening: Carpatastrophe! --- code/_globalvars/lists/names.dm | 2 + .../mob/living/simple_animal/hostile/carp.dm | 106 +++++++++++++++++- strings/names/megacarp1.txt | 79 +++++++++++++ strings/names/megacarp2.txt | 54 +++++++++ 4 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 strings/names/megacarp1.txt create mode 100644 strings/names/megacarp2.txt diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index d855c7f141..c6cc5d7330 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -16,6 +16,8 @@ GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt")) GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt")) GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt")) GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt")) +GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt")) +GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt")) GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt")) diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index fde10031d1..c680191508 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/living/simple_animal/hostile/carp name = "space carp" desc = "A ferocious, fang-bearing creature that resembles a fish." @@ -78,4 +79,107 @@ speak_emote = list("squeaks") gold_core_spawnable = 0 faction = list("syndicate") - AIStatus = AI_OFF \ No newline at end of file + AIStatus = AI_OFF +======= +#define REGENERATION_DELAY 60 // After taking damage, how long it takes for automatic regeneration to begin for megacarps (ty robustin!) + +/mob/living/simple_animal/hostile/carp + name = "space carp" + desc = "A ferocious, fang-bearing creature that resembles a fish." + icon_state = "carp" + icon_living = "carp" + icon_dead = "carp_dead" + icon_gib = "carp_gib" + speak_chance = 0 + turns_per_move = 5 + butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "hits" + emote_taunt = list("gnashes") + taunt_chance = 30 + speed = 0 + maxHealth = 25 + health = 25 + + harm_intent_damage = 8 + obj_damage = 50 + melee_damage_lower = 15 + melee_damage_upper = 15 + attacktext = "bites" + attack_sound = 'sound/weapons/bite.ogg' + speak_emote = list("gnashes") + + //Space carp aren't affected by cold. + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 + maxbodytemp = 1500 + faction = list("carp") + movement_type = FLYING + pressure_resistance = 200 + gold_core_spawnable = 1 + +/mob/living/simple_animal/hostile/carp/Process_Spacemove(movement_dir = 0) + return 1 //No drifting in space for space carp! //original comments do not steal + +/mob/living/simple_animal/hostile/carp/AttackingTarget() + . = ..() + if(. && ishuman(target)) + var/mob/living/carbon/human/H = target + H.adjustStaminaLoss(8) + +/mob/living/simple_animal/hostile/carp/holocarp + icon_state = "holocarp" + icon_living = "holocarp" + maxbodytemp = INFINITY + gold_core_spawnable = 0 + del_on_death = 1 + +/mob/living/simple_animal/hostile/carp/megacarp + icon = 'icons/mob/broadMobs.dmi' + name = "Mega Space Carp" + desc = "A ferocious, fang bearing creature that resembles a shark. This one seems especially ticked off." + icon_state = "megacarp" + icon_living = "megacarp" + icon_dead = "megacarp_dead" + icon_gib = "megacarp_gib" + maxHealth = 20 + health = 20 + pixel_x = -16 + mob_size = MOB_SIZE_LARGE + + obj_damage = 80 + melee_damage_lower = 20 + melee_damage_upper = 20 + + var/regen_cooldown = 0 + +/mob/living/simple_animal/hostile/carp/megacarp/Initialize() + . = ..() + name = "[pick(GLOB.megacarp_first_names)] [pick(GLOB.megacarp_last_names)]" + melee_damage_lower += rand(2, 10) + melee_damage_upper += rand(10,20) + maxHealth += rand(30,60) + move_to_delay = rand(3,7) + +/mob/living/simple_animal/hostile/carp/megacarp/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(.) + regen_cooldown = world.time + REGENERATION_DELAY + +/mob/living/simple_animal/hostile/carp/megacarp/Life() + . = ..() + if(regen_cooldown < world.time) + heal_overall_damage(4) + +/mob/living/simple_animal/hostile/carp/cayenne + name = "Cayenne" + desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot." + gender = FEMALE + speak_emote = list("squeaks") + gold_core_spawnable = 0 + faction = list("syndicate") + AIStatus = AI_OFF + +#undef REGENERATION_DELAY +>>>>>>> 15241d9... Mega Carp Re-Carpening: Carpatastrophe! (#31365) diff --git a/strings/names/megacarp1.txt b/strings/names/megacarp1.txt new file mode 100644 index 0000000000..e214c4cc01 --- /dev/null +++ b/strings/names/megacarp1.txt @@ -0,0 +1,79 @@ +Legendary +Epic +Rare +Common +Elusive +Lackluster +Bloody +Strange +Unremarkable +Scarcely Lethal +Mildly Menacing +Truly Feared +Wicked +Nasty +Normal +Unique +Vintage +Genuine +Unusual +Haunted +Big +Small +The +Savage +Hungry +Sated +Despicable +Nice +Helpful +Rogue +Spotted +Deep Blue +Quick +Slow +Beloved +Agressive +Angry +Bewildered +Clumsy +Defeated +Grumpy +Itchy +Scratchy +Lazy +Mysterious +Repulsive +Thoughtless +Broad +Chubby +Crooked +Curved +Deep +Flat +High +Hollow +Low +Narrow +Round +Shallow +Robust +Skinny +Square Nose +Steep Nose +Renegade +Ancient +Old +Fast +Brief +Short +Frustratingly Elusive +Curvy +Fitted +Forked +Rugged +Sinuous +Slimy +Sweeping +Twisted +Crooked \ No newline at end of file diff --git a/strings/names/megacarp2.txt b/strings/names/megacarp2.txt new file mode 100644 index 0000000000..f00ec8bb2c --- /dev/null +++ b/strings/names/megacarp2.txt @@ -0,0 +1,54 @@ +Laser Shark +Hammerhead Shark +Wobbegong Shark +Smooth-Hound Shark +Thresher Shark +Sand Shark +Mackerel Shark +Sawshark +Angel Shark +Cat Shark +Space Shark +Cow Shark +Goblin Shark +Ghast Shark +Ghost Shark +Nightmare Shark +Sharkling +Sharknado +Megalodon +Minilodon +Dog Shark +Moby Dick +Flipper Shark +Space Kraken +Great White Shark +Asteroid Shark +Meteor Shark +Derelict Shark +Lava Shark +Whale Shark +Traitor Shark +Magishark +Chaos Shark +Incinerator Shark +Shredder Shark +Shawshark +Judicator Shark +Snapjaw Shark +Bloodhound Shark +Vermin Shark +Chomper Shark +Megalomaniac Shark +Frog Shark +Buffalo Shark +Lizard Shark +Pulse Shark +Baby Gargantuan Shark +Flying Shark +Spacetime Shark +Freon Shark +Plasma Shark +Guru Shark +Toxic Shark +Spider Shark From 24a85f97abed498ab31304f0fdcac9e9a5699e8e Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 11 Oct 2017 18:04:30 -0400 Subject: [PATCH 27/44] Make SStgui actually read the html from the disk at runtime (#31464) * Make SStgui actually read the html from the disk at runtime * Remove the comment * Back to " --- code/controllers/subsystem/tgui.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index 52fd286eed..a9b307bc0d 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(tgui) var/basehtml // The HTML base used for all UIs. /datum/controller/subsystem/tgui/PreInit() - basehtml = file2text('tgui/tgui.html') // Read the HTML from disk. + basehtml = file2text("tgui/tgui.html") /datum/controller/subsystem/tgui/Shutdown() close_all_uis() From 856b6ba853dad76f272ebe1880b1154ae385ce5a Mon Sep 17 00:00:00 2001 From: Dax Dupont Date: Wed, 11 Oct 2017 22:20:44 +0200 Subject: [PATCH 29/44] Allows sillicons to use vending machines. (#31541) * Allows borgs to use vending machines. * Allows AI to use vending machines. --- code/game/machinery/vending.dm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index bf08e98992..c8775a8121 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -411,16 +411,6 @@ if(..()) return - if(issilicon(usr)) - if(iscyborg(usr)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module, /obj/item/robot_module/butler) )) - to_chat(usr, "The vending machine refuses to interface with you, as you are not in its target demographic!") - return - else - to_chat(usr, "The vending machine refuses to interface with you, as you are not in its target demographic!") - return - if(href_list["remove_coin"]) if(!(coin || bill)) to_chat(usr, "There is no money in this machine.") From acdc5c138043cf7a4bac3f5879231af228ca55d1 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 11 Oct 2017 16:17:36 -0400 Subject: [PATCH 31/44] Server maint logs when nulls enter the clients list (#31544) --- code/controllers/subsystem/server_maint.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 0b8fa750b6..43585a5896 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -16,6 +16,8 @@ SUBSYSTEM_DEF(server_maint) /datum/controller/subsystem/server_maint/fire(resumed = FALSE) if(!resumed) + if(listclearnulls(GLOB.clients)) + log_world("Found a null in clients list!") src.currentrun = GLOB.clients.Copy() var/list/currentrun = src.currentrun From c0e9cde5c2cf068202363d97ca3ace71f41af313 Mon Sep 17 00:00:00 2001 From: duncathan salt Date: Wed, 11 Oct 2017 13:04:12 -0600 Subject: [PATCH 33/44] Minor refactor of how gas IDs are handled --- _maps/RandomRuins/SpaceRuins/deepstorage.dmm | 4 +- _maps/RandomZLevels/undergroundoutpost45.dmm | 4 +- _maps/map_files/BoxStation/BoxStation.dmm | 14 ++-- .../map_files/Deltastation/DeltaStation2.dmm | 16 ++-- _maps/map_files/MetaStation/MetaStation.dmm | 14 ++-- _maps/map_files/OmegaStation/OmegaStation.dmm | 10 +-- _maps/map_files/PubbyStation/PubbyStation.dmm | 8 +- code/__DEFINES/atmospherics.dm | 1 + code/datums/helper_datums/teleport.dm | 6 +- code/game/gamemodes/objective_items.dm | 2 +- .../game/mecha/equipment/tools/other_tools.dm | 6 +- code/game/mecha/mecha.dm | 6 +- .../effects/effect_system/effects_foam.dm | 5 +- .../effects/effect_system/effects_smoke.dm | 8 +- code/game/objects/items/chrono_eraser.dm | 6 +- code/game/objects/items/devices/scanners.dm | 8 +- code/game/objects/items/flamethrower.dm | 4 +- code/game/objects/items/tanks/jetpack.dm | 4 +- code/game/objects/items/tanks/tank_types.dm | 34 ++++---- .../transit_tubes/transit_tube_pod.dm | 6 +- code/modules/admin/verbs/debug.dm | 4 +- code/modules/assembly/bomb.dm | 6 +- .../atmospherics/environmental/LINDA_fire.dm | 6 +- .../atmospherics/gasmixtures/gas_mixture.dm | 7 +- .../atmospherics/gasmixtures/gas_types.dm | 17 ++-- .../gasmixtures/immutable_mixtures.dm | 4 +- .../atmospherics/gasmixtures/reactions.dm | 82 +++++++++---------- .../atmospherics/machinery/airalarm.dm | 62 +++++++------- .../components/trinary_devices/filter.dm | 18 ++-- .../components/unary_devices/cryo.dm | 6 +- .../unary_devices/oxygen_generator.dm | 4 +- .../components/unary_devices/tank.dm | 16 ++-- .../components/unary_devices/vent_scrubber.dm | 39 ++++++++- .../atmospherics/machinery/other/miner.dm | 20 ++--- .../machinery/portable/canister.dm | 28 +++---- .../atmospherics/machinery/portable/pump.dm | 6 +- .../machinery/portable/scrubber.dm | 2 +- code/modules/events/spacevine.dm | 16 ++-- code/modules/hydroponics/grown/towercap.dm | 4 +- code/modules/mob/living/carbon/alien/life.dm | 59 ++++++++++++- .../carbon/human/species_types/plasmamen.dm | 2 +- code/modules/mob/living/carbon/life.dm | 27 +++--- code/modules/mob/living/life.dm | 4 +- .../mob/living/simple_animal/hostile/tree.dm | 6 +- .../mob/living/simple_animal/simple_animal.dm | 8 +- .../mob/living/simple_animal/slime/life.dm | 4 +- code/modules/power/singularity/collector.dm | 8 +- code/modules/power/supermatter/supermatter.dm | 20 ++--- code/modules/surgery/organs/lungs.dm | 52 ++++++------ tgui/assets/tgui.css | 2 +- tgui/assets/tgui.js | 32 ++++---- tgui/src/interfaces/atmos_filter.ract | 32 ++++---- 52 files changed, 438 insertions(+), 331 deletions(-) diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm index cfc78c0dbf..7613265273 100644 --- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm +++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm @@ -3305,7 +3305,7 @@ "ga" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; on = 1 }, /turf/open/floor/plasteel/floorgrime{ @@ -3719,7 +3719,7 @@ "gO" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "n2o"; + filter_type = /datum/gas/nitrous_oxide; on = 1 }, /turf/open/floor/plasteel/floorgrime{ diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm index 0f8c2e70bb..8911016cac 100644 --- a/_maps/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/undergroundoutpost45.dmm @@ -14187,7 +14187,7 @@ "um" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 4; - filter_type = "n2"; + filter_type = /datum/gas/nitrogen; on = 1 }, /turf/open/floor/plasteel/red/side{ @@ -14236,7 +14236,7 @@ "up" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 4; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; on = 1 }, /turf/open/floor/plasteel/blue/side{ diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 1db3e9697d..eb67456127 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -43123,7 +43123,7 @@ "bWb" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "n2o"; + filter_type = /datum/gas/nitrous_oxide; on = 1 }, /turf/open/floor/plasteel, @@ -44684,7 +44684,7 @@ "bZJ" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "plasma"; + filter_type = /datum/gas/plasma; on = 1 }, /turf/open/floor/plasteel, @@ -46475,7 +46475,7 @@ "cdB" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "co2"; + filter_type = /datum/gas/carbon_dioxide; on = 1 }, /turf/open/floor/plasteel, @@ -47103,7 +47103,7 @@ "cfi" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 2; - filter_type = "n2"; + filter_type = /datum/gas/nitrogen; on = 1 }, /turf/open/floor/plasteel, @@ -47355,7 +47355,7 @@ "cfR" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 4; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; on = 1 }, /turf/open/floor/plasteel, @@ -57434,7 +57434,7 @@ "cGf" = ( /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ dir = 8; - filter_type = "n2" + filter_type = /datum/gas/nitrogen }, /turf/open/floor/engine, /area/engine/engineering) @@ -58550,7 +58550,7 @@ "cSJ" = ( /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ dir = 8; - filter_type = "freon"; + filter_type = /datum/gas/freon; name = "gas filter (freon)" }, /turf/open/floor/engine, diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 95256fae4c..fee2e6cef5 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -6987,7 +6987,7 @@ }, /obj/machinery/atmospherics/components/trinary/filter/critical{ dir = 4; - filter_type = "n2" + filter_type = /datum/gas/nitrogen }, /turf/open/floor/plasteel/neutral, /area/engine/atmospherics_engine) @@ -10811,7 +10811,7 @@ /area/shuttle/supply) "aza" = ( /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - filter_type = "n2"; + filter_type = /datum/gas/nitrogen; name = "nitrogen filter" }, /turf/open/floor/plasteel/yellow, @@ -23007,7 +23007,7 @@ /obj/structure/window/reinforced, /obj/machinery/atmospherics/components/trinary/filter{ dir = 2; - filter_type = "co2"; + filter_type = /datum/gas/carbon_dioxide; name = "co2 filter"; on = 1 }, @@ -24580,7 +24580,7 @@ /obj/structure/window/reinforced, /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; name = "oxygen filter"; on = 1 }, @@ -25841,7 +25841,7 @@ /obj/structure/window/reinforced, /obj/machinery/atmospherics/components/trinary/filter{ dir = 2; - filter_type = "plasma"; + filter_type = /datum/gas/plasma; name = "waste filter"; on = 1 }, @@ -27484,7 +27484,7 @@ /obj/structure/window/reinforced, /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "n2"; + filter_type = /datum/gas/nitrogen; name = "nitrogen filter"; on = 1 }, @@ -29207,7 +29207,7 @@ /obj/structure/window/reinforced, /obj/machinery/atmospherics/components/trinary/filter{ dir = 2; - filter_type = "n2o"; + filter_type = /datum/gas/nitrous_oxide; name = "n2o filter"; on = 1 }, @@ -105710,7 +105710,7 @@ }, /obj/machinery/atmospherics/components/trinary/filter/critical{ dir = 4; - filter_type = "freon"; + filter_type = /datum/gas/freon; name = "gas filter (freon)" }, /turf/open/floor/plasteel/neutral, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 26bc13dde1..753b620498 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -46859,7 +46859,7 @@ "bMk" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "n2o"; + filter_type = /datum/gas/nitrous_oxide; on = 1 }, /obj/structure/window/reinforced{ @@ -49916,7 +49916,7 @@ "bSj" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "plasma"; + filter_type = /datum/gas/plasma; on = 1 }, /obj/structure/window/reinforced{ @@ -52635,7 +52635,7 @@ "bXq" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "co2"; + filter_type = /datum/gas/carbon_dioxide; on = 1 }, /obj/structure/window/reinforced{ @@ -54519,7 +54519,7 @@ "cbd" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 4; - filter_type = "n2"; + filter_type = /datum/gas/nitrogen; on = 1 }, /obj/structure/window/reinforced, @@ -54574,7 +54574,7 @@ /obj/structure/window/reinforced, /obj/machinery/atmospherics/components/trinary/filter{ dir = 4; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; on = 1 }, /turf/open/floor/plasteel/blue, @@ -82679,7 +82679,7 @@ dir = 4 }, /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - filter_type = "freon"; + filter_type = /datum/gas/freon; name = "gas filter (freon)" }, /turf/open/floor/engine, @@ -82879,7 +82879,7 @@ dir = 4 }, /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ - filter_type = "n2" + filter_type = /datum/gas/nitrogen }, /turf/open/floor/engine, /area/engine/engineering) diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 620f34dfb3..3e9d0e5f64 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -11009,7 +11009,7 @@ "asz" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 2; - filter_type = "n2"; + filter_type = /datum/gas/nitrogen; name = "nitrogen filter"; on = 1 }, @@ -13296,7 +13296,7 @@ "awD" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 2; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; name = "oxygen filter"; on = 1 }, @@ -14109,7 +14109,7 @@ "ayf" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "plasma"; + filter_type = /datum/gas/plasma; name = "waste filter"; on = 1 }, @@ -21607,7 +21607,7 @@ }, /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ dir = 1; - filter_type = "n2" + filter_type = /datum/gas/nitrogen }, /turf/open/floor/plasteel, /area/engine/engineering) @@ -23873,7 +23873,7 @@ }, /obj/machinery/atmospherics/components/trinary/filter/flipped/critical{ dir = 1; - filter_type = "freon"; + filter_type = /datum/gas/freon; name = "gas filter (freon)" }, /turf/open/floor/plasteel, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 154df34231..e8fe9762fa 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -41924,7 +41924,7 @@ "bQN" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "n2o"; + filter_type = /datum/gas/nitrous_oxide; on = 1 }, /turf/open/floor/plasteel, @@ -43351,7 +43351,7 @@ "bTU" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "plasma"; + filter_type = /datum/gas/plasma; on = 1 }, /turf/open/floor/plasteel, @@ -44738,7 +44738,7 @@ "bWK" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 4; - filter_type = "o2"; + filter_type = /datum/gas/oxygen; on = 1 }, /turf/open/floor/plasteel, @@ -44777,7 +44777,7 @@ "bWQ" = ( /obj/machinery/atmospherics/components/trinary/filter{ dir = 1; - filter_type = "co2"; + filter_type = /datum/gas/carbon_dioxide; on = 1 }, /turf/open/floor/plasteel, diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 98448336e1..d3d1445c7d 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -17,6 +17,7 @@ #define META_GAS_MOLES_VISIBLE 3 #define META_GAS_OVERLAY 4 #define META_GAS_DANGER 5 +#define META_GAS_ID 6 //stuff you should probably leave well alone! //ATMOS diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 0eb76388ae..b5436f0313 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -191,11 +191,11 @@ // Can most things breathe? if(trace_gases) continue - if(!(A_gases["o2"] && A_gases["o2"][MOLES] >= 16)) + if(!(A_gases[/datum/gas/oxygen] && A_gases[/datum/gas/oxygen][MOLES] >= 16)) continue - if(A_gases["plasma"]) + if(A_gases[/datum/gas/plasma]) continue - if(A_gases["co2"] && A_gases["co2"][MOLES] >= 10) + if(A_gases[/datum/gas/carbon_dioxide] && A_gases[/datum/gas/carbon_dioxide][MOLES] >= 10) continue // Aim for goldilocks temperatures and pressure diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm index c0aee8bb76..2dc8692294 100644 --- a/code/game/gamemodes/objective_items.dm +++ b/code/game/gamemodes/objective_items.dm @@ -121,7 +121,7 @@ /datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T) var/target_amount = text2num(name) var/found_amount = 0 - found_amount += T.air_contents.gases["plasma"] ? T.air_contents.gases["plasma"][MOLES] : 0 + found_amount += T.air_contents.gases[/datum/gas/plasma] ? T.air_contents.gases[/datum/gas/plasma][MOLES] : 0 return found_amount>=target_amount diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 3eaddc14d2..1256ab8315 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -426,14 +426,14 @@ if(!istype(T)) return var/datum/gas_mixture/GM = new - ASSERT_GAS("plasma", GM) + ADD_GAS(/datum/gas/plasma, GM.gases) if(prob(10)) - GM.gases["plasma"][MOLES] += 100 + GM.gases[/datum/gas/plasma][MOLES] += 100 GM.temperature = 1500+T0C //should be enough to start a fire T.visible_message("The [src] suddenly disgorges a cloud of heated plasma.") qdel(src) else - GM.gases["plasma"][MOLES] += 5 + GM.gases[/datum/gas/plasma][MOLES] += 5 GM.temperature = istype(T) ? T.air.return_temperature() : T20C T.visible_message("The [src] suddenly disgorges a cloud of plasma.") T.assume_air(GM) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 4a80d13215..811c4cfc3f 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -237,9 +237,9 @@ cabin_air = new cabin_air.temperature = T20C cabin_air.volume = 200 - cabin_air.assert_gases("o2","n2") - cabin_air.gases["o2"][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) - cabin_air.gases["n2"][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + cabin_air.gases[/datum/gas/oxygen][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) + cabin_air.gases[/datum/gas/nitrogen][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) return cabin_air /obj/mecha/proc/add_radio() diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 526aaedcf2..d42b11f776 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -279,8 +279,9 @@ qdel(H) var/list/G_gases = G.gases for(var/I in G_gases) - if(I != "o2" && I != "n2") - G.gases[I][MOLES] = 0 + if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen) + continue + G_gases[I][MOLES] = 0 G.garbage_collect() O.air_update_turf() for(var/obj/machinery/atmospherics/components/unary/U in O) diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 656c151b3f..1f3a5a7b02 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -168,10 +168,10 @@ for(var/obj/effect/hotspot/H in T) qdel(H) var/list/G_gases = G.gases - if(G_gases["plasma"]) - ASSERT_GAS("n2", G) - G_gases["n2"][MOLES] += (G_gases["plasma"][MOLES]) - G_gases["plasma"][MOLES] = 0 + if(G_gases[/datum/gas/plasma]) + ASSERT_GAS(/datum/gas/nitrogen, G) + G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES]) + G_gases[/datum/gas/plasma][MOLES] = 0 G.garbage_collect() for(var/obj/machinery/atmospherics/components/unary/U in T) if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber. diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index dcf9100799..6f1ab39013 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -240,9 +240,9 @@ /obj/effect/chrono_field/return_air() //we always have nominal air and temperature var/datum/gas_mixture/GM = new - GM.assert_gases("o2","n2") - GM.gases["o2"][MOLES] = MOLES_O2STANDARD - GM.gases["n2"][MOLES] = MOLES_N2STANDARD + GM.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + GM.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD + GM.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD GM.temperature = T20C return GM diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index e55c728121..bb2adda377 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -358,10 +358,10 @@ MASS SPECTROMETER var/list/env_gases = environment.gases environment.assert_gases(arglist(GLOB.hardcoded_gases)) - var/o2_concentration = env_gases["o2"][MOLES]/total_moles - var/n2_concentration = env_gases["n2"][MOLES]/total_moles - var/co2_concentration = env_gases["co2"][MOLES]/total_moles - var/plasma_concentration = env_gases["plasma"][MOLES]/total_moles + var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles + 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) diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index 720aacf619..4502d2bb48 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -201,8 +201,8 @@ //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... //Transfer 5% of current tank air contents to turf var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) - if(air_transfer.gases["plasma"]) - air_transfer.gases["plasma"][MOLES] *= 5 + if(air_transfer.gases[/datum/gas/plasma]) + air_transfer.gases[/datum/gas/plasma][MOLES] *= 5 target.assume_air(air_transfer) //Burn it based on transfered gas target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 63e9e0bb55..6946fa4a6d 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -8,7 +8,7 @@ w_class = WEIGHT_CLASS_BULKY distribute_pressure = ONE_ATMOSPHERE * O2STANDARD actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization) - var/gas_type = "o2" + var/gas_type = /datum/gas/oxygen var/on = FALSE var/stabilizers = FALSE var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not @@ -128,7 +128,7 @@ icon_state = "jetpack-black" item_state = "jetpack-black" distribute_pressure = 0 - gas_type = "co2" + gas_type = /datum/gas/carbon_dioxide /obj/item/tank/jetpack/suit diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index 146693dd05..c6b6b1edf4 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -21,8 +21,8 @@ /obj/item/tank/internals/oxygen/New() ..() - ASSERT_GAS("o2", air_contents) - air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -49,9 +49,9 @@ /obj/item/tank/internals/anesthetic/New() ..() - air_contents.assert_gases("o2", "n2o") - air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases["n2o"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) + air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD return /* @@ -67,9 +67,9 @@ /obj/item/tank/internals/air/New() ..() - air_contents.assert_gases("o2","n2") - air_contents.gases["o2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases["n2"][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases[/datum/gas/nitrogen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD return @@ -87,8 +87,8 @@ /obj/item/tank/internals/plasma/New() ..() - ASSERT_GAS("plasma", air_contents) - air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + ASSERT_GAS(/datum/gas/plasma, air_contents) + air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params) @@ -106,7 +106,7 @@ /obj/item/tank/internals/plasma/full/New() ..() // Plasma asserted in parent - air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -124,13 +124,13 @@ /obj/item/tank/internals/plasmaman/New() ..() - ASSERT_GAS("plasma", air_contents) - air_contents.gases["plasma"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + ASSERT_GAS(/datum/gas/plasma, air_contents) + air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/plasmaman/full/New() ..() // Plasma asserted in parent - air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -144,7 +144,7 @@ /obj/item/tank/internals/plasmaman/belt/full/New() ..() // Plasma asserted in parent - air_contents.gases["plasma"][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -166,8 +166,8 @@ /obj/item/tank/internals/emergency_oxygen/New() ..() - ASSERT_GAS("o2", air_contents) - air_contents.gases["o2"][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return /obj/item/tank/internals/emergency_oxygen/engi 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 16d1072779..0c89d3e8e9 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -11,9 +11,9 @@ /obj/structure/transit_tube_pod/Initialize() . = ..() - air_contents.add_gases("o2", "n2") - air_contents.gases["o2"][MOLES] = MOLES_O2STANDARD - air_contents.gases["n2"][MOLES] = MOLES_N2STANDARD + air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + air_contents.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD + air_contents.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD air_contents.temperature = T20C diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 7fc6bc2e9f..735d0d9f95 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -715,8 +715,8 @@ GLOBAL_PROTECT(LastAdminCalledProc) if(Rad.anchored) if(!Rad.loaded_tank) var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad) - ASSERT_GAS("plasma", Plasma.air_contents) - Plasma.air_contents.gases["plasma"][MOLES] = 70 + ASSERT_GAS(/datum/gas/plasma, Plasma.air_contents) + Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma Plasma.loc = Rad diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index ebd2214aba..993ee43401 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -107,8 +107,8 @@ return /obj/item/tank/proc/ignite() //This happens when a bomb is told to explode - air_contents.assert_gases("plasma", "o2") - var/fuel_moles = air_contents.gases["plasma"][MOLES] + air_contents.gases["o2"][MOLES]/6 + air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) + var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6 air_contents.garbage_collect() var/strength = 1 @@ -164,4 +164,4 @@ if(!T) return T.assume_air(removed) - air_update_turf() \ No newline at end of file + air_update_turf() diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index 93862f16b4..94b1b8ee45 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -12,8 +12,8 @@ if(!air_contents) return 0 - var/oxy = air_contents.gases["o2"] ? air_contents.gases["o2"][MOLES] : 0 - var/tox = air_contents.gases["plasma"] ? air_contents.gases["plasma"][MOLES] : 0 + var/oxy = air_contents.gases[/datum/gas/oxygen] ? air_contents.gases[/datum/gas/oxygen][MOLES] : 0 + var/tox = air_contents.gases[/datum/gas/plasma] ? air_contents.gases[/datum/gas/plasma][MOLES] : 0 if(active_hotspot) if(soh) @@ -112,7 +112,7 @@ qdel(src) return - if(!(location.air) || !location.air.gases["plasma"] || !location.air.gases["o2"] || location.air.gases["plasma"][MOLES] < 0.5 || location.air.gases["o2"][MOLES] < 0.5) + if(!(location.air) || !location.air.gases[/datum/gas/plasma] || !location.air.gases[/datum/gas/oxygen] || location.air.gases[/datum/gas/plasma][MOLES] < 0.5 || location.air.gases[/datum/gas/oxygen][MOLES] < 0.5) qdel(src) return diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index b9cba55ae6..605d9b455a 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -268,8 +268,11 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) gas -= "TEMP" gases.Cut() for(var/id in gas) - ADD_GAS(id, gases) - gases[id][MOLES] = text2num(gas[id]) + var/path = id + if(!ispath(path)) + path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around + ADD_GAS(path, gases) + gases[path][MOLES] = text2num(gas[id]) return 1 /datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4) diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm index 2135b9fbd0..db68a0a476 100644 --- a/code/modules/atmospherics/gasmixtures/gas_types.dm +++ b/code/modules/atmospherics/gasmixtures/gas_types.dm @@ -1,9 +1,9 @@ -GLOBAL_LIST_INIT(hardcoded_gases, list("o2","n2","co2","plasma")) //the main four gases, which were at one time hardcoded +GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded /proc/meta_gas_list() - . = new /list - for(var/gas_path in subtypesof(/datum/gas)) - var/list/gas_info = new(5) + . = subtypesof(/datum/gas) + for(var/gas_path in .) + var/list/gas_info = new(6) var/datum/gas/gas = gas_path gas_info[META_GAS_SPECIFIC_HEAT] = initial(gas.specific_heat) @@ -12,7 +12,14 @@ GLOBAL_LIST_INIT(hardcoded_gases, list("o2","n2","co2","plasma")) //the main fou if(initial(gas.moles_visible) != null) gas_info[META_GAS_OVERLAY] = new /obj/effect/overlay/gas(initial(gas.gas_overlay)) gas_info[META_GAS_DANGER] = initial(gas.dangerous) - .[initial(gas.id)] = gas_info + gas_info[META_GAS_ID] = initial(gas.id) + .[gas_path] = gas_info + +/proc/gas_id2path(id) + var/meta_gas = meta_gas_list() + for(var/path in meta_gas) + if(meta_gas[path][META_GAS_ID] == id) + return path /*||||||||||||||/----------\||||||||||||||*\ ||||||||||||||||[GAS DATUMS]|||||||||||||||| diff --git a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm index 50e1b38e52..55334cc087 100644 --- a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm +++ b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm @@ -69,8 +69,8 @@ /datum/gas_mixture/immutable/cloner/garbage_collect() ..() - ADD_GAS("n2", gases) - gases["n2"][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD + ADD_GAS(/datum/gas/nitrogen, gases) + gases[/datum/gas/nitrogen][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD /datum/gas_mixture/immutable/cloner/heat_capacity() return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20 diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index c466213409..bd38375289 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -44,21 +44,21 @@ /datum/gas_reaction/agent_b/init_reqs() min_requirements = list( "TEMP" = 900, - "agent_b" = MINIMUM_HEAT_CAPACITY, - "plasma" = MINIMUM_HEAT_CAPACITY, - "co2" = MINIMUM_HEAT_CAPACITY + /datum/gas/oxygen_agent_b = MINIMUM_HEAT_CAPACITY, + /datum/gas/plasma = MINIMUM_HEAT_CAPACITY, + /datum/gas/carbon_dioxide = MINIMUM_HEAT_CAPACITY ) /datum/gas_reaction/agent_b/react(datum/gas_mixture/air) var/list/cached_gases = air.gases - var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05) + var/reaction_rate = min(cached_gases[/datum/gas/carbon_dioxide][MOLES]*0.75, cached_gases[/datum/gas/plasma][MOLES]*0.25, cached_gases[/datum/gas/oxygen_agent_b][MOLES]*0.05) - cached_gases["co2"][MOLES] -= reaction_rate - cached_gases["agent_b"][MOLES] -= reaction_rate*0.05 + cached_gases[/datum/gas/carbon_dioxide][MOLES] -= reaction_rate + cached_gases[/datum/gas/oxygen_agent_b][MOLES] -= reaction_rate*0.05 - ASSERT_GAS("o2", air) //only need to assert oxygen, as this reaction doesn't occur without the other gases existing - cached_gases["o2"][MOLES] += reaction_rate + ASSERT_GAS(/datum/gas/oxygen, air) //only need to assert oxygen, as this reaction doesn't occur without the other gases existing + cached_gases[/datum/gas/oxygen][MOLES] += reaction_rate air.temperature -= (reaction_rate*20000)/air.heat_capacity() @@ -71,7 +71,7 @@ id = "freon" /datum/gas_reaction/freon/init_reqs() - min_requirements = list("freon" = MOLES_PLASMA_VISIBLE) + min_requirements = list(/datum/gas/freon = MOLES_PLASMA_VISIBLE) /datum/gas_reaction/freon/react(datum/gas_mixture/air, turf/open/location) . = NO_REACTION @@ -85,12 +85,12 @@ id = "vapor" /datum/gas_reaction/water_vapor/init_reqs() - min_requirements = list("water_vapor" = MOLES_PLASMA_VISIBLE) + min_requirements = list(/datum/gas/water_vapor = MOLES_PLASMA_VISIBLE) /datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, turf/open/location) . = NO_REACTION if(location && location.water_vapor_gas_act()) - air.gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE + air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_PLASMA_VISIBLE . = REACTING //fire: combustion of plasma and volatile fuel (treated as hydrocarbons). creates hotspots. exothermic @@ -111,28 +111,28 @@ cached_results[id] = 0 //General volatile gas burn - if(cached_gases["v_fuel"] && cached_gases["v_fuel"][MOLES]) + if(cached_gases[/datum/gas/volatile_fuel] && cached_gases[/datum/gas/volatile_fuel][MOLES]) var/burned_fuel - if(!cached_gases["o2"]) + if(!cached_gases[/datum/gas/oxygen]) burned_fuel = 0 - else if(cached_gases["o2"][MOLES] < cached_gases["v_fuel"][MOLES]) - burned_fuel = cached_gases["o2"][MOLES] - cached_gases["v_fuel"][MOLES] -= burned_fuel - cached_gases["o2"][MOLES] = 0 + else if(cached_gases[/datum/gas/oxygen][MOLES] < cached_gases[/datum/gas/volatile_fuel][MOLES]) + burned_fuel = cached_gases[/datum/gas/oxygen][MOLES] + cached_gases[/datum/gas/volatile_fuel][MOLES] -= burned_fuel + cached_gases[/datum/gas/oxygen][MOLES] = 0 else - burned_fuel = cached_gases["v_fuel"][MOLES] - cached_gases["o2"][MOLES] -= cached_gases["v_fuel"][MOLES] + burned_fuel = cached_gases[/datum/gas/volatile_fuel][MOLES] + cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/volatile_fuel][MOLES] if(burned_fuel) energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel - ASSERT_GAS("co2", air) - cached_gases["co2"][MOLES] += burned_fuel + ASSERT_GAS(/datum/gas/carbon_dioxide, air) + cached_gases[/datum/gas/carbon_dioxide][MOLES] += burned_fuel cached_results[id] += burned_fuel //Handle plasma burning - if(cached_gases["plasma"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY) + if(cached_gases[/datum/gas/plasma] && cached_gases[/datum/gas/plasma][MOLES] > MINIMUM_HEAT_CAPACITY) var/plasma_burn_rate = 0 var/oxygen_burn_rate = 0 //more plasma released at higher temperatures @@ -142,17 +142,17 @@ else temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) if(temperature_scale > 0) - ASSERT_GAS("o2", air) + ASSERT_GAS(/datum/gas/oxygen, air) oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale - if(cached_gases["o2"][MOLES] > cached_gases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN) - plasma_burn_rate = (cached_gases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA + if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN) + plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA else - plasma_burn_rate = (temperature_scale*(cached_gases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA + plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) - ASSERT_GAS("co2", air) - cached_gases["plasma"][MOLES] = QUANTIZE(cached_gases["plasma"][MOLES] - plasma_burn_rate) - cached_gases["o2"][MOLES] = QUANTIZE(cached_gases["o2"][MOLES] - (plasma_burn_rate * oxygen_burn_rate)) - cached_gases["co2"][MOLES] += plasma_burn_rate + ASSERT_GAS(/datum/gas/carbon_dioxide, air) + cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate) + cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate)) + cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) @@ -185,36 +185,36 @@ /datum/gas_reaction/fusion/init_reqs() min_requirements = list( "ENER" = PLASMA_BINDING_ENERGY * 10, - "plasma" = MINIMUM_HEAT_CAPACITY, - "co2" = MINIMUM_HEAT_CAPACITY + /datum/gas/plasma = MINIMUM_HEAT_CAPACITY, + /datum/gas/carbon_dioxide = MINIMUM_HEAT_CAPACITY ) /datum/gas_reaction/fusion/react(datum/gas_mixture/air) var/list/cached_gases = air.gases var/temperature = air.temperature - if((cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])/air.total_moles() < FUSION_PURITY_THRESHOLD) + if((cached_gases[/datum/gas/plasma][MOLES]+cached_gases[/datum/gas/carbon_dioxide][MOLES])/air.total_moles() < FUSION_PURITY_THRESHOLD) //Fusion wont occur if the level of impurities is too high. return NO_REACTION var/old_heat_capacity = air.heat_capacity() - var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY) + var/carbon_efficency = min(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/carbon_dioxide][MOLES],MAX_CARBON_EFFICENCY) var/reaction_energy = THERMAL_ENERGY(air) - var/moles_impurities = air.total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES]) + var/moles_impurities = air.total_moles()-(cached_gases[/datum/gas/plasma][MOLES]+cached_gases[/datum/gas/carbon_dioxide][MOLES]) var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY) var/oxygen_added = carbon_catalyzed var/nitrogen_added = (plasma_fused-oxygen_added)-(THERMAL_ENERGY(air)/PLASMA_BINDING_ENERGY) - reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0) + reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases[/datum/gas/plasma][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0) - air.assert_gases("o2", "n2") + air.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - cached_gases["plasma"][MOLES] -= plasma_fused - cached_gases["co2"][MOLES] -= carbon_catalyzed - cached_gases["o2"][MOLES] += oxygen_added - cached_gases["n2"][MOLES] += nitrogen_added + cached_gases[/datum/gas/plasma][MOLES] -= plasma_fused + cached_gases[/datum/gas/carbon_dioxide][MOLES] -= carbon_catalyzed + cached_gases[/datum/gas/oxygen][MOLES] += oxygen_added + cached_gases[/datum/gas/nitrogen][MOLES] += nitrogen_added if(reaction_energy > 0) var/new_heat_capacity = air.heat_capacity() diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 6de564da6d..c758568c1e 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -73,44 +73,44 @@ var/datum/radio_frequency/radio_connection var/list/TLV = list( // Breathable air. - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa - "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K - "o2" = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - "n2" = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa - "co2" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa - "plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa - "n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa - "bz" = new/datum/tlv(-1, -1, 0.2, 0.5), - "freon" = new/datum/tlv(-1, -1, 0.2, 0.5), - "water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5) + "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa + "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K + /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa + /datum/gas/plasma = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa + /datum/gas/nitrous_oxide = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa + /datum/gas/bz = new/datum/tlv(-1, -1, 0.2, 0.5), + /datum/gas/freon = new/datum/tlv(-1, -1, 0.2, 0.5), + /datum/gas/water_vapor = new/datum/tlv(-1, -1, 0.2, 0.5) ) /obj/machinery/airalarm/server // No checks here. TLV = list( - "pressure" = new/datum/tlv(-1, -1, -1, -1), - "temperature" = new/datum/tlv(-1, -1, -1, -1), - "o2" = new/datum/tlv(-1, -1, -1, -1), - "n2" = new/datum/tlv(-1, -1, -1, -1), - "co2" = new/datum/tlv(-1, -1, -1, -1), - "plasma" = new/datum/tlv(-1, -1, -1, -1), - "n2o" = new/datum/tlv(-1, -1, -1, -1), - "bz" = new/datum/tlv(-1, -1, -1, -1), - "freon" = new/datum/tlv(-1, -1, -1, -1), - "water_vapor" = new/datum/tlv(-1, -1, -1, -1) + "pressure" = new/datum/tlv(-1, -1, -1, -1), + "temperature" = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/oxygen = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/nitrogen = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/plasma = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/nitrous_oxide = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/bz = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/freon = new/datum/tlv(-1, -1, -1, -1), + /datum/gas/water_vapor = new/datum/tlv(-1, -1, -1, -1) ) /obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures. TLV = list( - "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa - "temperature" = new/datum/tlv(200,210,273.15,283.15), // K - "o2" = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa - "n2" = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa - "co2" = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa - "plasma" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa - "n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa - "bz" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa - "freon" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa - "water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5) + "pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa + "temperature" = new/datum/tlv(200,210,273.15,283.15), // K + /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa + /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000), // Partial pressure, kpa + /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10), // Partial pressure, kpa + /datum/gas/plasma = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa + /datum/gas/nitrous_oxide = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa + /datum/gas/bz = new/datum/tlv(-1, -1, 0.2, 0.5), + /datum/gas/freon = new/datum/tlv(-1, -1, 0.2, 0.5), + /datum/gas/water_vapor = new/datum/tlv(-1, -1, 0.2, 0.5) ) /obj/machinery/airalarm/engine @@ -760,4 +760,4 @@ #undef AALARM_MODE_SIPHON #undef AALARM_MODE_CONTAMINATED #undef AALARM_MODE_REFILL -#undef AALARM_REPORT_TIMEOUT \ No newline at end of file +#undef AALARM_REPORT_TIMEOUT diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4e3ef0f3cc..66ce534ee7 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -6,7 +6,7 @@ can_unwrench = TRUE var/on = FALSE var/target_pressure = ONE_ATMOSPHERE - var/filter_type = "" + var/filter_type = null var/frequency = 0 var/datum/radio_frequency/radio_connection @@ -28,6 +28,11 @@ if(frequency) radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_ATMOSIA) +/obj/machinery/atmospherics/components/trinary/filter/New() + ..() + if(istext(filter_type)) + filter_type = gas_id2path(filter_type) //support for mappers so they don't need to type out paths + /obj/machinery/atmospherics/components/trinary/filter/Destroy() SSradio.remove_object(src,frequency) return ..() @@ -86,9 +91,8 @@ if(!removed) return - var/filtering = filter_type ? TRUE : FALSE - - if(filtering && !istext(filter_type)) + var/filtering = TRUE + if(!ispath(filter_type)) WARNING("Wrong gas ID in [src]'s filter_type var. filter_type == [filter_type]") filtering = FALSE @@ -124,7 +128,7 @@ data["on"] = on data["pressure"] = round(target_pressure) data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) - data["filter_type"] = filter_type + data["filter_type"] = "[filter_type]" return data /obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params) @@ -151,9 +155,9 @@ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) if("filter") - filter_type = "" + filter_type = null var/filter_name = "nothing" - var/gas = params["mode"] + var/gas = text2path(params["mode"]) if(gas in GLOB.meta_gas_info) filter_type = gas filter_name = GLOB.meta_gas_info[gas][META_GAS_NAME] diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index ee7228fdca..69b15ef1f4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -187,7 +187,7 @@ if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic. beaker.reagents.reaction(occupant, VAPOR) - air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this. + air1.gases[/datum/gas/oxygen][MOLES] -= 2 / efficiency //Let's use gas for this if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). reagent_transfer = 0 @@ -201,7 +201,7 @@ var/datum/gas_mixture/air1 = AIR1 - if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases["o2"][MOLES] < 5) // Turn off if the machine won't work. + if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work. on = FALSE update_icon() return @@ -221,7 +221,7 @@ air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB) mob_occupant.bodytemperature = max(mob_occupant.bodytemperature + heat / heat_capacity, TCMB) - air1.gases["o2"][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic. + air1.gases[/datum/gas/oxygen][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic. /obj/machinery/atmospherics/components/unary/cryo_cell/power_change() ..() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm index c0a887e3aa..035618c5fb 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm @@ -49,8 +49,8 @@ var/added_oxygen = oxygen_content - total_moles air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen) - ASSERT_GAS("o2", air_contents) - air_contents.gases["o2"][MOLES] += added_oxygen + ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.gases[/datum/gas/oxygen][MOLES] += added_oxygen update_parents() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index 3b0055edab..ca60c9bf85 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -21,23 +21,23 @@ name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])" /obj/machinery/atmospherics/components/unary/tank/carbon_dioxide - gas_type = "co2" + gas_type = /datum/gas/carbon_dioxide /obj/machinery/atmospherics/components/unary/tank/toxins icon_state = "orange" - gas_type = "plasma" + gas_type = /datum/gas/plasma /obj/machinery/atmospherics/components/unary/tank/oxygen_agent_b icon_state = "orange_2" - gas_type = "agent_b" + gas_type = /datum/gas/oxygen_agent_b /obj/machinery/atmospherics/components/unary/tank/oxygen icon_state = "blue" - gas_type = "o2" + gas_type = /datum/gas/oxygen /obj/machinery/atmospherics/components/unary/tank/nitrogen icon_state = "red" - gas_type = "n2" + gas_type = /datum/gas/nitrogen /obj/machinery/atmospherics/components/unary/tank/air icon_state = "grey" @@ -46,6 +46,6 @@ /obj/machinery/atmospherics/components/unary/tank/air/New() ..() var/datum/gas_mixture/air_contents = AIR1 - air_contents.assert_gases("o2", "n2") - air_contents.gases["o2"][MOLES] = AIR_CONTENTS * 0.2 - air_contents.gases["n2"][MOLES] = AIR_CONTENTS * 0.8 + air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2 + air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index e1365e5a7e..5c8d1e4d24 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -174,7 +174,7 @@ if(scrubbing & SCRUBBING) var/should_we_scrub = FALSE for(var/id in env_gases) - if(id == "n2" || id == "o2") + if(id == /datum/gas/nitrogen || id == /datum/gas/oxygen) continue if(env_gases[id][MOLES]) should_we_scrub = TRUE @@ -194,6 +194,7 @@ var/list/filtered_gases = filtered_out.gases filtered_out.temperature = removed.temperature +<<<<<<< HEAD if(scrub_Toxins && removed_gases["plasma"]) ADD_GAS("plasma", filtered_out.gases) filtered_gases["plasma"][MOLES] = removed_gases["plasma"][MOLES] @@ -228,6 +229,42 @@ ADD_GAS("water_vapor", filtered_out.gases) filtered_gases["water_vapor"][MOLES] = removed_gases["water_vapor"][MOLES] removed_gases["water_vapor"][MOLES] = 0 +======= + if(scrub_Toxins && removed_gases[/datum/gas/plasma]) + ADD_GAS(/datum/gas/plasma, filtered_out.gases) + filtered_gases[/datum/gas/plasma][MOLES] = removed_gases[/datum/gas/plasma][MOLES] + removed_gases[/datum/gas/plasma][MOLES] = 0 + + if(scrub_CO2 && removed_gases[/datum/gas/carbon_dioxide]) + ADD_GAS(/datum/gas/carbon_dioxide, filtered_out.gases) + filtered_gases[/datum/gas/carbon_dioxide][MOLES] = removed_gases[/datum/gas/carbon_dioxide][MOLES] + removed_gases[/datum/gas/carbon_dioxide][MOLES] = 0 + + if(removed_gases[/datum/gas/oxygen_agent_b]) + ADD_GAS(/datum/gas/oxygen_agent_b, filtered_out.gases) + filtered_gases[/datum/gas/oxygen_agent_b][MOLES] = removed_gases[/datum/gas/oxygen_agent_b][MOLES] + removed_gases[/datum/gas/oxygen_agent_b][MOLES] = 0 + + if(scrub_N2O && removed_gases[/datum/gas/nitrous_oxide]) + ADD_GAS(/datum/gas/nitrous_oxide, filtered_out.gases) + filtered_gases[/datum/gas/nitrous_oxide][MOLES] = removed_gases[/datum/gas/nitrous_oxide][MOLES] + removed_gases[/datum/gas/nitrous_oxide][MOLES] = 0 + + if(scrub_BZ && removed_gases[/datum/gas/bz]) + ADD_GAS(/datum/gas/bz, filtered_out.gases) + filtered_gases[/datum/gas/bz][MOLES] = removed_gases[/datum/gas/bz][MOLES] + removed_gases[/datum/gas/bz][MOLES] = 0 + + if(scrub_Freon && removed_gases[/datum/gas/freon]) + ADD_GAS(/datum/gas/freon, filtered_out.gases) + filtered_gases[/datum/gas/freon][MOLES] = removed_gases[/datum/gas/freon][MOLES] + removed_gases[/datum/gas/freon][MOLES] = 0 + + if(scrub_WaterVapor && removed_gases[/datum/gas/water_vapor]) + ADD_GAS(/datum/gas/water_vapor, filtered_out.gases) + filtered_gases[/datum/gas/water_vapor][MOLES] = removed_gases[/datum/gas/water_vapor][MOLES] + removed_gases[/datum/gas/water_vapor][MOLES] = 0 +>>>>>>> 454d16f... Minor refactor of how gas IDs are handled (#31528) removed.garbage_collect() diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 75e6807fa5..99e6cda6af 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -146,49 +146,49 @@ /obj/machinery/atmospherics/miner/n2o name = "\improper N2O Gas Miner" overlay_color = "#FFCCCC" - spawn_id = "n2o" + spawn_id = /datum/gas/nitrous_oxide /obj/machinery/atmospherics/miner/nitrogen name = "\improper N2 Gas Miner" overlay_color = "#CCFFCC" - spawn_id = "n2" + spawn_id = /datum/gas/nitrogen /obj/machinery/atmospherics/miner/oxygen name = "\improper O2 Gas Miner" overlay_color = "#007FFF" - spawn_id = "o2" + spawn_id = /datum/gas/oxygen /obj/machinery/atmospherics/miner/toxins name = "\improper Plasma Gas Miner" overlay_color = "#FF0000" - spawn_id = "plasma" + spawn_id = /datum/gas/plasma /obj/machinery/atmospherics/miner/carbon_dioxide name = "\improper CO2 Gas Miner" overlay_color = "#CDCDCD" - spawn_id = "co2" + spawn_id = /datum/gas/carbon_dioxide /obj/machinery/atmospherics/miner/bz name = "\improper BZ Gas Miner" overlay_color = "#FAFF00" - spawn_id = "bz" + spawn_id = /datum/gas/bz /obj/machinery/atmospherics/miner/freon name = "\improper Freon Gas Miner" overlay_color = "#00FFE5" - spawn_id = "freon" + spawn_id = /datum/gas/freon /obj/machinery/atmospherics/miner/volatile_fuel name = "\improper Volatile Fuel Gas Miner" overlay_color = "#564040" - spawn_id = "v_fuel" + spawn_id = /datum/gas/volatile_fuel /obj/machinery/atmospherics/miner/agent_b name = "\improper Agent B Gas Miner" overlay_color = "#E81E24" - spawn_id = "agent_b" + spawn_id = /datum/gas/oxygen_agent_b /obj/machinery/atmospherics/miner/water_vapor name = "\improper Water Vapor Gas Miner" overlay_color = "#99928E" - spawn_id = "water_vapor" + spawn_id = /datum/gas/water_vapor diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index c08ef25b61..fa2a6fbcbf 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -12,7 +12,7 @@ volume = 1000 var/filled = 0.5 - var/gas_type = "" + var/gas_type var/release_pressure = ONE_ATMOSPHERE var/can_max_release_pressure = (ONE_ATMOSPHERE * 10) var/can_min_release_pressure = (ONE_ATMOSPHERE / 10) @@ -59,42 +59,42 @@ name = "n2 canister" desc = "Nitrogen gas. Reportedly useful for something." icon_state = "red" - gas_type = "n2" + gas_type = /datum/gas/nitrogen /obj/machinery/portable_atmospherics/canister/oxygen name = "o2 canister" desc = "Oxygen. Necessary for human life." icon_state = "blue" - gas_type = "o2" + gas_type = /datum/gas/oxygen /obj/machinery/portable_atmospherics/canister/carbon_dioxide name = "co2 canister" desc = "Carbon dioxide. What the fuck is carbon dioxide?" icon_state = "black" - gas_type = "co2" + gas_type = /datum/gas/carbon_dioxide /obj/machinery/portable_atmospherics/canister/toxins name = "plasma canister" desc = "Plasma gas. The reason YOU are here. Highly toxic." icon_state = "orange" - gas_type = "plasma" + gas_type = /datum/gas/plasma /obj/machinery/portable_atmospherics/canister/agent_b name = "agent b canister" desc = "Oxygen Agent B. You're not quite sure what it does." - gas_type = "agent_b" + gas_type = /datum/gas/oxygen_agent_b /obj/machinery/portable_atmospherics/canister/bz name = "BZ canister" desc = "BZ, a powerful hallucinogenic nerve agent." icon_state = "purple" - gas_type = "bz" + gas_type = /datum/gas/bz /obj/machinery/portable_atmospherics/canister/nitrous_oxide name = "n2o canister" desc = "Nitrous oxide gas. Known to cause drowsiness." icon_state = "redws" - gas_type = "n2o" + gas_type = /datum/gas/nitrous_oxide /obj/machinery/portable_atmospherics/canister/air name = "air canister" @@ -105,14 +105,14 @@ name = "freon canister" desc = "Freon. Great for the atmosphere!" icon_state = "freon" - gas_type = "freon" + gas_type = /datum/gas/freon starter_temp = 120 /obj/machinery/portable_atmospherics/canister/water_vapor name = "water vapor canister" desc = "Water Vapor. We get it, you vape." icon_state = "water_vapor" - gas_type = "water_vapor" + gas_type = /datum/gas/water_vapor filled = 1 /obj/machinery/portable_atmospherics/canister/proc/get_time_left() @@ -148,7 +148,7 @@ name = "prototype canister" desc = "A prototype canister for a prototype bike, what could go wrong?" icon_state = "proto" - gas_type = "o2" + gas_type = /datum/gas/oxygen filled = 1 release_pressure = ONE_ATMOSPHERE*2 @@ -181,9 +181,9 @@ if(starter_temp) air_contents.temperature = starter_temp /obj/machinery/portable_atmospherics/canister/air/create_gas() - air_contents.add_gases("o2","n2") - air_contents.gases["o2"][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - air_contents.gases["n2"][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) #define HOLDING 1 #define CONNECTED 2 diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index cca108757a..0cddd5cb4f 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -99,8 +99,8 @@ if("power") on = !on if(on && !holding) - var/plasma = air_contents.gases["plasma"] - var/n2o = air_contents.gases["n2o"] + var/plasma = air_contents.gases[/datum/gas/plasma] + var/n2o = air_contents.gases[/datum/gas/nitrous_oxide] if(n2o || plasma) var/area/A = get_area(src) message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][ADMIN_JMP(src)]") @@ -138,4 +138,4 @@ holding.loc = get_turf(src) holding = null . = TRUE - update_icon() \ No newline at end of file + update_icon() diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 7a76405a90..cd857d19a1 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -7,7 +7,7 @@ var/volume_rate = 1000 volume = 1000 - var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon", "water_vapor") + var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/oxygen_agent_b, /datum/gas/bz, /datum/gas/freon, /datum/gas/water_vapor) /obj/machinery/portable_atmospherics/scrubber/Destroy() var/turf/T = get_turf(src) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 287635742f..db7028411c 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -167,9 +167,9 @@ var/turf/open/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - if(!GM.gases["o2"]) + if(!GM.gases[/datum/gas/oxygen]) return - GM.gases["o2"][MOLES] -= severity * holder.energy + GM.gases[/datum/gas/oxygen][MOLES] -= severity * holder.energy GM.garbage_collect() /datum/spacevine_mutation/nitro_eater @@ -182,9 +182,9 @@ var/turf/open/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - if(!GM.gases["n2"]) + if(!GM.gases[/datum/gas/nitrogen]) return - GM.gases["n2"][MOLES] -= severity * holder.energy + GM.gases[/datum/gas/nitrogen][MOLES] -= severity * holder.energy GM.garbage_collect() /datum/spacevine_mutation/carbondioxide_eater @@ -197,9 +197,9 @@ var/turf/open/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - if(!GM.gases["co2"]) + if(!GM.gases[/datum/gas/carbon_dioxide]) return - GM.gases["co2"][MOLES] -= severity * holder.energy + GM.gases[/datum/gas/carbon_dioxide][MOLES] -= severity * holder.energy GM.garbage_collect() /datum/spacevine_mutation/plasma_eater @@ -212,9 +212,9 @@ var/turf/open/floor/T = holder.loc if(istype(T)) var/datum/gas_mixture/GM = T.air - if(!GM.gases["plasma"]) + if(!GM.gases[/datum/gas/plasma]) return - GM.gases["plasma"][MOLES] -= severity * holder.energy + GM.gases[/datum/gas/plasma][MOLES] -= severity * holder.energy GM.garbage_collect() /datum/spacevine_mutation/thorns diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 3a9e75fdaa..f11d6e0772 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -181,8 +181,8 @@ if(isopenturf(loc)) var/turf/open/O = loc if(O.air) - var/G = O.air.gases - if(G["o2"][MOLES] > 13) + var/loc_gases = O.air.gases + if(loc_gases[/datum/gas/oxygen][MOLES] > 13) return 1 return 0 diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 0bfd788846..4cfba35100 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/living/carbon/alien/Life() findQueen() return..() @@ -51,4 +52,60 @@ if(..()) return bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up! - return \ No newline at end of file + return +======= +/mob/living/carbon/alien/Life() + findQueen() + return..() + +/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath) + if(status_flags & GODMODE) + return + + if(!breath || (breath.total_moles() == 0)) + //Aliens breathe in vaccuum + return 0 + + var/toxins_used = 0 + var/tox_detect_threshold = 0.02 + var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME + var/list/breath_gases = breath.gases + + breath.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) + + //Partial pressure of the toxins in our breath + var/Toxins_pp = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure + + if(Toxins_pp > tox_detect_threshold) // Detect toxins in air + adjustPlasma(breath_gases[/datum/gas/plasma][MOLES]*250) + throw_alert("alien_tox", /obj/screen/alert/alien_tox) + + toxins_used = breath_gases[/datum/gas/plasma][MOLES] + + else + clear_alert("alien_tox") + + //Breathe in toxins and out oxygen + breath_gases[/datum/gas/plasma][MOLES] -= toxins_used + breath_gases[/datum/gas/oxygen][MOLES] += toxins_used + + breath.garbage_collect() + + //BREATH TEMPERATURE + handle_breath_temperature(breath) + +/mob/living/carbon/alien/handle_status_effects() + ..() + //natural reduction of movement delay due to stun. + if(move_delay_add > 0) + move_delay_add = max(0, move_delay_add - rand(1, 2)) + +/mob/living/carbon/alien/handle_changeling() + return + +/mob/living/carbon/alien/handle_fire()//Aliens on fire code + if(..()) + return + bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up! + return +>>>>>>> 454d16f... Minor refactor of how gas IDs are handled (#31528) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index c216052cea..817e22163a 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -26,7 +26,7 @@ if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed) if(environment) if(environment.total_moles()) - if(environment.gases["o2"] && (environment.gases["o2"][MOLES]) >= 1) //Same threshhold that extinguishes fire + if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire H.adjust_fire_stacks(0.5) if(!H.on_fire && H.fire_stacks > 0) H.visible_message("[H]'s body reacts with the atmosphere and bursts into flames!","Your body reacts with the atmosphere and bursts into flame!") diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 2bf605de9c..979bc2d89c 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -132,11 +132,10 @@ var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/list/breath_gases = breath.gases - breath.assert_gases("o2","plasma","co2","n2o", "bz") - - var/O2_partialpressure = (breath_gases["o2"][MOLES]/breath.total_moles())*breath_pressure - var/Toxins_partialpressure = (breath_gases["plasma"][MOLES]/breath.total_moles())*breath_pressure - var/CO2_partialpressure = (breath_gases["co2"][MOLES]/breath.total_moles())*breath_pressure + breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz) + var/O2_partialpressure = (breath_gases[/datum/gas/oxygen][MOLES]/breath.total_moles())*breath_pressure + var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure + var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide][MOLES]/breath.total_moles())*breath_pressure //OXYGEN @@ -147,7 +146,7 @@ var/ratio = 1 - O2_partialpressure/safe_oxy_min adjustOxyLoss(min(5*ratio, 3)) failed_last_breath = 1 - oxygen_used = breath_gases["o2"][MOLES]*ratio + oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]*ratio else adjustOxyLoss(3) failed_last_breath = 1 @@ -157,11 +156,11 @@ failed_last_breath = 0 if(health >= HEALTH_THRESHOLD_CRIT) adjustOxyLoss(-5) - oxygen_used = breath_gases["o2"][MOLES] + oxygen_used = breath_gases[/datum/gas/oxygen][MOLES] clear_alert("not_enough_oxy") - breath_gases["o2"][MOLES] -= oxygen_used - breath_gases["co2"][MOLES] += oxygen_used + breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used + breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used //CARBON DIOXIDE if(CO2_partialpressure > safe_co2_max) @@ -180,15 +179,15 @@ //TOXINS/PLASMA if(Toxins_partialpressure > safe_tox_max) - var/ratio = (breath_gases["plasma"][MOLES]/safe_tox_max) * 10 + var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_tox_max) * 10 adjustToxLoss(Clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else clear_alert("too_much_tox") //NITROUS OXIDE - if(breath_gases["n2o"]) - var/SA_partialpressure = (breath_gases["n2o"][MOLES]/breath.total_moles())*breath_pressure + if(breath_gases[/datum/gas/nitrous_oxide]) + var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide][MOLES]/breath.total_moles())*breath_pressure if(SA_partialpressure > SA_para_min) Unconscious(60) if(SA_partialpressure > SA_sleep_min) @@ -198,8 +197,8 @@ emote(pick("giggle","laugh")) //BZ (Facepunch port of their Agent B) - if(breath_gases["bz"]) - var/bz_partialpressure = (breath_gases["bz"][MOLES]/breath.total_moles())*breath_pressure + if(breath_gases[/datum/gas/bz]) + var/bz_partialpressure = (breath_gases[/datum/gas/bz][MOLES]/breath.total_moles())*breath_pressure if(bz_partialpressure > 1) hallucination += 20 else if(bz_partialpressure > 0.01) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 66ca8bf8e2..acbdea29c1 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -92,7 +92,7 @@ ExtinguishMob() return var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment - if(!G.gases["o2"] || G.gases["o2"][MOLES] < 1) + if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 1) ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire return var/turf/location = get_turf(src) @@ -123,5 +123,3 @@ /mob/living/proc/update_damage_hud() return - - diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 47fa2a8010..aa51fb4e17 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -43,12 +43,12 @@ ..() if(isopenturf(loc)) var/turf/open/T = src.loc - if(T.air && T.air.gases["co2"]) - var/co2 = T.air.gases["co2"][MOLES] + if(T.air && T.air.gases[/datum/gas/carbon_dioxide]) + var/co2 = T.air.gases[/datum/gas/carbon_dioxide][MOLES] if(co2 > 0) if(prob(25)) var/amt = min(co2, 9) - T.air.gases["co2"][MOLES] -= amt + T.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt T.atmos_spawn_air("o2=[amt]") /mob/living/simple_animal/hostile/tree/AttackingTarget() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d4b2c8f7c6..56ba972d6b 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -186,10 +186,10 @@ var/ST_gases = ST.air.gases ST.air.assert_gases(arglist(GLOB.hardcoded_gases)) - var/tox = ST_gases["plasma"][MOLES] - var/oxy = ST_gases["o2"][MOLES] - var/n2 = ST_gases["n2"][MOLES] - var/co2 = ST_gases["co2"][MOLES] + var/tox = ST_gases[/datum/gas/plasma][MOLES] + var/oxy = ST_gases[/datum/gas/oxygen][MOLES] + var/n2 = ST_gases[/datum/gas/nitrogen][MOLES] + var/co2 = ST_gases[/datum/gas/carbon_dioxide][MOLES] ST.air.garbage_collect() diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index a3c37e9889..0ec41119dc 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -134,8 +134,8 @@ if(stat != DEAD) var/bz_percentage =0 - if("bz" in environment.gases) - bz_percentage = environment.gases["bz"][MOLES] / environment.total_moles() + if(environment.gases[/datum/gas/bz]) + bz_percentage = environment.gases[/datum/gas/bz][MOLES] / environment.total_moles() var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis if(stat == CONSCIOUS && stasis) diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 9b5592af3b..b73285570a 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -31,11 +31,11 @@ GLOBAL_LIST_EMPTY(rad_collectors) /obj/machinery/power/rad_collector/process() if(loaded_tank) - if(!loaded_tank.air_contents.gases["plasma"]) + if(!loaded_tank.air_contents.gases[/datum/gas/plasma]) investigate_log("out of fuel.", INVESTIGATE_SINGULO) eject() else - loaded_tank.air_contents.gases["plasma"][MOLES] -= 0.001*drainratio + loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= 0.001*drainratio loaded_tank.air_contents.garbage_collect() return @@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(rad_collectors) "You turn the [src.name] [active? "on":"off"].") var/fuel if(loaded_tank) - fuel = loaded_tank.air_contents.gases["plasma"] + fuel = loaded_tank.air_contents.gases[/datum/gas/plasma] fuel = fuel ? fuel[MOLES] : 0 investigate_log("turned [active?"on":"off"] by [user.key]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"It is empty"].", INVESTIGATE_SINGULO) return @@ -139,7 +139,7 @@ GLOBAL_LIST_EMPTY(rad_collectors) /obj/machinery/power/rad_collector/proc/receive_pulse(pulse_strength) if(loaded_tank && active) - var/power_produced = loaded_tank.air_contents.gases["plasma"] ? loaded_tank.air_contents.gases["plasma"][MOLES] : 0 + var/power_produced = loaded_tank.air_contents.gases[/datum/gas/plasma] ? loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] : 0 power_produced *= pulse_strength*10 add_avail(power_produced) last_power = power_produced diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index b6f7d20fbc..1dc36f9097 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -284,17 +284,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) if(damage > damage_archived && prob(10)) playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1) - removed.assert_gases("o2", "plasma", "co2", "n2o", "n2", "freon") + removed.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/nitrogen, /datum/gas/freon) //calculating gas related values combined_gas = max(removed.total_moles(), 0) - plasmacomp = max(removed.gases["plasma"][MOLES]/combined_gas, 0) - o2comp = max(removed.gases["o2"][MOLES]/combined_gas, 0) - co2comp = max(removed.gases["co2"][MOLES]/combined_gas, 0) + plasmacomp = max(removed.gases[/datum/gas/plasma][MOLES]/combined_gas, 0) + o2comp = max(removed.gases[/datum/gas/oxygen][MOLES]/combined_gas, 0) + co2comp = max(removed.gases[/datum/gas/carbon_dioxide][MOLES]/combined_gas, 0) - n2ocomp = max(removed.gases["n2o"][MOLES]/combined_gas, 0) - n2comp = max(removed.gases["n2"][MOLES]/combined_gas, 0) - freoncomp = max(removed.gases["freon"][MOLES]/combined_gas, 0) + n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide][MOLES]/combined_gas, 0) + n2comp = max(removed.gases[/datum/gas/nitrogen][MOLES]/combined_gas, 0) + freoncomp = max(removed.gases[/datum/gas/freon][MOLES]/combined_gas, 0) gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp - freoncomp, 0), 1) @@ -348,12 +348,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier)) //Calculate how much gas to release - removed.gases["plasma"][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0) + removed.gases[/datum/gas/plasma][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0) - removed.gases["o2"][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + removed.gases[/datum/gas/oxygen][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0) if(combined_gas < 50) - removed.gases["freon"][MOLES] = max((removed.gases["freon"][MOLES] + device_energy) * freoncomp / FREON_BREEDING_MODIFIER, 0) + removed.gases[/datum/gas/freon][MOLES] = max((removed.gases[/datum/gas/freon][MOLES] + device_energy) * freoncomp / FREON_BREEDING_MODIFIER, 0) if(produces_gas) env.merge(removed) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 834a99d1ec..12ab61aaec 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -95,13 +95,13 @@ var/list/breath_gases = breath.gases - breath.assert_gases("o2", "n2", "plasma", "co2", "n2o", "bz") + breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitrogen) //Partial pressures in our breath - var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES]) - var/N2_pp = breath.get_breath_partial_pressure(breath_gases["n2"][MOLES]) - var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES]) - var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES]) + var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen][MOLES]) + var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen][MOLES]) + var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma][MOLES]) + var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide][MOLES]) //-- OXY --// @@ -109,7 +109,7 @@ //Too much oxygen! //Yes, some species may not like it. if(safe_oxygen_max) if(O2_pp > safe_oxygen_max) - var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10 + var/ratio = (breath_gases[/datum/gas/oxygen][MOLES]/safe_oxygen_max) * 10 H.apply_damage_type(Clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) else @@ -118,18 +118,18 @@ //Too little oxygen! if(safe_oxygen_min) if(O2_pp < safe_oxygen_min) - gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases["o2"][MOLES]) + gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen][MOLES]) H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) else H.failed_last_breath = FALSE if(H.health >= HEALTH_THRESHOLD_CRIT) H.adjustOxyLoss(-5) - gas_breathed = breath_gases["o2"][MOLES] + gas_breathed = breath_gases[/datum/gas/oxygen][MOLES] H.clear_alert("not_enough_oxy") //Exhale - breath_gases["o2"][MOLES] -= gas_breathed - breath_gases["co2"][MOLES] += gas_breathed + breath_gases[/datum/gas/oxygen][MOLES] -= gas_breathed + breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed gas_breathed = 0 //-- Nitrogen --// @@ -137,7 +137,7 @@ //Too much nitrogen! if(safe_nitro_max) if(N2_pp > safe_nitro_max) - var/ratio = (breath_gases["n2"][MOLES]/safe_nitro_max) * 10 + var/ratio = (breath_gases[/datum/gas/nitrogen][MOLES]/safe_nitro_max) * 10 H.apply_damage_type(Clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro) else @@ -146,18 +146,18 @@ //Too little nitrogen! if(safe_nitro_min) if(N2_pp < safe_nitro_min) - gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases["n2"][MOLES]) + gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen][MOLES]) H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro) else H.failed_last_breath = FALSE if(H.health >= HEALTH_THRESHOLD_CRIT) H.adjustOxyLoss(-5) - gas_breathed = breath_gases["n2"][MOLES] + gas_breathed = breath_gases[/datum/gas/nitrogen][MOLES] H.clear_alert("nitro") //Exhale - breath_gases["n2"][MOLES] -= gas_breathed - breath_gases["co2"][MOLES] += gas_breathed + breath_gases[/datum/gas/nitrogen][MOLES] -= gas_breathed + breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed gas_breathed = 0 //-- CO2 --// @@ -183,18 +183,18 @@ //Too little CO2! if(safe_co2_min) if(CO2_pp < safe_co2_min) - gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases["co2"][MOLES]) + gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide][MOLES]) H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) else H.failed_last_breath = FALSE if(H.health >= HEALTH_THRESHOLD_CRIT) H.adjustOxyLoss(-5) - gas_breathed = breath_gases["co2"][MOLES] + gas_breathed = breath_gases[/datum/gas/carbon_dioxide][MOLES] H.clear_alert("not_enough_co2") //Exhale - breath_gases["co2"][MOLES] -= gas_breathed - breath_gases["o2"][MOLES] += gas_breathed + breath_gases[/datum/gas/carbon_dioxide][MOLES] -= gas_breathed + breath_gases[/datum/gas/oxygen][MOLES] += gas_breathed gas_breathed = 0 @@ -203,7 +203,7 @@ //Too much toxins! if(safe_toxins_max) if(Toxins_pp > safe_toxins_max) - var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10 + var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_toxins_max) * 10 H.apply_damage_type(Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else @@ -213,18 +213,18 @@ //Too little toxins! if(safe_toxins_min) if(Toxins_pp < safe_toxins_min) - gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES]) + gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma][MOLES]) H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) else H.failed_last_breath = FALSE if(H.health >= HEALTH_THRESHOLD_CRIT) H.adjustOxyLoss(-5) - gas_breathed = breath_gases["plasma"][MOLES] + gas_breathed = breath_gases[/datum/gas/plasma][MOLES] H.clear_alert("not_enough_tox") //Exhale - breath_gases["plasma"][MOLES] -= gas_breathed - breath_gases["co2"][MOLES] += gas_breathed + breath_gases[/datum/gas/plasma][MOLES] -= gas_breathed + breath_gases[/datum/gas/carbon_dioxide][MOLES] += gas_breathed gas_breathed = 0 @@ -234,7 +234,7 @@ // N2O - var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES]) + var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide][MOLES]) if(SA_pp > SA_para_min) // Enough to make us stunned for a bit H.Unconscious(60) // 60 gives them one second to wake up and run away a bit! if(SA_pp > SA_sleep_min) // Enough to make us sleep as well @@ -245,7 +245,7 @@ // BZ - var/bz_pp = breath.get_breath_partial_pressure(breath_gases["bz"][MOLES]) + var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz][MOLES]) if(bz_pp > BZ_trip_balls_min) H.hallucination += 20 if(prob(33)) diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index ffe61666b9..256b53c106 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 43cc3133c8..90e398c153 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,17 +1,17 @@ -require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(i)return i(o,!0);var p=Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o2?p[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-u,o-s),f=1;for(s>u&&u+l>s&&(f=-1,u+=l-1,s+=l-1);l-- >0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},{76:76,79:79,80:80}],6:[function(t,e,n){"use strict";var a=t(80),r=t(76),i=t(79);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,u=r(s>1?o[1]:void 0,n),p=s>2?o[2]:void 0,c=void 0===p?n:r(p,n);c>u;)e[u++]=t;return e}},{76:76,79:79,80:80}],7:[function(t,e,n){var a=t(78),r=t(79),i=t(76);e.exports=function(t){return function(e,n,o){var s,u=a(e),p=r(u.length),c=i(o,p);if(t&&n!=n){for(;p>c;)if(s=u[c++],s!=s)return!0}else for(;p>c;c++)if((t||c in u)&&u[c]===n)return t||c;return!t&&-1}}},{76:76,78:78,79:79}],8:[function(t,e,n){var a=t(17),r=t(34),i=t(80),o=t(79),s=t(9);e.exports=function(t){var e=1==t,n=2==t,u=3==t,p=4==t,c=6==t,l=5==t||c;return function(f,d,h){for(var m,v,g=i(f),b=r(g),y=a(d,h,3),x=o(b.length),_=0,w=e?s(f,x):n?s(f,0):void 0;x>_;_++)if((l||_ in b)&&(m=b[_],v=y(m,_,g),t))if(e)w[_]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return _;case 2:w.push(m)}else if(p)return!1;return c?-1:u||p?p:w}}},{17:17,34:34,79:79,80:80,9:9}],9:[function(t,e,n){var a=t(38),r=t(36),i=t(83)("species");e.exports=function(t,e){var n;return r(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!r(n.prototype)||(n=void 0),a(n)&&(n=n[i],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{36:36,38:38,83:83}],10:[function(t,e,n){var a=t(11),r=t(83)("toStringTag"),i="Arguments"==a(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[r])?n:i?a(e):"Object"==(o=a(e))&&"function"==typeof e.callee?"Arguments":o}},{11:11,83:83}],11:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],12:[function(t,e,n){"use strict";var a=t(46),r=t(31),i=t(60),o=t(17),s=t(69),u=t(18),p=t(27),c=t(42),l=t(44),f=t(82)("id"),d=t(30),h=t(38),m=t(65),v=t(19),g=Object.isExtensible||h,b=v?"_s":"size",y=0,x=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";r(t,f,++y)}return"O"+t[f]},_=function(t,e){var n,a=x(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,r){var c=t(function(t,i){s(t,c,e),t._i=a.create(null),t._f=void 0,t._l=void 0,t[b]=0,void 0!=i&&p(i,n,t[r],t)});return i(c.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[b]=0},"delete":function(t){var e=this,n=_(e,t);if(n){var a=n.n,r=n.p;delete e._i[n.i],n.r=!0,r&&(r.n=a),a&&(a.p=r),e._f==n&&(e._f=a),e._l==n&&(e._l=r),e[b]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!_(this,t)}}),v&&a.setDesc(c.prototype,"size",{get:function(){return u(this[b])}}),c},def:function(t,e,n){var a,r,i=_(t,e);return i?i.v=n:(t._l=i={i:r=x(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[b]++,"F"!==r&&(t._i[r]=i)),t},getEntry:_,setStrong:function(t,e,n){c(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?l(0,n.k):"values"==e?l(0,n.v):l(0,[n.k,n.v]):(t._t=void 0,l(1))},n?"entries":"values",!n,!0),m(e)}}},{17:17,18:18,19:19,27:27,30:30,31:31,38:38,42:42,44:44,46:46,60:60,65:65,69:69,82:82}],13:[function(t,e,n){var a=t(27),r=t(10);e.exports=function(t){return function(){if(r(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return a(this,!1,e.push,e),e}}},{10:10,27:27}],14:[function(t,e,n){"use strict";var a=t(31),r=t(60),i=t(4),o=t(38),s=t(69),u=t(27),p=t(8),c=t(30),l=t(82)("weak"),f=Object.isExtensible||o,d=p(5),h=p(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},b=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=b(this,t);return e?e[1]:void 0},has:function(t){return!!b(this,t)},set:function(t,e){var n=b(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,a){var i=t(function(t,r){s(t,i,e),t._i=m++,t._l=void 0,void 0!=r&&u(r,n,t[a],t)});return r(i.prototype,{"delete":function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i)&&delete t[l][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i):v(this).has(t):!1}}),i},def:function(t,e,n){return f(i(e))?(c(e,l)||a(e,l,{}),e[l][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:l}},{27:27,30:30,31:31,38:38,4:4,60:60,69:69,8:8,82:82}],15:[function(t,e,n){"use strict";var a=t(29),r=t(22),i=t(61),o=t(60),s=t(27),u=t(69),p=t(38),c=t(24),l=t(43),f=t(66);e.exports=function(t,e,n,d,h,m){var v=a[t],g=v,b=h?"set":"add",y=g&&g.prototype,x={},_=function(t){var e=y[t];i(y,t,"delete"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!p(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||y.forEach&&!c(function(){(new g).entries().next()}))){var w,k=new g,E=k[b](m?{}:-0,1)!=k,S=c(function(){k.has(1)}),C=l(function(t){new g(t)});C||(g=e(function(e,n){u(e,g,t);var a=new v;return void 0!=n&&s(n,h,a[b],a),a}),g.prototype=y,y.constructor=g),m||k.forEach(function(t,e){w=1/e===-(1/0)}),(S||w)&&(_("delete"),_("has"),h&&_("get")),(w||E)&&_(b),m&&y.clear&&delete y.clear}else g=d.getConstructor(e,t,h,b),o(g.prototype,n);return f(g,t),x[t]=g,r(r.G+r.W+r.F*(g!=v),x),m||d.setStrong(g,t,h),g}},{22:22,24:24,27:27,29:29,38:38,43:43,60:60,61:61,66:66,69:69}],16:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],17:[function(t,e,n){var a=t(2);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{2:2}],18:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],19:[function(t,e,n){e.exports=!t(24)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{24:24}],20:[function(t,e,n){var a=t(38),r=t(29).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{29:29,38:38}],21:[function(t,e,n){var a=t(46);e.exports=function(t){var e=a.getKeys(t),n=a.getSymbols;if(n)for(var r,i=n(t),o=a.isEnum,s=0;i.length>s;)o.call(t,r=i[s++])&&e.push(r);return e}},{46:46}],22:[function(t,e,n){var a=t(29),r=t(16),i=t(31),o=t(61),s=t(17),u="prototype",p=function(t,e,n){var c,l,f,d,h=t&p.F,m=t&p.G,v=t&p.S,g=t&p.P,b=t&p.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[u],x=m?r:r[e]||(r[e]={}),_=x[u]||(x[u]={});m&&(n=e);for(c in n)l=!h&&y&&c in y,f=(l?y:n)[c],d=b&&l?s(f,a):g&&"function"==typeof f?s(Function.call,f):f,y&&!l&&o(y,c,f),x[c]!=f&&i(x,c,d),g&&_[c]!=f&&(_[c]=f)};a.core=r,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,e.exports=p},{16:16,17:17,29:29,31:31,61:61}],23:[function(t,e,n){var a=t(83)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{83:83}],24:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],25:[function(t,e,n){"use strict";var a=t(31),r=t(61),i=t(24),o=t(18),s=t(83);e.exports=function(t,e,n){var u=s(t),p=""[t];i(function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,u,p)),a(RegExp.prototype,u,2==e?function(t,e){return p.call(t,this,e)}:function(t){return p.call(t,this)}))}},{18:18,24:24,31:31,61:61,83:83}],26:[function(t,e,n){"use strict";var a=t(4);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{4:4}],27:[function(t,e,n){var a=t(17),r=t(40),i=t(35),o=t(4),s=t(79),u=t(84);e.exports=function(t,e,n,p){var c,l,f,d=u(t),h=a(n,p,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(i(d))for(c=s(t.length);c>m;m++)e?h(o(l=t[m])[0],l[1]):h(t[m]);else for(f=d.call(t);!(l=f.next()).done;)r(f,h,l.value,e)}},{17:17,35:35,4:4,40:40,79:79,84:84}],28:[function(t,e,n){var a=t(78),r=t(46).getNames,i={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{46:46,78:78}],29:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],30:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],31:[function(t,e,n){var a=t(46),r=t(59);e.exports=t(19)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{19:19,46:46,59:59}],32:[function(t,e,n){e.exports=t(29).document&&document.documentElement},{29:29}],33:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],34:[function(t,e,n){var a=t(11);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{11:11}],35:[function(t,e,n){var a=t(45),r=t(83)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{45:45,83:83}],36:[function(t,e,n){var a=t(11);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{11:11}],37:[function(t,e,n){var a=t(38),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{38:38}],38:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],39:[function(t,e,n){var a=t(38),r=t(11),i=t(83)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{11:11,38:38,83:83}],40:[function(t,e,n){var a=t(4);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{4:4}],41:[function(t,e,n){"use strict";var a=t(46),r=t(59),i=t(66),o={};t(31)(o,t(83)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{31:31,46:46,59:59,66:66,83:83}],42:[function(t,e,n){"use strict";var a=t(48),r=t(22),i=t(61),o=t(31),s=t(30),u=t(45),p=t(41),c=t(66),l=t(46).getProto,f=t(83)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,b,y,x,_){p(n,e,b);var w,k,E=function(t){if(!d&&t in A)return A[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",C=y==v,P=!1,A=t.prototype,O=A[f]||A[h]||y&&A[y],T=O||E(y);if(O){var R=l(T.call(new t));c(R,S,!0),!a&&s(A,h)&&o(R,f,g),C&&O.name!==v&&(P=!0,T=function(){return O.call(this)})}if(a&&!_||!d&&!P&&A[f]||o(A,f,T),u[e]=T,u[S]=g,y)if(w={values:C?T:E(v),keys:x?T:E(m),entries:C?E("entries"):T},_)for(k in w)k in A||i(A,k,w[k]);else r(r.P+r.F*(d||P),e,w);return w}},{22:22,30:30,31:31,41:41,45:45,46:46,48:48,61:61,66:66,83:83}],43:[function(t,e,n){var a=t(83)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){return{done:n=!0}},i[a]=function(){return o},t(i)}catch(s){}return n}},{83:83}],44:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],45:[function(t,e,n){e.exports={}},{}],46:[function(t,e,n){var a=Object;e.exports={create:a.create,getProto:a.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:a.getOwnPropertyDescriptor,setDesc:a.defineProperty,setDescs:a.defineProperties,getKeys:a.keys,getNames:a.getOwnPropertyNames,getSymbols:a.getOwnPropertySymbols,each:[].forEach}},{}],47:[function(t,e,n){var a=t(46),r=t(78);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,u=0;s>u;)if(i[n=o[u++]]===e)return n}},{46:46,78:78}],48:[function(t,e,n){e.exports=!1},{}],49:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],50:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],51:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],52:[function(t,e,n){var a,r,i,o=t(29),s=t(75).set,u=o.MutationObserver||o.WebKitMutationObserver,p=o.process,c=o.Promise,l="process"==t(11)(p),f=function(){var t,e,n;for(l&&(t=p.domain)&&(p.domain=null,t.exit());a;)e=a.domain,n=a.fn,e&&e.enter(),n(),e&&e.exit(),a=a.next;r=void 0,t&&t.enter()};if(l)i=function(){p.nextTick(f)};else if(u){var d=1,h=document.createTextNode("");new u(f).observe(h,{characterData:!0}),i=function(){h.data=d=-d}}else i=c&&c.resolve?function(){c.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:l&&p.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{11:11,29:29,75:75}],53:[function(t,e,n){var a=t(46),r=t(80),i=t(34);e.exports=t(24)(function(){var t=Object.assign,e={},n={},a=Symbol(),r="abcdefghijklmnopqrst";return e[a]=7,r.split("").forEach(function(t){n[t]=t}),7!=t({},e)[a]||Object.keys(t({},n)).join("")!=r})?function(t,e){for(var n=r(t),o=arguments,s=o.length,u=1,p=a.getKeys,c=a.getSymbols,l=a.isEnum;s>u;)for(var f,d=i(o[u++]),h=c?p(d).concat(c(d)):p(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{24:24,34:34,46:46,80:80}],54:[function(t,e,n){var a=t(22),r=t(16),i=t(24);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{16:16,22:22,24:24}],55:[function(t,e,n){var a=t(46),r=t(78),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),u=s.length,p=0,c=[];u>p;)i.call(o,n=s[p++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{46:46,78:78}],56:[function(t,e,n){var a=t(46),r=t(4),i=t(29).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{29:29,4:4,46:46}],57:[function(t,e,n){"use strict";var a=t(58),r=t(33),i=t(2);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,u=!1;e>o;)(n[o]=arguments[o++])===s&&(u=!0);return function(){var a,i=this,o=arguments,p=o.length,c=0,l=0;if(!u&&!p)return r(t,n,i);if(a=n.slice(),u)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;p>l;)a.push(o[l++]);return r(t,a,i)}}},{2:2,33:33,58:58}],58:[function(t,e,n){e.exports=t(29)},{29:29}],59:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],60:[function(t,e,n){var a=t(61);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{61:61}],61:[function(t,e,n){var a=t(29),r=t(31),i=t(82)("src"),o="toString",s=Function[o],u=(""+s).split(o);t(16).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(i)||r(n,i,t[e]?""+t[e]:u.join(e+"")),n.hasOwnProperty("name")||r(n,"name",e)),t===a?t[e]=n:(o||delete t[e],r(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||s.call(this)})},{16:16,29:29,31:31,82:82}],62:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],63:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],64:[function(t,e,n){var a=t(46).getDesc,r=t(38),i=t(4),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,r){try{r=t(17)(Function.call,a(Object.prototype,"__proto__").set,2),r(e,[]),n=!(e instanceof Array)}catch(i){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},{17:17,38:38,4:4,46:46}],65:[function(t,e,n){"use strict";var a=t(29),r=t(46),i=t(19),o=t(83)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{19:19,29:29,46:46,83:83}],66:[function(t,e,n){var a=t(46).setDesc,r=t(30),i=t(83)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{30:30,46:46,83:83}],67:[function(t,e,n){var a=t(29),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{29:29}],68:[function(t,e,n){var a=t(4),r=t(2),i=t(83)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{2:2,4:4,83:83}],69:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],70:[function(t,e,n){var a=t(77),r=t(18);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",u=a(n),p=s.length;return 0>u||u>=p?t?"":void 0:(i=s.charCodeAt(u),55296>i||i>56319||u+1===p||(o=s.charCodeAt(u+1))<56320||o>57343?t?s.charAt(u):i:t?s.slice(u,u+2):(i-55296<<10)+(o-56320)+65536)}}},{18:18,77:77}],71:[function(t,e,n){var a=t(39),r=t(18);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{18:18,39:39}],72:[function(t,e,n){var a=t(79),r=t(73),i=t(18);e.exports=function(t,e,n,o){var s=i(t)+"",u=s.length,p=void 0===n?" ":n+"",c=a(e);if(u>=c)return s;""==p&&(p=" ");var l=c-u,f=r.call(p,Math.ceil(l/p.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{18:18,73:73,79:79}],73:[function(t,e,n){"use strict";var a=t(77),r=t(18);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{18:18,77:77}],74:[function(t,e,n){var a=t(22),r=t(18),i=t(24),o=" \n\x0B\f\r   ᠎              \u2028\u2029\ufeff",s="["+o+"]",u="​…",p=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e){var n={};n[t]=e(f),a(a.P+a.F*i(function(){return!!o[t]()||u[t]()!=u}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(p,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{18:18,22:22,24:24}],75:[function(t,e,n){var a,r,i,o=t(17),s=t(33),u=t(32),p=t(20),c=t(29),l=c.process,f=c.setImmediate,d=c.clearImmediate,h=c.MessageChannel,m=0,v={},g="onreadystatechange",b=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},y=function(t){b.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},a(m),m},d=function(t){delete v[t]},"process"==t(11)(l)?a=function(t){l.nextTick(o(b,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=y,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",y,!1)):a=g in p("script")?function(t){u.appendChild(p("script"))[g]=function(){u.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{11:11,17:17,20:20,29:29,32:32,33:33}],76:[function(t,e,n){var a=t(77),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{77:77}],77:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],78:[function(t,e,n){var a=t(34),r=t(18);e.exports=function(t){return a(r(t))}},{18:18,34:34}],79:[function(t,e,n){var a=t(77),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{77:77}],80:[function(t,e,n){var a=t(18);e.exports=function(t){return Object(a(t))}},{18:18}],81:[function(t,e,n){var a=t(38);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{38:38}],82:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],83:[function(t,e,n){var a=t(67)("wks"),r=t(82),i=t(29).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{29:29,67:67,82:82}],84:[function(t,e,n){var a=t(10),r=t(83)("iterator"),i=t(45);e.exports=t(16).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{10:10,16:16,45:45,83:83}],85:[function(t,e,n){"use strict";var a,r=t(46),i=t(22),o=t(19),s=t(59),u=t(32),p=t(20),c=t(30),l=t(11),f=t(33),d=t(24),h=t(4),m=t(2),v=t(38),g=t(80),b=t(78),y=t(77),x=t(76),_=t(79),w=t(34),k=t(82)("__proto__"),E=t(8),S=t(7)(!1),C=Object.prototype,P=Array.prototype,A=P.slice,O=P.join,T=r.setDesc,R=r.getDesc,j=r.setDescs,M={};o||(a=!d(function(){return 7!=T(p("div"),"a",{get:function(){return 7}}).a}),r.setDesc=function(t,e,n){if(a)try{return T(t,e,n)}catch(r){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},r.getDesc=function(t,e){if(a)try{return R(t,e)}catch(n){}return c(t,e)?s(!C.propertyIsEnumerable.call(t,e),t[e]):void 0},r.setDescs=j=function(t,e){h(t);for(var n,a=r.getKeys(e),i=a.length,o=0;i>o;)r.setDesc(t,n=a[o++],e[n]);return t}),i(i.S+i.F*!o,"Object",{getOwnPropertyDescriptor:r.getDesc,defineProperty:r.setDesc,defineProperties:j});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),D=L.concat("length","prototype"),N=L.length,F=function(){var t,e=p("iframe"),n=N,a=">";for(e.style.display="none",u.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("