diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index 95d4929acb..48babcae96 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -56,6 +56,9 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define NETWORK_TELECOM "Tcomms" #define NETWORK_THUNDER "Thunderdome" #define NETWORK_COMMUNICATORS "Communicators" +#define NETWORK_ALARM_ATMOS "Atmosphere Alarms" +#define NETWORK_ALARM_POWER "Power Alarms" +#define NETWORK_ALARM_FIRE "Fire Alarms" // Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret", NETWORK_COMMUNICATORS) @@ -69,14 +72,6 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret #define STAGE_FIVE 9 #define STAGE_SUPER 11 -// computer3 error codes, move lower in the file when it passes dev -Sayu -#define PROG_CRASH 0x1 // Generic crash. -#define MISSING_PERIPHERAL 0x2 // Missing hardware. -#define BUSTED_ASS_COMPUTER 0x4 // Self-perpetuating error. BAC will continue to crash forever. -#define MISSING_PROGRAM 0x8 // Some files try to automatically launch a program. This is that failing. -#define FILE_DRM 0x10 // Some files want to not be copied/moved. This is them complaining that you tried. -#define NETWORK_FAILURE 0x20 - // NanoUI flags #define STATUS_INTERACTIVE 2 // GREEN Visability #define STATUS_UPDATE 1 // ORANGE Visability @@ -106,6 +101,16 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret #define ATMOS_DEFAULT_VOLUME_MIXER 200 // L. #define ATMOS_DEFAULT_VOLUME_PIPE 70 // L. +// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse! +#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case. +#define SUPERMATTER_INACTIVE 0 // No or minimal energy +#define SUPERMATTER_NORMAL 1 // Normal operation +#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE +#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged +#define SUPERMATTER_DANGER 4 // Integrity < 50% +#define SUPERMATTER_EMERGENCY 5 // Integrity < 25% +#define SUPERMATTER_DELAMINATING 6 // Pretty obvious. + //wIP - PORT ALL OF THESE TO SUBSYSTEMS AND GET RID OF THE WHOLE LIST PROCESS THING // Fancy-pants START/STOP_PROCESSING() macros that lets us custom define what the list is. #define START_PROCESSING_IN_LIST(DATUM, LIST) \ diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index c17e6d1594..7f9128a64f 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -113,6 +113,7 @@ #define MAX_RECORD_LENGTH 24576 #define MAX_LNAME_LEN 64 #define MAX_NAME_LEN 52 +#define MAX_TEXTFILE_LENGTH 128000 // 512GQ file // Event defines. #define EVENT_LEVEL_MUNDANE 1 @@ -191,6 +192,33 @@ #define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2) #define BOMBCAP_LIGHT_RADIUS max_explosion_range #define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5) + // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) +#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet +#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices +#define NTNET_COMMUNICATION 3 // Communication (messaging) +#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc. + +// NTNet transfer speeds, used when downloading/uploading a file/program. +#define NTNETSPEED_LOWSIGNAL 0.25 // GQ/s transfer speed when the device is wirelessly connected and on Low signal +#define NTNETSPEED_HIGHSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on High signal +#define NTNETSPEED_ETHERNET 1.0 // GQ/s transfer speed when the device is using wired connection +#define NTNETSPEED_DOS_AMPLIFICATION 5 // Multiplier for Denial of Service program. Resulting load on NTNet relay is this multiplied by NTNETSPEED of the device + +// Program bitflags +#define PROGRAM_ALL 15 +#define PROGRAM_CONSOLE 1 +#define PROGRAM_LAPTOP 2 +#define PROGRAM_TABLET 4 +#define PROGRAM_TELESCREEN 8 + +#define PROGRAM_STATE_KILLED 0 +#define PROGRAM_STATE_BACKGROUND 1 +#define PROGRAM_STATE_ACTIVE 2 + +// Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it. +#define MAX_NTNET_LOGS 500 +#define MIN_NTNET_LOGS 10 + // Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile. #define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act() diff --git a/code/_helpers/_lists.dm b/code/_helpers/_lists.dm index 553984330d..5e322e1928 100644 --- a/code/_helpers/_lists.dm +++ b/code/_helpers/_lists.dm @@ -756,3 +756,5 @@ proc/dd_sortedTextList(list/incoming) . = list() for(var/i in L) . |= i + +#define listequal(A, B) (A.len == B.len && !length(A^B)) diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index d4fa4a74bb..0343fe4249 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -331,6 +331,55 @@ proc/TextPreview(var/string,var/len=40) /proc/strip_improper(var/text) return replacetext(replacetext(text, "\proper", ""), "\improper", "") +/proc/pencode2html(t) + t = replacetext(t, "\n", "
") + t = replacetext(t, "\[center\]", "
") + t = replacetext(t, "\[/center\]", "
") + t = replacetext(t, "\[br\]", "
") + t = replacetext(t, "\[b\]", "") + t = replacetext(t, "\[/b\]", "") + t = replacetext(t, "\[i\]", "") + t = replacetext(t, "\[/i\]", "") + t = replacetext(t, "\[u\]", "") + t = replacetext(t, "\[/u\]", "") + t = replacetext(t, "\[time\]", "[stationtime2text()]") + t = replacetext(t, "\[date\]", "[stationdate2text()]") + t = replacetext(t, "\[large\]", "") + t = replacetext(t, "\[/large\]", "") + t = replacetext(t, "\[field\]", "") + t = replacetext(t, "\[h1\]", "

") + t = replacetext(t, "\[/h1\]", "

") + t = replacetext(t, "\[h2\]", "

") + t = replacetext(t, "\[/h2\]", "

") + t = replacetext(t, "\[h3\]", "

") + t = replacetext(t, "\[/h3\]", "

") + t = replacetext(t, "\[*\]", "
  • ") + t = replacetext(t, "\[hr\]", "
    ") + t = replacetext(t, "\[small\]", "") + t = replacetext(t, "\[/small\]", "") + t = replacetext(t, "\[list\]", "") + t = replacetext(t, "\[table\]", "") + t = replacetext(t, "\[/table\]", "
    ") + t = replacetext(t, "\[grid\]", "") + t = replacetext(t, "\[/grid\]", "
    ") + t = replacetext(t, "\[row\]", "") + t = replacetext(t, "\[cell\]", "") + t = replacetext(t, "\[logo\]", "") + t = replacetext(t, "\[redlogo\]", "") + t = replacetext(t, "\[sglogo\]", "") + t = replacetext(t, "\[editorbr\]", "") + return t + +// Random password generator +/proc/GenerateKey() + //Feel free to move to Helpers. + var/newKey + newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le") + newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai") + newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") + return newKey + //Used for applying byonds text macros to strings that are loaded at runtime /proc/apply_text_macros(string) var/next_backslash = findtext(string, "\\") diff --git a/code/_macros.dm b/code/_macros.dm index 0af691a90c..3860f63434 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -11,6 +11,7 @@ #define log_world(message) world.log << message #define to_file(file_entry, source_var) file_entry << source_var #define from_file(file_entry, target_var) file_entry >> target_var +#define show_browser(target, browser_content, browser_name) target << browse(browser_content, browser_name) // From TG, might be useful to have. // Didn't port SEND_TEXT() since to_chat() appears to serve the same purpose. @@ -20,4 +21,8 @@ #define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE) +#define qdel_null(x) if(x) { qdel(x) ; x = null } + +#define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id) + #define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") } diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 2a92ba20bc..7060451b27 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -108,6 +108,22 @@ screen_loc = "WEST,SOUTH to EAST,NORTH" icon_state = "druggy" +/obj/screen/fullscreen/noise + icon = 'icons/effects/static.dmi' + icon_state = "1 light" + screen_loc = ui_entire_screen + layer = FULLSCREEN_LAYER + +/obj/screen/fullscreen/scanline + icon = 'icons/effects/static.dmi' + icon_state = "scanlines" + screen_loc = ui_entire_screen + alpha = 50 + layer = FULLSCREEN_LAYER + +/obj/screen/fullscreen/fishbed + icon_state = "fishbed" + #undef FULLSCREEN_LAYER #undef BLIND_LAYER #undef DAMAGE_LAYER diff --git a/code/controllers/subsystems/nanoui.dm b/code/controllers/subsystems/nanoui.dm index b4ceee4d63..3c999cb5e2 100644 --- a/code/controllers/subsystems/nanoui.dm +++ b/code/controllers/subsystems/nanoui.dm @@ -12,6 +12,8 @@ SUBSYSTEM_DEF(nanoui) var/list/nano_asset_dirs = list(\ "nano/css/",\ "nano/images/",\ + "nano/images/status_icons/",\ + "nano/images/modular_computers/", "nano/js/",\ "nano/templates/"\ ) diff --git a/code/datums/repositories/unique.dm b/code/datums/repositories/unique.dm new file mode 100644 index 0000000000..a53111cb24 --- /dev/null +++ b/code/datums/repositories/unique.dm @@ -0,0 +1,70 @@ +var/repository/unique/uniqueness_repository = new() + +/repository/unique + var/list/generators + +/repository/unique/New() + ..() + generators = list() + +/repository/unique/proc/Generate() + var/generator_type = args[1] + var/datum/uniqueness_generator/generator = generators[generator_type] + if(!generator) + generator = new generator_type() + generators[generator_type] = generator + var/list/generator_args = args.Copy() // Cannot cut args directly, BYOND complains about it being readonly. + generator_args -= generator_type + return generator.Generate(arglist(generator_args)) + +/datum/uniqueness_generator/proc/Generate() + return + +/datum/uniqueness_generator/id_sequential + var/list/ids_by_key + +/datum/uniqueness_generator/id_sequential/New() + ..() + ids_by_key = list() + +/datum/uniqueness_generator/id_sequential/Generate(var/key, var/default_id = 100) + var/id = ids_by_key[key] + if(id) + id++ + else + id = default_id + + ids_by_key[key] = id + . = id + +/datum/uniqueness_generator/id_random + var/list/ids_by_key + +/datum/uniqueness_generator/id_random/New() + ..() + ids_by_key = list() + +/datum/uniqueness_generator/id_random/Generate(var/key, var/min, var/max) + var/list/ids = ids_by_key[key] + if(!ids) + ids = list() + ids_by_key[key] = ids + + if(ids.len >= (max - min) + 1) + error("Random ID limit reached for key [key].") + ids.Cut() + + if(ids.len >= 0.6 * ((max-min) + 1)) // if more than 60% of possible ids used + . = list() + for(var/i = min to max) + if(i in ids) + continue + . += i + var/id = pick(.) + ids += id + return id + else + do + . = rand(min, max) + while(. in ids) + ids += . diff --git a/code/datums/uplink/stealth_items.dm b/code/datums/uplink/stealth_items.dm index 23e0593cad..57d379d3fc 100644 --- a/code/datums/uplink/stealth_items.dm +++ b/code/datums/uplink/stealth_items.dm @@ -33,8 +33,3 @@ name = "Voice Changer" item_cost = 15 path = /obj/item/clothing/mask/gas/voice - -/datum/uplink_item/item/stealth_items/camera_floppy - name = "Camera Network Access - Floppy" - item_cost = 15 - path = /obj/item/weapon/disk/file/cameras/syndicate diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index 35bb07cbc5..1724b9469c 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -57,9 +57,6 @@ var/const/CAMERA_WIRE_NOTHING2 = 32 var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range)) C.setViewRange(new_range) - if(CAMERA_WIRE_POWER) - C.kick_viewers() // Kicks anyone watching the camera - if(CAMERA_WIRE_LIGHT) C.light_disabled = !C.light_disabled diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index 6a1e96e18a..3f48c656ba 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -39,7 +39,6 @@ var/const/BORG_WIRE_CAMERA = 16 if (BORG_WIRE_CAMERA) if(!isnull(R.camera) && !R.scrambledcodes) R.camera.status = mended - R.camera.kick_viewers() // Will kick anyone who is watching the Cyborg's camera. if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh if (R.lawupdate) @@ -59,7 +58,6 @@ var/const/BORG_WIRE_CAMERA = 16 if (BORG_WIRE_CAMERA) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) - R.camera.kick_viewers() // Kick anyone watching the Cyborg's camera R.visible_message("[R]'s camera lense focuses loudly.") R << "Your camera lense focuses loudly." diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm index b6e4146a9c..e6b4f9d456 100644 --- a/code/game/gamemodes/epidemic/epidemic.dm +++ b/code/game/gamemodes/epidemic/epidemic.dm @@ -46,14 +46,8 @@ intercepttext += "* A cure is to be researched immediately, but NanoTrasen intellectual property must be respected. To prevent knowledge of [virus_name] from falling into unauthorized hands, all medical staff that work with the pathogen must be enhanced with a NanoTrasen loyality implant.
    " - for (var/obj/machinery/computer/communications/comm in world) - if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) - var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper" - intercept.info = intercepttext - - comm.messagetitle.Add("CentCom CONFIDENTIAL REPORT") - comm.messagetext.Add(intercepttext) + //New message handling won't hurt if someone enables epidemic + post_comm_message("Cent. Com. CONFIDENTIAL REPORT", intercepttext) world << sound('sound/AI/commandreport.ogg') @@ -68,14 +62,7 @@ intercepttext += "PATHOGEN [virus_name] IS STILL PRESENT ON [station_name()]. IN COMPLIANCE WITH NANOTRASEN LAWS FOR INTERSTELLAR SAFETY, EMERGENCY SAFETY MEASURES HAVE BEEN AUTHORIZED. ALL INFECTED CREW MEMBERS ON [station_name()] ARE TO BE NEUTRALIZED AND DISPOSED OF IN A MANNER THAT WILL DESTROY ALL TRACES OF THE PATHOGEN. FAILURE TO COMPLY WILL RESULT IN IMMEDIATE DESTRUCTION OF [station_name].
    " intercepttext += "CRUISER WILL ARRIVE IN [round(cruiser_seconds()/60)] MINUTES
    " - for (var/obj/machinery/computer/communications/comm in world) - if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) - var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper" - intercept.info = intercepttext - - comm.messagetitle.Add("CentCom CONFIDENTIAL REPORT") - comm.messagetext.Add(intercepttext) + post_comm_message("Cent. Com. CONFIDENTIAL REPORT", intercepttext) world << sound('sound/AI/commandreport.ogg') diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 519a1bd5a2..4ee64999fa 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -178,6 +178,10 @@ /proc/get_centcom_access_desc(A) return get_access_desc(A) +/proc/get_access_by_id(id) + var/list/AS = get_all_access_datums_by_id() + return AS[id] + /proc/get_all_jobs() var/list/all_jobs = list() var/list/all_datums = typesof(/datum/job) diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm index b63662cd86..084b54cb5c 100644 --- a/code/game/jobs/access_datum.dm +++ b/code/game/jobs/access_datum.dm @@ -256,7 +256,12 @@ desc = "Quartermaster" region = ACCESS_REGION_SUPPLY -// /var/const/free_access_id = 43 +/var/const/access_network = 42 +/datum/access/network + id = access_network + desc = "Station Network" + region = ACCESS_REGION_RESEARCH + // /var/const/free_access_id = 43 // /var/const/free_access_id = 44 diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index bbf4720dfd..f355b9538c 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -15,12 +15,20 @@ access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, access_tox_storage, access_teleporter, access_sec_doors, access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, +<<<<<<< HEAD access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva) //VOREStation Edit minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, access_tox_storage, access_teleporter, access_sec_doors, access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva) //VOREStation Edit alt_titles = list("Research Supervisor") +======= + access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_network) + minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, + access_tox_storage, access_teleporter, access_sec_doors, + access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, + access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_network) +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd minimum_character_age = 25 minimal_player_age = 14 diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 8792a7ba35..b6251dc281 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -508,6 +508,29 @@ var/global/datum/controller/occupations/job_master if(job.req_admin_notify) H << "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp." + // EMAIL GENERATION + // Email addresses will be created under this domain name. Mostly for the looks. + var/domain = "freemail.nt" + var/sanitized_name = sanitize(replacetext(replacetext(lowertext(H.real_name), " ", "."), "'", "")) + var/complete_login = "[sanitized_name]@[domain]" + + // It is VERY unlikely that we'll have two players, in the same round, with the same name and branch, but still, this is here. + // If such conflict is encountered, a random number will be appended to the email address. If this fails too, no email account will be created. + if(ntnet_global.does_email_exist(complete_login)) + complete_login = "[sanitized_name][random_id(/datum/computer_file/data/email_account/, 100, 999)]@[domain]" + + // If even fallback login generation failed, just don't give them an email. The chance of this happening is astronomically low. + if(ntnet_global.does_email_exist(complete_login)) + to_chat(H, "You were not assigned an email address.") + H.mind.store_memory("You were not assigned an email address.") + else + var/datum/computer_file/data/email_account/EA = new/datum/computer_file/data/email_account() + EA.password = GenerateKey() + EA.login = complete_login + to_chat(H, "Your email account address is [EA.login] and the password is [EA.password]. This information has also been placed into your notes.") + H.mind.store_memory("Your email account address is [EA.login] and the password is [EA.password].") + // END EMAIL GENERATION + //Gives glasses to the vision impaired if(H.disabilities & NEARSIGHTED) var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index e8b845ca78..b3d5af5f3e 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -40,6 +40,24 @@ var/list/camera_computers_using_this = list() +/obj/machinery/camera/apply_visual(mob/living/carbon/human/M) + if(!M.client) + return + M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed) + M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline) + M.overlay_fullscreen("whitenoise",/obj/screen/fullscreen/noise) + M.machine_visual = src + return 1 + +/obj/machinery/camera/remove_visual(mob/living/carbon/human/M) + if(!M.client) + return + M.clear_fullscreen("fishbed",0) + M.clear_fullscreen("scanlines") + M.clear_fullscreen("whitenoise") + M.machine_visual = null + return 1 + /obj/machinery/camera/New() wires = new(src) assembly = new(src) @@ -93,7 +111,6 @@ stat |= EMPED set_light(0) triggerCameraAlarm() - kick_viewers() update_icon() update_coverage() START_PROCESSING(SSobj, src) @@ -246,26 +263,25 @@ user = null if(choice != 1) - //legacy support, if choice is != 1 then just kick viewers without changing status - kick_viewers() - else - set_status(!src.status) - if (!(src.status)) - if(user) - visible_message(" [user] has deactivated [src]!") - else - visible_message(" [src] clicks and shuts down. ") - playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) - icon_state = "[initial(icon_state)]1" - add_hiddenprint(user) + return + + set_status(!src.status) + if (!(src.status)) + if(user) + visible_message(" [user] has deactivated [src]!") else - if(user) - visible_message(" [user] has reactivated [src]!") - else - visible_message(" [src] clicks and reactivates itself. ") - playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) - icon_state = initial(icon_state) - add_hiddenprint(user) + visible_message(" [src] clicks and shuts down. ") + playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) + icon_state = "[initial(icon_state)]1" + add_hiddenprint(user) + else + if(user) + visible_message(" [user] has reactivated [src]!") + else + visible_message(" [src] clicks and reactivates itself. ") + playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) + icon_state = initial(icon_state) + add_hiddenprint(user) /obj/machinery/camera/proc/take_damage(var/force, var/message) //prob(25) gives an average of 3-4 hits @@ -277,7 +293,6 @@ stat |= BROKEN wires.RandomCutAll() - kick_viewers() triggerCameraAlarm() update_icon() update_coverage() @@ -292,26 +307,12 @@ if (status != newstatus) status = newstatus update_coverage() - // now disconnect anyone using the camera - //Apparently, this will disconnect anyone even if the camera was re-activated. - //I guess that doesn't matter since they couldn't use it anyway? - kick_viewers() /obj/machinery/camera/check_eye(mob/user) if(!can_use()) return -1 if(isXRay()) return SEE_TURFS|SEE_MOBS|SEE_OBJS return 0 -//This might be redundant, because of check_eye() -/obj/machinery/camera/proc/kick_viewers() - for(var/mob/O in player_list) - if (istype(O.machine, /obj/machinery/computer/security)) - var/obj/machinery/computer/security/S = O.machine - if (S.current_camera == src) - O.unset_machine() - O.reset_view(null) - O << "The screen bursts into static." - /obj/machinery/camera/update_icon() if (!status || (stat & BROKEN)) icon_state = "[initial(icon_state)]1" diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index d4b29b217e..abd0434c5e 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -26,9 +26,9 @@ var/global/list/engineering_networks = list( NETWORK_ENGINE, NETWORK_ENGINEERING, NETWORK_ENGINEERING_OUTPOST, - "Atmosphere Alarms", - "Fire Alarms", - "Power Alarms") + NETWORK_ALARM_ATMOS, + NETWORK_ALARM_FIRE, + NETWORK_ALARM_POWER) /obj/machinery/camera/network/crescent network = list(NETWORK_CRESCENT) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 5aca29433b..8cd15a260c 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -531,6 +531,13 @@ message_admins("[key_name_admin(user)] has recalled the shuttle.", 1) return + +/proc/is_relay_online() + for(var/obj/machinery/telecomms/relay/M in world) + if(M.stat == 0) + return 1 + return 0 + /obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2) var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) diff --git a/code/game/machinery/computer3/NTOS.dm b/code/game/machinery/computer3/NTOS.dm deleted file mode 100644 index a9068a634f..0000000000 --- a/code/game/machinery/computer3/NTOS.dm +++ /dev/null @@ -1,233 +0,0 @@ -/* - The Big Bad NT Operating System -*/ - -/datum/file/program/ntos - name = "NanoTrasen Operating System" - extension = "prog" - active_state = "ntos" - var/obj/item/part/computer/storage/current // the drive being viewed, null for desktop/computer - var/fileop = "runfile" - -/* - Generate a basic list of files in the selected scope -*/ - -/datum/file/program/ntos/proc/list_files() - if(!computer || !current) return null - return current.files - - -/datum/file/program/ntos/proc/filegrid(var/list/filelist) - var/dat = "" - var/i = 0 - for(var/datum/file/F in filelist) - if(!F.hidden_file) - i++ - if(i==1) - dat += "" - if(i>= 6) - i = 0 - dat += "" - continue - dat += {" - "} - - dat += "
    -
    -
    - [F.name] -
    -
    " - return dat - -// -// I am separating this from filegrid so that I don't have to -// make metadata peripheral files -// -/datum/file/program/ntos/proc/desktop(var/peripheralop = "viewperipheral") - var/dat = "" - var/i = 0 - var/list/peripherals = list(computer.hdd,computer.floppy,computer.cardslot) - for(var/obj/item/part/computer/C in peripherals) - if(!istype(C)) continue - i++ - if(i==1) - dat += "" - if(i>= 6) - i = 0 - dat += "" - continue - dat += {" - "} - - dat += "
    - - \icon[C]
    - [C.name] -
    -
    " - return dat - - -/datum/file/program/ntos/proc/window(var/title,var/buttonbar,var/content) - return {" -
    -
    [title]
    -
    [buttonbar]
    -
    [content]
    -
    "} - -/datum/file/program/ntos/proc/buttonbar(var/type = 0) - switch(type) - if(0) // FILE OPERATIONS - return {""} - -/datum/file/program/ntos/interact() - if(!interactable()) - return - var/dat = {" - - - Operating System - - - -
    "} - - - dat += generate_status_bar() - var/list/files = list_files() - if(current) - dat +=window(current.name,buttonbar(),filegrid(files)) - else - dat += desktop() - - dat += "
    " - - usr << browse(dat, "window=\ref[computer];size=670x510") - onclose(usr, "\ref[computer]") - - // STATUS BAR - // Small 16x16 icons representing status of components, etc. - // Currently only used by battery icon - // TODO: Add more icons! -/datum/file/program/ntos/proc/generate_status_bar() - var/dat = "" - - // Battery level icon - switch(computer.check_battery_status()) - if(-1) - dat += "" - if(0 to 5) - dat += "" - if(6 to 20) - dat += "" - if(21 to 40) - dat += "" - if(41 to 60) - dat += "" - if(61 to 80) - dat += "" - if(81 to 100) - dat += "" - dat += "
    " - return dat - -/datum/file/program/ntos/Topic(href, list/href_list) - if(!interactable() || ..(href,href_list)) - return - - if("viewperipheral" in href_list) // open drive, show status of peripheral - var/obj/item/part/computer/C = locate(href_list["viewperipheral"]) in src.computer - if(!istype(C)) - return - - if(istype(C,/obj/item/part/computer/storage)) - current = C - interact() - return - // else ??? - if(istype(C,/obj/item/part/computer/cardslot)) - computer.cardslot.remove(usr) - interact() - return - - // distinct from close, this is the file dialog window - if("winclose" in href_list) - current = null - interact() - return - -#undef MAX_ROWS -#undef MAX_COLUMNS diff --git a/code/game/machinery/computer3/bios.dm b/code/game/machinery/computer3/bios.dm deleted file mode 100644 index c5b69e755b..0000000000 --- a/code/game/machinery/computer3/bios.dm +++ /dev/null @@ -1,176 +0,0 @@ -/* - Okay so my last effort to have a central BIOS function was interesting - but completely unmaintainable, I have scrapped it. - - The parts that were actually useful will be put here in functions instead. - If we want a central bios function we can add one that just indexes them. - That should at least allow sensible debugging. -*/ - -/obj/machinery/computer3 - - /* - interactable(user): performs all standard sanity checks - Call in topic() and interact(). - */ -/obj/machinery/computer3/proc/interactable(var/mob/user) - if( !src || !user || stat || user.stat || user.lying || user.blinded ) - return 0 - if(!program) - return 0 - if(!isturf(loc) || !isturf(user.loc)) // todo handheld maybe - return 0 - if(user.restrained()) - to_chat(user, "You need a free hand!") - return 0 - - if(issilicon(user) &&!program.ai_allowed ) - to_chat(user, "You are forbidden from accessing this program.") - return 0 - if(!ishuman(user) && program.human_controls) - to_chat(user, "Your body can't work the controls!") - return 0 - - - if(!in_range(src,user) && (!program.human_controls || !istype(user.get_active_hand(),/obj/item/tk_grab))) - // telekinesis check - to_chat(user, "It's too complicated to work at a distance!") - return 0 - - add_fingerprint(user) - user.set_machine(src) - return 1 - - /* - Deduplicates an item list and gives you range and direction. - This is used for networking so you can determine which of several - identically named objects you're referring to. - */ -/obj/machinery/computer3/proc/format_atomlist(var/list/atoms) - var/list/output = list() - for(var/atom/A in atoms) - var/title = "[A] (Range [get_dist(A,src)] meters, [dir2text(get_dir(src,A))])" - output[title] = A - return output - - /* - This is used by the camera monitoring program to see if you're still in range - */ -/obj/machinery/computer3/check_eye(var/mob/user as mob) - if(!interactable(user) || user.machine != src) - if(user.machine == src) - user.unset_machine() - return -1 - - var/datum/file/program/security/S = program - if( !istype(S) || !S.current || !S.current.status || !camnet ) - if( user.machine == src ) - user.unset_machine() - return -1 - - user.reset_view(S.current, 0) - return 0 - - /* - List all files, including removable disks and data cards - (I don't know why but I don't want to rip data cards out. - It just seems... interesting?) - */ -/obj/machinery/computer3/proc/list_files(var/typekey = null) - var/list/files = list() - if(hdd) - files += hdd.files - if(floppy && floppy.inserted) - files += floppy.inserted.files - if(cardslot && istype(cardslot.reader,/obj/item/weapon/card/data)) - files += cardslot.reader:files - if(!ispath(typekey)) - return files - - var/i = 1 - while(i<=files.len) - if(istype(files[i],typekey)) - i++ - continue - files.Cut(i,i+1) - return files - - /* - Crash the computer with an error. - Todo: redo - */ -/obj/machinery/computer3/proc/Crash(var/errorcode = PROG_CRASH) - if(!src) - return null - - switch(errorcode) - if(PROG_CRASH) - if(usr) - usr << "The program crashed!" - usr << browse(null,"\ref[src]") - Reset() - - if(MISSING_PERIPHERAL) - Reset() - if(usr) - usr << browse("

    ERROR: Missing or disabled component

    A hardware failure has occured. Please insert or replace the missing or damaged component and restart the computer.","window=\ref[src]") - - if(BUSTED_ASS_COMPUTER) - Reset() - os.error = BUSTED_ASS_COMPUTER - if(usr) - usr << browse("

    ERROR: Missing or disabled component

    A hardware failure has occured. Please insert or replace the missing or damaged component and restart the computer.","window=\ref[src]") - - if(MISSING_PROGRAM) - Reset() - if(usr) - usr << browse("

    ERROR: No associated program

    This file requires a specific program to open, which cannot be located. Please install the related program and try again.","window=\ref[src]") - - if(FILE_DRM) - Reset() - if(usr) - usr << browse("

    ERROR: File operation prohibited

    Copy protection exception: missing authorization token.","window=\ref[src]") - - if(NETWORK_FAILURE) - Reset() - if(usr) - usr << browse("

    ERROR: Networking exception: Unable to connect to remote host.

    ","window=\ref[src]") - - else - if(usr) - usr << "The program crashed!" - usr << browse(null,"\ref[src]") - testing("computer/Crash() - unknown error code [errorcode]") - Reset() - return null - - #define ANY_DRIVE 0 - #define PREFER_FLOPPY 1 - #define PREFER_CARD 2 - #define PREFER_HDD 4 - - - // required_location: only put on preferred devices -/obj/machinery/computer3/proc/writefile(var/datum/file/F, var/where = ANY_DRIVE, var/required_location = 0) - if(where != ANY_DRIVE) - if((where&PREFER_FLOPPY) && floppy && floppy.addfile(F)) - return 1 - if((where&PREFER_CARD) && istype(cardslot, /obj/item/part/computer/cardslot/dual)) - var/obj/item/part/computer/cardslot/dual/D = cardslot - if(D.addfile(F)) - return 1 - if((where&PREFER_HDD) && hdd && hdd.addfile(F)) - return 1 - - if(required_location) - return 0 - - if(floppy && floppy.addfile(F)) - return 1 - if(istype(cardslot, /obj/item/part/computer/cardslot/dual)) - var/obj/item/part/computer/cardslot/dual/D = cardslot - if(D.addfile(F)) - return 1 - if(hdd && hdd.addfile(F)) - return 1 - return 0 diff --git a/code/game/machinery/computer3/buildandrepair.dm b/code/game/machinery/computer3/buildandrepair.dm deleted file mode 100644 index 928675769c..0000000000 --- a/code/game/machinery/computer3/buildandrepair.dm +++ /dev/null @@ -1,303 +0,0 @@ -// Computer3 circuitboard specifically -/obj/item/part/computer/circuitboard - density = 0 - anchored = 0 - w_class = ITEMSIZE_SMALL - name = "Circuit board" - icon = 'icons/obj/module.dmi' - icon_state = "id_mod" - item_state = "electronic" - origin_tech = list(TECH_DATA = 2) - var/id = null - var/frequency = null - var/build_path = null - var/board_type = "computer" - var/list/req_components = null - var/powernet = null - var/list/records = null - - var/datum/file/program/OS = new/datum/file/program/ntos - -/obj/machinery/computer3/proc/disassemble(mob/user as mob) // todo - return - - -/obj/structure/computer3frame - density = 1 - anchored = 0 - name = "computer frame" - icon = 'icons/obj/stock_parts.dmi' - icon_state = "0" - var/state = 0 - - var/obj/item/part/computer/circuitboard/circuit = null - var/completed = /obj/machinery/computer - - // Computer3 components - a carbon copy of the list from - // computer.dm; however, we will need to check to make sure - // we don't install more components than the computer frame - // can handle. This will be different for certain formfactors. - - var/max_components = 4 - var/list/components = list() - - // Storage - var/obj/item/part/computer/storage/hdd/hdd = null - var/obj/item/part/computer/storage/removable/floppy = null - // Networking - var/obj/item/part/computer/networking/radio/radio = null // not handled the same as other networks - var/obj/item/part/computer/networking/cameras/camnet = null // just plain special - var/obj/item/part/computer/networking/net = null // Proximity, area, or cable network - var/obj/item/part/computer/networking/subspace/centcom = null // only for offstation communications - - // Card reader - note the HoP reader is a subtype - var/obj/item/part/computer/cardslot/cardslot = null - - // Misc & special purpose - var/obj/item/part/computer/ai_holder/cradle = null - var/obj/item/part/computer/toybox/toybox = null - - // Battery must be installed BEFORE wiring the computer. - // if installing it in an existing computer, you will have to - // get back to this state first. - var/obj/item/weapon/cell/battery = null - -/obj/structure/computer3frame/server - name = "server frame" - completed = /obj/machinery/computer3/server - max_components = 6 -/obj/structure/computer3frame/wallcomp - name = "wall-computer frame" - completed = /obj/machinery/computer3/wall_comp - max_components = 3 -/obj/structure/computer3frame/laptop - name = "laptop frame" - completed = /obj/machinery/computer3/laptop - max_components = 3 - -/obj/structure/computer3frame/attackby(obj/item/P as obj, mob/user as mob) - switch(state) - if(0) - if(P.is_wrench()) - playsound(src.loc, P.usesound, 50, 1) - if(do_after(user, 20 * P.toolspeed)) - to_chat(user, "You wrench the frame into place.") - src.anchored = 1 - src.state = 1 - if(istype(P, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = P - if(!WT.remove_fuel(0, user)) - to_chat(user, "The welding tool must be on to complete this task.") - return - playsound(src.loc, WT.usesound, 50, 1) - if(do_after(user, 20 * WT.toolspeed)) - if(!src || !WT.isOn()) return - to_chat(user, "You deconstruct the frame.") - new /obj/item/stack/material/steel( src.loc, 5 ) - qdel(src) - if(1) - if(P.is_wrench()) - playsound(src.loc, P.usesound, 50, 1) - if(do_after(user, 20 * P.toolspeed)) - to_chat(user, "You unfasten the frame.") - src.anchored = 0 - src.state = 0 - if(istype(P, /obj/item/weapon/circuitboard) && !circuit) - var/obj/item/weapon/circuitboard/B = P - if(B.board_type == "computer") - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - to_chat(user, "You place the circuit board inside the frame.") - src.icon_state = "1" - src.circuit = P - user.drop_item() - P.loc = src - else - to_chat(user, "This frame does not accept circuit boards of this type!") - if(P.is_screwdriver() && circuit) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You screw the circuit board into place.") - src.state = 2 - src.icon_state = "2" - if(P.is_crowbar() && circuit) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You remove the circuit board.") - src.state = 1 - src.icon_state = "0" - circuit.loc = src.loc - src.circuit = null - if(2) - if(P.is_screwdriver() && circuit) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You unfasten the circuit board.") - src.state = 1 - src.icon_state = "1" - - if(P.is_crowbar()) - if(battery) - playsound(src.loc, P.usesound, 50, 1) - if(do_after(10 * P.toolspeed)) - battery.loc = loc - to_chat(user, "You remove [battery].") - battery = null - else - to_chat(user, "There's no battery to remove!") - - if(istype(P, /obj/item/weapon/cell)) - if(!battery) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(do_after(5)) - battery = P - P.loc = src - to_chat(user, "You insert [battery].") - else - to_chat(user, "There's already \an [battery] in [src]!") - - - if(istype(P, /obj/item/stack/cable_coil)) - if(P:amount >= 5) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(do_after(user, 20)) - if(P) - P:amount -= 5 - if(!P:amount) qdel(P) - to_chat(user, "You add cables to the frame.") - src.state = 3 - src.icon_state = "3" - if(3) - if(P.is_wirecutter()) - if(components.len) - to_chat(user, "There are parts in the way!") - return - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You remove the cables.") - src.state = 2 - src.icon_state = "2" - var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc ) - A.amount = 5 - - if(P.is_crowbar()) - remove_peripheral() - - if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass") - var/obj/item/stack/S = P - if(S.amount >= 2) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(do_after(user, 20)) - if(S) - S.use(2) - to_chat(user, "You put in the glass panel.") - src.state = 4 - src.icon_state = "4" - if(4) - if(P.is_crowbar()) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You remove the glass panel.") - src.state = 3 - src.icon_state = "3" - new /obj/item/stack/material/glass( src.loc, 2 ) - if(P.is_screwdriver()) - playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You connect the monitor.") - var/obj/machinery/computer3/B = new src.circuit.build_path ( src.loc, built=1 ) - /*if(circuit.powernet) B:powernet = circuit.powernet - if(circuit.id) B:id = circuit.id - //if(circuit.records) B:records = circuit.records - if(circuit.frequency) B:frequency = circuit.frequency - if(istype(circuit,/obj/item/weapon/circuitboard/supplycomp)) - var/obj/machinery/computer/supplycomp/SC = B - var/obj/item/weapon/circuitboard/supplycomp/C = circuit - SC.can_order_contraband = C.contraband_enabled*/ - B.circuit = circuit - circuit.loc = B - if(circuit.OS) - circuit.OS.computer = B - B.RefreshParts() // todo - qdel(src) - -/* - This will remove peripherals if you specify one, but the main function is to - allow the user to remove a part specifically. -*/ -/obj/structure/computer3frame/proc/remove_peripheral(var/obj/item/I = null) - if(!components || !components.len) - to_chat(usr, "There are no components in [src] to take out!") - return 0 - if(!I) - I = input(usr, "Remove which component?","Remove component", null) as null|obj in components - - if(I) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - if(do_after(usr,25)) - if(I==hdd) - components -= hdd - hdd.loc = loc - hdd = null - else if(I==floppy) - components -= floppy - floppy.loc = loc - floppy = null - else if(I==radio) - components -= radio - radio.loc = loc - radio = null - else if(I==camnet) - components -= camnet - camnet.loc = loc - camnet = null - else if(I==net) - components -= net - net.loc = loc - net = null - else if(I==cradle) - components -= cradle - cradle.loc = loc - cradle = null - else if(I==toybox) - components -= toybox - toybox.loc = loc - toybox = null - else - warning("Erronous component in computerframe/remove_peripheral: [I]") - I.loc = loc - to_chat(usr, "You remove [I]") - return 1 - return 0 - -/obj/structure/computer3frame/proc/insert_peripheral(var/obj/item/I) - if(components.len >= max_components) - to_chat(usr, "There isn't room in [src] for another component!") - return 0 - switch(I.type) - if(/obj/item/part/computer/storage/hdd) - if(hdd) - to_chat(usr, "There is already \an [hdd] in [src]!") - return 0 - hdd = I - components += hdd - hdd.loc = src - if(/obj/item/part/computer/storage/removable) - if(floppy) - to_chat(usr, "There is already \an [floppy] in [src]!") - return 0 - floppy = I - components += floppy - floppy.loc = src - if(/obj/item/part/computer/networking/radio) - if(radio) - to_chat(usr, "There is already \an [radio] in [src]!") - return 0 - radio = I - components += radio - radio.loc = src - if(/obj/item/part/computer/networking/cameras) - if(camnet) - to_chat(usr, "There is already \an [camnet] in [src]!") - return 0 - camnet = I - components += camnet - camnet.loc = src - if(/obj/item/part/computer/networking) - if(net) - to_chat(usr, "There is already \an [net] in [src]!") - - diff --git a/code/game/machinery/computer3/component.dm b/code/game/machinery/computer3/component.dm deleted file mode 100644 index 3c8d972825..0000000000 --- a/code/game/machinery/computer3/component.dm +++ /dev/null @@ -1,230 +0,0 @@ - -/* - Objects used to construct computers, and objects that can be inserted into them, etc. - - TODO: - * Synthesizer part (toybox, injectors, etc) -*/ - - - -/obj/item/part/computer - name = "computer part" - desc = "Holy jesus you donnit now" - gender = PLURAL - icon = 'icons/obj/stock_parts.dmi' - icon_state = "hdd1" - w_class = ITEMSIZE_SMALL - - var/emagged = 0 - - // the computer that this device is attached to - var/obj/machinery/computer3/computer - - // If the computer is attacked by an item it will reference this to decide which peripheral(s) are affected. - var/list/attackby_types = list() - -/obj/item/part/computer/proc/allow_attackby(var/obj/item/I, var/mob/user) - for(var/typepath in attackby_types) - if(istype(I, typepath)) - return 1 - return 0 - -/obj/item/part/computer/proc/init(var/obj/machinery/computer/target) - computer = target - // continue to handle all other type-specific procedures - -/* - Below are all the miscellaneous components - For storage drives, see storage.dm - For networking parts, see -*/ - -/obj/item/part/computer/ai_holder - name = "intelliCore computer module" - desc = "Contains a specialized nacelle for dealing with highly sensitive equipment without interference." - - attackby_types = list(/obj/item/device/aicard) - - var/mob/living/silicon/ai/occupant = null - var/busy = 0 - -/obj/item/part/computer/ai_holder/attackby(obj/I as obj,mob/user as mob) - if(computer && !computer.stat) - if(istype(I, /obj/item/device/aicard)) - var/obj/item/device/aicard/card = I - var/mob/living/silicon/ai/comp_ai = locate() in src - var/mob/living/silicon/ai/card_ai = locate() in card - - if(istype(comp_ai)) - if(busy) - to_chat(user, "ERROR: Reconstruction in progress.") - return - - if(card.grab_ai(comp_ai, user)) - occupant = null - - else if(istype(card_ai)) - load_ai(card_ai,card,user) - - if(computer.program) - computer.program.update_icon() - - computer.update_icon() - ..() - return - -/obj/item/part/computer/ai_holder/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user) - - if(!istype(transfer)) - return - - // Transfer over the AI. - to_chat(transfer, "You have been transferred into a mobile terminal. Sadly, there is no remote access from here.") - to_chat(user, "Transfer successful: [transfer.name] placed within mobile terminal.") - - transfer.loc = src - transfer.cancel_camera() - transfer.control_disabled = 1 - occupant = transfer - - if(card) - card.clear() - - -/* - ID computer cardslot - reading and writing slots -*/ - -/obj/item/part/computer/cardslot - name = "magnetic card slot" - desc = "Contains a slot for reading magnetic swipe cards." - - var/obj/item/weapon/card/reader = null - - attackby_types = list(/obj/item/weapon/card) - -/obj/item/part/computer/cardslot/attackby(var/obj/item/I as obj, var/mob/user) - if(istype(I,/obj/item/weapon/card) && computer) - if(istype(I,/obj/item/weapon/card/emag) && !reader) // emag reader slot - user.visible_message("[computer]'s screen flickers for a moment.","You insert \the [I]. After a moment, the card ejects itself, and [computer] beeps.","[computer] beeps.") - computer.emagged = 1 - return - - insert(I, user) - return - ..(I,user) - - // cardslot.insert(card, slot) - // card: The card obj you want to insert (usually your ID) - // user: The mob inserting the card -/obj/item/part/computer/cardslot/proc/insert(var/obj/item/weapon/card/card, var/mob/user) - if(equip_to_reader(card, user)) - to_chat(user, "You insert the card into reader slot") - return 1 - to_chat(user, "There is already something in the reader slot.") - return 0 - - - // Usage of insert() preferred, as it also tells result to the user. -/obj/item/part/computer/cardslot/proc/equip_to_reader(var/obj/item/weapon/card/card, var/mob/living/L) - if(!reader) - L.drop_item() - card.loc = src - reader = card - return 1 - return 0 - - // cardslot.remove(slot) - // user: The mob removing the card -/obj/item/part/computer/cardslot/proc/remove(var/mob/user) - if(remove_reader(user)) - to_chat(user, "You remove the card from reader slot") - return 1 - to_chat(user, "There is nothing in the reader slot") - return 0 - -/obj/item/part/computer/cardslot/proc/remove_reader(var/mob/living/L) - if(reader) - if(ishuman(L) && !L.get_active_hand()) - L.put_in_hands(reader) - else - reader.loc = get_turf(computer) - reader = null - return 1 - return 0 - - // Authorizes the user based on the computer's requirements -/obj/item/part/computer/cardslot/proc/authenticate() - return computer.check_access(reader) - - -/obj/item/part/computer/cardslot/dual - name = "magnetic card reader" - desc = "Contains slots for inserting magnetic swipe cards for reading and writing." - - var/obj/item/weapon/card/writer = null - - - // Ater: Single- and dual-slot card readers have separate functions. - // According to OOP principles, they should be separate classes and use inheritance, polymorphism. - - -/obj/item/part/computer/cardslot/dual/proc/equip_to_writer(var/obj/item/weapon/card/card, var/mob/living/L) - if(!writer) - L.drop_item() - card.loc = src - writer = card - return 1 - return 0 - -/obj/item/part/computer/cardslot/dual/proc/remove_from_writer(var/mob/living/L) - if(writer) - if(ishuman(L) && !L.get_active_hand()) - L.put_in_hands(writer) - else - writer.loc = get_turf(computer) - writer = null - return 1 - return 0 - - // cardslot.insert(card, slot) - // card: The card obj you want to insert (usually your ID) - // user: The mob inserting the card - // slot: Which slot to insert into (1->Reader, 2->Writer, 3->Auto) Default 3 -/obj/item/part/computer/cardslot/dual/insert(var/obj/item/weapon/card/card, var/mob/user, var/slot = 3) - if(slot != 2) - if(..(card, user)) - return 1 - - if(slot != 1) - if(equip_to_writer(card, user)) - to_chat(user, "You insert the card into writer slot") - return 1 - else - to_chat(user, "There is already something in the writer slot.") - return 0 - - // cardslot/dual.insert(card, slot) - // user: The mob removing the card - // slot: Which slot to remove from (1->Reader, 2->Writer, 3->Both, 4->Reader and if empty, Writer) Default 3 -/obj/item/part/computer/cardslot/dual/remove(var/mob/user, var/slot = 3) - if(slot != 2) - if(..(user) && slot != 3) // ..() probes reader - return 1 // slot is either 1 or 4, where we only probe reader if there's anything in it - - if(slot != 1) // If slot is 1, then we only probe reader - if(remove_from_writer(user)) // Probe writer - to_chat(user, "You remove the card from the writer slot") - return 1 - to_chat(user, "There is nothing in the writer slot.") - return 0 - -/obj/item/part/computer/cardslot/dual/proc/addfile(var/datum/file/F) - if(!istype(writer,/obj/item/weapon/card/data)) - return 0 - var/obj/item/weapon/card/data/D = writer - if(D.files.len > 3) - return 0 - D.files += F - return 1 diff --git a/code/game/machinery/computer3/computer.dm b/code/game/machinery/computer3/computer.dm deleted file mode 100644 index c9d8eb22de..0000000000 --- a/code/game/machinery/computer3/computer.dm +++ /dev/null @@ -1,459 +0,0 @@ -/obj/machinery/computer3 - name = "computer" - icon = 'icons/obj/computer3.dmi' - icon_state = "frame" - density = 1 - anchored = 1.0 - - idle_power_usage = 20 - active_power_usage = 50 - - var/allow_disassemble = 1 - var/legacy_icon = 0 // if 1, use old style icons - var/show_keyboard = 1 - - // These is all you should need to change when creating a new computer. - // If there is no default program, the OS will run instead. - // If there is no hard drive, but there is a default program, the OS rom on - // the circuitboard will be overridden. - - // For these, typepaths are used, NOT objects - - var/default_prog = null // the program running when spawned - var/list/spawn_files = list() // files added when spawned - var/list/spawn_parts = list(/obj/item/part/computer/storage/hdd/big) // peripherals to spawn - - // Computer3 components - put an object in them in New() when not built - // I used to have a more pliable /list, but the ambiguities - // there in how many of what you had was killing me, especially - // when you had to search the list to find what you had. - - // Mostly decorative, holds the OS rom - var/obj/item/part/computer/circuitboard/circuitb - - // Storage - var/obj/item/part/computer/storage/hdd/hdd = null - var/obj/item/part/computer/storage/removable/floppy = null - // Networking - var/obj/item/part/computer/networking/radio/radio = null // not handled the same as other networks - var/obj/item/part/computer/networking/cameras/camnet = null // just plain special - var/obj/item/part/computer/networking/net = null // Proximity, area, or cable network - - // Card reader - note the HoP reader is a subtype - var/obj/item/part/computer/cardslot/cardslot = null - - // Misc & special purpose - var/obj/item/part/computer/ai_holder/cradle = null - var/obj/item/part/computer/toybox/toybox = null - - - // Legacy variables - // camera networking - overview (???) - var/mapping = 0 - var/last_pic = 1.0 - - // Purely graphical effect - var/icon/kb = null - - // These are necessary in order to consolidate all computer types into one - var/datum/wires/wires = null - var/powernet = null - - // Used internally - var/datum/file/program/program = null // the active program (null if defaulting to os) - var/datum/file/program/os = null // the base code of the machine (os or hardcoded program) - - // If you want the computer to have a UPS, add a battery during construction. This is useful for things like - // the comms computer, solar trackers, etc, that should function when all else is off. - // Laptops will require batteries and have no mains power. - - var/obj/item/weapon/cell/battery = null // uninterruptible power supply aka battery - -/obj/machinery/computer3/New(var/L, var/built = 0) - ..() - spawn(2) - power_change() - - if(show_keyboard) - var/kb_state = "kb[rand(1,15)]" - kb = image('icons/obj/computer3.dmi',icon_state=kb_state) - overlays += kb - - if(!built) - if(!circuitb || !istype(circuitb)) - circuitb = new(src) - if(circuitb.OS) - os = circuitb.OS - circuitb.OS.computer = src - else - os = null - - // separated into its own function because blech - spawn_parts() - - if(default_prog) // Add the default software if applicable - var/datum/file/program/P = new default_prog - if(hdd) - hdd.addfile(P,1) - program = P - if(!os) - os = P - else if(floppy) - floppy.inserted = new(floppy) - floppy.files = floppy.inserted.files - floppy.addfile(P) - program = P - else - circuitb.OS = P - circuitb.OS.computer = src - os = circuitb.OS - circuitb.name = "Circuitboard ([P])" - - if(hdd) // Spawn files - for(var/typekey in spawn_files) - hdd.addfile(new typekey,1) - - update_icon() - -/obj/machinery/computer3/verb/ResetComputer() - set name = "Reset Computer" - set category = "Object" - set src in view(1) - - if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) - to_chat(usr, "You can't do that.") - return - - if(!Adjacent(usr)) - to_chat(usr, "You can't reach it.") - return - - Reset() - -/obj/machinery/computer3/proc/update_spawn_files() - for(var/typekey in spawn_files) - hdd.addfile(new typekey,1) - -/obj/machinery/computer3/proc/spawn_parts() - for(var/typekey in spawn_parts) - if(ispath(typekey,/obj/item/part/computer/storage/removable)) - if(floppy) - continue - floppy = new typekey(src) - floppy.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/storage/hdd)) - if(hdd) - continue - hdd = new typekey(src) - hdd.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/networking/cameras)) - if(camnet) - continue - camnet = new typekey(src) - camnet.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/networking/radio)) - if(radio) - continue - radio = new typekey(src) - radio.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/networking)) - if(net) - continue - net = new typekey(src) - net.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/cardslot)) - if(cardslot) - continue - cardslot = new typekey(src) - cardslot.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/ai_holder)) - if(cradle) - continue - cradle = new typekey(src) - cradle.init(src) - continue - - if(ispath(typekey,/obj/item/part/computer/toybox)) - if(toybox) - continue - toybox = new typekey(src) - toybox.init(src) - continue - - if(ispath(typekey,/obj/item/weapon/cell)) - if(battery) - continue - battery = new typekey(src) - continue - -/obj/machinery/computer3/proc/Reset(var/error = 0) - for(var/mob/living/M in range(1)) - M << browse(null,"window=\ref[src]") - if(program) - program.Reset() - program = null - req_access = os.req_access - update_icon() - - // todo does this do enough - -/obj/machinery/computer3/emp_act(severity) - if(prob(20/severity)) set_broken() - ..() - - -/obj/machinery/computer3/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if (prob(25)) - qdel(src) - return - if (prob(50)) - for(var/x in verbs) - verbs -= x - set_broken() - if(3.0) - if (prob(25)) - for(var/x in verbs) - verbs -= x - set_broken() - else - return - - /* - Computers have the capability to use a battery backup. - Note that auto_use_power's return value is strictly whether - or not it is successfully powered. - - This allows laptops, and also allows you to create computers that - remain active when: - - * the APC is destroy'd, emag'd, malf'd, emp'd, ninja'd etc - * the computer was built in an unpowered zone - * the station power is out, cables are cut, etc - - By default, most computers will NOT spawn with a battery backup, and - SHOULD not. Players can take apart a computer to insert the battery - if they want to ensure, for example, the AI upload remains when the - power is cut off. - - Make sure to use use_power() a bunch in peripherals code - */ -/obj/machinery/computer3/auto_use_power() - if(!powered(power_channel)) - if(battery && battery.charge > 0) - if(use_power == 1) - battery.use(idle_power_usage) - else - battery.use(active_power_usage) - return 1 - return 0 - if(src.use_power == 1) - use_power(idle_power_usage,power_channel) - else if(src.use_power >= 2) - use_power(active_power_usage,power_channel) - return 1 - -/obj/machinery/computer3/use_power(var/amount, var/chan = -1) - if(chan == -1) - chan = power_channel - - var/area/A = get_area(loc) - if(istype(A) && A.powered(chan)) - A.use_power(amount, chan) - else if(battery && battery.charge > 0) - battery.use(amount) - -/obj/machinery/computer3/power_change() - if( !powered(power_channel) && (!battery || battery.charge <= 0) ) - stat |= NOPOWER - else - stat &= ~NOPOWER - -/obj/machinery/computer3/process() - auto_use_power() - power_change() - update_icon() - if(stat & (NOPOWER|BROKEN)) - return - - if(program) - program.process() - return - - if(os) - program = os - os.process() - return - -/obj/machinery/computer3/proc/set_broken() - icon_state = "computer_b" - stat |= BROKEN - if(program) - program.error = BUSTED_ASS_COMPUTER - if(os) - os.error = BUSTED_ASS_COMPUTER - -/obj/machinery/computer3/attackby(obj/item/I as obj, mob/user as mob) - if(I.is_screwdriver() && allow_disassemble) - disassemble(user) - return - - /* - +++++++++++ - |IMPORTANT| If you add a peripheral, put it in this list - +++++++++++ -------------------------------------------- - */ - - var/list/p_list = list() - for(var/obj/item/part/computer/C in src) - if(!isnull(C) && C.allow_attackby(I,user)) - p_list += C - if(p_list.len) - var/obj/item/part/computer/P = null - if(p_list.len == 1) - P = p_list[1] - else - P = input(user,"Which component?") as null|anything in p_list - - if(P) - P.attackby(I,user) - return - ..() - -/obj/machinery/computer3/attack_hand(var/mob/user as mob) - if(stat) - Reset() - return - - // I don't want to deal with computers that you can't walk up to and use - // there is still cardauth anyway - //if(!allowed(user)) - // return - - if(program) - if(program.computer != src) // floppy disk may have been removed, etc - Reset() - attack_hand(user) - return - if(program.error) - Crash(program.error) - return - user.set_machine(src) - program.attack_hand(user) // will normally translate to program/interact() - return - - if(os) - program = os - user.set_machine(src) - os.attack_hand(user) - return - - to_chat(user, "\The [src] won't boot!") - -/obj/machinery/computer3/attack_ai(var/mob/user as mob) // copypasta because server racks lose attack_hand() - if(stat) - Reset() - return - - if(program) - if(program.computer != src) // floppy disk may have been removed, etc - Reset() - attack_ai(user) - return - if(program.error) - Crash(program.error) - return - user.set_machine(src) - program.attack_hand(user) // will normally translate to program/interact() - return - - if(os) - program = os - user.set_machine(src) - os.attack_hand(user) - return - - to_chat(user, "\The [src] won't boot!") - -/obj/machinery/computer3/interact() - if(stat) - Reset() - return - if(!allowed(usr) || !usr in view(1)) - usr.unset_machine() - return - - if(program) - program.interact() - return - - if(os) - program = os - os.interact() - return - -/obj/machinery/computer3/update_icon() - if(legacy_icon) - icon_state = initial(icon_state) - // Broken - if(stat & BROKEN) - icon_state += "b" - - // Powered - else if(stat & NOPOWER) - icon_state = initial(icon_state) - icon_state += "0" - return - if(stat) - overlays.Cut() - return - if(program) - overlays = list(program.overlay) - if(show_keyboard) - overlays += kb - name = "[program.name] [initial(name)]" - else if(os) - overlays = list(os.overlay) - if(show_keyboard) - overlays += kb - name = initial(name) - else - var/global/image/generic = image('icons/obj/computer3.dmi',icon_state="osod") // orange screen of death - overlays = list(generic) - if(show_keyboard) - overlays += kb - name = initial(name) + " (orange screen of death)" - -//Returns percentage of battery charge remaining. Returns -1 if no battery is installed. -/obj/machinery/computer3/proc/check_battery_status() - if (battery) - var/obj/item/weapon/cell/B = battery - return round(B.charge / (B.maxcharge / 100)) - else - return -1 - - - -/obj/machinery/computer3/wall_comp - name = "terminal" - icon = 'icons/obj/computer3.dmi' - icon_state = "wallframe" - density = 0 - pixel_y = -3 - show_keyboard = 0 diff --git a/code/game/machinery/computer3/computer3_notes.dm b/code/game/machinery/computer3/computer3_notes.dm deleted file mode 100644 index c27410e637..0000000000 --- a/code/game/machinery/computer3/computer3_notes.dm +++ /dev/null @@ -1,34 +0,0 @@ -/* - 1. Do NOT confuse Computer.Crash(errorcode) with byond CRASH(message) - 2 Do NOT talk about fight club. - 3 If this if your first night here, you have to crash the computer. - 4 Where am I? - 5 Someone help me, please... - 6. Be sure to use computer.use_power() appropriately. Laptops should run out of battery occasionally. - 7 Everyone fights, no-one quits. If you don't do your job, I'll crash you myself. - 6 Don't allow more than 42 angels to dance on the head of a pin. - 5. Once a computer has spawned, they are just like the rest, except when they aren't. - 4 Get me four glasses of apple juice. - 3. Components are only added or removed when disassembled and rebuilt. However, they may be EMP'd. - 2 Only you can prevent friendly fire. - 1 Do not talk about fight club. - 2. If a component subtype needs to be handled separately (removable drives, radio networks), declare it separately. - 3 Television rules the nation - 4. interactable() does all the sanity checks, adds fingerprints, sets machines, initializes popup, and makes a damn fine pot of coffee. - 5 Love conquers all. - 6 If at all possible, do a barrel roll. - 7. Don't forget to use the network verify function to make sure you still have access to remote machines. - - - - - TODO: - * "Nothing left to call the shuttle" check - * Communications terminal printing - move it to a printer of some sort? Make a printer peripheral--but then which ones print the comms? - * Remove the partially transparent border on program screens, as it clashes with some frames - * Chop the corners on program screens now that screen sizes are standard - * ntos: - * Needs a text editor/viewer - * Needs file copy and file move - I think I know how I'm gonna do it - * Needs a peripheral view (eject disks and cards, network actions, ???) -*/ \ No newline at end of file diff --git a/code/game/machinery/computer3/computers/HolodeckControl.dm b/code/game/machinery/computer3/computers/HolodeckControl.dm deleted file mode 100644 index da3c2416fd..0000000000 --- a/code/game/machinery/computer3/computers/HolodeckControl.dm +++ /dev/null @@ -1,245 +0,0 @@ -/obj/machinery/computer3/HolodeckControl - default_prog = /datum/file/program/holodeck - - -// Todo: I personally would like to add a second holodeck in the theater for making appropriate playgrounds. -// perhaps a holodeck association keyfile? -// One more thing while I'm here -// C3 allows multiple computers to run this program, but it was designed on the assumption that only one would, ever -// I am not going to add or remove anything right now, I'm just porting it - - -/datum/file/program/holodeck - name = "Holodeck Control Console" - desc = "Used to control a nearby holodeck." - active_state = "holocontrol" - var/area/linkedholodeck = null - var/area/target = null - var/active = 0 - var/list/holographic_items = list() - var/damaged = 0 - var/last_change = 0 - var/emagged = 0 - - -/datum/file/program/holodeck/interact() - if(!interactable()) - return - var/dat = "

    Current Loaded Programs

    " - dat += "((Empty Court))
    " - dat += "((Boxing Court))
    " - dat += "((Basketball Court))
    " - dat += "((Thunderdome Court))
    " - dat += "((Beach))
    " -// dat += "((Shutdown System))
    " - - dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
    " - - if(emagged) - dat += "(Begin Atmospheric Burn Simulation)
    " - dat += "Ensure the holodeck is empty before testing.
    " - dat += "
    " - dat += "(Begin Wildlife Simulation)
    " - dat += "Ensure the holodeck is empty before testing.
    " - dat += "
    " - if(issilicon(usr)) - dat += "(Re-Enable Safety Protocols?)
    " - dat += "Safety Protocols are DISABLED
    " - else - if(issilicon(usr)) - dat += "(Override Safety Protocols?)
    " - dat += "
    " - dat += "Safety Protocols are ENABLED
    " - - popup.set_content(dat) - popup.open() - return - -/datum/file/program/holodeck/Topic(var/href, var/list/href_list) - if(!interactable() || ..(href,href_list)) - return - - if("emptycourt" in href_list) - target = locate(/area/holodeck/source_emptycourt) - if(target) - loadProgram(target) - - else if("boxingcourt" in href_list) - target = locate(/area/holodeck/source_boxingcourt) - if(target) - loadProgram(target) - - else if("basketball" in href_list) - target = locate(/area/holodeck/source_basketball) - if(target) - loadProgram(target) - - else if("thunderdomecourt" in href_list) - target = locate(/area/holodeck/source_thunderdomecourt) - if(target) - loadProgram(target) - - else if("beach" in href_list) - target = locate(/area/holodeck/source_beach) - if(target) - loadProgram(target) - - else if("turnoff" in href_list) - target = locate(/area/holodeck/source_plating) - if(target) - loadProgram(target) - - else if("burntest" in href_list) - if(!emagged) - return - target = locate(/area/holodeck/source_burntest) - if(target) - loadProgram(target) - - else if("wildlifecarp" in href_list) - if(!emagged) - return - target = locate(/area/holodeck/source_wildlife) - if(target) - loadProgram(target) - - else if("AIoverride" in href_list) - if(!issilicon(usr)) - return - emagged = !emagged - if(emagged) - message_admins("[key_name_admin(usr)] overrode the holodeck's safeties") - log_game("[key_name(usr)] overrided the holodeck's safeties") - else - message_admins("[key_name_admin(usr)] restored the holodeck's safeties") - log_game("[key_name(usr)] restored the holodeck's safeties") - - interact() - return - -/datum/file/program/holodeck/Reset() - emergencyShutdown() - -/datum/file/program/holodeck/process() - if(active) - if(!checkInteg(linkedholodeck)) - damaged = 1 - target = locate(/area/holodeck/source_plating) - if(target) - loadProgram(target) - active = 0 - for(var/mob/M in range(10,src)) - M.show_message("The holodeck overloads!") - - for(var/turf/T in linkedholodeck) - if(prob(30)) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, T) - s.start() - T.ex_act(3) - T.hotspot_expose(1000,500,1) - - for(var/item in holographic_items) - if(!(get_turf(item) in linkedholodeck)) - derez(item, 0) - -/datum/file/program/holodeck/proc/derez(var/obj/obj , var/silent = 1) - holographic_items.Remove(obj) - - if(obj == null) - return - - if(isobj(obj)) - var/mob/M = obj.loc - if(ismob(M)) - M.remove_from_mob(obj) - - if(!silent) - var/obj/oldobj = obj - obj.visible_message("The [oldobj.name] fades away!") - qdel(obj) - -/datum/file/program/holodeck/proc/checkInteg(var/area/A) - for(var/turf/T in A) - if(istype(T, /turf/space)) - return 0 - return 1 - -/datum/file/program/holodeck/proc/togglePower(var/toggleOn = 0) - if(toggleOn) - var/area/targetsource = locate(/area/holodeck/source_emptycourt) - holographic_items = targetsource.copy_contents_to(linkedholodeck) - - spawn(30) - for(var/obj/effect/landmark/L in linkedholodeck) - if(L.name=="Atmospheric Test Start") - spawn(20) - var/turf/T = get_turf(L) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, T) - s.start() - if(T) - T.temperature = 5000 - T.hotspot_expose(50000,50000,1) - active = 1 - else - for(var/item in holographic_items) - derez(item) - var/area/targetsource = locate(/area/holodeck/source_plating) - targetsource.copy_contents_to(linkedholodeck , 1) - active = 0 - -/datum/file/program/holodeck/proc/loadProgram(var/area/A) - if(world.time < (last_change + 25)) - if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve - return - for(var/mob/M in range(3,src)) - M.show_message("ERROR. Recalibrating projetion apparatus.") - last_change = world.time - return - - last_change = world.time - active = 1 - - for(var/item in holographic_items) - derez(item) - - for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck) - qdel(B) - - for(var/mob/living/simple_mob/animal/space/carp/C in linkedholodeck) - qdel(C) - - holographic_items = A.copy_contents_to(linkedholodeck , 1) - - if(emagged) - for(var/obj/item/weapon/holo/esword/H in linkedholodeck) - H.damtype = BRUTE - - spawn(30) - for(var/obj/effect/landmark/L in linkedholodeck) - if(L.name=="Atmospheric Test Start") - spawn(20) - var/turf/T = get_turf(L) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, T) - s.start() - if(T) - T.temperature = 5000 - T.hotspot_expose(50000,50000,1) - if(L.name=="Holocarp Spawn") - new /mob/living/simple_mob/animal/space/carp(L.loc) - - -/datum/file/program/holodeck/proc/emergencyShutdown() - //Get rid of any items - for(var/item in holographic_items) - derez(item) - //Turn it back to the regular non-holographic room - target = locate(/area/holodeck/source_plating) - if(target) - loadProgram(target) - - var/area/targetsource = locate(/area/holodeck/source_plating) - targetsource.copy_contents_to(linkedholodeck , 1) - active = 0 diff --git a/code/game/machinery/computer3/computers/Operating.dm b/code/game/machinery/computer3/computers/Operating.dm deleted file mode 100644 index 0f989780d7..0000000000 --- a/code/game/machinery/computer3/computers/Operating.dm +++ /dev/null @@ -1,47 +0,0 @@ -/obj/machinery/computer3/operating - default_prog = /datum/file/program/op_monitor - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/prox) - icon_state = "frame-med" - -/datum/file/program/op_monitor - name = "operating table monitor" - desc = "Monitors patient status during surgery." - active_state = "operating" - var/mob/living/carbon/human/patient = null - var/obj/machinery/optable/table = null - - -/datum/file/program/op_monitor/interact() - if(!interactable()) - return - if(!computer.net) - computer.Crash(MISSING_PERIPHERAL) - return - table = computer.net.connect_to(/obj/machinery/optable,table) - - var/dat = "" - if(table) - dat += "Patient information:
    " - if(src.table && (src.table.check_victim())) - src.patient = src.table.victim - dat += {"Patient Status: [patient.stat ? "Non-Responsive" : "Stable"]
    - Blood Type: [patient.b_type]
    -
    - Health: [round(patient.health)]
    - Brute Damage: [round(patient.getBruteLoss())]
    - Toxins Damage: [round(patient.getToxLoss())]
    - Fire Damage: [round(patient.getFireLoss())]
    - Suffocation Damage: [round(patient.getOxyLoss())]
    - "} - else - src.patient = null - dat += "No patient detected" - else - dat += "Operating table not found." - - popup.set_content(dat) - popup.open() -/datum/file/program/op_monitor/Topic() - if(!interactable()) - return - ..() \ No newline at end of file diff --git a/code/game/machinery/computer3/computers/arcade.dm b/code/game/machinery/computer3/computers/arcade.dm deleted file mode 100644 index 6b235659cf..0000000000 --- a/code/game/machinery/computer3/computers/arcade.dm +++ /dev/null @@ -1,183 +0,0 @@ -/obj/machinery/computer3/arcade - default_prog = /datum/file/program/arcade - spawn_parts = list(/obj/item/part/computer/toybox) //NO HDD - the game is loaded on the circuitboard's OS slot - -/obj/item/part/computer/toybox - var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, - /obj/item/toy/blink = 2, - /obj/item/clothing/under/syndicate/tacticool = 2, - /obj/item/toy/sword = 2, - /obj/item/weapon/gun/projectile/revolver/capgun = 2, - /obj/item/toy/crossbow = 2, - /obj/item/clothing/suit/syndicatefake = 2, - /obj/item/weapon/storage/fancy/crayons = 2, - /obj/item/toy/spinningtoy = 2, - /obj/item/toy/prize/ripley = 1, - /obj/item/toy/prize/fireripley = 1, - /obj/item/toy/prize/deathripley = 1, - /obj/item/toy/prize/gygax = 1, - /obj/item/toy/prize/durand = 1, - /obj/item/toy/prize/honk = 1, - /obj/item/toy/prize/marauder = 1, - /obj/item/toy/prize/seraph = 1, - /obj/item/toy/prize/mauler = 1, - /obj/item/toy/prize/odysseus = 1, - /obj/item/toy/prize/phazon = 1 - ) - -/obj/item/part/computer/toybox/allow_attackby(var/obj/item/I, var/mob/user) - return 0 - -/obj/item/part/computer/toybox/proc/dispense() - if(computer && !computer.stat) - var/prizeselect = pickweight(prizes) - new prizeselect(computer.loc) - if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun - new /obj/item/projectile/bullet/pistol/cap(src.loc) - else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit - new /obj/item/clothing/head/syndicatefake(computer.loc) - feedback_inc("arcade_win_normal") - computer.use_power(500) - -/datum/file/program/arcade - desc = "The best arcade game ever produced by the Company's short-lived entertainment divison." - //headcanon: they also ported E.T. for the atari 2600, superman 64, and basically every other movie tie-in game ever - - active_state = "generic" - - var/turtle = 0 - var/enemy_name = "Space Villian" - var/temp = "Winners Don't Use Spacedrugs" //Temporary message, for attack messages, etc - var/player_hp = 30 //Player health/attack points - var/player_mp = 10 - var/enemy_hp = 45 //Enemy health/attack points - var/enemy_mp = 20 - var/gameover = 0 - var/blocked = 0 //Player cannot attack/heal while set - -/datum/file/program/arcade/New() - ..() - var/name_action - var/name_part1 - var/name_part2 - - name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "ERP ") - - name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") - name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn") - - enemy_name = replacetext(name_part1, "the ", "") + name_part2 - name = (name_action + name_part1 + name_part2) - -/datum/file/program/arcade/interact() - if(!interactable()) - return - var/dat// = topic_link(src,"close","Close") - dat = "

    [enemy_name]

    " - - dat += "

    [temp]

    " - dat += "
    Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
    " - dat += "
    " - - if (gameover) - dat += "[topic_link(src,"newgame","New Game")]" - else - dat += "[topic_link(src,"attack","Attack")] | [topic_link(src,"heal","Heal")] | [topic_link(src,"charge","Recharge Power")]" - - dat += "
    " - - popup.set_content(dat) - popup.open() - -/datum/file/program/arcade/Topic(href, list/href_list) - if(!interactable() || ..(href,href_list)) - return - if (!blocked && !gameover) - if ("attack" in href_list) - blocked = 1 - var/attackamt = rand(2,6) - temp = "You attack for [attackamt] damage!" - computer.updateUsrDialog() - if(turtle > 0) - turtle-- - - sleep(10) - enemy_hp -= attackamt - arcade_action() - - else if ("heal" in href_list) - blocked = 1 - var/pointamt = rand(1,3) - var/healamt = rand(6,8) - temp = "You use [pointamt] magic to heal for [healamt] damage!" - computer.updateUsrDialog() - turtle++ - - sleep(10) - player_mp -= pointamt - player_hp += healamt - blocked = 1 - computer.updateUsrDialog() - arcade_action() - - else if ("charge" in href_list) - blocked = 1 - var/chargeamt = rand(4,7) - temp = "You regain [chargeamt] points" - player_mp += chargeamt - if(turtle > 0) - turtle-- - - computer.updateUsrDialog() - sleep(10) - arcade_action() - - if ("newgame" in href_list) //Reset everything - temp = "New Round" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = 0 - turtle = 0 - computer.updateUsrDialog() - - -/datum/file/program/arcade/proc/arcade_action() - if ((enemy_mp <= 0) || (enemy_hp <= 0)) - if(!gameover) - gameover = 1 - temp = "[enemy_name] has fallen! Rejoice!" - if(computer.toybox) - computer.toybox.dispense() - - else if ((enemy_mp <= 5) && (prob(70))) - var/stealamt = rand(2,3) - temp = "[enemy_name] steals [stealamt] of your power!" - player_mp -= stealamt - - if (player_mp <= 0) - gameover = 1 - sleep(10) - temp = "You have been drained! GAME OVER" - feedback_inc("arcade_loss_mana_normal") - - else if ((enemy_hp <= 10) && (enemy_mp > 4)) - temp = "[enemy_name] heals for 4 health!" - enemy_hp += 4 - enemy_mp -= 4 - - else - var/attackamt = rand(3,6) - temp = "[enemy_name] attacks for [attackamt] damage!" - player_hp -= attackamt - - if ((player_mp <= 0) || (player_hp <= 0)) - gameover = 1 - temp = "You have been crushed! GAME OVER" - feedback_inc("arcade_loss_hp_normal") - - if(interactable()) - computer.updateUsrDialog() - blocked = 0 - return \ No newline at end of file diff --git a/code/game/machinery/computer3/computers/atmos_alert.dm b/code/game/machinery/computer3/computers/atmos_alert.dm deleted file mode 100644 index aaa677974c..0000000000 --- a/code/game/machinery/computer3/computers/atmos_alert.dm +++ /dev/null @@ -1,100 +0,0 @@ -/obj/machinery/computer3/atmos_alert - default_prog = /datum/file/program/atmos_alert - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) - icon_state = "frame-eng" - -/datum/file/program/atmos_alert - name = "atmospheric alert monitor" - desc = "Recieves alerts over the radio." - active_state = "alert:2" - refresh = 1 - -/datum/file/program/atmos_alert/execute(var/datum/file/program/source) - ..(source) - - if(!computer.radio) - computer.Crash(MISSING_PERIPHERAL) - - computer.radio.set_frequency(1437,RADIO_ATMOSIA) - -// This will be called as long as the program is running on the parent computer -// and the computer has the radio peripheral -/datum/file/program/atmos_alert/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) - return - - var/zone = signal.data["zone"] - var/severity = signal.data["alert"] - if(!zone || !severity) - return - - minor_air_alarms -= zone - priority_air_alarms -= zone - if(severity=="severe") - priority_air_alarms += zone - else if (severity=="minor") - minor_air_alarms += zone - update_icon() - return - - -/datum/file/program/atmos_alert/interact() - if(!interactable()) - return - if(!computer.radio) - computer.Crash(MISSING_PERIPHERAL) - - popup.set_content(return_text()) - popup.open() - -/datum/file/program/atmos_alert/update_icon() - ..() - if(priority_air_alarms.len > 0) - overlay.icon_state = "alert:2" - else if(minor_air_alarms.len > 0) - overlay.icon_state = "alert:1" - else - overlay.icon_state = "alert:0" - - if(computer) - computer.update_icon() - - -/datum/file/program/atmos_alert/proc/return_text() - var/priority_text = "

    Priority Alerts:

    " - var/minor_text = "

    Minor Alerts:

    " - - if(priority_air_alarms.len) - for(var/zone in priority_air_alarms) - priority_text += "[format_text(zone)] [topic_link(src,"priority_clear=[ckey(zone)]","X")]
    " - else - priority_text += "No priority alerts detected.
    " - - if(minor_air_alarms.len) - for(var/zone in minor_air_alarms) - minor_text += "[format_text(zone)] [topic_link(src,"minor_clear=[ckey(zone)]","X")]
    " - else - minor_text += "No minor alerts detected.
    " - - return "[priority_text]

    [minor_text]
    [topic_link(src,"close","Close")]" - - -/datum/file/program/atmos_alert/Topic(var/href, var/list/href_list) - if(!interactable() || ..(href,href_list)) - return - - if("priority_clear" in href_list) - var/removing_zone = href_list["priority_clear"] - for(var/zone in priority_air_alarms) - if(ckey(zone) == removing_zone) - to_chat(usr, "Priority Alert for area [zone] cleared.") - priority_air_alarms -= zone - - if("minor_clear" in href_list) - var/removing_zone = href_list["minor_clear"] - for(var/zone in minor_air_alarms) - if(ckey(zone) == removing_zone) - to_chat(usr, "Minor Alert for area [zone] cleared.") - minor_air_alarms -= zone - - computer.updateUsrDialog() diff --git a/code/game/machinery/computer3/computers/camera.dm b/code/game/machinery/computer3/computers/camera.dm deleted file mode 100644 index 0017a83531..0000000000 --- a/code/game/machinery/computer3/computers/camera.dm +++ /dev/null @@ -1,352 +0,0 @@ -/* - Camera monitoring computers - - NOTE: If we actually split the station camera network into regions that will help with sorting through the - tediously large list of cameras. The new camnet_key architecture lets you switch between keys easily, - so you don't lose the capability of seeing everything, you just switch to a subnet. -*/ - -/obj/machinery/computer3/security - default_prog = /datum/file/program/security - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/cameras) - spawn_files = list(/datum/file/camnet_key) - icon_state = "frame-sec" - - -/obj/machinery/computer3/security/wooden_tv - name = "security cameras" - desc = "An old TV hooked into the stations camera network." - icon = 'icons/obj/computer.dmi' - icon_state = "security_det" - - legacy_icon = 1 - allow_disassemble = 0 - - // No operating system -/obj/machinery/computer3/security/wooden_tv/New() - ..(built=0) - os = program - circuitb.OS = os - - -/obj/machinery/computer3/security/mining - name = "Outpost Cameras" - desc = "Used to access the various cameras on the outpost." - spawn_files = list(/datum/file/camnet_key/mining) - -/* - Camera monitoring computers, wall-mounted -*/ -/obj/machinery/computer3/wall_comp/telescreen - default_prog = /datum/file/program/security - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/cameras) - spawn_files = list(/datum/file/camnet_key) - -/obj/machinery/computer3/wall_comp/telescreen/entertainment - desc = "Damn, they better have /tg/thechannel on these things." - spawn_files = list(/datum/file/camnet_key/entertainment) - - -/* - File containing an encrypted camera network key. - - (Where by encrypted I don't actually mean encrypted at all) -*/ -/datum/file/camnet_key - name = "Security Camera Network Main Key" - var/title = "Station" - var/desc = "Connects to station security cameras." - var/networks = list("ALL") // A little workaround as it is not possible to place station_networks here - var/screen = "cameras" - -/datum/file/camnet_key/execute(var/datum/file/source) - if(istype(source,/datum/file/program/security)) - var/datum/file/program/security/prog = source - prog.key = src - prog.camera_list = null - return - if(istype(source,/datum/file/program/ntos)) - for(var/obj/item/part/computer/storage/S in list(computer.hdd,computer.floppy)) - for(var/datum/file/F in S.files) - if(istype(F,/datum/file/program/security)) - var/datum/file/program/security/Sec = F - Sec.key = src - Sec.camera_list = null - Sec.execute(source) - return - computer.Crash(MISSING_PROGRAM) - -/datum/file/camnet_key/New() - for(var/N in networks) - if(N == "ALL") - networks = using_map.station_networks - break - return ..() - -/datum/file/camnet_key/mining - name = "Mining Camera Network Key" - title = "mining station" - desc = "Connects to mining security cameras." - networks = list(NETWORK_MINE) - screen = "miningcameras" - -/datum/file/camnet_key/research - name = "Research Camera Network Key" - title = "research" - networks = list(NETWORK_RESEARCH) - -/datum/file/camnet_key/bombrange - name = "R&D Bomb Range Camera Network Key" - title = "bomb range" - desc = "Monitors the bomb range." - networks = list(NETWORK_RESEARCH) - -/datum/file/camnet_key/xeno - name = "R&D Misc. Research Camera Network Key" - title = "special research" - networks = list(NETWORK_RESEARCH) - -/datum/file/camnet_key/singulo - name = "Singularity Camera Network Key" - title = "singularity" - networks = list(NETWORK_ENGINE) - -/datum/file/camnet_key/entertainment - name = "Entertainment Channel Encryption Key" - title = "entertainment" - desc = "Damn, I hope they have /tg/thechannel on here." - networks = list(NETWORK_THUNDER) - screen = "entertainment" - -/datum/file/camnet_key/creed - name = "Special Ops Camera Encryption Key" - title = "special ops" - desc = "Connects to special ops secure camera feeds." - networks = list(NETWORK_ERT) - -/datum/file/camnet_key/prison - name = "Prison Camera Network Key" - title = "prison" - desc = "Monitors the prison." - networks = list(NETWORK_SECURITY) - -/datum/file/camnet_key/syndicate - name = "Camera Network Key" - title = "%!#BUFFER OVERFLOW" - desc = "Connects to security cameras." - networks = list("ALL") - hidden_file = 1 - - -/* - Computer part needed to connect to cameras -*/ - -/obj/item/part/computer/networking/cameras - name = "camera network access module" - desc = "Connects a computer to the camera network." - - // I have no idea what the following does - var/mapping = 0//For the overview file, interesting bit of code. - - //proc/camera_list(var/datum/file/camnet_key/key) -/obj/item/part/computer/networking/cameras/get_machines(var/datum/file/camnet_key/key) - if (!computer || computer.z > 6) - return null - - cameranet.process_sort() - - var/list/L = list() - for(var/obj/machinery/camera/C in cameranet.cameras) - var/list/temp = C.network & key.networks - if(temp.len) - L.Add(C) - - return L - -/obj/item/part/computer/networking/cameras/verify_machine(var/obj/machinery/camera/C,var/datum/file/camnet_key/key = null) - if(!istype(C) || !C.can_use()) - return 0 - - if(key) - var/list/temp = C.network & key.networks - if(!temp.len) - return 0 - return 1 - -/* - Camera monitoring program - - The following things should break you out of the camera view: - * The computer resetting, being damaged, losing power, etc - * The program quitting - * Closing the window - * Going out of range of the computer - * Becoming incapacitated - * The camera breaking, emping, disconnecting, etc -*/ - -/datum/file/program/security - name = "camera monitor" - desc = "Connects to the station camera network." - image = 'icons/ntos/camera.png' - active_state = "camera-static" - - var/datum/file/camnet_key/key = null - var/last_pic = 1.0 - var/last_camera_refresh = 0 - var/camera_list = null - - var/obj/machinery/camera/current = null - -/datum/file/program/security/execute(var/datum/file/program/caller) - ..(caller) - if(computer && !key) - var/list/fkeys = computer.list_files(/datum/file/camnet_key) - if(fkeys && fkeys.len) - key = fkeys[1] - update_icon() - computer.update_icon() - for(var/mob/living/L in viewers(1)) - if(!istype(L,/mob/living/silicon/ai) && L.machine == src) - L.reset_view(null) - - -/datum/file/program/security/Reset() - ..() - reset_current() - for(var/mob/living/L in viewers(1)) - if(!istype(L,/mob/living/silicon/ai) && L.machine == src) - L.reset_view(null) - -/datum/file/program/security/interact() - if(!interactable()) - return - - if(!computer.camnet) - computer.Crash(MISSING_PERIPHERAL) - return - - if(!key) - var/list/fkeys = computer.list_files(/datum/file/camnet_key) - if(fkeys && fkeys.len) - key = fkeys[1] - update_icon() - computer.update_icon() - if(!key) - return - - if(computer.camnet.verify_machine(current)) - usr.reset_view(current) - - if(world.time - last_camera_refresh > 50 || !camera_list) - last_camera_refresh = world.time - - var/list/temp_list = computer.camnet.get_machines(key) - - camera_list = "Network Key: [key.title] [topic_link(src,"keyselect","\[ Select key \]")]
    " - for(var/obj/machinery/camera/C in temp_list) - if(C.can_use()) - camera_list += "[C.c_tag] - [topic_link(src,"show=\ref[C]","Show")]
    " - else - camera_list += "[C.c_tag] - DEACTIVATED
    " - //camera_list += "
    " + topic_link(src,"close","Close") - - popup.set_content(camera_list) - popup.open() - - -/datum/file/program/security/update_icon() - if(key) - overlay.icon_state = key.screen - name = key.title + " Camera Monitor" - else - overlay.icon_state = "camera-static" - name = initial(name) - - - -/datum/file/program/security/Topic(var/href,var/list/href_list) - if(!interactable() || !computer.camnet || ..(href,href_list)) - return - - if("show" in href_list) - var/obj/machinery/camera/C = locate(href_list["show"]) - if(istype(C) && C.can_use()) - set_current(C) - usr.reset_view(C) - interact() - return - - if("keyselect" in href_list) - reset_current() - usr.reset_view(null) - key = input(usr,"Select a camera network key:", "Key Select", null) as null|anything in computer.list_files(/datum/file/camnet_key) - select_key(key) - if(key) - interact() - else - to_chat(usr, "The screen turns to static.") - return - -/datum/file/program/security/proc/select_key(var/selected_key) - key = selected_key - camera_list = null - update_icon() - computer.update_icon() - -/datum/file/program/security/proc/set_current(var/obj/machinery/camera/C) - if(current == C) - return - - if(current) - reset_current() - - src.current = C - if(current) - var/mob/living/L = current.loc - if(istype(L)) - L.tracking_initiated() - -/datum/file/program/security/proc/reset_current() - if(current) - var/mob/living/L = current.loc - if(istype(L)) - L.tracking_cancelled() - current = null - - // Atlantis: Required for camnetkeys to work. -/datum/file/program/security/hidden - hidden_file = 1 - -/* - Camera monitoring program - - Works much as the parent program, except: - * It requires a camera to be found using the proximity network card. - * It begins with all cam-access. -*/ - -/datum/file/program/security/syndicate - name = "camer# moni!%r" - desc = "Cons the Nanotrash Camera Network" - var/special_key = new/datum/file/camnet_key/syndicate - var/camera_conn = null - -/datum/file/program/security/syndicate/interact() - if(!interactable()) - return - - if(!computer.net) - computer.Crash(MISSING_PERIPHERAL) - return - - camera_conn = computer.net.connect_to(/obj/machinery/camera,camera_conn) - - if(!camera_conn) - computer.Crash(NETWORK_FAILURE) - return - - // On interact, override camera key selection - select_key(special_key) - ..() diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm deleted file mode 100644 index de4f9c3dc1..0000000000 --- a/code/game/machinery/computer3/computers/communications.dm +++ /dev/null @@ -1,422 +0,0 @@ -/obj/machinery/computer3/communications - default_prog = /datum/file/program/communications - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace) - -/obj/machinery/computer3/communications/captain - default_prog = /datum/file/program/communications - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/cardslot/dual) - spawn_files = list(/datum/file/program/card_comp, /datum/file/program/security, /datum/file/program/crew, /datum/file/program/arcade, - /datum/file/camnet_key, /datum/file/camnet_key/entertainment, /datum/file/camnet_key/singulo) - - -/datum/file/program/communications - var/const/STATE_DEFAULT = 1 - var/const/STATE_CALLSHUTTLE = 2 - var/const/STATE_CANCELSHUTTLE = 3 - var/const/STATE_MESSAGELIST = 4 - var/const/STATE_VIEWMESSAGE = 5 - var/const/STATE_DELMESSAGE = 6 - var/const/STATE_STATUSDISPLAY = 7 - var/const/STATE_ALERT_LEVEL = 8 - var/const/STATE_CONFIRM_LEVEL = 9 - - -/datum/file/program/communications - name = "CentCom communications relay" - desc = "Used to connect to CentCom." - active_state = "comm" - req_access = list(access_heads) - - var/prints_intercept = 1 - var/authenticated = 0 - var/list/messagetitle = list() - var/list/messagetext = list() - var/currmsg = 0 - var/aicurrmsg = 0 - var/state = STATE_DEFAULT - var/aistate = STATE_DEFAULT - var/message_cooldown = 0 - var/centcomm_message_cooldown = 0 - var/tmp_alertlevel = 0 - - var/status_display_freq = "1435" - var/stat_msg1 - var/stat_msg2 - - var/datum/announcement/priority/crew_announcement = new - -/datum/file/program/communications/New() - ..() - crew_announcement.newscast = 1 - -/datum/file/program/communications/Reset() - ..() - authenticated = 0 - state = STATE_DEFAULT - aistate = STATE_DEFAULT - - -/datum/file/program/communications/Topic(var/href, var/list/href_list) - if(!interactable() || !computer.radio || ..(href,href_list) ) - return - if (computer.z > 1) - to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return - - if("main" in href_list) - state = STATE_DEFAULT - - if("login" in href_list) - var/mob/M = usr - var/obj/item/I = M.get_active_hand() - if(I) - I = I.GetID() - if(istype(I,/obj/item/weapon/card/id) && check_access(I)) - authenticated = 1 - if(access_captain in I.GetAccess()) - authenticated = 2 - crew_announcement.announcer = GetNameAndAssignmentFromId(I) - if(istype(I,/obj/item/weapon/card/emag)) - authenticated = 2 - computer.emagged = 1 - - if("logout" in href_list) - authenticated = 0 - crew_announcement.announcer = "" - - if("swipeidseclevel" in href_list) - var/mob/M = usr - var/obj/item/I = M.get_active_hand() - I = I.GetID() - - if (istype(I,/obj/item/weapon/card/id)) - if(access_captain in I.GetAccess()) - var/old_level = security_level - if(!tmp_alertlevel) - tmp_alertlevel = SEC_LEVEL_GREEN - if(tmp_alertlevel < SEC_LEVEL_GREEN) - tmp_alertlevel = SEC_LEVEL_GREEN - if(tmp_alertlevel > SEC_LEVEL_BLUE) - tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this - set_security_level(tmp_alertlevel) - if(security_level != old_level) - //Only notify the admins if an actual change happened - log_game("[key_name(usr)] has changed the security level to [get_security_level()].") - message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].") - switch(security_level) - if(SEC_LEVEL_GREEN) - feedback_inc("alert_comms_green",1) - if(SEC_LEVEL_YELLOW) - feedback_inc("alert_comms_yellow",1) - if(SEC_LEVEL_VIOLET) - feedback_inc("alert_comms_violet",1) - if(SEC_LEVEL_ORANGE) - feedback_inc("alert_comms_orange",1) - if(SEC_LEVEL_BLUE) - feedback_inc("alert_comms_blue",1) - tmp_alertlevel = 0 - else - to_chat(usr, "You are not authorized to do this.") - tmp_alertlevel = 0 - state = STATE_DEFAULT - else - to_chat(usr, "You need to swipe your ID.") - - if("announce" in href_list) - if(authenticated==2) - if(message_cooldown) - usr << "Please allow at least one minute to pass between announcements" - return - var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") - if(!input || !interactable()) - return - crew_announcement.Announce(input) - message_cooldown = 1 - spawn(600)//One minute cooldown - message_cooldown = 0 - - if("callshuttle" in href_list) - state = STATE_DEFAULT - if(authenticated) - state = STATE_CALLSHUTTLE - - if("callshuttle2" in href_list) - if(!computer.radio.subspace) - return - if(authenticated) - call_shuttle_proc(usr) - if(emergency_shuttle.online()) - post_status("shuttle") - state = STATE_DEFAULT - - if("cancelshuttle" in href_list) - state = STATE_DEFAULT - if(authenticated) - state = STATE_CANCELSHUTTLE - - if("messagelist" in href_list) - currmsg = 0 - state = STATE_MESSAGELIST - - if("viewmessage" in href_list) - state = STATE_VIEWMESSAGE - if (!currmsg) - if(href_list["message-num"]) - currmsg = text2num(href_list["message-num"]) - else - state = STATE_MESSAGELIST - - if("delmessage" in href_list) - state = (currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST - - if("delmessage2" in href_list) - if(authenticated) - if(currmsg) - var/title = messagetitle[currmsg] - var/text = messagetext[currmsg] - messagetitle.Remove(title) - messagetext.Remove(text) - if(currmsg == aicurrmsg) - aicurrmsg = 0 - currmsg = 0 - state = STATE_MESSAGELIST - else - state = STATE_VIEWMESSAGE - - if("status" in href_list) - state = STATE_STATUSDISPLAY - - // Status display stuff - if("setstat" in href_list) - switch(href_list["statdisp"]) - if("message") - post_status("message", stat_msg1, stat_msg2) - if("alert") - post_status("alert", href_list["alert"]) - else - post_status(href_list["statdisp"]) - - if("setmsg1" in href_list) - stat_msg1 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40) - computer.updateDialog() - - if("setmsg2" in href_list) - stat_msg2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40) - computer.updateDialog() - - // OMG CENTCOM LETTERHEAD - if("MessageCentCom" in href_list) - if(!computer.radio.subspace) - return - if(authenticated==2) - if(centcomm_message_cooldown) - to_chat(usr, "Arrays recycling. Please stand by.") - return - var/input = sanitize(input("Please choose a message to transmit to [using_map.boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")) - if(!input || !interactable()) - return - CentCom_announce(input, usr) - to_chat(usr, "Message transmitted.") - log_game("[key_name(usr)] has made a [using_map.boss_short] announcement: [input]") - centcomm_message_cooldown = 1 - spawn(600)//10 minute cooldown - centcomm_message_cooldown = 0 - - // OMG SYNDICATE ...LETTERHEAD - if("MessageSyndicate" in href_list) - if((authenticated==2) && (computer.emagged)) - if(centcomm_message_cooldown) - to_chat(usr, "Arrays recycling. Please stand by.") - return - var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")) - if(!input || !interactable()) - return - Syndicate_announce(input, usr) - to_chat(usr, "Message transmitted.") - log_game("[key_name(usr)] has made an illegal announcement: [input]") - centcomm_message_cooldown = 1 - spawn(600)//10 minute cooldown - centcomm_message_cooldown = 0 - - if("RestoreBackup" in href_list) - to_chat(usr, "Backup routing data restored!") - computer.emagged = 0 - computer.updateDialog() - - - // AI interface - if("ai-main" in href_list) - aicurrmsg = 0 - aistate = STATE_DEFAULT - - if("ai-callshuttle" in href_list) - aistate = STATE_CALLSHUTTLE - - if("ai-callshuttle2" in href_list) - if(!computer.radio.subspace) - return - call_shuttle_proc(usr) - aistate = STATE_DEFAULT - - if("ai-messagelist" in href_list) - aicurrmsg = 0 - aistate = STATE_MESSAGELIST - - if("ai-viewmessage" in href_list) - aistate = STATE_VIEWMESSAGE - if (!aicurrmsg) - if(href_list["message-num"]) - aicurrmsg = text2num(href_list["message-num"]) - else - aistate = STATE_MESSAGELIST - - if("ai-delmessage" in href_list) - aistate = (aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST - - if("ai-delmessage2" in href_list) - if(aicurrmsg) - var/title = messagetitle[aicurrmsg] - var/text = messagetext[aicurrmsg] - messagetitle.Remove(title) - messagetext.Remove(text) - if(currmsg == aicurrmsg) - currmsg = 0 - aicurrmsg = 0 - aistate = STATE_MESSAGELIST - - if("ai-status" in href_list) - aistate = STATE_STATUSDISPLAY - - if("securitylevel" in href_list) - tmp_alertlevel = text2num( href_list["newalertlevel"] ) - if(!tmp_alertlevel) tmp_alertlevel = 0 - state = STATE_CONFIRM_LEVEL - - if("changeseclevel" in href_list) - state = STATE_ALERT_LEVEL - - computer.updateUsrDialog() - - - -/datum/file/program/communications/proc/main_menu() - var/dat = "" - if (computer.radio.subspace) - if(emergency_shuttle.online() && emergency_shuttle.location()) - var/timeleft = emergency_shuttle.estimate_arrival_time() - dat += "Emergency shuttle\n
    \nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]
    " - refresh = 1 - else - refresh = 0 - if (authenticated) - dat += "
    \[ Log Out \]" - if (authenticated==2) - dat += "
    \[ Make An Announcement \]" - if(computer.emagged == 0) - dat += "
    \[ Send an emergency message to [using_map.boss_short] \]" - else - dat += "
    \[ Send an emergency message to \[UNKNOWN\] \]" - dat += "
    \[ Restore Backup Routing Data \]" - - dat += "
    \[ Change alert level \]" - if(emergency_shuttle.location()) - if (emergency_shuttle.online()) - dat += "
    \[ Cancel Shuttle Call \]" - else - dat += "
    \[ Call Emergency Shuttle \]" - - dat += "
    \[ Set Status Display \]" - else - dat += "
    \[ Log In \]" - dat += "
    \[ Message List \]" - return dat - -/datum/file/program/communications/proc/confirm_menu(var/prompt,var/yes_option) - return "Are you sure you want to [prompt]? \[ [topic_link(src,yes_option,"OK")] | [topic_link(src,"main","Cancel")] \]" - -/datum/file/program/communications/interact() - if(!interactable()) - return - if(!computer.radio) - computer.Crash(MISSING_PERIPHERAL) - return - - var/dat = "" - switch(state) - if(STATE_DEFAULT) - dat = main_menu() - if(STATE_CALLSHUTTLE) - dat = confirm_menu("call the shuttle","callshuttle2") - if(STATE_CANCELSHUTTLE) - dat = confirm_menu("cancel the shuttle","cancelshuttle2") - if(STATE_MESSAGELIST) - dat += "Messages:" - for(var/i = 1; i<=messagetitle.len; i++) - dat += "
    [messagetitle[i]]" - if(STATE_VIEWMESSAGE) - if (currmsg) - dat += "[messagetitle[currmsg]]

    [messagetext[currmsg]]" - if (authenticated) - dat += "

    \[ Delete \]" - else - state = STATE_MESSAGELIST - interact() - return - if(STATE_DELMESSAGE) - if (currmsg) - dat += "Are you sure you want to delete this message? \[ OK | Cancel \]" - else - state = STATE_MESSAGELIST - interact() - return - if(STATE_STATUSDISPLAY) - dat += "\[ Back \]
    " - dat += "Set Status Displays
    " - dat += "\[ Clear \]
    " - dat += "\[ Station Time \]" - dat += "\[ Shuttle ETA \]
    " - dat += "\[ Message \]" - dat += "
    " - dat += "\[ Alert: None |" - dat += " Red Alert |" - dat += " Lockdown |" - dat += " Biohazard \]

    " - if(STATE_ALERT_LEVEL) - dat += "Current alert level: [get_security_level()]
    " - if(security_level == SEC_LEVEL_DELTA) - dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." - else - dat += "Blue
    " - dat += "Orange
    " - dat += "Violet
    " - dat += "Yellow
    " - dat += "Green" - if(STATE_CONFIRM_LEVEL) - dat += "Current alert level: [get_security_level()]
    " - dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
    " - dat += "Swipe ID to confirm change.
    " - - popup.set_content(dat) - popup.open() - - -/datum/file/program/communications/proc/post_status(var/command, var/data1, var/data2) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) - - if(!frequency) - return - - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - if("alert") - status_signal.data["picture_state"] = data1 - - frequency.post_signal(src, status_signal) diff --git a/code/game/machinery/computer3/computers/crew.dm b/code/game/machinery/computer3/computers/crew.dm deleted file mode 100644 index e0112532dd..0000000000 --- a/code/game/machinery/computer3/computers/crew.dm +++ /dev/null @@ -1,76 +0,0 @@ -/obj/machinery/computer3/crew - default_prog = /datum/file/program/crew - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) - icon_state = "frame-med" - -/datum/file/program/crew - name = "Crew Monitoring Console" - desc = "Used to monitor active health sensors built into most of the crew's uniforms." - active_state = "crew" - var/list/tracked = list( ) - -/datum/file/program/crew/interact(mob/user) - if(!interactable()) - return - - scan() - var/t = "Crew Monitoring
    " - t += "
    Refresh " - t += "Close
    " - t += "" - var/list/logs = list() - for(var/obj/item/clothing/under/C in src.tracked) - var/log = "" - var/turf/pos = get_turf(C) - if((C) && (C.has_sensor) && (pos) && (pos.z == computer.z) && C.sensor_mode) - if(istype(C.loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = C.loc - - var/dam1 = round(H.getOxyLoss(),1) - var/dam2 = round(H.getToxLoss(),1) - var/dam3 = round(H.getFireLoss(),1) - var/dam4 = round(H.getBruteLoss(),1) - - var/life_status = "[H.stat > 1 ? "Deceased" : "Living"]" - var/damage_report = "([dam1]/[dam2]/[dam3]/[dam4])" - - log += "" - - switch(C.sensor_mode) - if(1) - log += "" - if(2) - log += "" - if(3) - var/area/player_area = get_area(H) - log += "" - logs += log - logs = sortList(logs) - for(var/log in logs) - t += log - t += "
    NameVitalsPosition
    [H.get_authentification_name()] ([H.get_assignment()])[life_status]Not Available
    [life_status] [damage_report]Not Available
    [life_status] [damage_report][sanitize(player_area.name)] ([pos.x], [pos.y])
    " - t += "
    " - - popup.set_content(t) - popup.open() - - -/datum/file/program/crew/proc/scan() - for(var/obj/item/clothing/under/C in world) - if((C.has_sensor) && (istype(C.loc, /mob/living/carbon/human))) - tracked |= C - return 1 - -/datum/file/program/crew/Topic(href, list/href_list) - if(!interactable() || !computer.cardslot || ..(href,href_list)) - return - - if( href_list["close"] ) - usr << browse(null, "window=crewcomp") - usr.unset_machine() - return - - if(href_list["update"]) - interact() - //src.updateUsrDialog() - return diff --git a/code/game/machinery/computer3/computers/customs.dm b/code/game/machinery/computer3/computers/customs.dm deleted file mode 100644 index bca73055b8..0000000000 --- a/code/game/machinery/computer3/computers/customs.dm +++ /dev/null @@ -1,3 +0,0 @@ -/obj/machinery/computer3/customs - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras) - spawn_files = list(/datum/file/program/arcade,/datum/file/program/security,/datum/file/camnet_key/entertainment,/datum/file/program/crew) \ No newline at end of file diff --git a/code/game/machinery/computer3/computers/law.dm b/code/game/machinery/computer3/computers/law.dm deleted file mode 100644 index e79b09c9e9..0000000000 --- a/code/game/machinery/computer3/computers/law.dm +++ /dev/null @@ -1,84 +0,0 @@ - - -/obj/machinery/computer3/aiupload - name = "AI Upload" - desc = "Used to upload laws to the AI." - icon_state = "frame-rnd" - circuit = /obj/item/weapon/circuitboard/aiupload - var/mob/living/silicon/ai/current = null - var/opened = 0 - - -/obj/machinery/computer3/aiupload/verb/AccessInternals() - set category = "Object" - set name = "Access Computer's Internals" - set src in oview(1) - if(!Adjacent(usr) || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon) || !istype(usr, /mob/living)) - return - - opened = !opened - if(opened) - to_chat(usr, "The access panel is now open.") - else - to_chat(usr, "The access panel is now closed.") - return - - -/obj/machinery/computer3/aiupload/attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) - if (user.z > 6) - to_chat(user, "Unable to establish a connection: You're too far away from the station!") - return - if(istype(module, /obj/item/weapon/aiModule)) - module.install(src, user) - else - return ..() - - -/obj/machinery/computer3/aiupload/attack_hand(var/mob/user as mob) - if(src.stat & NOPOWER) - to_chat(user, "The upload computer has no power!") - return - if(src.stat & BROKEN) - to_chat(user, "The upload computer is broken!") - return - - src.current = select_active_ai(user) - - if (!src.current) - to_chat(user, "No active AIs detected.") - else - to_chat(user, "[src.current.name] selected for law changes.") - return - - - -/obj/machinery/computer3/borgupload - name = "Cyborg Upload" - desc = "Used to upload laws to Cyborgs." - icon_state = "frame-rnd" - circuit = /obj/item/weapon/circuitboard/borgupload - var/mob/living/silicon/robot/current = null - - -/obj/machinery/computer3/borgupload/attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) - if(istype(module, /obj/item/weapon/aiModule)) - module.install(src, user) - else - return ..() - - -/obj/machinery/computer3/borgupload/attack_hand(var/mob/user as mob) - if(src.stat & NOPOWER) - to_chat(user, "The upload computer has no power!") - return - if(src.stat & BROKEN) - to_chat(user, "The upload computer is broken!") - return - - src.current = freeborg() - - if (!src.current) - to_chat(user, "No free cyborgs detected.") - else - to_chat(user, "[src.current.name] selected for law changes.") - return diff --git a/code/game/machinery/computer3/computers/medical.dm b/code/game/machinery/computer3/computers/medical.dm deleted file mode 100644 index d1f20c7363..0000000000 --- a/code/game/machinery/computer3/computers/medical.dm +++ /dev/null @@ -1,512 +0,0 @@ -/* - I hate to make this a todo, but I cannot possibly complete all of computer3 - if I have to rearchitecture datacores and everything else that uses them right now. - - In the future the datacore should probably be a server, perhaps on station, perhaps on centcom, - with data records as files probably. It's not difficult unless you're trying to do a million - impossible things before breakfast. -*/ - -/obj/machinery/computer3/med_data - default_prog = /datum/file/program/med_data - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) - - -/obj/machinery/computer3/laptop/medical - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) - spawn_files = list(/datum/file/program/arcade,/datum/file/program/crew,/datum/file/program/med_data) - -/datum/file/program/med_data - name = "Medical Records" - desc = "This can be used to check medical records." - active_state = "medcomp" - req_one_access = list(access_medical, access_forensics_lockers) - - var/obj/item/weapon/card/id/scan = null - var/obj/item/weapon/card/id/scan2 = null - var/authenticated = null - var/rank = null - var/screen = null - var/datum/data/record/active1 = null - var/datum/data/record/active2 = null - var/a_id = null - var/temp = null - var/printing = null - - -/datum/file/program/med_data/proc/authenticate() - if(isAI(usr) || access_medical in scan.access) - return 1 - return 0 - -/datum/file/program/med_data/interact() - if(!computer.cardslot) - computer.Crash(MISSING_PERIPHERAL) - return - usr.set_machine(src) - scan = computer.cardslot.reader - if(!interactable()) - return - if(computer.z > 6) - to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return - var/dat - - if (temp) - dat = text("[src.temp]

    Clear Screen") - else - dat = text("Confirm Identity (R): []
    ", src, (scan ? text("[]", scan.name) : "----------")) - if (istype(computer.cardslot, /obj/item/part/computer/cardslot/dual)) - dat += text("Check Identity (W): []
    ", src, (scan2 ? text("[]", scan2.name) : "----------")) - if(scan2 && !scan) - dat += text("
    Insert card into reader slot to log in.

    ") - - if (src.authenticated) - switch(src.screen) - if(1.0) - dat += {" - Search Records -
    List Records -
    -
    Virus Database -
    Medbot Tracking -
    -
    Record Maintenance -
    {Log Out}
    - "} - if(2.0) - dat += "Record List:
    " - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
    ", src, R, R.fields["id"], R.fields["name"]) - //Foreach goto(132) - dat += text("
    Back", src) - if(3.0) - dat += text("Records Maintenance
    \nBackup To Disk
    \nUpload From disk
    \nDelete All Records
    \n
    \nBack", src, src, src, src) - if(4.0) - dat += "
    Medical Record

    " - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - usr << browse_rsc(front, "front.png") - usr << browse_rsc(side, "side.png") - - dat += "
    Name: [active1.fields["name"]] \ - ID: [active1.fields["id"]]
    \n \ - Entity Classification: [active1.fields["brain_type"]]
    \n \ - Sex: [active1.fields["sex"]]
    \n \ - Age: [active1.fields["age"]]
    \n \ - Fingerprint: [active1.fields["fingerprint"]]
    \n \ - Physical Status: [active1.fields["p_stat"]]
    \n \ - Mental Status: [active1.fields["m_stat"]]
    \ - Photo:
    " - else - dat += "General Record Lost!
    " - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - dat += text("
    \n
    Medical Data

    \nBlood Type: []
    \nDNA: []
    \n
    \nMinor Disabilities: []
    \nDetails: []
    \n
    \nMajor Disabilities: []
    \nDetails: []
    \n
    \nAllergies: []
    \nDetails: []
    \n
    \nCurrent Diseases: [] (per disease info placed in log/comment section)
    \nDetails: []
    \n
    \nImportant Notes:
    \n\t[]
    \n
    \n
    Comments/Log

    ", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, decode(src.active2.fields["notes"])) - var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - dat += text("[]
    Delete Entry

    ", src.active2.fields[text("com_[]", counter)], src, counter) - counter++ - dat += text("Add Entry

    ", src) - dat += text("Delete Record (Medical Only)

    ", src) - else - dat += "Medical Record Lost!
    " - dat += text("New Record

    ") - dat += text("\nPrint Record
    \nBack
    ", src, src) - if(5.0) - dat += "
    Virus Database
    " - for (var/ID in virusDB) - var/datum/data/record/v = virusDB[ID] - dat += "
    [v.fields["name"]]" - - dat += "
    Back" - if(6.0) - dat += "
    Medical Robot Monitor
    " - dat += "Back" - dat += "
    Medical Robots:" - var/bdat = null - for(var/mob/living/bot/medbot/M in mob_list) - - if(M.z != computer.z) continue //only find medibots on the same z-level as the computer - var/turf/bl = get_turf(M) - if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up - bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
    " - if((!isnull(M.reagent_glass)) && M.use_beaker) - bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
    " - else - bdat += "Using Internal Synthesizer.
    " - if(!bdat) - dat += "
    None detected
    " - else - dat += "
    [bdat]" - - else - dat += text("{Log In}", src) - popup.width = 600 - popup.height = 400 - popup.set_content(dat) - popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) - popup.open() - return - -/datum/file/program/med_data/Topic(href, href_list) - if(!interactable() || !computer.cardslot || ..(href,href_list)) - return - if(!data_core.general.Find(src.active1)) - src.active1 = null - if(!data_core.medical.Find(src.active2)) - src.active2 = null - - if(href_list["temp"]) - src.temp = null - - if(href_list["cardr"]) - if(scan) - if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) - computer.cardslot.remove(usr, 1) - else - scan.loc = get_turf(src) - scan = null - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/weapon/card/id)) - computer.cardslot.insert(I, usr) - scan = I - - if(href_list["cardw"]) - if(scan2) - if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) - computer.cardslot.remove(usr, 2) - else - scan2.loc = get_turf(src) - scan2 = null - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/weapon/card/id)) - computer.cardslot.insert(I, usr, 2) - scan2 = I - - else if(href_list["logout"]) - src.authenticated = null - src.screen = null - src.active1 = null - src.active2 = null - - else if(href_list["login"]) - - if(isAI(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - - else if(isrobot(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - var/mob/living/silicon/robot/R = usr - src.rank = "[R.modtype] [R.braintype]" - src.screen = 1 - - else if(istype(src.scan, /obj/item/weapon/card/id)) - src.active1 = null - src.active2 = null - - if(src.check_access(src.scan)) - src.authenticated = src.scan.registered_name - src.rank = src.scan.assignment - src.screen = 1 - - if(src.authenticated) - - if(href_list["screen"]) - src.screen = text2num(href_list["screen"]) - if(src.screen < 1) - src.screen = 1 - - src.active1 = null - src.active2 = null - - if(href_list["vir"]) - var/datum/data/record/v = locate(href_list["vir"]) - src.temp = "
    GNAv2 based virus lifeform V-[v.fields["id"]]
    " - src.temp += "
    Name: [v.fields["name"]]" - src.temp += "
    Antigen: [v.fields["antigen"]]" - src.temp += "
    Spread: [v.fields["spread type"]] " - src.temp += "
    Details:
    [v.fields["description"]]" - - if(href_list["del_all"]) - src.temp = text("Are you sure you wish to delete all records?
    \n\tYes
    \n\tNo
    ", src, src) - - if(href_list["del_all2"]) - for(var/datum/data/record/R in data_core.medical) - //R = null - qdel(R) - //Foreach goto(494) - src.temp = "All records deleted." - - if(href_list["field"]) - var/a1 = src.active1 - var/a2 = src.active2 - switch(href_list["field"]) - if("fingerprint") - if(istype(src.active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active1 != a1) - return - src.active1.fields["fingerprint"] = t1 - if("sex") - if(istype(src.active1, /datum/data/record)) - if (src.active1.fields["sex"] == "Male") - src.active1.fields["sex"] = "Female" - else - src.active1.fields["sex"] = "Male" - if("age") - if(istype(src.active1, /datum/data/record)) - var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active1 != a1) - return - src.active1.fields["age"] = t1 - if("mi_dis") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["mi_dis"] = t1 - if("mi_dis_d") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["mi_dis_d"] = t1 - if("ma_dis") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["ma_dis"] = t1 - if("ma_dis_d") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["ma_dis_d"] = t1 - if("alg") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["alg"] = t1 - if("alg_d") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["alg_d"] = t1 - if("cdi") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["cdi"] = t1 - if("cdi_d") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["cdi_d"] = t1 - if("notes") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["notes"] = t1 - if("p_stat") - if (istype(src.active1, /datum/data/record)) - src.temp = text("Physical Condition:
    \n\t*Deceased*
    \n\t*SSD*
    \n\tActive
    \n\tPhysically Unfit
    \n\tDisabled
    ", src, src, src, src, src) - if("m_stat") - if (istype(src.active1, /datum/data/record)) - src.temp = text("Mental Condition:
    \n\t*Insane*
    \n\t*Unstable*
    \n\t*Watch*
    \n\tStable
    ", src, src, src, src) - if("b_type") - if (istype(src.active2, /datum/data/record)) - src.temp = text("Blood Type:
    \n\tA- A+
    \n\tB- B+
    \n\tAB- AB+
    \n\tO- O+
    ", src, src, src, src, src, src, src, src) - if("b_dna") - if(istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - src.active2.fields["b_dna"] = t1 - if("vir_name") - var/datum/data/record/v = locate(href_list["edit_vir"]) - if(v) - var/t1 = sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text) - if (!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active1 != a1) - return - v.fields["name"] = t1 - if("vir_desc") - var/datum/data/record/v = locate(href_list["edit_vir"]) - if(v) - var/t1 = sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active1 != a1) - return - v.fields["description"] = t1 - - if(href_list["p_stat"]) - if(src.active1) - switch(href_list["p_stat"]) - if("deceased") - src.active1.fields["p_stat"] = "*Deceased*" - if("ssd") - src.active1.fields["p_stat"] = "*SSD*" - if("active") - src.active1.fields["p_stat"] = "Active" - if("unfit") - src.active1.fields["p_stat"] = "Physically Unfit" - if("disabled") - src.active1.fields["p_stat"] = "Disabled" - if(PDA_Manifest.len) - PDA_Manifest.Cut() - - if(href_list["m_stat"]) - if(src.active1) - switch(href_list["m_stat"]) - if("insane") - src.active1.fields["m_stat"] = "*Insane*" - if("unstable") - src.active1.fields["m_stat"] = "*Unstable*" - if("watch") - src.active1.fields["m_stat"] = "*Watch*" - if("stable") - src.active1.fields["m_stat"] = "Stable" - - if(href_list["b_type"]) - if(src.active2) - switch(href_list["b_type"]) - if("an") - src.active2.fields["b_type"] = "A-" - if("bn") - src.active2.fields["b_type"] = "B-" - if("abn") - src.active2.fields["b_type"] = "AB-" - if("on") - src.active2.fields["b_type"] = "O-" - if("ap") - src.active2.fields["b_type"] = "A+" - if("bp") - src.active2.fields["b_type"] = "B+" - if("abp") - src.active2.fields["b_type"] = "AB+" - if("op") - src.active2.fields["b_type"] = "O+" - - if(href_list["del_r"]) - if(src.active2) - src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
    \n\tYes
    \n\tNo
    ", src, src) - - if(href_list["del_r2"]) - if(src.active2) - //src.active2 = null - qdel(src.active2) - - if(href_list["d_rec"]) - var/datum/data/record/R = locate(href_list["d_rec"]) - var/datum/data/record/M = locate(href_list["d_rec"]) - if(!data_core.general.Find(R)) - src.temp = "Record Not Found!" - return - for(var/datum/data/record/E in data_core.medical) - if(E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]) - M = E - else - //Foreach continue //goto(2540) - src.active1 = R - src.active2 = M - src.screen = 4 - - if(href_list["new"]) - if(istype(src.active1, /datum/data/record) && !istype(src.active2, /datum/data/record)) - var/datum/data/record/R = new /datum/data/record( ) - R.fields["name"] = src.active1.fields["name"] - R.fields["id"] = src.active1.fields["id"] - R.name = text("Medical Record #[]", R.fields["id"]) - R.fields["b_type"] = "Unknown" - R.fields["b_dna"] = "Unknown" - R.fields["mi_dis"] = "None" - R.fields["mi_dis_d"] = "No minor disabilities have been declared." - R.fields["ma_dis"] = "None" - R.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - R.fields["alg"] = "None" - R.fields["alg_d"] = "No allergies have been detected in this patient." - R.fields["cdi"] = "None" - R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - R.fields["notes"] = "No notes." - data_core.medical += R - src.active2 = R - src.screen = 4 - - if(href_list["add_c"]) - if(!istype(src.active2, /datum/data/record)) - return - var/a2 = src.active2 - var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) - if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2) - return - var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - counter++ - src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
    [t1]") - - if(href_list["del_c"]) - if(istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]) - src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" - - if(href_list["search"]) - var/t1 = input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text - if(!t1 || usr.stat || !src.authenticated || usr.restrained() || (!interactable() && !issilicon(usr))) - return - src.active1 = null - src.active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in data_core.medical) - if(lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"])) - src.active2 = R - if (!src.active2) - src.temp = text("Could not locate record [].", t1) - else - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"]) - src.active1 = E - src.screen = 4 - - if(href_list["print_p"]) - if(!src.printing) - src.printing = 1 - var/datum/data/record/record1 = null - var/datum/data/record/record2 = null - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - record1 = active1 - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - record2 = active2 - sleep(50) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( computer.loc ) - P.info = "
    Medical Record

    " - if(record1) - P.info += text("Name: [] ID: []
    \nSex: []
    \nAge: []
    \nFingerprint: []
    \nPhysical Status: []
    \nMental Status: []
    ", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) - P.name = text("Medical Record ([])", record1.fields["name"]) - else - P.info += "General Record Lost!
    " - P.name = "Medical Record" - if(record2) - P.info += text("
    \n
    Medical Data

    \nBlood Type: []
    \nDNA: []
    \n
    \nMinor Disabilities: []
    \nDetails: []
    \n
    \nMajor Disabilities: []
    \nDetails: []
    \n
    \nAllergies: []
    \nDetails: []
    \n
    \nCurrent Diseases: [] (per disease info placed in log/comment section)
    \nDetails: []
    \n
    \nImportant Notes:
    \n\t[]
    \n
    \n
    Comments/Log

    ", record2.fields["b_type"], record2.fields["b_dna"], record2.fields["mi_dis"], record2.fields["mi_dis_d"], record2.fields["ma_dis"], record2.fields["ma_dis_d"], record2.fields["alg"], record2.fields["alg_d"], record2.fields["cdi"], record2.fields["cdi_d"], decode(record2.fields["notes"])) - var/counter = 1 - while(record2.fields[text("com_[]", counter)]) - P.info += text("[]
    ", record2.fields[text("com_[]", counter)]) - counter++ - else - P.info += "Medical Record Lost!
    " - P.info += "" - src.printing = null - interact() - return diff --git a/code/game/machinery/computer3/computers/power.dm b/code/game/machinery/computer3/computers/power.dm deleted file mode 100644 index b6830a4cd3..0000000000 --- a/code/game/machinery/computer3/computers/power.dm +++ /dev/null @@ -1,48 +0,0 @@ -/obj/machinery/computer3/powermonitor - default_prog = /datum/file/program/powermon - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/cable) - icon_state = "frame-eng" - -/datum/file/program/powermon - name = "power monitoring console" - desc = "It monitors APC status." - active_state = "power" - -/datum/file/program/powermon/proc/format(var/obj/machinery/power/apc/A) - var/static/list/S = list(" Off","AOff"," On", " AOn") - var/static/list/chg = list("N","C","F") - return "[copytext(add_tspace("\The [A.area]", 30), 1, 30)] [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] \ - [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]
    " - -/datum/file/program/powermon/interact() - if(!interactable()) - return - if(!computer.net) - computer.Crash(MISSING_PERIPHERAL) - return - var/list/L = computer.net.get_machines(/obj/machinery/power/apc) - var/t = "" - t += "Refresh

    " - if(!L || !L.len) - t += "No connection" - else - var/datum/powernet/powernet = computer.net.connect_to(/datum/powernet,null) - if(powernet) - t += "
    Total power: [powernet.avail] W
    Total load: [num2text(powernet.viewload,10)] W
    " - else - t += "
    Power statistics unavailable
    " - t += "" - - if(L.len > 0) - t += "Area Eqp./Lgt./Env. Load Cell
    " - for(var/obj/machinery/power/apc/A in L) - t += src.format(A) - t += "
    " - - popup.set_content(t) - popup.open() - -/datum/file/program/powermon/Topic(var/href, var/list/href_list) - if(!interactable() || ..(href,href_list)) - return - interact() diff --git a/code/game/machinery/computer3/computers/prisoner.dm b/code/game/machinery/computer3/computers/prisoner.dm deleted file mode 100644 index b702c25ba2..0000000000 --- a/code/game/machinery/computer3/computers/prisoner.dm +++ /dev/null @@ -1,106 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 -/obj/machinery/computer3/prisoner - default_prog = /datum/file/program/prisoner - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) - icon_state = "frame-sec" - -/datum/file/program/prisoner - name = "Prisoner Management Console" - active_state = "explosive" - req_access = list(access_armory) - - var/id = 0.0 - var/temp = null - var/status = 0 - var/timeleft = 60 - var/stop = 0.0 - var/screen = 0 // 0 - No Access Denied, 1 - Access allowed - - -/datum/file/program/prisoner/interact() - if(!interactable()) - return - var/dat - dat += "Prisoner Implant Manager System
    " - if(screen == 0) - dat += "
    Unlock Console" - else if(screen == 1) - dat += "
    Chemical Implants
    " - var/turf/Tr = null - for(var/obj/item/weapon/implant/chem/C in all_chem_implants) - Tr = get_turf(C) - if((Tr) && (Tr.z != computer.z)) - continue //Out of range - if(!C.implanted) - continue - dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: " - dat += "((1))" - dat += "((5))" - dat += "((10))
    " - dat += "********************************
    " - dat += "
    Tracking Implants
    " - for(var/obj/item/weapon/implant/tracking/T in all_tracking_implants) - Tr = get_turf(T) - if((Tr) && (Tr.z != computer.z)) - continue //Out of range - if(!T.implanted) - continue - var/loc_display = "Unknown" - var/mob/living/carbon/M = T.imp_in - if(M.z in using_map.station_levels && !istype(M.loc, /turf/space)) - var/turf/mob_loc = get_turf(M) - loc_display = mob_loc.loc - if(T.malfunction) - loc_display = pick(teleportlocs) - dat += "ID: [T.id] | Location: [loc_display]
    " - dat += "(Send Message) |
    " - dat += "********************************
    " - dat += "
    Lock Console" - - popup.width = 400 - popup.height = 500 - popup.set_content(dat) - popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) - popup.open() - return - -/datum/file/program/prisoner/process() - if(!..()) - interact() - return - -/datum/file/program/prisoner/Topic(href, href_list) - if(!interactable() || ..(href,href_list)) - return - - if(href_list["inject1"]) - var/obj/item/weapon/implant/I = locate(href_list["inject1"]) - if(istype(I)) - I.activate(1) - - else if(href_list["inject5"]) - var/obj/item/weapon/implant/I = locate(href_list["inject5"]) - if(istype(I)) - I.activate(5) - - else if(href_list["inject10"]) - var/obj/item/weapon/implant/I = locate(href_list["inject10"]) - if(istype(I)) - I.activate(10) - - else if(href_list["lock"]) - screen = !screen - - else if(href_list["warn"]) - var/warning = sanitize(input(usr,"Message:","Enter your message here!","")) - if(!warning) return - var/obj/item/weapon/implant/I = locate(href_list["warn"]) - if(istype(I) && I.imp_in) - var/mob/living/carbon/R = I.imp_in - log_game("PrisonComputer3 message: [key_name(usr)]->[key_name(R)] : [warning]") - to_chat(R, "You hear a voice in your head saying: '[warning]'") - - interact() - return - - diff --git a/code/game/machinery/computer3/computers/robot.dm b/code/game/machinery/computer3/computers/robot.dm deleted file mode 100644 index 35c1090f67..0000000000 --- a/code/game/machinery/computer3/computers/robot.dm +++ /dev/null @@ -1,210 +0,0 @@ -/obj/machinery/computer3/robotics - default_prog = /datum/file/program/borg_control - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) - icon_state = "frame-rnd" - -/datum/file/program/borg_control - name = "Cyborg Control" - desc = "Used to remotely lockdown or detonate linked Cyborgs." - active_state = "robot" - var/id = 0.0 - var/temp = null - var/status = 0 - var/timeleft = 60 - var/stop = 0.0 - var/screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text - req_access = list(access_robotics) - -/datum/file/program/borg_control/proc/start_sequence() - do - if(src.stop) - src.stop = 0 - return - src.timeleft-- - sleep(10) - while(src.timeleft) - - for(var/mob/living/silicon/robot/R in mob_list) - if(!R.scrambledcodes) - R.self_destruct() - return - - -/datum/file/program/borg_control/interact() - if(!interactable() || computer.z > 6) - return - var/dat - if (src.temp) - dat = "[src.temp]

    Clear Screen" - else - if(screen == 0) - //dat += "

    Cyborg Control Console


    " - dat += "1. Cyborg Status
    " - dat += "2. Emergency Full Destruct
    " - if(screen == 1) - for(var/mob/living/silicon/robot/R in mob_list) - if(istype(usr, /mob/living/silicon/ai)) - if (R.connected_ai != usr) - continue - if(istype(usr, /mob/living/silicon/robot)) - if (R != usr) - continue - if(R.scrambledcodes) - continue - - dat += "[R.name] |" - if(R.stat) - dat += " Not Responding |" - else if (!R.canmove) - dat += " Locked Down |" - else - dat += " Operating Normally |" - if (!R.canmove) - else if(R.cell) - dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |" - else - dat += " No Cell Installed |" - if(R.module) - dat += " Module Installed ([R.module.name]) |" - else - dat += " No Module Installed |" - if(R.connected_ai) - dat += " Slaved to [R.connected_ai.name] |" - else - dat += " Independent from AI |" - if (istype(usr, /mob/living/silicon)) - if(issilicon(usr) && is_special_character(usr) && !R.emagged) - dat += "(Hack) " - dat += "([R.canmove ? "Lockdown" : "Release"]) " - dat += "(Destroy)" - dat += "
    " - dat += "(Return to Main Menu)
    " - if(screen == 2) - if(!src.status) - dat += {"
    Emergency Robot Self-Destruct
    \nStatus: Off
    - \n
    - \nCountdown: [src.timeleft]/60 \[Reset\]
    - \n
    - \nStart Sequence
    - \n
    - \nClose"} - else - dat = {"Emergency Robot Self-Destruct
    \nStatus: Activated
    - \n
    - \nCountdown: [src.timeleft]/60 \[Reset\]
    - \n
    \nStop Sequence
    - \n
    - \nClose"} - dat += "(Return to Main Menu)
    " - popup.set_content(dat) - popup.open() - return - -/datum/file/program/borg_control/Topic(var/href, var/list/href_list) - if(!interactable() || ..(href,href_list)) - return - - if("killall" in href_list) - src.temp = {"Destroy Robots?
    -
    \[Swipe ID to initiate destruction sequence\]
    - Cancel"} - - if("do_killall" in href_list) - var/obj/item/weapon/card/id/I = usr.get_active_hand() - if(istype(I, /obj/item/device/pda)) - var/obj/item/device/pda/pda = I - I = pda.id - if(istype(I)) - if(src.check_access(I)) - if(!status) - message_admins("[key_name_admin(usr)] has initiated the global cyborg killswitch!") - log_game("[key_name(usr)] has initiated the global cyborg killswitch!") - src.status = 1 - src.start_sequence() - src.temp = null - - else - to_chat(usr, "Access Denied.") - - if("stop" in href_list) - src.temp = {" - Stop Robot Destruction Sequence?
    -
    Yes
    - No"} - - if("stop2" in href_list) - src.stop = 1 - src.temp = null - src.status = 0 - - if("reset" in href_list) - src.timeleft = 60 - - if("temp" in href_list) - src.temp = null - if("screen" in href_list) - switch(href_list["screen"]) - if("0") - screen = 0 - if("1") - screen = 1 - if("2") - screen = 2 - if("killbot" in href_list) - if(computer.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["killbot"]) - if(R) - var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm") - if(R && istype(R)) - if(R.mind && R.mind.special_role && R.emagged) - to_chat(R, "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered.") - R.ResetSecurityCodes() - - else - message_admins("[key_name_admin(usr)] detonated [key_name(R.name)]!") - log_game("[key_name_admin(usr)] detonated [key_name(R.name)]!") - if(R.connected_ai) - to_chat(R.connected_ai, "

    ALERT - Cyborg kill-switch activated: [R.name]
    ") - R.self_destruct() - else - to_chat(usr, "Access Denied.") - - if("stopbot" in href_list) - if(computer.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) - if(R && istype(R)) // Extra sancheck because of input var references - var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm") - if(R && istype(R)) - message_admins("[key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") - log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R.name)]!") - R.canmove = !R.canmove - if(R.lockcharge) - R.lockcharge = !R.lockcharge - to_chat(R, "Your lockdown has been lifted!") - else - R.lockcharge = !R.lockcharge - to_chat(R, "You have been locked down!") - - else - to_chat(usr, "Access Denied.") - - if ("magbot" in href_list) - if(computer.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["magbot"]) - if(R) - var/choice = input("Are you certain you wish to hack [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm") - if(R && istype(R)) -// message_admins("[key_name_admin(usr)] emagged [R.name] using robotic console!") // why is this commented out? - log_game("[key_name(usr)] emagged [R.name] using robotic console!") - R.emagged = 1 - if(R.mind.special_role) - R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes - - interact() - return - - - diff --git a/code/game/machinery/computer3/computers/security.dm b/code/game/machinery/computer3/computers/security.dm deleted file mode 100644 index 92b1469edd..0000000000 --- a/code/game/machinery/computer3/computers/security.dm +++ /dev/null @@ -1,613 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 -/obj/machinery/computer3/secure_data - default_prog = /datum/file/program/secure_data - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) - icon_state = "frame-sec" - -/obj/machinery/computer3/laptop/secure_data - default_prog = /datum/file/program/secure_data - spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) - icon_state = "laptop" - - -/datum/file/program/secure_data - name = "Security Records" - desc = "Used to view and edit personnel's security records" - active_state = "security" - image = 'icons/ntos/records.png' - - req_one_access = list(access_security, access_forensics_lockers) - - var/obj/item/weapon/card/id/scan = null - var/obj/item/weapon/card/id/scan2 = null - var/authenticated = null - var/rank = null - var/screen = null - var/datum/data/record/active1 = null - var/datum/data/record/active2 = null - var/a_id = null - var/temp = null - var/printing = null - var/can_change_id = 0 - var/list/Perp - var/tempname = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending // 1 = Ascending - - - -/datum/file/program/secure_data/proc/authenticate() - if(access_security in scan.access || access_forensics_lockers in scan.access ) - return 1 - if(isAI(usr)) - return 1 - return 0 - -/datum/file/program/secure_data/interact() - if(!computer.cardslot) - computer.Crash(MISSING_PERIPHERAL) - return - usr.set_machine(src) - scan = computer.cardslot.reader - - if(istype(computer.cardslot, /obj/item/part/computer/cardslot/dual)) - var/obj/item/part/computer/cardslot/dual/D = computer.cardslot - scan2 = D.writer - - if(!interactable()) - return - - if(computer.z > 6) - to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return - var/dat - - if(temp) - dat = text("[]

    Clear Screen", temp, src) - else - dat = text("Confirm Identity (R): []
    ", src, (scan ? text("[]", scan.name) : "----------")) - if(istype(computer.cardslot, /obj/item/part/computer/cardslot/dual)) - dat += text("Confirm Identity (W): []
    ", src, (scan2 ? text("[]", scan2.name) : "----------")) - if(scan2 && !scan) - dat += text("
    Insert card into reader slot to log in.

    ") - if(authenticated) - switch(screen) - if(1.0) - dat += "

    " - dat += text("Search Records
    ", src) - dat += text("New Record
    ", src) - dat += {" -

    - - - - -
    Records:
    - - - - - - - - "} - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order)) - var/crimstat = "" - for(var/datum/data/record/E in data_core.security) - if(E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]) - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#DC143C;'" - if("Incarcerated") - background = "'background-color:#CD853F;'" - if("Parolled") - background = "'background-color:#CD853F;'" - if("Released") - background = "'background-color:#3BB9FF;'" - if("None") - background = "'background-color:#00FF00;'" - if("") - background = "'background-color:#00FF7F;'" - crimstat = "No Record." - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
    NameIDRankFingerprintsCriminal Status
    [][][][][]

    " - dat += text("Record Maintenance

    ", src) - dat += text("{Log Out}",src) - if(2.0) - dat += "Records Maintenance
    " - dat += "
    Delete All Records

    Back" - if(3.0) - dat += "
    Security Record

    " - if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - usr << browse_rsc(front, "front.png") - usr << browse_rsc(side, "side.png") - dat += text(" \ -
    \ - Name: [active1.fields["name"]]
    \ - ID: [active1.fields["id"]]
    \n \ - Entity Classification: [active1.fields["brain_type"]]
    \n \ - Sex: [active1.fields["sex"]]
    \n \ - Age: [active1.fields["age"]]
    \n \ - Rank: [active1.fields["rank"]]
    \n \ - Fingerprint: [active1.fields["fingerprint"]]
    \n \ - Physical Status: [active1.fields["p_stat"]]
    \n \ - Mental Status: [active1.fields["m_stat"]]
    Photo:
    \ -
    ") - else - dat += "General Record Lost!
    " - if(istype(active2, /datum/data/record) && data_core.security.Find(active2)) - dat += text("
    \n
    Security Data

    \nCriminal Status: []
    \n
    \nMinor Crimes: []
    \nDetails: []
    \n
    \nMajor Crimes: []
    \nDetails: []
    \n
    \nImportant Notes:
    \n\t[]
    \n
    \n
    Comments/Log

    ", src, active2.fields["criminal"], src, active2.fields["mi_crim"], src, active2.fields["mi_crim_d"], src, active2.fields["ma_crim"], src, active2.fields["ma_crim_d"], src, decode(active2.fields["notes"])) - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - dat += text("[]
    Delete Entry

    ", active2.fields[text("com_[]", counter)], src, counter) - counter++ - dat += text("Add Entry

    ", src) - dat += text("Delete Record (Security Only)

    ", src) - else - dat += "Security Record Lost!
    " - dat += text("New Security Record

    ", src) - dat += text("\nDelete Record (ALL)

    \nPrint Record
    \nBack
    ", src, src, src) - if(4.0) - if(!Perp.len) - dat += text("ERROR. String could not be located.

    Back", src) - else - dat += {" - - "} - dat += text("", tempname) - dat += {" - -
    Search Results for '[]':
    - - - - - - - - "} - for(var/i=1, i<=Perp.len, i += 2) - var/crimstat = "" - var/datum/data/record/R = Perp[i] - if(istype(Perp[i+1],/datum/data/record/)) - var/datum/data/record/E = Perp[i+1] - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#DC143C;'" - if("Incarcerated") - background = "'background-color:#CD853F;'" - if("Parolled") - background = "'background-color:#CD853F;'" - if("Released") - background = "'background-color:#3BB9FF;'" - if("None") - background = "'background-color:#00FF7F;'" - if("") - background = "'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
    NameIDRankFingerprintsCriminal Status
    [][][][][]

    " - dat += text("
    Return to index.", src) - else - else - dat += text("{Log In}", src) - popup.width = 600 - popup.height = 400 - popup.set_content(dat) - popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) - popup.open() - return - -/*Revised /N -I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. -What a mess.*/ -/datum/file/program/secure_data/Topic(href, href_list) - if(!interactable() || !computer.cardslot || ..(href,href_list)) - return - if (!data_core.general.Find(active1)) - active1 = null - if(!data_core.security.Find(active2)) - active2 = null - switch(href_list["choice"]) - // SORTING! - if("Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) - //BASIC FUNCTIONS - if("Clear Screen") - temp = null - - if("Return") - screen = 1 - active1 = null - active2 = null - - if("Confirm Identity R") - if(scan) - if(ishuman(usr) && !usr.get_active_hand()) - computer.cardslot.remove(usr, 1) - else - scan.loc = get_turf(src) - scan = null - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/weapon/card/id)) - usr << "Attempting to insert" - computer.cardslot.insert(I, usr) // No slot, will autofill - scan = I - - if("Confirm Identity W") - if(scan2) - if(ishuman(usr) && !usr.get_active_hand()) - computer.cardslot.remove(usr, 2) - else - scan2.loc = get_turf(src) - scan2 = null - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/weapon/card/id)) - computer.cardslot.insert(I, usr, 2) // Specifically writer slot - scan2 = I - - if("Log Out") - authenticated = null - screen = null - active1 = null - active2 = null - - if("Log In") - if(isAI(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - else if(isrobot(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - var/mob/living/silicon/robot/R = usr - src.rank = "[R.modtype] [R.braintype]" - src.screen = 1 - else if(istype(scan, /obj/item/weapon/card/id)) - active1 = null - active2 = null - if(authenticate()) - authenticated = scan.registered_name - rank = scan.assignment - screen = 1 - //RECORD FUNCTIONS - if("Search Records") - var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text - if(!t1 || usr.stat || !authenticated || usr.restrained() || !interactable()) - return - Perp = new/list() - t1 = lowertext(t1) - var/list/components = splittext(t1, " ") - if(components.len > 5) - return //Lets not let them search too greedily. - for(var/datum/data/record/R in data_core.general) - var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"] - for(var/i = 1, i<=components.len, i++) - if(findtext(temptext,components[i])) - var/prelist = new/list(2) - prelist[1] = R - Perp += prelist - for(var/i = 1, i<=Perp.len, i+=2) - for(var/datum/data/record/E in data_core.security) - var/datum/data/record/R = Perp[i] - if(E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]) - Perp[i+1] = E - tempname = t1 - screen = 4 - - if("Record Maintenance") - screen = 2 - active1 = null - active2 = null - - if("Browse Record") - var/datum/data/record/R = locate(href_list["d_rec"]) - var/S = locate(href_list["d_rec"]) - if(!data_core.general.Find(R)) - temp = "Record Not Found!" - else - for(var/datum/data/record/E in data_core.security) - if(E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]) - S = E - active1 = R - active2 = S - screen = 3 - -/* if ("Search Fingerprints") - var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!interactable()) && (!istype(usr, /mob/living/silicon)))) - return - active1 = null - active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in data_core.general) - if (lowertext(R.fields["fingerprint"]) == t1) - active1 = R - if (!( active1 )) - temp = text("Could not locate record [].", t1) - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"])) - active2 = E - screen = 3 */ - - if("Print Record") - if(!printing) - printing = 1 - var/datum/data/record/record1 = null - var/datum/data/record/record2 = null - if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) - record1 = active1 - if(istype(active2, /datum/data/record) && data_core.security.Find(active2)) - record2 = active2 - sleep(50) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( computer.loc ) - P.info = "
    Security Record

    " - if(record1) - P.info += text("Name: [] ID: []
    \nSex: []
    \nAge: []
    \nFingerprint: []
    \nPhysical Status: []
    \nMental Status: []
    ", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) - P.name = text("Security Record ([])", record1.fields["name"]) - else - P.info += "General Record Lost!
    " - P.name = "Security Record" - if(record2) - P.info += text("
    \n
    Security Data

    \nCriminal Status: []
    \n
    \nMinor Crimes: []
    \nDetails: []
    \n
    \nMajor Crimes: []
    \nDetails: []
    \n
    \nImportant Notes:
    \n\t[]
    \n
    \n
    Comments/Log

    ", record2.fields["criminal"], record2.fields["mi_crim"], record2.fields["mi_crim_d"], record2.fields["ma_crim"], record2.fields["ma_crim_d"], decode(record2.fields["notes"])) - var/counter = 1 - while(record2.fields[text("com_[]", counter)]) - P.info += text("[]
    ", record2.fields[text("com_[]", counter)]) - counter++ - else - P.info += "Security Record Lost!
    " - P.info += "" - printing = null - computer.updateUsrDialog() - //RECORD DELETE - if("Delete All Records") - temp = "" - temp += "Are you sure you wish to delete all Security records?
    " - temp += "Yes
    " - temp += "No" - - if("Purge All Records") - for(var/datum/data/record/R in data_core.security) - qdel(R) - temp = "All Security records deleted." - - if("Add Entry") - if(!istype(active2, /datum/data/record)) - return - var/a2 = active2 - var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2) - return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
    [t1]") - - if("Delete Record (ALL)") - if(active1) - temp = "
    Are you sure you wish to delete the record (ALL)?
    " - temp += "Yes
    " - temp += "No" - - if("Delete Record (Security)") - if(active2) - temp = "
    Are you sure you wish to delete the record (Security Portion Only)?
    " - temp += "Yes
    " - temp += "No" - - if("Delete Entry") - if(istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" - //RECORD CREATE - if("New Record (Security)") - if(istype(active1, /datum/data/record) && !istype(active2, /datum/data/record)) - active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"]) - screen = 3 - - if("New Record (General)") - active1 = data_core.CreateGeneralRecord() - active2 = null - - //FIELD FUNCTIONS - if("Edit Field") - var/a1 = active1 - var/a2 = active2 - switch(href_list["field"]) - if("name") - if(istype(active1, /datum/data/record)) - var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) - if(!t1 || !length(trim(t1)) || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1) - return - active1.fields["name"] = t1 - if("id") - if(istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1) - return - active1.fields["id"] = t1 - if("fingerprint") - if(istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1) - return - active1.fields["fingerprint"] = t1 - if("sex") - if(istype(active1, /datum/data/record)) - if(active1.fields["sex"] == "Male") - active1.fields["sex"] = "Female" - else - active1.fields["sex"] = "Male" - if("age") - if(istype(active1, /datum/data/record)) - var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1) - return - active1.fields["age"] = t1 - if("mi_crim") - if(istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2) - return - active2.fields["mi_crim"] = t1 - if("mi_crim_d") - if(istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message) - if (!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2) - return - active2.fields["mi_crim_d"] = t1 - if("ma_crim") - if(istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2) - return - active2.fields["ma_crim"] = t1 - if("ma_crim_d") - if(istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2) - return - active2.fields["ma_crim_d"] = t1 - if("notes") - if(istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2) - return - active2.fields["notes"] = t1 - if("criminal") - if (istype(active2, /datum/data/record)) - temp = "
    Criminal Status:
    " - temp += "" - if("rank") - var/list/L = list( "Head of Personnel", "Colony Director", "AI" ) - //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N - if ((istype(active1, /datum/data/record) && L.Find(rank))) - temp = "
    Rank:
    " - temp += "" - else - alert(usr, "You do not have the required rank to do this!") - if("species") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) - if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1) - return - active1.fields["species"] = t1 - - //TEMPORARY MENU FUNCTIONS - else//To properly clear as per clear screen. - temp=null - switch(href_list["choice"]) - if("Change Rank") - if(active1) - active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in joblist) - active1.fields["real_rank"] = href_list["real_rank"] - - if("Change Criminal Status") - if(active2) - for(var/mob/living/carbon/human/H in player_list) - BITSET(H.hud_updateflag, WANTED_HUD) - switch(href_list["criminal2"]) - if("none") - active2.fields["criminal"] = "None" - if("arrest") - active2.fields["criminal"] = "*Arrest*" - if("incarcerated") - active2.fields["criminal"] = "Incarcerated" - if("parolled") - active2.fields["criminal"] = "Parolled" - if("released") - active2.fields["criminal"] = "Released" - - if("Delete Record (Security) Execute") - if(active2) - qdel(active2) - - if("Delete Record (ALL) Execute") - if(active1) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]) - qdel(R) - else - qdel(active1) - if(active2) - qdel(active2) - else - temp = "This function does not appear to be working at the moment. Our apologies." - - //computer.updateUsrDialog() - interact() - return - -/obj/machinery/computer3/secure_data/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - - for(var/datum/data/record/R in data_core.security) - if(prob(10/severity)) - switch(rand(1,6)) - if(1) - R.fields["name"] = "[pick(pick(first_names_male), pick(first_names_female))] [pick(last_names)]" - if(2) - R.fields["sex"] = pick("Male", "Female") - if(3) - R.fields["age"] = rand(5, 85) - if(4) - R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Parolled", "Released") - if(5) - R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit") - if(PDA_Manifest.len) - PDA_Manifest.Cut() - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - continue - - else if(prob(1)) - qdel(R) - continue - - ..(severity) - -/obj/machinery/computer3/secure_data/detective_computer - icon = 'icons/obj/computer.dmi' - icon_state = "messyfiles" diff --git a/code/game/machinery/computer3/computers/welcome.dm b/code/game/machinery/computer3/computers/welcome.dm deleted file mode 100644 index 801a6cd93c..0000000000 --- a/code/game/machinery/computer3/computers/welcome.dm +++ /dev/null @@ -1,34 +0,0 @@ -/obj/machinery/computer3/laptop/vended - default_prog = /datum/file/program/welcome - - -/datum/file/program/welcome - name = "Welcome Screen" - desc = "First time boot splash screen" - active_state = "osod" - image = 'icons/ntos/program.png' - - -/datum/file/program/welcome/interact() - usr.set_machine(src) - if(!interactable()) - return - var/dat = "" - dat += "
    Welcome to NTOS
    " - dat += "
    Thank you for choosing NTOS, your gateway to the future of mobile computing technology, sponsored by [using_map.company_name] (R)

    " - dat += "Getting started with NTOS:
    " - dat += "To leave a current program, click the X button in the top right corner of the window. This will return you to the NTOS desktop. \ - From the desktop, you can open the hard drive, usually located in the top left corner to access all the programs installed on your computer. \ - When you rented your laptop, you were supplied with programs that your [using_map.company_name] Issued ID has given you access to use. \ - In the event of a serious error, the right click menu will give you the ability to reset your computer. To open and close your laptop, alt-click your device.\ - If you have any questions or technical issues, please contact your local computer technical experts at your local [using_map.boss_name]." - popup.set_content(dat) - popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) - popup.open() - return - -/datum/file/program/welcome/Topic(href, href_list) - if(!interactable() || ..(href,href_list)) - return - interact() - return \ No newline at end of file diff --git a/code/game/machinery/computer3/file.dm b/code/game/machinery/computer3/file.dm deleted file mode 100644 index 528aff8c87..0000000000 --- a/code/game/machinery/computer3/file.dm +++ /dev/null @@ -1,166 +0,0 @@ -// I am deciding that for sayustation's purposes directories are right out, -// we can't even get backpacks to work right with recursion, and that -// actually fucking matters. Metadata too, that can be added if ever needed. - -/* - Files are datums that can be stored in digital storage devices -*/ - -/datum/file - var/name = "File" - var/extension = "dat" - var/volume = 10 // in KB - var/image = 'icons/ntos/file.png' // determines the icon to use, found in icons/ntos - var/obj/machinery/computer3/computer // the parent computer, if fixed - var/obj/item/part/computer/storage/device // the device that is containing this file - var/hidden_file = 0 // Prevents file from showing up on NTOS program list. - var/drm = 0 // Copy protection, called by copy() and move() - var/readonly = 0 // Edit protection, called by edit(), which is just a failcheck proc - -/datum/file/proc/execute(var/datum/file/source) - return - -// -// Copy file to device. -// If you overwrite this function, use the return value to make sure it succeeded -// -/datum/file/proc/copy(var/obj/item/part/computer/storage/dest) - if(!computer) return null - if(drm) - if(!computer.emagged) - return null - var/datum/file/F = new type() - if(!dest.addfile(F)) - return null // todo: arf here even though the player can't do a damn thing due to concurrency - return F - -// -// Move file to device -// Returns null on failure even though the existing file doesn't go away -// -/datum/file/proc/move(var/obj/item/part/computer/storage/dest) - if(!computer) return null - if(drm) - if(!computer.emagged) - return null - var/obj/item/part/computer/storage/current = device - if(!dest.addfile(src)) - return null - current.removefile(src) - return src - -// -// Determines if the file is editable. This does not use the DRM flag, -// but instead the readonly flag. -// - -/datum/file/proc/edit() - if(!computer) - return 0 - if(readonly && !computer.emagged) - return 0 - return 1 - -/* - CentCom root authorization certificate - - Non-destructive, officially sanctioned. - Has the same effect on computers as an emag. -*/ -/datum/file/centcom_auth - name = "CentCom Root Access Token" - extension = "auth" - volume = 100 - copy() - return null - -/* - A file that contains information -*/ - -/datum/file/data - - var/content = "content goes here" - var/file_increment = 1 - var/binary = 0 // determines if the file can't be opened by editor - -/datum/file/data/New() - if(content) - if(file_increment > 1) - volume = round(file_increment * length(content)) - ..() - -// Set the content to a specific amount, increase filesize appropriately. -/datum/file/data/proc/set_content(var/text) - content = text - if(file_increment > 1) - volume = round(file_increment * length(text)) - -/datum/file/data/copy(var/obj/O) - var/datum/file/data/D = ..(O) - if(D) - D.content = content - D.readonly = readonly - -/* - A generic file that contains text -*/ - -/datum/file/data/text - name = "Text File" - extension = "txt" - image = 'icons/ntos/file.png' - content = "" - file_increment = 0.002 // 0.002 kilobytes per character (1024 characters per KB) - -/datum/file/data/text/ClownProphecy - name = "Clown Prophecy" - content = "HONKhHONKeHONKlHONKpHONKHONmKHONKeHONKHONKpHONKlHONKeHONKaHONKsHONKe" - - -/* - A file that contains research -*/ - -/datum/file/data/research - name = "Untitled Research" - binary = 1 - content = "Untitled Tier X Research" - var/datum/tech/stored // the actual tech contents - volume = 1440 - -/* - A file that contains genetic information -*/ - -/datum/file/data/genome - name = "Genetic Buffer" - binary = 1 - var/real_name = "Poop" - - -/datum/file/data/genome/SE - name = "Structural Enzymes" - -/datum/file/data/genome/UE - name = "Unique Enzymes" - -/* -the way genome computers now work, a subtype is the wrong way to do this; -it will no longer be picked up. You can change this later if you need to. -for now put it on a disk - -/datum/file/data/genome/UE/GodEmperorOfMankind - name = "G.E.M.K." - content = "066000033000000000AF00330660FF4DB002690" - label = "God Emperor of Mankind" -*/ -/datum/file/data/genome/UI - name = "Unique Identifier" - -/datum/file/data/genome/UI/UE - name = "Unique Identifier + Unique Enzymes" - -/datum/file/data/genome/cloning - name = "Cloning Data" - var/datum/data/record/record diff --git a/code/game/machinery/computer3/laptop.dm b/code/game/machinery/computer3/laptop.dm deleted file mode 100644 index 9a8ba02b00..0000000000 --- a/code/game/machinery/computer3/laptop.dm +++ /dev/null @@ -1,183 +0,0 @@ -/* - Computer3 portable computer. - - Battery powered only; it does not use the APC network at all. - - When picked up, becomes an inert item. This item can be put in a recharger, - or set down and re-opened into the original machine. While closed, the computer - has the MAINT stat flag. If you want to ignore this, you will have to bitmask it out. - - The unused(?) alt+click will toggle laptops open and closed. If we find a better - answer for this in the future, by all means use it. I just don't want it limited - to the verb, which is SIGNIFICANTLY less accessible than shutting a laptop. - Ctrl-click would work for closing the machine, since it's anchored, but not for - opening it back up again. And obviously, I don't want to override shift-click. - There's no double-click because that's used in regular click events. Alt-click is the - only obvious one left. -*/ - - -/obj/item/device/laptop - name = "Laptop Computer" - desc = "A clamshell portable computer. It is closed." - icon = 'icons/obj/computer3.dmi' - icon_state = "laptop-closed" - pixel_x = 2 - pixel_y = -3 - w_class = ITEMSIZE_NORMAL - - var/obj/machinery/computer3/laptop/stored_computer = null - -/obj/item/device/laptop/get_cell() - return stored_computer.battery - -/obj/item/device/laptop/verb/open_computer() - set name = "Open Laptop" - set category = "Object" - set src in view(1) - - if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) - to_chat(usr, "You can't do that.") - return - - if(!Adjacent(usr)) - to_chat(usr, "You can't reach it.") - return - - if(!istype(loc,/turf)) - to_chat(usr, "[src] is too bulky! You'll have to set it down.") - return - - if(!stored_computer) - if(contents.len) - for(var/obj/O in contents) - O.loc = loc - to_chat(usr, "\The [src] crumbles to pieces.") - spawn(5) - qdel(src) - return - - stored_computer.loc = loc - stored_computer.stat &= ~MAINT - stored_computer.update_icon() - loc = stored_computer - to_chat(usr, "You open \the [src].") - -/obj/item/device/laptop/AltClick() - if(Adjacent(usr)) - open_computer() - -//Quickfix until Snapshot works out how he wants to redo power. ~Z -/obj/item/device/laptop/verb/eject_id() - set category = "Object" - set name = "Eject ID Card" - set src in oview(1) - - if(stored_computer) - stored_computer.eject_id() - -/obj/machinery/computer3/laptop/verb/eject_id() - set category = "Object" - set name = "Eject ID Card" - set src in oview(1) - var/obj/item/part/computer/cardslot/C = locate() in src.contents - - if(!C) - to_chat(usr, "There is no card port on the laptop.") - return - - C.remove(usr) - return - -/obj/machinery/computer3/laptop - name = "Laptop Computer" - desc = "A clamshell portable computer. It is open." - - icon_state = "laptop" - density = 0 - pixel_x = 2 - pixel_y = -3 - show_keyboard = 0 - active_power_usage = 200 // Stationary consoles we use on station have 300, laptops are probably slightly more power efficient - idle_power_usage = 100 - - var/obj/item/device/laptop/portable = null - -/obj/machinery/computer3/laptop/New(var/L, var/built = 0) - if(!built && !battery) - battery = new /obj/item/weapon/cell(src) - battery.maxcharge = 500 - battery.charge = 500 - ..(L,built) - -/obj/machinery/computer3/laptop/verb/close_computer() - set name = "Close Laptop" - set category = "Object" - set src in view(1) - - if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) - to_chat(usr, "You can't do that.") - return - - if(!Adjacent(usr)) - to_chat(usr, "You can't reach it.") - return - - close_laptop(usr) - -/obj/machinery/computer3/laptop/proc/close_laptop(mob/user = null) - if(istype(loc,/obj/item/device/laptop)) - testing("Close closed computer") - return - if(!istype(loc,/turf)) - testing("Odd computer location: [loc] - close laptop") - return - - if(stat&BROKEN) - if(user) - to_chat(user, "\The [src] is broken! You can't quite get it closed.") - return - - if(!portable) - portable=new - portable.stored_computer = src - - portable.loc = loc - loc = portable - stat |= MAINT - if(user) - to_chat(user, "You close \the [src].") - -/obj/machinery/computer3/laptop/auto_use_power() - if(stat&MAINT) - return - if(use_power && istype(battery) && battery.charge > 0) - if(use_power == 1) - battery.use(idle_power_usage*CELLRATE) //idle and active_power_usage are in WATTS. battery.use() expects CHARGE. - else - battery.use(active_power_usage*CELLRATE) - return 1 - return 0 - -/obj/machinery/computer3/laptop/use_power(var/amount, var/chan = -1) - if(battery && battery.charge > 0) - battery.use(amount*CELLRATE) - -/obj/machinery/computer3/laptop/power_change() - if( !battery || battery.charge <= 0 ) - stat |= NOPOWER - else - stat &= ~NOPOWER - -/obj/machinery/computer3/laptop/Destroy() - if(istype(loc,/obj/item/device/laptop)) - var/obj/O = loc - spawn(5) - if(O) - qdel(O) - ..() - - -/obj/machinery/computer3/laptop/AltClick() - if(Adjacent(usr)) - close_computer() diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm deleted file mode 100644 index 7c4e458832..0000000000 --- a/code/game/machinery/computer3/lapvend.dm +++ /dev/null @@ -1,374 +0,0 @@ -/obj/machinery/lapvend - name = "Laptop Vendor" - desc = "A generic vending machine." - icon = 'icons/obj/vending.dmi' - icon_state = "robotics" - anchored = 1 - density = 1 - var/obj/machinery/computer3/laptop/vended/newlap = null - var/obj/item/device/laptop/relap = null - var/vendmode = 0 - - var/cardreader = 0 - var/floppy = 0 - var/radionet = 0 - var/camera = 0 - var/network = 0 - var/power = 0 - - -/obj/machinery/lapvend/New() - ..() - spawn(4) - power_change() - return - return - - -/obj/machinery/lapvend/attackby(obj/item/weapon/W as obj, mob/user as mob) - var/obj/item/weapon/card/id/I = W.GetID() - - if(default_unfasten_wrench(user, W, 20)) - return - - if(vendmode == 1 && I) - scan_id(I, W) - vendmode = 0 - SSnanoui.update_uis(src) - if(vendmode == 2 && I) - if(reimburse_id(I, W)) - vendmode = 0 - SSnanoui.update_uis(src) - if(vendmode == 0) - if(istype(W, /obj/item/device/laptop)) - var/obj/item/device/laptop/L = W - relap = L - calc_reimburse(L) - usr.drop_item() - L.loc = src - vendmode = 2 - to_chat(user, "You slot your [L.name] into \The [src.name]") - SSnanoui.update_uis(src) - else - ..() - - -/obj/machinery/lapvend/attack_hand(mob/user as mob) - if(stat & (BROKEN|NOPOWER)) - return - - ui_interact(user) - -/** - * Display the NanoUI window for the vending machine. - * - * See NanoUI documentation for details. - */ -/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) - - var/list/data = list() - data["mode"] = vendmode - data["cardreader"] = cardreader - data["floppy"] = floppy - data["radionet"] = radionet - data["camera"] = camera - data["network"] = network - data["power"] = power - data["total"] = total() - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "laptop_vendor.tmpl", src.name, 480, 425) - ui.set_initial_data(data) - ui.open() - //ui.set_auto_update(5) - -/obj/machinery/lapvend/Topic(href, href_list) - if(stat & (BROKEN|NOPOWER)) - return - if(usr.stat || usr.restrained()) - return - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) - usr.set_machine(src) - switch(href_list["choice"]) - if("single_add") - cardreader = 1 - if ("dual_add") - cardreader = 2 - if ("floppy_add") - floppy = 1 - if ("radio_add") - radionet = 1 - if ("camnet_add") - camera = 1 - if ("area_add") - network = 1 - if ("prox_add") - network = 2 - if ("cable_add") - network = 3 - if ("high_add") - power = 1 - if ("super_add") - power = 2 - - if ("cardreader_rem") - cardreader = 0 - if ("floppy_rem") - floppy = 0 - if ("radio_rem") - radionet = 0 - if ("camnet_rem") - camera = 0 - if ("network_rem") - network = 0 - if ("power_rem") - power = 0 - - if("vend") - vendmode = 1 - - if("cancel") - if(relap) - relap.loc = src.loc - relap = null - vendmode = 0 - - src.add_fingerprint(usr) - SSnanoui.update_uis(src) - -/obj/machinery/lapvend/proc/vend() - if(cardreader > 0) - if(cardreader == 1) - newlap.spawn_parts += (/obj/item/part/computer/cardslot) - else - newlap.spawn_parts += (/obj/item/part/computer/cardslot/dual) - if(floppy == 1) - newlap.spawn_parts += (/obj/item/part/computer/storage/removable) - if(radionet == 1) - newlap.spawn_parts += (/obj/item/part/computer/networking/radio) - if(camera == 1) - newlap.spawn_parts += (/obj/item/part/computer/networking/cameras) - if (network == 1) - newlap.spawn_parts += (/obj/item/part/computer/networking/area) - if (network == 2) - newlap.spawn_parts += (/obj/item/part/computer/networking/prox) - if (network == 3) - newlap.spawn_parts += (/obj/item/part/computer/networking/cable) - if (power == 1) - newlap.battery.maxcharge = 1000 - newlap.battery.charge = 1000 - if (power == 2) - newlap.battery.maxcharge = 1750 - newlap.battery.charge = 1750 - - newlap.spawn_parts() - -/obj/machinery/lapvend/proc/scan_id(var/obj/item/weapon/card/id/C, var/obj/item/I) - visible_message("\The [usr] swipes \the [I] through \the [src].") - var/datum/money_account/CH = get_account(C.associated_account_number) - if(!CH) - to_chat(usr, "\icon[src]No valid account number is associated with this card.") - return - if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) - if(vendor_account) - var/attempt_pin = input("Enter pin code", "Vendor transaction") as num - var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) - if(D) - transfer_and_vend(D, C) - else - to_chat(usr, "\icon[src]Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.") - else - to_chat(usr, "\icon[src]Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.") - else - transfer_and_vend(CH, C) - - -// Transfers money and vends the laptop. -/obj/machinery/lapvend/proc/transfer_and_vend(var/datum/money_account/D, var/obj/item/weapon/card/C) - var/transaction_amount = total() - if(transaction_amount <= D.money) - - //transfer the money - D.money -= transaction_amount - vendor_account.money += transaction_amount - //Transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of Laptop" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = stationtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Purchase of Laptop" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = stationtime2text() - vendor_account.transaction_log.Add(T) - - newlap = new /obj/machinery/computer3/laptop/vended(src.loc) - - choose_progs(C) - vend() - newlap.close_laptop() - newlap = null - cardreader = 0 - floppy = 0 - radionet = 0 - camera = 0 - network = 0 - power = 0 - else - to_chat(usr, "\icon[src]You don't have that much money!") - -/obj/machinery/lapvend/proc/total() - var/total = 0 - - if(cardreader == 1) - total += 50 - if(cardreader == 2) - total += 125 - if(floppy == 1) - total += 50 - if(radionet == 1) - total += 50 - if(camera == 1) - total += 100 - if(network == 1) - total += 75 - if(network == 2) - total += 50 - if(network == 3) - total += 25 - if(power == 1) - total += 175 - if(power == 2) - total += 250 - - return total - -/obj/machinery/lapvend/proc/choose_progs(var/obj/item/weapon/card/id/C) - if(access_security in C.access) - newlap.spawn_files += (/datum/file/program/secure_data) - newlap.spawn_files += (/datum/file/camnet_key) - newlap.spawn_files += (/datum/file/program/security) - if(access_armory in C.access) - newlap.spawn_files += (/datum/file/program/prisoner) - if(access_atmospherics in C.access) - newlap.spawn_files += (/datum/file/program/atmos_alert) - if(access_change_ids in C.access) - newlap.spawn_files += (/datum/file/program/card_comp) - if(access_heads in C.access) - newlap.spawn_files += (/datum/file/program/communications) - if((access_medical in C.access) || (access_forensics_lockers in C.access)) //Gives detective the medical records program, but not the crew monitoring one. - newlap.spawn_files += (/datum/file/program/med_data) - if (access_medical in C.access) - newlap.spawn_files += (/datum/file/program/crew) - if(access_engine in C.access) - newlap.spawn_files += (/datum/file/program/powermon) - if(access_research in C.access) - newlap.spawn_files += (/datum/file/camnet_key/research) - newlap.spawn_files += (/datum/file/camnet_key/bombrange) - newlap.spawn_files += (/datum/file/camnet_key/xeno) - if(access_rd in C.access) - newlap.spawn_files += (/datum/file/program/borg_control) - if(access_cent_specops in C.access) - newlap.spawn_files += (/datum/file/camnet_key/creed) - newlap.spawn_files += (/datum/file/program/arcade) - newlap.spawn_files += (/datum/file/camnet_key/entertainment) - //Atlantis: Each laptop gets "invisible" program/security - REQUIRED for camnetkeys to work. - newlap.spawn_files += (/datum/file/program/security/hidden) - newlap.update_spawn_files() - -/obj/machinery/lapvend/proc/calc_reimburse(var/obj/item/device/laptop/L) - if(istype(L.stored_computer.cardslot,/obj/item/part/computer/cardslot)) - cardreader = 1 - if(istype(L.stored_computer.cardslot,/obj/item/part/computer/cardslot/dual)) - cardreader = 2 - if(istype(L.stored_computer.floppy,/obj/item/part/computer/storage/removable)) - floppy = 1 - if(istype(L.stored_computer.radio,/obj/item/part/computer/networking/radio)) - radionet = 1 - if(istype(L.stored_computer.camnet,/obj/item/part/computer/networking/cameras)) - camera = 1 - if(istype(L.stored_computer.net,/obj/item/part/computer/networking/area)) - network = 1 - if(istype(L.stored_computer.net,/obj/item/part/computer/networking/prox)) - network = 2 - if(istype(L.stored_computer.net,/obj/item/part/computer/networking/cable)) - network = 3 - if(istype(L.stored_computer.battery, /obj/item/weapon/cell/high)) - power = 1 - if(istype(L.stored_computer.battery, /obj/item/weapon/cell/super)) - power = 2 - - - -/obj/machinery/lapvend/proc/reimburse_id(var/obj/item/weapon/card/id/C, var/obj/item/I) - visible_message("\The [usr] swipes \the [I] through \the [src].") - var/datum/money_account/CH = get_account(C.associated_account_number) - if(!CH) - to_chat(usr, "\icon[src]No valid account number is associated with this card.") - return 0 - if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) - if(vendor_account) - var/attempt_pin = input("Enter pin code", "Vendor transaction") as num - var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) - if(D) - transfer_and_reimburse(D) - return 1 - else - to_chat(usr, "\icon[src]Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.") - return 0 - else - to_chat(usr, "\icon[src]Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.") - return 0 - else - transfer_and_reimburse(CH) - return 1 - -/obj/machinery/lapvend/proc/transfer_and_reimburse(var/datum/money_account/D) - var/transaction_amount = total() - //transfer the money - D.money += transaction_amount - vendor_account.money -= transaction_amount - - //Transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Return purchase of Laptop" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = stationtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Return purchase of Laptop" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = stationtime2text() - vendor_account.transaction_log.Add(T) - - qdel(relap) - vendmode = 0 - cardreader = 0 - floppy = 0 - radionet = 0 - camera = 0 - network = 0 - power = 0 diff --git a/code/game/machinery/computer3/networking.dm b/code/game/machinery/computer3/networking.dm deleted file mode 100644 index 7b7922a635..0000000000 --- a/code/game/machinery/computer3/networking.dm +++ /dev/null @@ -1,243 +0,0 @@ -/obj/item/part/computer/networking - name = "Computer networking component" - -/obj/item/part/computer/networking/allow_attackby(var/obj/item/I, var/mob/user) - return 0 - -/* - This is the public-facing proc used by NETUP. - It does additional checking before and after calling get_machines() -*/ -/obj/item/part/computer/networking/proc/connect_to(var/typekey,var/atom/previous) - if(!computer || computer.stat) - return null - - if(istype(previous,typekey) && verify_machine(previous)) - return previous - - var/result = get_machines(typekey) - - if(!result) - return null - - if(islist(result)) - var/list/R = result - if(R.len == 0) - return null - else if(R.len == 1) - return R[1] - else - var/list/atomlist = computer.format_atomlist(R) - result = input("Select:","Multiple destination machines located",atomlist[1]) as null|anything in atomlist - return atomlist[result] - - if(isobj(result)) - return result - - return null // ? - -/* - This one is used to determine the candidate machines. - It may return an object, a list of objects, or null. - - Overwite this on any networking component. -*/ -/obj/item/part/computer/networking/proc/get_machines(var/typekey) - return list() - -/* - This is used to verify that an existing machine is within the network. - Calling NETUP() with an object argument will run this check, and if - the object is still accessible, it will be used. Otherwise, another - search will be run. - - Overwrite this on any networking component. -*/ -/obj/item/part/computer/networking/proc/verify_machine(var/obj/previous) - return 0 - -/* - Provides radio/signaler functionality, and also - network-connects to anything on the same z-level - which is tuned to the same frequency. -*/ -/obj/item/part/computer/networking/radio - name = "Wireless networking component" - desc = "Radio module for computers" - - var/datum/radio_frequency/radio_connection = null - var/frequency = PUB_FREQ - var/rad_filter = null - var/range = null - var/subspace = 0 - -/obj/item/part/computer/networking/radio/init() - ..() - spawn(5) - radio_connection = radio_controller.add_object(src, src.frequency, src.rad_filter) - -/obj/item/part/computer/networking/radio/proc/set_frequency(new_frequency) - if(radio_controller) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, rad_filter) - else - frequency = new_frequency - spawn(rand(5,10)) - set_frequency(new_frequency) - -/obj/item/part/computer/networking/radio/receive_signal(var/datum/signal/signal) - if(!signal || !computer || (computer.stat&~MAINT)) // closed laptops use maint, allow it - return - if(computer.program) - computer.program.receive_signal(signal) - -/obj/item/part/computer/networking/radio/proc/post_signal(var/datum/signal/signal) - if(!computer || (computer.stat&~MAINT) || !computer.program) - return - if(!radio_connection) - return - radio_connection.post_signal(src,signal,rad_filter,range) - -/obj/item/part/computer/networking/radio/get_machines(var/typekey) - if(!radio_connection || !radio_connection.frequency) - return list() - var/list/result = list() - var/turf/T = get_turf(loc) - var/z_level = T.z - for(var/obj/O in radio_connection.devices) - if(istype(O,typekey)) - T = get_turf(O) - if(istype(O) && (subspace || (O.z == z_level))) // radio does not work across z-levels - result |= O - return result - -/obj/item/part/computer/networking/radio/verify_machine(var/obj/previous) - if(!previous) - return 0 - if(subspace) - return ( radio_connection && (previous in radio_connection.devices) ) - else - var/turf/T = get_turf(loc) - var/turf/O = get_turf(previous) - if(!T || !O) - return 0 - return ( radio_connection && (previous in radio_connection.devices) && (T.z == O.z)) - -/* - Subspace networking: Communicates off-station. Allows centcom communications. -*/ -/obj/item/part/computer/networking/radio/subspace - name = "subspace networking terminal" - desc = "Communicates long distances and through spatial anomalies." - subspace = 1 - -/* - APC (/area) networking -*/ - -/obj/item/part/computer/networking/area - name = "short-wave networking terminal" - desc = "Connects to nearby computers through the area power network" - -/obj/item/part/computer/networking/area/get_machines(var/typekey) - var/area/A = get_area(loc) - if(!istype(A) || A == /area) - return list() - if(typekey == null) - typekey = /obj/machinery - var/list/machines = list() - for(var/obj/O in A.contents) - if(istype(O,typekey)) - machines |= O - return machines - -/obj/item/part/computer/networking/area/verify_machine(var/obj/previous) - if(!previous) return 0 - var/area/A = get_area(src) - if( A && A == get_area(previous) ) - return 1 - return 0 - -/* - Proximity networking: Connects to machines or computers adjacent to this device -*/ -/obj/item/part/computer/networking/prox - name = "proximity networking terminal" - desc = "Connects a computer to adjacent machines" - -/obj/item/part/computer/networking/prox/get_machines(var/typekey) - var/turf/T = get_turf(loc) - if(!istype(T)) - return list() - if(typekey == null) - typekey = /obj/machinery - var/list/nearby_machines = list() - for(var/obj/O in T) - if(istype(O,typekey)) - nearby_machines += O - for(var/d in cardinal) - var/turf/T2 = get_step(T,d) - for(var/obj/O in T2) - if(istype(O,typekey)) - nearby_machines += O - return nearby_machines - -/obj/item/part/computer/networking/prox/verify_machine(var/obj/previous) - if(!previous) - return 0 - if(get_dist(get_turf(previous),get_turf(loc)) == 1) - return 1 - return 0 - -/* - Cable networking: Not currently used -*/ -/obj/item/part/computer/networking/cable - name = "cable networking terminal" - desc = "Connects to other machines on the same cable network." - -/obj/item/part/computer/networking/cable/get_machines(var/typekey) -// if(istype(computer,/obj/machinery/computer/laptop)) // laptops move, this could get breaky -// return list() - var/turf/T = get_turf(loc) - var/datum/powernet/P = null - for(var/obj/structure/cable/C in T) - if(C.d1 == 0) - P = C.powernet - break - if(!P) - return list() - if(!typekey) - typekey = /obj/machinery - else if(typekey == /datum/powernet) - return list(P) - var/list/candidates = list() - for(var/atom/A in P.nodes) - if(istype(A,typekey)) - candidates += A - else if(istype(A,/obj/machinery/power/terminal)) - var/obj/machinery/power/terminal/PT = A - if(istype(PT.master,typekey)) - candidates += PT.master - return candidates - -/obj/item/part/computer/networking/cable/verify_machine(var/obj/previous) - if(!previous) - return 0 - var/turf/T = get_turf(loc) - var/datum/powernet/P = null - for(var/obj/structure/cable/C in T) - if(C.d1 == 0) - P = C.powernet - break - if(istype(previous,/datum/powernet)) - if(previous == P) - return 1 - return 0 - T = get_turf(previous.loc) - for(var/obj/structure/cable/C in T) - if(C.d1 == 0 && (C.powernet == P)) - return 1 - return 0 - diff --git a/code/game/machinery/computer3/program.dm b/code/game/machinery/computer3/program.dm deleted file mode 100644 index bf84c1622e..0000000000 --- a/code/game/machinery/computer3/program.dm +++ /dev/null @@ -1,404 +0,0 @@ - -/* -Programs are a file that can be executed -*/ - -/datum/file/program - name = "Untitled" - extension = "prog" - image = 'icons/ntos/program.png' - var/desc = "An unidentifiable program." - - var/image/overlay = null // Icon to be put on top of the computer frame. - - var/active_state = "generic" // the icon_state that the computer goes to when the program is active - - drm = 0 // prevents a program from being copied - var/refresh = 0 // if true, computer does screen updates during process(). - var/error = 0 // set by background programs so an error pops up when used - - var/human_controls = 0 // if true, non-human animals cannot interact with this program (monkeys, xenos, etc) - var/ai_allowed = 1 // if true, silicon mobs (AI/cyborg) are allowed to use this program. - - var/datum/browser/popup = null - - // ID access: Note that computer3 does not normally check your ID. - // By default this is only really used for inserted cards. - var/list/req_access = list() // requires all of these UNLESS below succeeds - var/list/req_one_access = list() // requires one of these - - -/datum/file/program/New() - ..() - if(!active_state) - active_state = "generic" - overlay = image('icons/obj/computer3.dmi',icon_state = active_state) - - -/datum/file/program/proc/decode(text) - //adds line breaks - text = replacetext(text, "\n","
    ") - return text - - - -/datum/file/program/execute(var/datum/file/source) - if(computer && !computer.stat) - computer.program = src - computer.req_access = req_access - computer.req_one_access = req_one_access - update_icon() - computer.update_icon() - if(usr) - usr << browse(null, "window=\ref[computer]") - computer.attack_hand(usr) - - ..() - -/* - Standard Topic() for links -*/ - -/datum/file/program/Topic(href, href_list) - return - -/* - The computer object will transfer all empty-hand calls to the program (this includes AIs, Cyborgs, and Monkies) -*/ -/datum/file/program/proc/interact() - return - -/* - Standard receive_signal() -*/ - -/datum/file/program/proc/receive_signal(var/datum/signal/signal) - return -/* - The computer object will transfer all attackby() calls to the program - If the item is a valid interactable object, return 1. Else, return 0. - This helps identify what to use to actually hit the computer with, and - what can be used to interact with it. - - Screwdrivers will, by default, never call program/attackby(). That's used - for deconstruction instead. -*/ - - -/datum/file/program/proc/attackby(O as obj, user as mob) - return - -/* - Try not to overwrite this proc, I'd prefer we stayed - with interact() as the main proc -*/ -/datum/file/program/proc/attack_hand(mob/user as mob) - usr = user - interact() - -/* - Called when the computer is rebooted or the program exits/restarts. - Be sure not to save any work. Do NOT start the program again. - If it is the os, the computer will run it again automatically. - - Also, we are deleting the browser window on the chance that this is happening - when the computer is damaged or disassembled, causing us to lose our computer. - The popup window's title is a reference to the computer, making it unique, so - it could introduce bugs in that case. -*/ -/datum/file/program/proc/Reset() - error = 0 - update_icon() - if(popup) - popup.close() - qdel(popup) - return - -/* - The computer object will transfer process() calls to the program. -*/ -/datum/file/program/process() - if(refresh && computer && !computer.stat) - computer.updateDialog() - update_icon() - -/datum/file/program/proc/update_icon() - return - -/datum/file/program/proc/check_access(obj/item/I) - if( (!istype(req_access) || !req_access.len) && (!istype(req_one_access) || !req_one_access.len) ) //no requirements - return 1 - - if(!I) - return 0 - - var/list/iAccess = I.GetAccess() - if(!iAccess || !iAccess.len) - return 0 - - var/list/temp = req_one_access & iAccess - if(temp.len) // a required access in item access list - return 1 - temp = req_access - iAccess - if(temp.len) // a required access not in item access list - return 0 - return 1 - - -/* - Because this does sanity checks I have added the code to make a popup here. - It also does sanity checks there that should prevent some edge case madness. -*/ -/datum/file/program/proc/interactable(var/mob/user = usr) - if(computer && computer.interactable(user)) - if(!popup) - popup = new(user, "\ref[computer]", name, nref=src) - popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) - popup.set_title_buttons(topic_link(src,"quit","")) - if(popup.user != user) - popup.user = user - popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) - popup.set_title(name) - return 1 - return 0 - - -/datum/file/program/proc/fake_link(var/text) - return "[text]" - -/* - Meant for text (not icons) - - lists all installed drives and their files - - I am NOT adding a computer sanity check here, - because why the flying fuck would you get to this - proc before having run it at least once? - If you cause runtimes with this function - may the shame of all ages come upon you. -*/ -/datum/file/program/proc/list_all_files_by_drive(var/typekey,var/linkop = "runfile") - var/dat = "" - if(!typekey) typekey = /datum/file - if(computer.hdd) - dat += "

    [computer.hdd]

    " - for(var/datum/file/F in computer.hdd.files) - if(istype(F,typekey)) - dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "
    " - if(computer.hdd.files.len == 0) - dat += "No files
    " - dat += "
    " - - if(computer.floppy) - if(!computer.floppy.inserted) - dat += "

    [computer.floppy] - Eject



    " - else - dat += "

    [computer.floppy] - [topic_link(src,"eject_disk","Eject")]

    " - for(var/datum/file/F in computer.floppy.inserted.files) - dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "
    " - if(computer.floppy.inserted.files.len == 0) - dat += "No files
    " - dat += "
    " - - if(computer.cardslot && istype(computer.cardslot.reader,/obj/item/weapon/card/data)) - dat += "

    [computer.cardslot.reader] - [topic_link(src,"eject_card=reader","Eject")]

    " - var/obj/item/weapon/card/data/D = computer.cardslot.reader - for(var/datum/file/F in D.files) - dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "
    " - if(D.files.len == 0) - dat += "No files
    " - return dat - -// You don't NEED to use this version of topic() for this, you can do it yourself if you prefer -// If you do, do the interactable() check first, please, I don't want to repeat it here. It's not hard. -/datum/file/program/Topic(var/href,var/list/href_list) - if(!computer) - return 0 - - // - // usage: eject_disk - // only functions if there is a removable drive - // - if("eject_disk" in href_list) - if(computer.floppy) - computer.floppy.eject_disk() - return 1 - // - // usage: eject_card | eject_card=reader | eject_card=writer - // only functions if there is a cardslot - // - if("eject_card" in href_list) - if(computer.cardslot) - if(istype(computer.cardslot, /obj/item/part/computer/cardslot/dual) && href_list["eject_card"] == "writer") - computer.cardslot.remove(usr) - else - computer.cardslot.remove(usr) - return 1 - // - // usage: runfile=\ref[file] - // executes the file - // - if("runfile" in href_list) - var/datum/file/F = locate(href_list["runfile"]) - if(istype(F) && F.computer == computer) - F.execute(src) - return 1 - - if("close" in href_list) - usr.unset_machine() - popup.close() - return 1 - // - // usage: quit - // unloads the program, returning control to the OS - // - if("quit" in href_list) - computer.program = null - usr << browse(null,"window=\ref[computer]") // ntos will need to resize the window - computer.update_icon() - computer.updateDialog() - return 1 - return 0 - - -/datum/file/program/RD - name = "R&D Manager" - image = 'icons/ntos/research.png' - desc = "A software suit for generic research and development machinery interaction. Comes pre-packaged with extensive cryptographic databanks for secure connections with external devices." - active_state = "rdcomp" - volume = 11000 - -/datum/file/program/RDserv - name = "R&D Server" - image = 'icons/ntos/server.png' - active_state = "rdcomp" - volume = 9000 - -/datum/file/program/SuitSensors - name = "Crew Monitoring" - image = 'icons/ntos/monitoring.png' - active_state = "crew" - volume = 3400 - -/datum/file/program/Genetics - name = "Genetics Suite" - image = 'icons/ntos/genetics.png' - desc = "A sophisticated software suite containing read-only genetics hardware specifications and a highly compressed genome databank." - active_state = "dna" - volume = 8000 - -/datum/file/program/Cloning - name = "Cloning Platform" - image = 'icons/ntos/cloning.png' - desc = "A software platform for accessing external cloning apparatus." - active_state = "dna" - volume = 7000 - -/datum/file/program/TCOMmonitor - name = "TComm Monitor" - image = 'icons/ntos/tcomms.png' - active_state = "comm_monitor" - volume = 5500 - -/datum/file/program/TCOMlogs - name = "TComm Log View" - image = 'icons/ntos/tcomms.png' - active_state = "comm_logs" - volume = 5230 - -/datum/file/program/TCOMtraffic - name = "TComm Traffic" - image = 'icons/ntos/tcomms.png' - active_state = "generic" - volume = 8080 - -/datum/file/program/securitycam - name = "Sec-Cam Viewport" - image = 'icons/ntos/camera.png' - drm = 1 - active_state = "cameras" - volume = 2190 - -/datum/file/program/securityrecords - name = "Security Records" - image = 'icons/ntos/records.png' - drm = 1 - active_state = "security" - volume = 2520 - -/datum/file/program/medicalrecords - name = "Medical Records" - image = 'icons/ntos/medical.png' - drm = 1 - active_state = "medcomp" - volume = 5000 - -/datum/file/program/SMSmonitor - name = "Messaging Monitor" - image = 'icons/ntos/pda.png' - active_state = "comm_monitor" - volume = 3070 - -/datum/file/program/OperationMonitor - name = "OR Monitor" - image = 'icons/ntos/operating.png' - active_state = "operating" - volume = 4750 - -/datum/file/program/PodLaunch - name = "Pod Launch" - active_state = "computer_generic" - volume = 520 - -/datum/file/program/powermon - name = "Power Grid" - image = 'icons/ntos/power.png' - active_state = "power" - volume = 7200 - -/datum/file/program/prisoner - name = "Prisoner Control" - image = 'icons/ntos/prison.png' - drm = 1 - active_state = "power" - volume = 5000 - -/datum/file/program/borg_control - name = "Cyborg Maint" - image = 'icons/ntos/borgcontrol.png' - active_state = "robot" - volume = 9050 - -/datum/file/program/AIupload - name = "AI Upload" - image = 'icons/ntos/aiupload.png' - active_state = "command" - volume = 5000 - -/datum/file/program/Cyborgupload - name = "Cyborg Upload" - image = 'icons/ntos/borgupload.png' - active_state = "command" - volume = 5000 - -/datum/file/program/Exosuit - name = "Exosuit Monitor" - image = 'icons/ntos/exocontrol.png' - active_state = "mecha" - volume = 7000 - -/datum/file/program/EmergencyShuttle - name = "Shuttle Console" - active_state = "shuttle" - volume = 10000 - -/datum/file/program/Stationalert - name = "Alert Monitor" - image = 'icons/ntos/alerts.png' - active_state = "computer_generic" - volume = 10150 - - - - - - diff --git a/code/game/machinery/computer3/program_disks.dm b/code/game/machinery/computer3/program_disks.dm deleted file mode 100644 index e9a649499b..0000000000 --- a/code/game/machinery/computer3/program_disks.dm +++ /dev/null @@ -1,51 +0,0 @@ - - -/obj/item/weapon/disk/file/arcade - name = "Arcade game grab pack" - desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/arcade,/datum/file/program/arcade,/datum/file/program/arcade,/datum/file/program/arcade) - -/*/obj/item/weapon/disk/file/aifixer - name = "AI System Integrity Restorer" - desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/aifixer)*/ - -/obj/item/weapon/disk/file/atmos_alert - name = "Atmospheric Alert Notifier" - desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/atmos_alert) - -/obj/item/weapon/disk/file/cameras - name = "Camera Viewer" - desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/security) - -/obj/item/weapon/disk/file/cameras/syndicate - name = "Camera Viewer" - desc = "A program install disk. A crude skull has been drawn on it and there is a list of items:\nFloppy Drive\nCamera Card\nNetwork Card: Adjacent\nPosition laptop nearby camera, enjoy." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/security/syndicate) - -/obj/item/weapon/disk/file/card - name = "ID Card Modifier" - desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/card_comp) -/* -/obj/item/weapon/disk/file/genetics - name = "Genetics & Cloning" - desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" - spawn_files = list(/datum/file/program/cloning,/datum/file/program/dnascanner) -*/ diff --git a/code/game/machinery/computer3/server.dm b/code/game/machinery/computer3/server.dm deleted file mode 100644 index 5c820ce0ca..0000000000 --- a/code/game/machinery/computer3/server.dm +++ /dev/null @@ -1,32 +0,0 @@ -/* - Todo: - I can probably get away with a global list on servers that contains database sort of stuff - (replacing the datacore probably) - with the justification that they loadbalance and duplicate data across each other. As long as - one server-type computer exists, the station will still have access to datacore-type info. - - I can doubtless use this for station alerts as well, which is good, because I was sort of - wondering how the hell I was going to port that. - - Also todo: Server computers should maybe generate heat the way the R&D server does? - At least the rack computer probably should. -*/ - -/obj/machinery/computer3/server - name = "server" - icon = 'icons/obj/computer3.dmi' - icon_state = "serverframe" - show_keyboard = 0 - -/obj/machinery/computer3/server/rack - name = "server rack" - icon_state = "rackframe" - - spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace) - -/obj/machinery/computer3/server/rack/update_icon() - //overlays.Cut() - return - -/obj/machinery/computer3/server/rack/attack_hand() // Racks have no screen, only AI can use them - return diff --git a/code/game/machinery/computer3/storage.dm b/code/game/machinery/computer3/storage.dm deleted file mode 100644 index 671d28c3a6..0000000000 --- a/code/game/machinery/computer3/storage.dm +++ /dev/null @@ -1,181 +0,0 @@ -/* - Computer devices that can store programs, files, etc. -*/ - -/obj/item/part/computer/storage - name = "Storage Device" - desc = "A device used for storing and retrieving digital information." - - // storage capacity, kb - var/volume = 0 - var/max_volume = 64 // should be enough for anyone - - var/driveletter = null // drive letter according to the computer - - var/list/files = list() // a list of files in the memory (ALL files) - var/removeable = 0 // determinse if the storage device is a removable hard drive (ie floppy) - - - var/writeprotect = 0 // determines if the drive forbids writing. - // note that write-protect is hardware and does not respect emagging. - - var/list/spawnfiles = list()// For mappers, special drives, and data disks - -/obj/item/part/computer/storage/New() - ..() - if(islist(spawnfiles)) - if(removeable && spawnfiles.len) - var/obj/item/part/computer/storage/removable/R = src - R.inserted = new(src) - if(writeprotect) - R.inserted.writeprotect = 1 - for(var/typekey in spawnfiles) - addfile(new typekey(),1) - -// Add a file to the hard drive, returns 0 if failed -// forced is used when spawning files on a write-protect drive -/obj/item/part/computer/storage/proc/addfile(var/datum/file/F,var/forced = 0) - if(!F || (F in files)) - return 1 - if(writeprotect && !forced) - return 0 - if(volume + F.volume > max_volume) - if(!forced) - return 0 - max_volume = volume + F.volume - - files.Add(F) - volume += F.volume - F.computer = computer - F.device = src - return 1 -/obj/item/part/computer/storage/proc/removefile(var/datum/file/F,var/forced = 0) - if(!F || !(F in files)) - return 1 - if(writeprotect && !forced) - return 0 - - files -= F - volume -= F.volume - if(F.device == src) - F.device = null - F.computer = null - return 1 - -/obj/item/part/computer/storage/init(var/obj/machinery/computer/target) - computer = target - for(var/datum/file/F in files) - F.computer = computer - -/* - Standard hard drives for computers. Used in computer construction -*/ -/obj/item/part/computer/storage/hdd - name = "Hard Drive" - max_volume = 25000 - icon_state = "hdd1" - - -/obj/item/part/computer/storage/hdd/big - name = "Big Hard Drive" - max_volume = 50000 - icon_state = "hdd2" - -/obj/item/part/computer/storage/hdd/gigantic - name = "Gigantic Hard Drive" - max_volume = 75000 - icon_state = "hdd3" - -/* - Removeable hard drives for portable storage -*/ - -/obj/item/part/computer/storage/removable - name = "Disk Drive" - max_volume = 3000 - removeable = 1 - - attackby_types = list(/obj/item/weapon/disk/file, /obj/item/weapon/pen) - var/obj/item/weapon/disk/file/inserted = null - -/obj/item/part/computer/storage/removable/proc/eject_disk(var/forced = 0) - if(!forced) - return - files = list() - inserted.loc = computer.loc - if(usr) - if(!usr.get_active_hand()) - usr.put_in_active_hand(inserted) - else if(forced && !usr.get_inactive_hand()) - usr.put_in_inactive_hand(inserted) - for(var/datum/file/F in inserted.files) - F.computer = null - inserted = null - - -/obj/item/part/computer/storage/removable/attackby(obj/O as obj, mob/user as mob) - if(inserted && istype(O,/obj/item/weapon/pen)) - to_chat(usr, "You use [O] to carefully pry [inserted] out of [src].") - eject_disk(forced = 1) - return - - if(istype(O,/obj/item/weapon/disk/file)) - if(inserted) - to_chat(usr, "There's already a disk in [src]!") - return - - to_chat(usr, "You insert [O] into [src].") - usr.drop_item() - O.loc = src - inserted = O - writeprotect = inserted.writeprotect - - files = inserted.files - for(var/datum/file/F in inserted.files) - F.computer = computer - - return - ..() - -/obj/item/part/computer/storage/removable/addfile(var/datum/file/F) - if(!F || !inserted) - return 0 - - if(F in inserted.files) - return 1 - - if(inserted.volume + F.volume > inserted.max_volume) - return 0 - - inserted.files.Add(F) - F.computer = computer - F.device = inserted - return 1 - -/* - Removable hard drive presents... - removeable disk! -*/ -/obj/item/weapon/disk/file - //parent_type = /obj/item/part/computer/storage // todon't: do this - name = "Data Disk" - desc = "A device that can be inserted and removed into computers easily as a form of portable data storage. This one stores 1 Megabyte" - var/list/files - var/list/spawn_files = list() - var/writeprotect = 0 - var/volume = 0 - var/max_volume = 1028 - - -/obj/item/weapon/disk/file/New() - ..() - icon_state = "datadisk[rand(0,6)]" - src.pixel_x = rand(-5, 5) - src.pixel_y = rand(-5, 5) - files = list() - if(istype(spawn_files)) - for(var/typekey in spawn_files) - var/datum/file/F = new typekey() - F.device = src - files += F - volume += F.volume diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 0729121195..5486facff1 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -446,3 +446,9 @@ Class Procs: M.deconstruct(src) qdel(src) return 1 + +/datum/proc/apply_visual(mob/M) + return + +/datum/proc/remove_visual(mob/M) + return \ No newline at end of file diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 0b985d3047..b23897e9eb 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -8,7 +8,11 @@ obj/machinery/recharger idle_power_usage = 4 active_power_usage = 40000 //40 kW var/obj/item/charging = null +<<<<<<< HEAD var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/device/laptop, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/ammo_casing/nsfw_batt) //VOREStation Add - NSFW Batteries +======= + var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash) +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd var/icon_state_charged = "recharger2" var/icon_state_charging = "recharger1" var/icon_state_idle = "recharger0" //also when unpowered @@ -44,7 +48,16 @@ obj/machinery/recharger if(E.self_recharge) to_chat(user, "Your gun has no recharge port.") return +<<<<<<< HEAD if(!G.get_cell() && !istype(G, /obj/item/ammo_casing/nsfw_batt)) //VOREStation Edit: NSFW charging +======= + if(istype(G, /obj/item/modular_computer)) + var/obj/item/modular_computer/C = G + if(!C.battery_module) + to_chat(user, "This device does not have a battery installed.") + return + else if(!G.get_cell()) +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd to_chat(user, "This device does not have a battery installed.") return @@ -86,6 +99,27 @@ obj/machinery/recharger update_use_power(1) icon_state = icon_state_idle else + if(istype(charging, /obj/item/modular_computer)) + var/obj/item/modular_computer/C = charging + if(!C.battery_module.battery.fully_charged()) + icon_state = icon_state_charging + C.battery_module.battery.give(active_power_usage*CELLRATE) + update_use_power(2) + else + icon_state = icon_state_charged + update_use_power(1) + return + else if(istype(charging, /obj/item/weapon/computer_hardware/battery_module)) + var/obj/item/weapon/computer_hardware/battery_module/BM = charging + if(!BM.battery.fully_charged()) + icon_state = icon_state_charging + BM.battery.give(active_power_usage*CELLRATE) + update_use_power(2) + else + icon_state = icon_state_charged + update_use_power(1) + return + var/obj/item/weapon/cell/C = charging.get_cell() if(istype(C)) if(!C.fully_charged()) diff --git a/code/game/objects/items/devices/holowarrant.dm b/code/game/objects/items/devices/holowarrant.dm new file mode 100644 index 0000000000..e2fdd4269e --- /dev/null +++ b/code/game/objects/items/devices/holowarrant.dm @@ -0,0 +1,110 @@ +/obj/item/device/holowarrant + name = "warrant projector" + desc = "The practical paperwork replacement for the officer on the go." + icon_state = "holowarrant" + item_state = "flashtool" + throwforce = 5 + w_class = ITEMSIZE_SMALL + throw_speed = 4 + throw_range = 10 + var/datum/data/record/warrant/active + +//look at it +/obj/item/device/holowarrant/examine(mob/user) + . = ..() + if(active) + to_chat(user, "It's a holographic warrant for '[active.fields["namewarrant"]]'.") + if(in_range(user, src) || isghost(user)) + show_content(user) + else + to_chat(user, "You have to go closer if you want to read it.") + +//hit yourself with it +/obj/item/device/holowarrant/attack_self(mob/living/user as mob) + active = null + var/list/warrants = list() + if(!isnull(data_core.general)) + for(var/datum/data/record/warrant/W in data_core.warrants) + warrants += W.fields["namewarrant"] + if(warrants.len == 0) + to_chat(user,"There are no warrants available") + return + var/temp + temp = input(user, "Which warrant would you like to load?") as null|anything in warrants + for(var/datum/data/record/warrant/W in data_core.warrants) + if(W.fields["namewarrant"] == temp) + active = W + update_icon() + +/obj/item/device/holowarrant/attackby(obj/item/weapon/W, mob/user) + if(active) + var/obj/item/weapon/card/id/I = W.GetIdCard() + if(I) + var/choice = alert(user, "Would you like to authorize this warrant?","Warrant authorization","Yes","No") + if(choice == "Yes") + active.fields["auth"] = "[I.registered_name] - [I.assignment ? I.assignment : "(Unknown)"]" + user.visible_message("You swipe \the [I] through the [src].", \ + "[user] swipes \the [I] through the [src].") + return 1 + ..() + +//hit other people with it +/obj/item/device/holowarrant/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) + user.visible_message("You show the warrant to [M].", \ + "[user] holds up a warrant projector and shows the contents to [M].") + M.examinate(src) + +/obj/item/device/holowarrant/update_icon() + if(active) + icon_state = "holowarrant_filled" + else + icon_state = "holowarrant" + +/obj/item/device/holowarrant/proc/show_content(mob/user, forceshow) + if(!active) + return + if(active.fields["arrestsearch"] == "arrest") + var/output = {" + [active.fields["namewarrant"]] +
    Sol Central Government Colonial Marshal Bureau
    + in the jurisdiction of the
    + [using_map.boss_name] in [using_map.system_name]
    +
    + ARREST WARRANT

    +
    + This document serves as authorization and notice for the arrest of _[active.fields["namewarrant"]]____ for the crime(s) of:
    [active.fields["charges"]]
    +
    + Vessel or habitat: _[using_map.station_name]____
    +
    _[active.fields["auth"]]____
    + Person authorizing arrest
    + + "} + + show_browser(user, output, "window=Warrant for the arrest of [active.fields["namewarrant"]]") + if(active.fields["arrestsearch"] == "search") + var/output= {" + Search Warrant: [active.fields["namewarrant"]] +
    in the jurisdiction of the
    + [using_map.boss_name] in [using_map.system_name]
    +
    + SEARCH WARRANT

    +
    + The Security Officer(s) bearing this Warrant are hereby authorized by the Issuer
    + to conduct a one time lawful search of the Suspect's person/belongings/premises and/or Department
    + for any items and materials that could be connected to the suspected criminal act described below,
    + pending an investigation in progress. The Security Officer(s) are obligated to remove any and all
    + such items from the Suspects posession and/or Department and file it as evidence. The Suspect/Department
    + staff is expected to offer full co-operation. In the event of the Suspect/Department staff attempting
    + to resist/impede this search or flee, they must be taken into custody immediately!
    + All confiscated items must be filed and taken to Evidence!

    +
    + Suspect's/location name: [active.fields["namewarrant"]]
    +
    + For the following reasons: [active.fields["charges"]]
    +
    + Warrant issued by: [active.fields ["auth"]]
    +
    + Vessel or habitat: _[using_map.station_name]____
    + + "} + show_browser(user, output, "window=Search warrant for [active.fields["namewarrant"]]") \ No newline at end of file diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm index 38605da018..23dc77d143 100644 --- a/code/game/objects/items/devices/uplink_random_lists.dm +++ b/code/game/objects/items/devices/uplink_random_lists.dm @@ -74,7 +74,6 @@ var/datum/uplink_random_selection/all_uplink_selection = new/datum/uplink_random items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit) items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector) items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice) - items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/camera_floppy, 10, 0) items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/heavy_vest) items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/combat) diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/weapons/circuitboards/machinery/research.dm index 3fc0aa26ab..2bfdde4977 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/research.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/research.dm @@ -85,4 +85,12 @@ obj/item/weapon/circuitboard/rdserver/attackby(obj/item/I as obj, mob/user as mo /obj/item/weapon/stock_parts/matter_bin = 2, /obj/item/weapon/stock_parts/manipulator = 1, /obj/item/weapon/stock_parts/micro_laser = 1, - /obj/item/weapon/stock_parts/console_screen = 1) \ No newline at end of file + /obj/item/weapon/stock_parts/console_screen = 1) + +obj/item/weapon/circuitboard/ntnet_relay + name = "Circuit board (NTNet Quantum Relay)" + build_path = "/obj/machinery/ntnet_relay" + board_type = "machine" + origin_tech = list(TECH_DATA = 4) + req_components = list( + "/obj/item/stack/cable_coil" = 15) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 7d0b7ee259..3475e60314 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -575,15 +575,9 @@ Traitors and the like can also be revived with the previous role mostly intact. return if(!customname) customname = "[using_map.company_name] Update" - for (var/obj/machinery/computer/communications/C in machines) - if(! (C.stat & (BROKEN|NOPOWER) ) ) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc ) - P.name = "'[command_name()] Update.'" - P.info = replacetext(input, "\n", "
    ") - P.update_space(P.info) - P.update_icon() - C.messagetitle.Add("[command_name()] Update") - C.messagetext.Add(P.info) + + //New message handling + post_comm_message(customname, replacetext(input, "\n", "
    ")) switch(alert("Should this be announced to the general population?",,"Yes","No")) if("Yes") diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm index d7a7cdf713..22b069093a 100644 --- a/code/modules/alarm/alarm_handler.dm +++ b/code/modules/alarm/alarm_handler.dm @@ -50,6 +50,11 @@ /datum/alarm_handler/proc/major_alarms() return visible_alarms() +/datum/alarm_handler/proc/has_major_alarms() + if(alarms && alarms.len) + return 1 + return 0 + /datum/alarm_handler/proc/minor_alarms() return visible_alarms() diff --git a/code/modules/client/preference_setup/loadout/gear_tweaks.dm b/code/modules/client/preference_setup/loadout/gear_tweaks.dm index e8b1a56d62..2b86685f17 100644 --- a/code/modules/client/preference_setup/loadout/gear_tweaks.dm +++ b/code/modules/client/preference_setup/loadout/gear_tweaks.dm @@ -140,3 +140,300 @@ else . = valid_reagents[metadata] I.reagents.add_reagent(., I.reagents.get_free_space()) + + +/datum/gear_tweak/tablet + var/list/ValidProcessors = list(/obj/item/weapon/computer_hardware/processor_unit/small) + var/list/ValidBatteries = list(/obj/item/weapon/computer_hardware/battery_module/nano, /obj/item/weapon/computer_hardware/battery_module/micro, /obj/item/weapon/computer_hardware/battery_module) + var/list/ValidHardDrives = list(/obj/item/weapon/computer_hardware/hard_drive/micro, /obj/item/weapon/computer_hardware/hard_drive/small, /obj/item/weapon/computer_hardware/hard_drive) + var/list/ValidNetworkCards = list(/obj/item/weapon/computer_hardware/network_card, /obj/item/weapon/computer_hardware/network_card/advanced) + var/list/ValidNanoPrinters = list(null, /obj/item/weapon/computer_hardware/nano_printer) + var/list/ValidCardSlots = list(null, /obj/item/weapon/computer_hardware/card_slot) + var/list/ValidTeslaLinks = list(null, /obj/item/weapon/computer_hardware/tesla_link) + +/datum/gear_tweak/tablet/get_contents(var/list/metadata) + var/list/names = list() + var/obj/O = ValidProcessors[metadata[1]] + if(O) + names += initial(O.name) + O = ValidBatteries[metadata[2]] + if(O) + names += initial(O.name) + O = ValidHardDrives[metadata[3]] + if(O) + names += initial(O.name) + O = ValidNetworkCards[metadata[4]] + if(O) + names += initial(O.name) + O = ValidNanoPrinters[metadata[5]] + if(O) + names += initial(O.name) + O = ValidCardSlots[metadata[6]] + if(O) + names += initial(O.name) + O = ValidTeslaLinks[metadata[7]] + if(O) + names += initial(O.name) + return "[english_list(names, and_text = ", ")]" + +/datum/gear_tweak/tablet/get_metadata(var/user, var/metadata) + . = list() + + var/list/names = list() + var/counter = 1 + for(var/i in ValidProcessors) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + var/entry = input(user, "Choose a processor.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidBatteries) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a battery.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidHardDrives) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a hard drive.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidNetworkCards) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a network card.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidNanoPrinters) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a nanoprinter.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidCardSlots) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a card slot.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidTeslaLinks) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a tesla link.", "Character Preference") in names + . += names[entry] + +/datum/gear_tweak/tablet/get_default() + return list(1, 1, 1, 1, 1, 1, 1) + +/datum/gear_tweak/tablet/tweak_item(var/obj/item/modular_computer/tablet/I, var/list/metadata) + if(ValidProcessors[metadata[1]]) + var/t = ValidProcessors[metadata[1]] + I.processor_unit = new t(I) + if(ValidBatteries[metadata[2]]) + var/t = ValidBatteries[metadata[2]] + I.battery_module = new t(I) + I.battery_module.charge_to_full() + if(ValidHardDrives[metadata[3]]) + var/t = ValidHardDrives[metadata[3]] + I.hard_drive = new t(I) + if(ValidNetworkCards[metadata[4]]) + var/t = ValidNetworkCards[metadata[4]] + I.network_card = new t(I) + if(ValidNanoPrinters[metadata[5]]) + var/t = ValidNanoPrinters[metadata[5]] + I.nano_printer = new t(I) + if(ValidCardSlots[metadata[6]]) + var/t = ValidCardSlots[metadata[6]] + I.card_slot = new t(I) + if(ValidTeslaLinks[metadata[7]]) + var/t = ValidTeslaLinks[metadata[7]] + I.tesla_link = new t(I) + +/datum/gear_tweak/laptop + var/list/ValidProcessors = list(/obj/item/weapon/computer_hardware/processor_unit/small, /obj/item/weapon/computer_hardware/processor_unit) + var/list/ValidBatteries = list(/obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/computer_hardware/battery_module/advanced, /obj/item/weapon/computer_hardware/battery_module/super) + var/list/ValidHardDrives = list(/obj/item/weapon/computer_hardware/hard_drive, /obj/item/weapon/computer_hardware/hard_drive/advanced, /obj/item/weapon/computer_hardware/hard_drive/super) + var/list/ValidNetworkCards = list(/obj/item/weapon/computer_hardware/network_card, /obj/item/weapon/computer_hardware/network_card/advanced) + var/list/ValidNanoPrinters = list(null, /obj/item/weapon/computer_hardware/nano_printer) + var/list/ValidCardSlots = list(null, /obj/item/weapon/computer_hardware/card_slot) + var/list/ValidTeslaLinks = list(null, /obj/item/weapon/computer_hardware/tesla_link) + +/datum/gear_tweak/laptop/get_contents(var/list/metadata) + var/list/names = list() + var/obj/O = ValidProcessors[metadata[1]] + if(O) + names += initial(O.name) + O = ValidBatteries[metadata[2]] + if(O) + names += initial(O.name) + O = ValidHardDrives[metadata[3]] + if(O) + names += initial(O.name) + O = ValidNetworkCards[metadata[4]] + if(O) + names += initial(O.name) + O = ValidNanoPrinters[metadata[5]] + if(O) + names += initial(O.name) + O = ValidCardSlots[metadata[6]] + if(O) + names += initial(O.name) + O = ValidTeslaLinks[metadata[7]] + if(O) + names += initial(O.name) + return "[english_list(names, and_text = ", ")]" + +/datum/gear_tweak/laptop/get_metadata(var/user, var/metadata) + . = list() + + var/list/names = list() + var/counter = 1 + for(var/i in ValidProcessors) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + var/entry = input(user, "Choose a processor.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidBatteries) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a battery.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidHardDrives) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a hard drive.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidNetworkCards) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a network card.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidNanoPrinters) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a nanoprinter.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidCardSlots) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a card slot.", "Character Preference") in names + . += names[entry] + + names = list() + counter = 1 + for(var/i in ValidTeslaLinks) + if(i) + var/obj/O = i + names[initial(O.name)] = counter++ + else + names["None"] = counter++ + + entry = input(user, "Choose a tesla link.", "Character Preference") in names + . += names[entry] + +/datum/gear_tweak/laptop/get_default() + return list(1, 1, 1, 1, 1, 1, 1) + +/datum/gear_tweak/laptop/tweak_item(var/obj/item/modular_computer/laptop/preset/I, var/list/metadata) + if(ValidProcessors[metadata[1]]) + var/t = ValidProcessors[metadata[1]] + I.processor_unit = new t(I) + if(ValidBatteries[metadata[2]]) + var/t = ValidBatteries[metadata[2]] + I.battery_module = new t(I) + I.battery_module.charge_to_full() + if(ValidHardDrives[metadata[3]]) + var/t = ValidHardDrives[metadata[3]] + I.hard_drive = new t(I) + if(ValidNetworkCards[metadata[4]]) + var/t = ValidNetworkCards[metadata[4]] + I.network_card = new t(I) + if(ValidNanoPrinters[metadata[5]]) + var/t = ValidNanoPrinters[metadata[5]] + I.nano_printer = new t(I) + if(ValidCardSlots[metadata[6]]) + var/t = ValidCardSlots[metadata[6]] + I.card_slot = new t(I) + if(ValidTeslaLinks[metadata[7]]) + var/t = ValidTeslaLinks[metadata[7]] + I.tesla_link = new t(I) diff --git a/code/modules/client/preference_setup/loadout/loadout_utility.dm b/code/modules/client/preference_setup/loadout/loadout_utility.dm index 52fce45031..06753139c7 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility.dm @@ -159,3 +159,48 @@ /datum/gear/utility/umbrella/New() ..() gear_tweaks = list(gear_tweak_free_color_choice) + +/**************** +modular computers +****************/ + +/datum/gear/utility/cheaptablet + display_name = "tablet computer: cheap" + display_name = "tablet computer, cheap" + path = /obj/item/modular_computer/tablet/preset/custom_loadout/cheap + cost = 3 + +/datum/gear/utility/normaltablet + display_name = "tablet computer: advanced" + display_name = "tablet computer, advanced" + path = /obj/item/modular_computer/tablet/preset/custom_loadout/advanced + cost = 4 + +/datum/gear/utility/customtablet + display_name = "tablet computer: custom" + display_name = "tablet computer, custom" + path = /obj/item/modular_computer/tablet + cost = 4 + +/datum/gear/utility/customtablet/New() + ..() + gear_tweaks += new /datum/gear_tweak/tablet() + +/datum/gear/utility/cheaplaptop + display_name = "laptop computer, cheap" + path = /obj/item/modular_computer/laptop/preset/custom_loadout/cheap + cost = 4 + +/datum/gear/utility/normallaptop + display_name = "laptop computer, advanced" + path = /obj/item/modular_computer/laptop/preset/custom_loadout/advanced + cost = 5 + +/datum/gear/utility/customlaptop + display_name = "laptop computer, custom" + path = /obj/item/modular_computer/laptop/preset/ + cost = 6 + +/datum/gear/utility/customlaptop/New() + ..() + gear_tweaks += new /datum/gear_tweak/laptop() diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index f62356d83c..764a99ad97 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -89,6 +89,12 @@ recipes += new/datum/stack_recipe("small light fixture frame", /obj/item/frame/light/small, 1) recipes += new/datum/stack_recipe("floor lamp fixture frame", /obj/machinery/light_construct/flamp, 2) recipes += new/datum/stack_recipe("apc frame", /obj/item/frame/apc, 2) + recipes += new/datum/stack_recipe_list("modular computer frames", list( \ + new/datum/stack_recipe("modular console frame", /obj/item/modular_computer/console, 20),\ + new/datum/stack_recipe("modular telescreen frame", /obj/item/modular_computer/telescreen, 10),\ + new/datum/stack_recipe("modular laptop frame", /obj/item/modular_computer/laptop, 10),\ + new/datum/stack_recipe("modular tablet frame", /obj/item/modular_computer/tablet, 5),\ + )) recipes += new/datum/stack_recipe_list("filing cabinets", list( \ new/datum/stack_recipe("filing cabinet", /obj/structure/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("tall filing cabinet", /obj/structure/filingcabinet/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1), \ diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index a730d811b4..5df33d70e2 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -109,4 +109,6 @@ // Used by mobs in virtual reality to point back to the "real" mob the client belongs to. var/mob/living/carbon/human/vr_holder = null // Used by "real" mobs after they leave a VR session - var/mob/living/carbon/human/vr_link = null \ No newline at end of file + var/mob/living/carbon/human/vr_link = null + + var/obj/machinery/machine_visual //machine that is currently applying visual effects to this mob. Only used for camera monitors currently. diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index fe409a9799..cb63df8d56 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1316,6 +1316,11 @@ if(found_welder) client.screen |= global_hud.darkMask +/mob/living/carbon/human/reset_view(atom/A) + ..() + if(machine_visual && machine_visual != A) + machine_visual.remove_visual(src) + /mob/living/carbon/human/handle_vision() if(stat == DEAD) sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF @@ -1377,6 +1382,7 @@ if(machine) var/viewflags = machine.check_eye(src) + machine.apply_visual(src) if(viewflags < 0) reset_view(null, 0) else if(viewflags && !looking_elsewhere) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 24d56945b8..0b37b89076 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -9,6 +9,10 @@ handle_modifiers() //VOREStation Edit - Needs to be done even if in nullspace. if(!loc) return + + if(machine && !CanMouseDrop(machine, src)) + machine = null + var/datum/gas_mixture/environment = loc.return_air() //handle_modifiers() // Do this early since it might affect other things later. //VOREStation Edit diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 7d2848f9bf..bfff010d03 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -145,9 +145,6 @@ /datum/robot_component/camera/update_power_state() ..() if (camera) - //check if camera component was deactivated - if (!powered && camera.status != powered) - camera.kick_viewers() camera.status = powered /datum/robot_component/camera/install() @@ -157,12 +154,10 @@ /datum/robot_component/camera/uninstall() if (camera) camera.status = 0 - camera.kick_viewers() /datum/robot_component/camera/destroy() if (camera) camera.status = 0 - camera.kick_viewers() // SELF DIAGNOSIS MODULE // Analyses cyborg's modules, providing damage readouts and basic information diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 6c31f54f8e..af06226e15 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -158,7 +158,7 @@ proc/getsensorlevel(A) /proc/stars(n, pr) if (pr == null) pr = 25 - if (pr <= 0) + if (pr < 0) return null else if (pr >= 100) diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm new file mode 100644 index 0000000000..28173c09d0 --- /dev/null +++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm @@ -0,0 +1,65 @@ +var/global/ntnrc_uid = 0 + +/datum/ntnet_conversation/ + var/id = null + var/title = "Untitled Conversation" + var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator, + var/list/messages = list() + var/list/clients = list() + var/password + +/datum/ntnet_conversation/New() + id = ntnrc_uid + ntnrc_uid++ + if(ntnet_global) + ntnet_global.chat_channels.Add(src) + ..() + +/datum/ntnet_conversation/proc/add_message(var/message, var/username) + message = "[stationtime2text()] [username]: [message]" + messages.Add(message) + trim_message_list() + +/datum/ntnet_conversation/proc/add_status_message(var/message) + messages.Add("[stationtime2text()] -!- [message]") + trim_message_list() + +/datum/ntnet_conversation/proc/trim_message_list() + if(messages.len <= 50) + return + messages.Cut(1, (messages.len-49)) + +/datum/ntnet_conversation/proc/add_client(var/datum/computer_file/program/chatclient/C) + if(!istype(C)) + return + clients.Add(C) + add_status_message("[C.username] has joined the channel.") + // No operator, so we assume the channel was empty. Assign this user as operator. + if(!operator) + changeop(C) + +/datum/ntnet_conversation/proc/remove_client(var/datum/computer_file/program/chatclient/C) + if(!istype(C) || !(C in clients)) + return + clients.Remove(C) + add_status_message("[C.username] has left the channel.") + + // Channel operator left, pick new operator + if(C == operator) + operator = null + if(clients.len) + var/datum/computer_file/program/chatclient/newop = pick(clients) + changeop(newop) + + +/datum/ntnet_conversation/proc/changeop(var/datum/computer_file/program/chatclient/newop) + if(istype(newop)) + operator = newop + add_status_message("Channel operator status transferred to [newop.username].") + +/datum/ntnet_conversation/proc/change_title(var/newtitle, var/datum/computer_file/program/chatclient/client) + if(operator != client) + return 0 // Not Authorised + + add_status_message("[client.username] has changed channel title from [title] to [newtitle]") + title = newtitle \ No newline at end of file diff --git a/code/modules/modular_computers/NTNet/NTNet.dm b/code/modules/modular_computers/NTNet/NTNet.dm new file mode 100644 index 0000000000..be42cec23f --- /dev/null +++ b/code/modules/modular_computers/NTNet/NTNet.dm @@ -0,0 +1,184 @@ +var/global/datum/ntnet/ntnet_global = new() + + +// This is the NTNet datum. There can be only one NTNet datum in game at once. Modular computers read data from this. +/datum/ntnet/ + var/list/relays = list() + var/list/logs = list() + var/list/available_station_software = list() + var/list/available_antag_software = list() + var/list/available_news = list() + var/list/chat_channels = list() + var/list/fileservers = list() + var/list/email_accounts = list() // I guess we won't have more than 999 email accounts active at once in single round, so this will do until Servers are implemented someday. + var/list/banned_nids = list() + // Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly. + // High values make displaying logs much laggier. + var/setting_maxlogcount = 100 + + // These only affect wireless. LAN (consoles) are unaffected since it would be possible to create scenario where someone turns off NTNet, and is unable to turn it back on since it refuses connections + var/setting_softwaredownload = 1 + var/setting_peertopeer = 1 + var/setting_communication = 1 + var/setting_systemcontrol = 1 + var/setting_disabled = 0 // Setting to 1 will disable all wireless, independently on relays status. + + var/intrusion_detection_enabled = 1 // Whether the IDS warning system is enabled + var/intrusion_detection_alarm = 0 // Set when there is an IDS warning due to malicious (antag) software. + + +// If new NTNet datum is spawned, it replaces the old one. +/datum/ntnet/New() + if(ntnet_global && (ntnet_global != src)) + ntnet_global = src // There can be only one. + for(var/obj/machinery/ntnet_relay/R in machines) + relays.Add(R) + R.NTNet = src + build_software_lists() + build_news_list() + build_emails_list() + add_log("NTNet logging system activated.") + +/datum/ntnet/proc/add_log_with_ids_check(var/log_string, var/obj/item/weapon/computer_hardware/network_card/source = null) + if(intrusion_detection_enabled) + add_log(log_string, source) + +// Simplified logging: Adds a log. log_string is mandatory parameter, source is optional. +/datum/ntnet/proc/add_log(var/log_string, var/obj/item/weapon/computer_hardware/network_card/source = null) + var/log_text = "[stationtime2text()] - " + if(source) + log_text += "[source.get_network_tag()] - " + else + log_text += "*SYSTEM* - " + log_text += log_string + logs.Add(log_text) + + if(logs.len > setting_maxlogcount) + // We have too many logs, remove the oldest entries until we get into the limit + for(var/L in logs) + if(logs.len > setting_maxlogcount) + logs.Remove(L) + else + break + +/datum/ntnet/proc/check_banned(var/NID) + if(!relays || !relays.len) + return FALSE + + for(var/obj/machinery/ntnet_relay/R in relays) + if(R.operable()) + return (NID in banned_nids) + + return FALSE + +// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled. +/datum/ntnet/proc/check_function(var/specific_action = 0) + if(!relays || !relays.len) // No relays found. NTNet is down + return 0 + + var/operating = 0 + + // Check all relays. If we have at least one working relay, network is up. + for(var/obj/machinery/ntnet_relay/R in relays) + if(R.operable()) + operating = 1 + break + + if(setting_disabled) + return 0 + + if(specific_action == NTNET_SOFTWAREDOWNLOAD) + return (operating && setting_softwaredownload) + if(specific_action == NTNET_PEERTOPEER) + return (operating && setting_peertopeer) + if(specific_action == NTNET_COMMUNICATION) + return (operating && setting_communication) + if(specific_action == NTNET_SYSTEMCONTROL) + return (operating && setting_systemcontrol) + return operating + +// Builds lists that contain downloadable software. +/datum/ntnet/proc/build_software_lists() + available_station_software = list() + available_antag_software = list() + for(var/F in typesof(/datum/computer_file/program)) + var/datum/computer_file/program/prog = new F + // Invalid type (shouldn't be possible but just in case), invalid filetype (not executable program) or invalid filename (unset program) + if(!prog || !istype(prog) || prog.filename == "UnknownProgram" || prog.filetype != "PRG") + continue + // Check whether the program should be available for station/antag download, if yes, add it to lists. + if(prog.available_on_ntnet) + available_station_software.Add(prog) + if(prog.available_on_syndinet) + available_antag_software.Add(prog) + +// Builds lists that contain downloadable software. +/datum/ntnet/proc/build_news_list() + available_news = list() + for(var/F in typesof(/datum/computer_file/data/news_article/)) + var/datum/computer_file/data/news_article/news = new F(1) + if(news.stored_data) + available_news.Add(news) + +// Generates service email list. Currently only used by broadcaster service +/datum/ntnet/proc/build_emails_list() + for(var/F in subtypesof(/datum/computer_file/data/email_account/service)) + new F() + +// Attempts to find a downloadable file according to filename var +/datum/ntnet/proc/find_ntnet_file_by_name(var/filename) + for(var/datum/computer_file/program/P in available_station_software) + if(filename == P.filename) + return P + for(var/datum/computer_file/program/P in available_antag_software) + if(filename == P.filename) + return P + +// Resets the IDS alarm +/datum/ntnet/proc/resetIDS() + intrusion_detection_alarm = 0 + +/datum/ntnet/proc/toggleIDS() + resetIDS() + intrusion_detection_enabled = !intrusion_detection_enabled + +// Removes all logs +/datum/ntnet/proc/purge_logs() + logs = list() + add_log("-!- LOGS DELETED BY SYSTEM OPERATOR -!-") + +// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks. +/datum/ntnet/proc/update_max_log_count(var/lognumber) + if(!lognumber) + return 0 + // Trim the value if necessary + lognumber = between(MIN_NTNET_LOGS, lognumber, MAX_NTNET_LOGS) + setting_maxlogcount = lognumber + add_log("Configuration Updated. Now keeping [setting_maxlogcount] logs in system memory.") + +/datum/ntnet/proc/toggle_function(var/function) + if(!function) + return + function = text2num(function) + switch(function) + if(NTNET_SOFTWAREDOWNLOAD) + setting_softwaredownload = !setting_softwaredownload + add_log("Configuration Updated. Wireless network firewall now [setting_softwaredownload ? "allows" : "disallows"] connection to software repositories.") + if(NTNET_PEERTOPEER) + setting_peertopeer = !setting_peertopeer + add_log("Configuration Updated. Wireless network firewall now [setting_peertopeer ? "allows" : "disallows"] peer to peer network traffic.") + if(NTNET_COMMUNICATION) + setting_communication = !setting_communication + add_log("Configuration Updated. Wireless network firewall now [setting_communication ? "allows" : "disallows"] instant messaging and similar communication services.") + if(NTNET_SYSTEMCONTROL) + setting_systemcontrol = !setting_systemcontrol + add_log("Configuration Updated. Wireless network firewall now [setting_systemcontrol ? "allows" : "disallows"] remote control of station's systems.") + +/datum/ntnet/proc/does_email_exist(var/login) + for(var/datum/computer_file/data/email_account/A in ntnet_global.email_accounts) + if(A.login == login) + return 1 + return 0 + + + diff --git a/code/modules/modular_computers/NTNet/NTNet_relay.dm b/code/modules/modular_computers/NTNet/NTNet_relay.dm new file mode 100644 index 0000000000..7c76fdd2e3 --- /dev/null +++ b/code/modules/modular_computers/NTNet/NTNet_relay.dm @@ -0,0 +1,136 @@ +// Relays don't handle any actual communication. Global NTNet datum does that, relays only tell the datum if it should or shouldn't work. +/obj/machinery/ntnet_relay + name = "NTNet Quantum Relay" + desc = "A very complex router and transmitter capable of connecting electronic devices together. Looks fragile." + use_power = 2 + active_power_usage = 20000 //20kW, apropriate for machine that keeps massive cross-Zlevel wireless network operational. + idle_power_usage = 100 + icon_state = "bus" + anchored = 1 + density = 1 + var/datum/ntnet/NTNet = null // This is mostly for backwards reference and to allow varedit modifications from ingame. + var/enabled = 1 // Set to 0 if the relay was turned off + var/dos_failure = 0 // Set to 1 if the relay failed due to (D)DoS attack + var/list/dos_sources = list() // Backwards reference for qdel() stuff + + // Denial of Service attack variables + var/dos_overload = 0 // Amount of DoS "packets" in this relay's buffer + var/dos_capacity = 500 // Amount of DoS "packets" in buffer required to crash the relay + var/dos_dissipate = 1 // Amount of DoS "packets" dissipated over time. + + +// TODO: Implement more logic here. For now it's only a placeholder. +/obj/machinery/ntnet_relay/operable() + if(!..(EMPED)) + return 0 + if(dos_failure) + return 0 + if(!enabled) + return 0 + return 1 + +/obj/machinery/ntnet_relay/update_icon() + if(operable()) + icon_state = "bus" + else + icon_state = "bus_off" + +/obj/machinery/ntnet_relay/process() + if(operable()) + use_power = 2 + else + use_power = 1 + + if(dos_overload) + dos_overload = max(0, dos_overload - dos_dissipate) + + // If DoS traffic exceeded capacity, crash. + if((dos_overload > dos_capacity) && !dos_failure) + dos_failure = 1 + update_icon() + ntnet_global.add_log("Quantum relay switched from normal operation mode to overload recovery mode.") + // If the DoS buffer reaches 0 again, restart. + if((dos_overload == 0) && dos_failure) + dos_failure = 0 + update_icon() + ntnet_global.add_log("Quantum relay switched from overload recovery mode to normal operation mode.") + ..() + +/obj/machinery/ntnet_relay/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = list() + data["enabled"] = enabled + data["dos_capacity"] = dos_capacity + data["dos_overload"] = dos_overload + data["dos_crashed"] = dos_failure + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "ntnet_relay.tmpl", "NTNet Quantum Relay", 500, 300, state = state) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/ntnet_relay/attack_hand(var/mob/living/user) + ui_interact(user) + +/obj/machinery/ntnet_relay/Topic(href, href_list) + if(..()) + return 1 + if(href_list["restart"]) + dos_overload = 0 + dos_failure = 0 + update_icon() + ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.") + return 1 + else if(href_list["toggle"]) + enabled = !enabled + ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].") + update_icon() + return 1 + else if(href_list["purge"]) + ntnet_global.banned_nids.Cut() + ntnet_global.add_log("Manual override: Network blacklist cleared.") + return 1 + +/obj/machinery/ntnet_relay/New() + uid = gl_uid + gl_uid++ + component_parts = list() + component_parts += new /obj/item/stack/cable_coil(src,15) + component_parts += new /obj/item/weapon/circuitboard/ntnet_relay(src) + + if(ntnet_global) + ntnet_global.relays.Add(src) + NTNet = ntnet_global + ntnet_global.add_log("New quantum relay activated. Current amount of linked relays: [NTNet.relays.len]") + ..() + +/obj/machinery/ntnet_relay/Destroy() + if(ntnet_global) + ntnet_global.relays.Remove(src) + ntnet_global.add_log("Quantum relay connection severed. Current amount of linked relays: [NTNet.relays.len]") + NTNet = null + for(var/datum/computer_file/program/ntnet_dos/D in dos_sources) + D.target = null + D.error = "Connection to quantum relay severed" + ..() + +/obj/machinery/ntnet_relay/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(W.is_screwdriver()) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + panel_open = !panel_open + to_chat(user, "You [panel_open ? "open" : "close"] the maintenance hatch") + return + if(W.is_crowbar()) + if(!panel_open) + to_chat(user, "Open the maintenance panel first.") + return + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + to_chat(user, "You disassemble \the [src]!") + + for(var/atom/movable/A in component_parts) + A.forceMove(src.loc) + new /obj/structure/frame(src.loc) + qdel(src) + return + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/NTNet/emails/email_account.dm b/code/modules/modular_computers/NTNet/emails/email_account.dm new file mode 100644 index 0000000000..b5f9388714 --- /dev/null +++ b/code/modules/modular_computers/NTNet/emails/email_account.dm @@ -0,0 +1,82 @@ +/datum/computer_file/data/email_account/ + var/list/inbox = list() + var/list/spam = list() + var/list/deleted = list() + + var/login = "" + var/password = "" + var/can_login = TRUE // Whether you can log in with this account. Set to false for system accounts + var/suspended = FALSE // Whether the account is banned by the SA. + +/datum/computer_file/data/email_account/calculate_size() + size = 1 + for(var/datum/computer_file/data/email_message/stored_message in all_emails()) + stored_message.calculate_size() + size += stored_message.size + +/datum/computer_file/data/email_account/New() + ntnet_global.email_accounts.Add(src) + ..() + +/datum/computer_file/data/email_account/Destroy() + ntnet_global.email_accounts.Remove(src) + . = ..() + +/datum/computer_file/data/email_account/proc/all_emails() + return (inbox | spam | deleted) + +/datum/computer_file/data/email_account/proc/send_mail(var/recipient_address, var/datum/computer_file/data/email_message/message, var/relayed = 0) + var/datum/computer_file/data/email_account/recipient + for(var/datum/computer_file/data/email_account/account in ntnet_global.email_accounts) + if(account.login == recipient_address) + recipient = account + break + + if(!istype(recipient)) + return 0 + + if(!recipient.receive_mail(message, relayed)) + return + + ntnet_global.add_log_with_ids_check("EMAIL LOG: [login] -> [recipient.login] title: [message.title].") + return 1 + +/datum/computer_file/data/email_account/proc/receive_mail(var/datum/computer_file/data/email_message/received_message, var/relayed) + received_message.set_timestamp() + if(!ntnet_global.intrusion_detection_enabled) + inbox.Add(received_message) + return 1 + // Spam filters may occassionally let something through, or mark something as spam that isn't spam. + if(received_message.spam) + if(prob(98)) + spam.Add(received_message) + else + inbox.Add(received_message) + else + if(prob(1)) + spam.Add(received_message) + else + inbox.Add(received_message) + return 1 + +// Address namespace (@internal-services.nt) for email addresses with special purpose only!. +/datum/computer_file/data/email_account/service/ + can_login = FALSE + +/datum/computer_file/data/email_account/service/broadcaster/ + login = "broadcast@internal-services.nt" + +/datum/computer_file/data/email_account/service/broadcaster/receive_mail(var/datum/computer_file/data/email_message/received_message, var/relayed) + if(!istype(received_message) || relayed) + return 0 + // Possibly exploitable for user spamming so keep admins informed. + if(!received_message.spam) + log_and_message_admins("Broadcast email address used by [usr]. Message title: [received_message.title].") + + spawn(0) + for(var/datum/computer_file/data/email_account/email_account in ntnet_global.email_accounts) + var/datum/computer_file/data/email_message/new_message = received_message.clone() + send_mail(email_account.login, new_message, 1) + sleep(2) + + return 1 \ No newline at end of file diff --git a/code/modules/modular_computers/NTNet/emails/email_message.dm b/code/modules/modular_computers/NTNet/emails/email_message.dm new file mode 100644 index 0000000000..d499195db2 --- /dev/null +++ b/code/modules/modular_computers/NTNet/emails/email_message.dm @@ -0,0 +1,32 @@ +// Currently not actually represented in file systems, though the support for it is in place already. +/datum/computer_file/data/email_message/ + stored_data = "" + var/title = "" + var/source = "" + var/spam = FALSE + var/timestamp = "" + var/datum/computer_file/attachment = null + +/datum/computer_file/data/email_message/clone() + var/datum/computer_file/data/email_message/temp = ..() + temp.title = title + temp.source = source + temp.spam = spam + temp.timestamp = timestamp + if(attachment) + temp.attachment = attachment.clone() + return temp + + +// Turns /email_message/ file into regular /data/ file. +/datum/computer_file/data/email_message/proc/export() + var/datum/computer_file/data/dat = new/datum/computer_file/data() + dat.stored_data = "Received from [source] at [timestamp]." + dat.stored_data += "\[b\][title]\[/b\]" + dat.stored_data += stored_data + dat.calculate_size() + return dat + +/datum/computer_file/data/email_message/proc/set_timestamp() + timestamp = stationtime2text() + diff --git a/code/modules/modular_computers/_description.dm b/code/modules/modular_computers/_description.dm new file mode 100644 index 0000000000..2335ce08e7 --- /dev/null +++ b/code/modules/modular_computers/_description.dm @@ -0,0 +1,121 @@ +/* +Program-based computers, designed to replace computer3 project and eventually most consoles on station + + +1. Basic information +Program based computers will allow you to do multiple things from single computer. Each computer will have programs, with more being downloadable from NTNet (stationwide network with wireless coverage) +if user has apropriate ID card access. It will be possible to hack the computer by using an emag on it - the emag will have to be completely new and will be consumed on use, but it will +lift ALL locks on ALL installed programs, and allow download of programs even if your ID doesn't have access to them. Computers will have hard drives that can store files. +Files can be programs (datum/computer_file/program/ subtype) or data files (datum/computer_file/data/ subtypes). Program for sending files will be available that will allow transfer via NTNet. +NTNet coverage will be limited to station's Z level, but better network card (=more expensive and higher power use) will allow usage everywhere. Hard drives will have limited capacity for files +which will be related to how good hard drive you buy when purchasing the laptop. For storing more files USB-style drives will be buildable with Protolathe in research. + +2. Available devices +CONSOLES +Consoles will come in various pre-fabricated loadouts, each loadout starting with certain set of programs (aka Engineering console, Medical console, etc.), of course, more software may be downloaded. +Consoles won't usually have integrated battery, but the possibility to install one will exist for critical applications. Consoles are considered hardwired into NTNet network which means they +will have working coverage on higher speed (Ethernet is faster than Wi-Fi) and won't require wireless coverage to exist. +LAPTOPS +Laptops are middle ground between actual portable devices and full consoles. They offer certain level of mobility, as they can be closed, moved somewhere else and then opened again. +Laptops will by default have internal battery to power them, and may be recharged with rechargers. However, laptops rely on wireless NTNet coverage. Laptop HDDs are also designed with power efficiency +in mind, which means they sacrifice some storage space for higher battery life. Laptops may be dispensed from computer vendor machine, and may be customised before vending. For people which don't +want to rely on internal battery, tesla link exists that connects to APC, if one exists. +TABLETS +Tablets are smallest available devices, designed with full mobility in mind. Tablets have only weak CPU which means the software they can run is somewhat limited. They are also designed with high +battery life in mind, which means the hardware focuses on power efficiency rather than high performance. This is most visible with hard drives which have quite small storage capacity. +Tablets can't be equipped with tesla link, which means they have to be recharged manually. + + +3. Computer Hardware +Computers will come with basic hardware installed, with upgrades being selectable when purchasing the device. +Hard Drive: Stores data, mandatory for the computer to work +Network Card: Connects to NTNet +Battery: Internal power source that ensures the computer operates when not connected to APC. +Extras (those won't be installed by default, but can be bought) +ID Card Slot: Required for HoP-style programs to work. Access for security record-style programs is read from ID of user [RFID?] without requiring this +APC Tesla Relay: Wirelessly powers the device from APC. Consoles have it by default. Laptops can buy it. +Disk Drive: Allows usage of portable data disks. +Nano Printer: Allows the computer to scan paper contents and save them to file, as well as recycle papers and print stuff on it. + +4. NTNet +NTNet is stationwide network that allows users to download programs needed for their work. It will be possible to send any files to other active computers using relevant program (NTN Transfer). +NTNet is under jurisdiction of both Engineering and Research. Engineering is responsible for any repairs if necessary and research is responsible for monitoring. It is similar to PDA messaging. +Operation requires functional "NTNet Relay" which is by default placed on tcommsat. If the relay is damaged NTNet will be offline until it is replaced. Multiple relays bring extra redundancy, +if one is destroyed the second will take over. If all relays are gone it stops working, simple as that. NTNet may be altered via administration console available to Research Director. It is +possible to enable/disable Software Downloading, P2P file transfers and Communication (IC version of IRC, PDA messages for more than two people) + +5. Software +Software would almost exclusively use NanoUI modules. Few exceptions are text editor (uses similar screen as TCS IDE used for editing and classic HTML for previewing as Nano looks differently) +and similar programs which for some reason require HTML UI. Most software will be highly dependent on NTNet to work as laptops are not physically connected to the station's network. +What i plan to add: + +Note: XXXXDB programs will use ingame_manuals to display basic help for players, similar to how books, etc. do + +Basic - Software in this bundle is automagically preinstalled in every new computer + NTN Transfer - Allows P2P transfer of files to other computers that run this. + Configurator - Allows configuration of computer's hardware, basically status screen. + File Browser - Allows you to browse all files stored on the computer. Allows renaming/deleting of files. + TXT Editor - Allows you editing data files in text editor mode. + NanoPrint - Allows you to operate NanoPrinter hardware to print text files. + NTNRC Chat - NTNet Relay Chat client. Allows PDA-messaging style messaging for more than two users. Person which created the conversation is Host and has administrative privilegies (kicking, etc.) + NTNet News - Allows reading news from newscaster network. + +Engineering - Requires "Engineering" access on ID card (ie. CE, Atmostech, Engineer) + Alarm Monitor - Allows monitoring alarms, same as the stationbound one. + Power Monitor - Power monitoring computer, connects to sensors in same way as regular one does. + Atmospheric Control - Allows access to the Atmospherics Monitor Console that operates air alarms. Requires extra access: "Atmospherics" + RCON Remote Control Console - Allows access to the RCON Remote Control Console. Requires extra access: "Power Equipment" + EngiDB - Allows accessing NTNet information repository for information about engineering-related things. + +Medical - Requires "Medbay" access on ID card (ie. CMO, Doctor,..) + Medical Records Uplink - Allows editing/reading of medical records. Printing requires NanoPrinter hardware. + MediDB - Allows accessing NTNet information repository for information about medical procedures + ChemDB - Requires extra access: "Chemistry" - Downloads basic information about recipes from NTNet + +Research - Requires "Research and Development" access on ID card (ie. RD, Roboticist, etc.) + Research Server Monitor - Allows monitoring of research levels on RnD servers. (read only) + Robotics Monitor Console - Allows monitoring of robots and exosuits. Lockdown/Self-Destruct options are unavailable [balance reasons for malf/traitor AIs]. Requires extra access: "Robotics" + NTNRC Administration Console - Allows administrative access to NTNRC. This includes bypassing any channel passwords and enabling "invisible" mode for spying on conversations. Requires extra access: "Research Director" + NTNet Administration Console - Allows remote configuration of NTNet Relay - CAUTION: If NTNet is turned off it won't be possible to turn it on again from the computer, as operation requires NTNet to work! Requires extra access: "Research Director" + NTNet Monitor - Allows monitoring of NTNet and it's various components, including simplified network logs and system status. + +Security - Requires "Security" access on ID card (ie. HOS, Security officer, Detective) + Security Records Uplink - Allows editing/reading of security records. Printing requires Nanoprinter hardware. + LawDB - Allows accessing NTNet information repository for security information (corporate regulations) + Camera Uplink - Allows viewing cameras around the station. + +Command - Requires "Bridge" access on ID card (all heads) + Alertcon Access - Allows changing of alert levels. Red requires activation from two computers with two IDs similar to how those wall mounted devices do. + Employment Records Access - Allows reading of employment records. Printing requires NanoPrinter hardware. + Communication Console - Allows sending emergency messages to Central. + Emergency Shuttle Control Console - Allows calling/recalling the emergency shuttle. + Shuttle Control Console - Allows control of various shuttles around the station (mining, research, engineering) + +*REDACTED* - Can be downloaded from SyndiCorp servers, only via emagged devices. These files are very large and limited to laptops/consoles only. + SYSCRACK - Allows cracking of secure network terminals, such as, NTNet administration. The sysadmin will probably notice this. + SYSOVERRIDE - Allows hacking into any device connected to NTNet. User will notice this and may stop the hack by disconnecting from NTNet first. After hacking various options exist, such as stealing/deleting files. + SYSKILL - Tricks NTNet to force-disconnect a device. The sysadmin will probably notice this. + SYSDOS - Launches a Denial of Service attack on NTNet relay. Can DoS only one relay at once. Requires NTNet connection. After some time the relay crashes until attack stops. The sysadmin will probably notice this. + AIHACK - Hacks an AI, allowing you to upload/remove/modify a law even without relevant circuit board. The AI is alerted once the hack starts, and it takes a while for it to complete. Does not work on AIs with zeroth law. + COREPURGE - Deletes all files on the hard drive, including the undeletable ones. Something like software self-destruct for computer. + +6. Security +Laptops will be password-lockable. If password is set a MD5 hash of it is stored and password is required every time you turn on the laptop. +Passwords may be decrypted by using special Decrypter (protolathable, RDs office starts with one) device that will slowly decrypt the password. +Decryption time would be length_of_password * 30 seconds, with maximum being 9 minutes (due to battery life limitations, which is 10+ min). +If decrypted the password is cleared, so you can keep using your favorite password without people ever actually revealing it (for meta prevention reasons mostly). +Emagged laptops will have option to enable "Safe Encryption". If safely encrypted laptop is decrypted it loses it's emag status and 50% of files is deleted (randomly selected). + +7. System Administrator +System Administrator will be new job under Research. It's main specifics will be maintaining of computer systems on station, espicially from software side. +From IC perspective they'd probably know how to build a console or something given they work with computers, but they are mostly programmers/network experts. +They will have office in research, which will probably replace (and contain) the server room and part of the toxins storage which is currently oversized. +They will have access to DOWNLOAD (not run) all programs that exist on NTNet. They'll have fairly good amount of available programs, most of them being +administrative consoles and other very useful things. They'll also be able to monitor NTNet. There will probably be one or two job slots. + +8. IDS +With addition of various antag programs, IDS(Intrusion Detection System) will be added to NTNet. This system can be turned on/off via administration console. +If enabled, this system automatically detects any abnormality and triggers a warning that's visible on the NTNet status screen, as well as generating a security log. +IDS can be disabled by simple on/off switch in the configuration. + +*/ \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm new file mode 100644 index 0000000000..30d9cf6039 --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -0,0 +1,269 @@ +/obj/item/modular_computer/process() + if(!enabled) // The computer is turned off + last_power_usage = 0 + return 0 + + if(damage > broken_damage) + shutdown_computer() + return 0 + + if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) // Active program requires NTNet to run but we've just lost connection. Crash. + active_program.event_networkfailure(0) + + for(var/datum/computer_file/program/P in idle_threads) + if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) + P.event_networkfailure(1) + + if(active_program) + if(active_program.program_state != PROGRAM_STATE_KILLED) + active_program.ntnet_status = get_ntnet_status() + active_program.computer_emagged = computer_emagged + active_program.process_tick() + else + active_program = null + + for(var/datum/computer_file/program/P in idle_threads) + if(P.program_state != PROGRAM_STATE_KILLED) + P.ntnet_status = get_ntnet_status() + P.computer_emagged = computer_emagged + P.process_tick() + else + idle_threads.Remove(P) + + handle_power() // Handles all computer power interaction + check_update_ui_need() + +// Used to perform preset-specific hardware changes. +/obj/item/modular_computer/proc/install_default_hardware() + return 1 + +// Used to install preset-specific programs +/obj/item/modular_computer/proc/install_default_programs() + return 1 + +/obj/item/modular_computer/New() + START_PROCESSING(SSobj, src) + install_default_hardware() + if(hard_drive) + install_default_programs() + update_icon() + update_verbs() + ..() + +/obj/item/modular_computer/Destroy() + kill_program(1) + STOP_PROCESSING(SSobj, src) + for(var/obj/item/weapon/computer_hardware/CH in src.get_all_components()) + uninstall_component(null, CH) + qdel(CH) + return ..() + +/obj/item/modular_computer/emag_act(var/remaining_charges, var/mob/user) + if(computer_emagged) + to_chat(user, "\The [src] was already emagged.") + return //NO_EMAG_ACT + else + computer_emagged = 1 + to_chat(user, "You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message.") + return 1 + +/obj/item/modular_computer/update_icon() + icon_state = icon_state_unpowered + + overlays.Cut() + if(bsod) + overlays.Add("bsod") + return + if(!enabled) + if(icon_state_screensaver) + overlays.Add(icon_state_screensaver) + set_light(0) + return + set_light(light_strength) + if(active_program) + overlays.Add(active_program.program_icon_state ? active_program.program_icon_state : icon_state_menu) + if(active_program.program_key_state) + overlays.Add(active_program.program_key_state) + else + overlays.Add(icon_state_menu) + +/obj/item/modular_computer/proc/turn_on(var/mob/user) + if(bsod) + return + if(tesla_link) + tesla_link.enabled = 1 + var/issynth = issilicon(user) // Robots and AIs get different activation messages. + if(damage > broken_damage) + if(issynth) + to_chat(user, "You send an activation signal to \the [src], but it responds with an error code. It must be damaged.") + else + to_chat(user, "You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.") + return + if(processor_unit && (apc_power(0) || battery_power(0))) // Battery-run and charged or non-battery but powered by APC. + if(issynth) + to_chat(user, "You send an activation signal to \the [src], turning it on") + else + to_chat(user, "You press the power button and start up \the [src]") + enable_computer(user) + + else // Unpowered + if(issynth) + to_chat(user, "You send an activation signal to \the [src] but it does not respond") + else + to_chat(user, "You press the power button but \the [src] does not respond") + +// Relays kill program request to currently active program. Use this to quit current program. +/obj/item/modular_computer/proc/kill_program(var/forced = 0) + if(active_program) + active_program.kill_program(forced) + active_program = null + var/mob/user = usr + if(user && istype(user)) + ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. + update_icon() + +// Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on) +/obj/item/modular_computer/proc/get_ntnet_status(var/specific_action = 0) + if(network_card) + return network_card.get_signal(specific_action) + else + return 0 + +/obj/item/modular_computer/proc/add_log(var/text) + if(!get_ntnet_status()) + return 0 + return ntnet_global.add_log(text, network_card) + +/obj/item/modular_computer/proc/shutdown_computer(var/loud = 1) + kill_program(1) + for(var/datum/computer_file/program/P in idle_threads) + P.kill_program(1) + idle_threads.Remove(P) + if(loud) + visible_message("\The [src] shuts down.") + enabled = 0 + update_icon() + +/obj/item/modular_computer/proc/enable_computer(var/mob/user = null) + enabled = 1 + update_icon() + + // Autorun feature + var/datum/computer_file/data/autorun = hard_drive ? hard_drive.find_file_by_name("autorun") : null + if(istype(autorun)) + run_program(autorun.stored_data) + + if(user) + ui_interact(user) + +/obj/item/modular_computer/proc/minimize_program(mob/user) + if(!active_program || !processor_unit) + return + + idle_threads.Add(active_program) + active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs + SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program) + active_program = null + update_icon() + if(istype(user)) + ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. + + +/obj/item/modular_computer/proc/run_program(prog) + var/datum/computer_file/program/P = null + var/mob/user = usr + if(hard_drive) + P = hard_drive.find_file_by_name(prog) + + if(!P || !istype(P)) // Program not found or it's not executable program. + to_chat(user, "\The [src]'s screen shows \"I/O ERROR - Unable to run [prog]\" warning.") + return + + P.computer = src + + if(!P.is_supported_by_hardware(hardware_flag, 1, user)) + return + if(P in idle_threads) + P.program_state = PROGRAM_STATE_ACTIVE + active_program = P + idle_threads.Remove(P) + update_icon() + return + + if(idle_threads.len >= processor_unit.max_idle_programs+1) + to_chat(user, "\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error") + return + + if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet. + to_chat(user, "\The [src]'s screen shows \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.") + return + + if(active_program) + minimize_program(user) + + if(P.run_program(user)) + active_program = P + update_icon() + return 1 + +/obj/item/modular_computer/proc/update_uis() + if(active_program) //Should we update program ui or computer ui? + SSnanoui.update_uis(active_program) + if(active_program.NM) + SSnanoui.update_uis(active_program.NM) + else + SSnanoui.update_uis(src) + +/obj/item/modular_computer/proc/check_update_ui_need() + var/ui_update_needed = 0 + if(battery_module) + var/batery_percent = battery_module.battery.percent() + if(last_battery_percent != batery_percent) //Let's update UI on percent change + ui_update_needed = 1 + last_battery_percent = batery_percent + + if(stationtime2text() != last_world_time) + last_world_time = stationtime2text() + ui_update_needed = 1 + + if(idle_threads.len) + var/list/current_header_icons = list() + for(var/datum/computer_file/program/P in idle_threads) + if(!P.ui_header) + continue + current_header_icons[P.type] = P.ui_header + if(!last_header_icons) + last_header_icons = current_header_icons + + else if(!listequal(last_header_icons, current_header_icons)) + last_header_icons = current_header_icons + ui_update_needed = 1 + else + for(var/x in last_header_icons|current_header_icons) + if(last_header_icons[x]!=current_header_icons[x]) + last_header_icons = current_header_icons + ui_update_needed = 1 + break + + if(ui_update_needed) + update_uis() + +// Used by camera monitor program +/obj/item/modular_computer/check_eye(var/mob/user) + if(active_program) + return active_program.check_eye(user) + else + return ..() + +/obj/item/modular_computer/proc/set_autorun(program) + if(!hard_drive) + return + var/datum/computer_file/data/autorun = hard_drive.find_file_by_name("autorun") + if(!istype(autorun)) + autorun = new/datum/computer_file/data() + autorun.filename = "autorun" + hard_drive.store_file(autorun) + if(autorun.stored_data == program) + autorun.stored_data = null + else + autorun.stored_data = program \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/damage.dm b/code/modules/modular_computers/computers/modular_computer/damage.dm new file mode 100644 index 0000000000..d63bf39fdf --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/damage.dm @@ -0,0 +1,55 @@ +/obj/item/modular_computer/examine(var/mob/user) + . = ..() + if(damage > broken_damage) + to_chat(user, "It is heavily damaged!") + else if(damage) + to_chat(user, "It is damaged.") + +/obj/item/modular_computer/proc/break_apart() + visible_message("\The [src] breaks apart!") + var/turf/newloc = get_turf(src) + new /obj/item/stack/material/steel(newloc, round(steel_sheet_cost/2)) + for(var/obj/item/weapon/computer_hardware/H in get_all_components()) + uninstall_component(null, H) + H.forceMove(newloc) + if(prob(25)) + H.take_damage(rand(10,30)) + qdel() + +/obj/item/modular_computer/proc/take_damage(var/amount, var/component_probability, var/damage_casing = 1, var/randomize = 1) + if(randomize) + // 75%-125%, rand() works with integers, apparently. + amount *= (rand(75, 125) / 100.0) + amount = round(amount) + if(damage_casing) + damage += amount + damage = between(0, damage, max_damage) + + if(component_probability) + for(var/obj/item/weapon/computer_hardware/H in get_all_components()) + if(prob(component_probability)) + H.take_damage(round(amount / 2)) + + if(damage >= max_damage) + break_apart() + +// Stronger explosions cause serious damage to internal components +// Minor explosions are mostly mitigitated by casing. +/obj/item/modular_computer/ex_act(var/severity) + take_damage(rand(100,200) / severity, 30 / severity) + +// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components +/obj/item/modular_computer/emp_act(var/severity) + take_damage(rand(100,200) / severity, 50 / severity, 0) + +// "Stun" weapons can cause minor damage to components (short-circuits?) +// "Burn" damage is equally strong against internal components and exterior casing +// "Brute" damage mostly damages the casing. +/obj/item/modular_computer/bullet_act(var/obj/item/projectile/Proj) + switch(Proj.damage_type) + if(BRUTE) + take_damage(Proj.damage, Proj.damage / 2) + if(HALLOSS) + take_damage(Proj.damage, Proj.damage / 3, 0) + if(BURN) + take_damage(Proj.damage, Proj.damage / 1.5) \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/hardware.dm b/code/modules/modular_computers/computers/modular_computer/hardware.dm new file mode 100644 index 0000000000..38545e8176 --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/hardware.dm @@ -0,0 +1,139 @@ +// Attempts to install the hardware into apropriate slot. +/obj/item/modular_computer/proc/try_install_component(var/mob/living/user, var/obj/item/weapon/computer_hardware/H, var/found = 0) + // "USB" flash drive. + if(istype(H, /obj/item/weapon/computer_hardware/hard_drive/portable)) + if(portable_drive) + to_chat(user, "This computer's portable drive slot is already occupied by \the [portable_drive].") + return + found = 1 + portable_drive = H + else if(istype(H, /obj/item/weapon/computer_hardware/hard_drive)) + if(hard_drive) + to_chat(user, "This computer's hard drive slot is already occupied by \the [hard_drive].") + return + found = 1 + hard_drive = H + else if(istype(H, /obj/item/weapon/computer_hardware/network_card)) + if(network_card) + to_chat(user, "This computer's network card slot is already occupied by \the [network_card].") + return + found = 1 + network_card = H + else if(istype(H, /obj/item/weapon/computer_hardware/nano_printer)) + if(nano_printer) + to_chat(user, "This computer's nano printer slot is already occupied by \the [nano_printer].") + return + found = 1 + nano_printer = H + else if(istype(H, /obj/item/weapon/computer_hardware/card_slot)) + if(card_slot) + to_chat(user, "This computer's card slot is already occupied by \the [card_slot].") + return + found = 1 + card_slot = H + else if(istype(H, /obj/item/weapon/computer_hardware/battery_module)) + if(battery_module) + to_chat(user, "This computer's battery slot is already occupied by \the [battery_module].") + return + found = 1 + battery_module = H + else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit)) + if(processor_unit) + to_chat(user, "This computer's processor slot is already occupied by \the [processor_unit].") + return + found = 1 + processor_unit = H + else if(istype(H, /obj/item/weapon/computer_hardware/tesla_link)) + if(tesla_link) + to_chat(user, "This computer's tesla link slot is already occupied by \the [tesla_link].") + return + found = 1 + tesla_link = H + if(found) + to_chat(user, "You install \the [H] into \the [src]") + H.holder2 = src + user.drop_from_inventory(H) + H.forceMove(src) + update_verbs() + +// Uninstalls component. Found and Critical vars may be passed by parent types, if they have additional hardware. +/obj/item/modular_computer/proc/uninstall_component(var/mob/living/user, var/obj/item/weapon/computer_hardware/H, var/found = 0, var/critical = 0) + if(portable_drive == H) + portable_drive = null + found = 1 + if(hard_drive == H) + hard_drive = null + found = 1 + critical = 1 + if(network_card == H) + network_card = null + found = 1 + if(nano_printer == H) + nano_printer = null + found = 1 + if(card_slot == H) + card_slot = null + found = 1 + if(battery_module == H) + battery_module = null + found = 1 + if(processor_unit == H) + processor_unit = null + found = 1 + critical = 1 + if(tesla_link == H) + tesla_link = null + found = 1 + if(found) + if(user) + to_chat(user, "You remove \the [H] from \the [src].") + H.forceMove(get_turf(src)) + H.holder2 = null + update_verbs() + if(critical && enabled) + if(user) + to_chat(user, "\The [src]'s screen freezes for few seconds and then displays an \"HARDWARE ERROR: Critical component disconnected. Please verify component connection and reboot the device. If the problem persists contact technical support for assistance.\" warning.") + shutdown_computer() + update_icon() + + +// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null +/obj/item/modular_computer/proc/find_hardware_by_name(var/name) + if(portable_drive && (portable_drive.name == name)) + return portable_drive + if(hard_drive && (hard_drive.name == name)) + return hard_drive + if(network_card && (network_card.name == name)) + return network_card + if(nano_printer && (nano_printer.name == name)) + return nano_printer + if(card_slot && (card_slot.name == name)) + return card_slot + if(battery_module && (battery_module.name == name)) + return battery_module + if(processor_unit && (processor_unit.name == name)) + return processor_unit + if(tesla_link && (tesla_link.name == name)) + return tesla_link + return null + +// Returns list of all components +/obj/item/modular_computer/proc/get_all_components() + var/list/all_components = list() + if(hard_drive) + all_components.Add(hard_drive) + if(network_card) + all_components.Add(network_card) + if(portable_drive) + all_components.Add(portable_drive) + if(nano_printer) + all_components.Add(nano_printer) + if(card_slot) + all_components.Add(card_slot) + if(battery_module) + all_components.Add(battery_module) + if(processor_unit) + all_components.Add(processor_unit) + if(tesla_link) + all_components.Add(tesla_link) + return all_components \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/interaction.dm b/code/modules/modular_computers/computers/modular_computer/interaction.dm new file mode 100644 index 0000000000..bf70bb7d28 --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/interaction.dm @@ -0,0 +1,200 @@ +/obj/item/modular_computer/proc/update_verbs() + verbs.Cut() + if(portable_drive) + verbs |= /obj/item/modular_computer/verb/eject_usb + if(card_slot) + verbs |= /obj/item/modular_computer/verb/eject_id + verbs |= /obj/item/modular_computer/verb/emergency_shutdown + +// Forcibly shut down the device. To be used when something bugs out and the UI is nonfunctional. +/obj/item/modular_computer/verb/emergency_shutdown() + set name = "Forced Shutdown" + set category = "Object" + set src in view(1) + + if(usr.incapacitated() || !istype(usr, /mob/living)) + to_chat(usr, "You can't do that.") + return + + if(!Adjacent(usr)) + to_chat(usr, "You can't reach it.") + return + + if(enabled) + bsod = 1 + update_icon() + shutdown_computer() + to_chat(usr, "You press a hard-reset button on \the [src]. It displays a brief debug screen before shutting down.") + spawn(2 SECONDS) + bsod = 0 + update_icon() + + +// Eject ID card from computer, if it has ID slot with card inside. +/obj/item/modular_computer/verb/eject_id() + set name = "Eject ID" + set category = "Object" + set src in view(1) + + if(usr.incapacitated() || !istype(usr, /mob/living)) + to_chat(usr, "You can't do that.") + return + + if(!Adjacent(usr)) + to_chat(usr, "You can't reach it.") + return + + proc_eject_id(usr) + +// Eject ID card from computer, if it has ID slot with card inside. +/obj/item/modular_computer/verb/eject_usb() + set name = "Eject Portable Storage" + set category = "Object" + set src in view(1) + + if(usr.incapacitated() || !istype(usr, /mob/living)) + to_chat(usr, "You can't do that.") + return + + if(!Adjacent(usr)) + to_chat(usr, "You can't reach it.") + return + + proc_eject_usb(usr) + +/obj/item/modular_computer/proc/proc_eject_id(mob/user) + if(!user) + user = usr + + if(!card_slot) + to_chat(user, "\The [src] does not have an ID card slot") + return + + if(!card_slot.stored_card) + to_chat(user, "There is no card in \the [src]") + return + + if(active_program) + active_program.event_idremoved(0) + + for(var/datum/computer_file/program/P in idle_threads) + P.event_idremoved(1) + + card_slot.stored_card.forceMove(get_turf(src)) + card_slot.stored_card = null + update_uis() + to_chat(user, "You remove the card from \the [src]") + + +/obj/item/modular_computer/proc/proc_eject_usb(mob/user) + if(!user) + user = usr + + if(!portable_drive) + to_chat(user, "There is no portable device connected to \the [src].") + return + + uninstall_component(user, portable_drive) + update_uis() + +/obj/item/modular_computer/attack_ghost(var/mob/observer/ghost/user) + if(enabled) + ui_interact(user) + else if(check_rights(R_ADMIN, 0, user)) + var/response = alert(user, "This computer is turned off. Would you like to turn it on?", "Admin Override", "Yes", "No") + if(response == "Yes") + turn_on(user) + +/obj/item/modular_computer/attack_ai(var/mob/user) + return attack_self(user) + +/obj/item/modular_computer/attack_hand(var/mob/user) + if(anchored) + return attack_self(user) + return ..() + +// On-click handling. Turns on the computer if it's off and opens the GUI. +/obj/item/modular_computer/attack_self(var/mob/user) + if(enabled && screen_on) + ui_interact(user) + else if(!enabled && screen_on) + turn_on(user) + +/obj/item/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/weapon/card/id)) // ID Card, try to insert it. + var/obj/item/weapon/card/id/I = W + if(!card_slot) + to_chat(user, "You try to insert \the [I] into \the [src], but it does not have an ID card slot installed.") + return + + if(card_slot.stored_card) + to_chat(user, "You try to insert \the [I] into \the [src], but it's ID card slot is occupied.") + return + user.drop_from_inventory(I) + card_slot.stored_card = I + I.forceMove(src) + update_uis() + to_chat(user, "You insert \the [I] into \the [src].") + return + if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/paper_bundle)) + if(!nano_printer) + return + nano_printer.attackby(W, user) + if(istype(W, /obj/item/weapon/computer_hardware)) + var/obj/item/weapon/computer_hardware/C = W + if(C.hardware_size <= max_hardware_size) + try_install_component(user, C) + else + to_chat(user, "This component is too large for \the [src].") + if(W.is_wrench()) + var/list/components = get_all_components() + if(components.len) + to_chat(user, "Remove all components from \the [src] before disassembling it.") + return + new /obj/item/stack/material/steel( get_turf(src.loc), steel_sheet_cost ) + src.visible_message("\The [src] has been disassembled by [user].") + qdel(src) + return + if(istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = W + if(!WT.isOn()) + to_chat(user, "\The [W] is off.") + return + + if(!damage) + to_chat(user, "\The [src] does not require repairs.") + return + + to_chat(user, "You begin repairing damage to \the [src]...") + if(WT.remove_fuel(round(damage/75)) && do_after(usr, damage/10)) + damage = 0 + to_chat(user, "You repair \the [src].") + return + + if(W.is_screwdriver()) + var/list/all_components = get_all_components() + if(!all_components.len) + to_chat(user, "This device doesn't have any components installed.") + return + var/list/component_names = list() + for(var/obj/item/weapon/computer_hardware/H in all_components) + component_names.Add(H.name) + + var/choice = input(usr, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in component_names + + if(!choice) + return + + if(!Adjacent(usr)) + return + + var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(choice) + + if(!H) + return + + uninstall_component(user, H) + + return + + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/power.dm b/code/modules/modular_computers/computers/modular_computer/power.dm new file mode 100644 index 0000000000..48871619fa --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/power.dm @@ -0,0 +1,51 @@ +/obj/item/modular_computer/proc/power_failure(var/malfunction = 0) + if(enabled) // Shut down the computer + visible_message("\The [src]'s screen flickers briefly and then goes dark.") + if(active_program) + active_program.event_powerfailure(0) + for(var/datum/computer_file/program/PRG in idle_threads) + PRG.event_powerfailure(1) + shutdown_computer(0) + +// Tries to use power from battery. Passing 0 as parameter results in this proc returning whether battery is functional or not. +/obj/item/modular_computer/proc/battery_power(var/power_usage = 0) + apc_powered = FALSE + if(!battery_module || !battery_module.check_functionality() || battery_module.battery.charge <= 0) + return FALSE + if(battery_module.battery.use(power_usage * CELLRATE) || ((power_usage == 0) && battery_module.battery.charge)) + return TRUE + return FALSE + +// Tries to use power from APC, if present. +/obj/item/modular_computer/proc/apc_power(var/power_usage = 0) + apc_powered = TRUE + // Tesla link was originally limited to machinery only, but this probably works too, and the benefit of being able to power all devices from an APC outweights + // the possible minor performance loss. + if(!tesla_link || !tesla_link.check_functionality()) + return FALSE + var/area/A = get_area(src) + if(!istype(A) || !A.powered(EQUIP)) + return FALSE + + // At this point, we know that APC can power us for this tick. Check if we also need to charge our battery, and then actually use the power. + if(battery_module && (battery_module.battery.charge < battery_module.battery.maxcharge) && (power_usage > 0)) + power_usage += tesla_link.passive_charging_rate + battery_module.battery.give(tesla_link.passive_charging_rate * CELLRATE) + + A.use_power(power_usage, EQUIP) + return TRUE + +// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged +/obj/item/modular_computer/proc/handle_power() + var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage + for(var/obj/item/weapon/computer_hardware/H in get_all_components()) + if(H.enabled) + power_usage += H.power_usage + last_power_usage = power_usage + + // First tries to charge from an APC, if APC is unavailable switches to battery power. If neither works the computer fails. + if(apc_power(power_usage)) + return + if(battery_power(power_usage)) + return + power_failure() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/ui.dm b/code/modules/modular_computers/computers/modular_computer/ui.dm new file mode 100644 index 0000000000..81081c0cb1 --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/ui.dm @@ -0,0 +1,155 @@ +// Operates NanoUI +/obj/item/modular_computer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + if(!screen_on || !enabled) + if(ui) + ui.close() + return 0 + if(!apc_power(0) && !battery_power(0)) + if(ui) + ui.close() + return 0 + + // If we have an active program switch to it now. + if(active_program) + if(ui) // This is the main laptop screen. Since we are switching to program's UI close it for now. + ui.close() + active_program.ui_interact(user) + return + + // We are still here, that means there is no program loaded. Load the BIOS/ROM/OS/whatever you want to call it. + // This screen simply lists available programs and user may select them. + if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len) + visible_message("\The [src] beeps three times, it's screen displaying \"DISK ERROR\" warning.") + return // No HDD, No HDD files list or no stored files. Something is very broken. + + var/datum/computer_file/data/autorun = hard_drive.find_file_by_name("autorun") + + var/list/data = get_header_data() + + var/list/programs = list() + for(var/datum/computer_file/program/P in hard_drive.stored_files) + var/list/program = list() + program["name"] = P.filename + program["desc"] = P.filedesc + program["icon"] = P.program_menu_icon + program["autorun"] = (istype(autorun) && (autorun.stored_data == P.filename)) ? 1 : 0 + if(P in idle_threads) + program["running"] = 1 + programs.Add(list(program)) + + data["programs"] = programs + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "laptop_mainscreen.tmpl", "NTOS Main Menu", 400, 500) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +// Handles user's GUI input +/obj/item/modular_computer/Topic(href, href_list) + if(..()) + return 1 + if( href_list["PC_exit"] ) + kill_program() + return 1 + if( href_list["PC_enable_component"] ) + var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(href_list["PC_enable_component"]) + if(H && istype(H) && !H.enabled) + H.enabled = 1 + . = 1 + if( href_list["PC_disable_component"] ) + var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(href_list["PC_disable_component"]) + if(H && istype(H) && H.enabled) + H.enabled = 0 + . = 1 + if( href_list["PC_shutdown"] ) + shutdown_computer() + return 1 + if( href_list["PC_minimize"] ) + var/mob/user = usr + minimize_program(user) + + if( href_list["PC_killprogram"] ) + var/prog = href_list["PC_killprogram"] + var/datum/computer_file/program/P = null + var/mob/user = usr + if(hard_drive) + P = hard_drive.find_file_by_name(prog) + + if(!istype(P) || P.program_state == PROGRAM_STATE_KILLED) + return + + P.kill_program(1) + update_uis() + to_chat(user, "Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.") + + if( href_list["PC_runprogram"] ) + return run_program(href_list["PC_runprogram"]) + + if( href_list["PC_setautorun"] ) + if(!hard_drive) + return + set_autorun(href_list["PC_setautorun"]) + + if(.) + update_uis() + +// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_" +/obj/item/modular_computer/proc/get_header_data() + var/list/data = list() + + if(battery_module) + switch(battery_module.battery.percent()) + if(80 to 200) // 100 should be maximal but just in case.. + data["PC_batteryicon"] = "batt_100.gif" + if(60 to 80) + data["PC_batteryicon"] = "batt_80.gif" + if(40 to 60) + data["PC_batteryicon"] = "batt_60.gif" + if(20 to 40) + data["PC_batteryicon"] = "batt_40.gif" + if(5 to 20) + data["PC_batteryicon"] = "batt_20.gif" + else + data["PC_batteryicon"] = "batt_5.gif" + data["PC_batterypercent"] = "[round(battery_module.battery.percent())] %" + data["PC_showbatteryicon"] = 1 + else + data["PC_batteryicon"] = "batt_5.gif" + data["PC_batterypercent"] = "N/C" + data["PC_showbatteryicon"] = battery_module ? 1 : 0 + + if(tesla_link && tesla_link.enabled && apc_powered) + data["PC_apclinkicon"] = "charging.gif" + + if(network_card && network_card.is_banned()) + data["PC_ntneticon"] = "sig_warning.gif" + else + switch(get_ntnet_status()) + if(0) + data["PC_ntneticon"] = "sig_none.gif" + if(1) + data["PC_ntneticon"] = "sig_low.gif" + if(2) + data["PC_ntneticon"] = "sig_high.gif" + if(3) + data["PC_ntneticon"] = "sig_lan.gif" + + var/list/program_headers = list() + for(var/datum/computer_file/program/P in idle_threads) + if(!P.ui_header) + continue + program_headers.Add(list(list( + "icon" = P.ui_header + ))) + if(active_program && active_program.ui_header) + program_headers.Add(list(list( + "icon" = active_program.ui_header + ))) + data["PC_programheaders"] = program_headers + + data["PC_stationtime"] = stationtime2text() + data["PC_hasheader"] = 1 + data["PC_showexitprogram"] = active_program ? 1 : 0 // Hides "Exit Program" button on mainscreen + return data \ No newline at end of file diff --git a/code/modules/modular_computers/computers/modular_computer/variables.dm b/code/modules/modular_computers/computers/modular_computer/variables.dm new file mode 100644 index 0000000000..c746493ff8 --- /dev/null +++ b/code/modules/modular_computers/computers/modular_computer/variables.dm @@ -0,0 +1,53 @@ +// This is the base type that handles everything. Subtypes can be easily created by tweaking variables in this file to your liking. + +/obj/item/modular_computer + name = "Modular Computer" + desc = "A modular computer. You shouldn't see this." + + var/enabled = 0 // Whether the computer is turned on. + var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. + var/datum/computer_file/program/active_program = null // A currently active program running on the computer. + var/hardware_flag = 0 // A flag that describes this device type + var/last_power_usage = 0 // Last tick power usage of this computer + var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged + var/last_world_time = "00:00" + var/list/last_header_icons + var/computer_emagged = FALSE // Whether the computer is emagged. + var/apc_powered = FALSE // Set automatically. Whether the computer used APC power last tick. + var/base_active_power_usage = 50 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too. + var/base_idle_power_usage = 5 // Power usage when the computer is idle and screen is off (currently only applies to laptops) + var/bsod = FALSE // Error screen displayed + + // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..) + // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently + // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example. + + icon = null // This thing isn't meant to be used on it's own. Subtypes should supply their own icon. + icon_state = null + //center_of_mass = null // No pixelshifting by placing on tables, etc. + //randpixel = 0 // And no random pixelshifting on-creation either. + var/icon_state_unpowered = null // Icon state when the computer is turned off + var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. + var/icon_state_screensaver = null + var/max_hardware_size = 0 // Maximal hardware size. Currently, tablets have 1, laptops 2 and consoles 3. Limits what hardware types can be installed. + var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer. + var/light_strength = 0 // Intensity of light this computer emits. Comparable to numbers light fixtures use. + var/list/idle_threads = list() // Idle programs on background. They still receive process calls but can't be interacted with. + + // Damage of the chassis. If the chassis takes too much damage it will break apart. + var/damage = 0 // Current damage level + var/broken_damage = 50 // Damage level at which the computer ceases to operate + var/max_damage = 100 // Damage level at which the computer breaks apart. + + // Important hardware (must be installed for computer to work) + var/obj/item/weapon/computer_hardware/processor_unit/processor_unit // CPU. Without it the computer won't run. Better CPUs can run more programs at once. + var/obj/item/weapon/computer_hardware/network_card/network_card // Network Card component of this computer. Allows connection to NTNet + var/obj/item/weapon/computer_hardware/hard_drive/hard_drive // Hard Drive component of this computer. Stores programs and files. + + // Optional hardware (improves functionality, but is not critical for computer to work in most cases) + var/obj/item/weapon/computer_hardware/battery_module/battery_module // An internal power source for this computer. Can be recharged. + var/obj/item/weapon/computer_hardware/card_slot/card_slot // ID Card slot component of this computer. Mostly for HoP modification console that needs ID slot for modification. + var/obj/item/weapon/computer_hardware/nano_printer/nano_printer // Nano Printer component of this computer, for your everyday paperwork needs. + var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive // Portable data storage + var/obj/item/weapon/computer_hardware/ai_slot/ai_slot // AI slot, an intellicard housing that allows modifications of AIs. + var/obj/item/weapon/computer_hardware/tesla_link/tesla_link // Tesla Link, Allows remote charging from nearest APC. \ No newline at end of file diff --git a/code/modules/modular_computers/computers/status_icons.dmi b/code/modules/modular_computers/computers/status_icons.dmi new file mode 100644 index 0000000000..52127ec484 Binary files /dev/null and b/code/modules/modular_computers/computers/status_icons.dmi differ diff --git a/code/modules/modular_computers/computers/subtypes/dev_console.dm b/code/modules/modular_computers/computers/subtypes/dev_console.dm new file mode 100644 index 0000000000..4a8981d41b --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/dev_console.dm @@ -0,0 +1,18 @@ +/obj/item/modular_computer/console + name = "console" + desc = "A stationary computer." + icon = 'icons/obj/modular_console.dmi' + icon_state = "console" + icon_state_unpowered = "console" + icon_state_screensaver = "standby" + icon_state_menu = "menu" + hardware_flag = PROGRAM_CONSOLE + anchored = TRUE + density = 1 + base_idle_power_usage = 100 + base_active_power_usage = 500 + max_hardware_size = 3 + steel_sheet_cost = 20 + light_strength = 4 + max_damage = 300 + broken_damage = 150 \ No newline at end of file diff --git a/code/modules/modular_computers/computers/subtypes/dev_laptop.dm b/code/modules/modular_computers/computers/subtypes/dev_laptop.dm new file mode 100644 index 0000000000..eddae93f74 --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/dev_laptop.dm @@ -0,0 +1,37 @@ +/obj/item/modular_computer/laptop + anchored = TRUE + name = "laptop computer" + desc = "A portable computer." + hardware_flag = PROGRAM_LAPTOP + icon_state_unpowered = "laptop-open" + icon = 'icons/obj/modular_laptop.dmi' + icon_state = "laptop-open" + icon_state_screensaver = "standby" + base_idle_power_usage = 25 + base_active_power_usage = 200 + max_hardware_size = 2 + light_strength = 3 + max_damage = 200 + broken_damage = 100 + w_class = ITEMSIZE_NORMAL + var/icon_state_closed = "laptop-closed" + +/obj/item/modular_computer/laptop/AltClick() + // Prevents carrying of open laptops inhand. + // While they work inhand, i feel it'd make tablets lose some of their high-mobility advantage they have over laptops now. + if(!istype(loc, /turf/)) + to_chat(usr, "\The [src] has to be on a stable surface first!") + return + anchored = !anchored + screen_on = anchored + update_icon() + +/obj/item/modular_computer/laptop/update_icon() + if(anchored) + ..() + else + overlays.Cut() + icon_state = icon_state_closed + +/obj/item/modular_computer/laptop/preset + anchored = FALSE diff --git a/code/modules/modular_computers/computers/subtypes/dev_tablet.dm b/code/modules/modular_computers/computers/subtypes/dev_tablet.dm new file mode 100644 index 0000000000..62d12ba545 --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/dev_tablet.dm @@ -0,0 +1,16 @@ +/obj/item/modular_computer/tablet + name = "tablet computer" + desc = "A small portable microcomputer" + icon = 'icons/obj/modular_tablet.dmi' + icon_state = "tablet" + icon_state_unpowered = "tablet" + icon_state_menu = "menu" + hardware_flag = PROGRAM_TABLET + max_hardware_size = 1 + w_class = ITEMSIZE_SMALL + light_strength = 2 // Same as PDAs + +/obj/item/modular_computer/tablet/lease + desc = "A small portable microcomputer. This one has a gold and blue stripe, and a serial number stamped into the case." + icon_state = "tabletsol" + icon_state_unpowered = "tabletsol" \ No newline at end of file diff --git a/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm b/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm new file mode 100644 index 0000000000..1f88ed6cb2 --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/dev_telescreen.dm @@ -0,0 +1,59 @@ +/obj/item/modular_computer/telescreen + name = "telescreen" + desc = "A wall-mounted touchscreen computer." + icon = 'icons/obj/modular_telescreen.dmi' + icon_state = "telescreen" + icon_state_unpowered = "telescreen" + icon_state_menu = "menu" + icon_state_screensaver = "standby" + hardware_flag = PROGRAM_TELESCREEN + anchored = TRUE + density = 0 + base_idle_power_usage = 75 + base_active_power_usage = 300 + max_hardware_size = 2 + steel_sheet_cost = 10 + light_strength = 4 + max_damage = 300 + broken_damage = 150 + w_class = ITEMSIZE_HUGE + +/obj/item/modular_computer/telescreen/New() + ..() + // Allows us to create "north bump" "south bump" etc. named objects, for more comfortable mapping. + name = "telescreen" + +/obj/item/modular_computer/telescreen/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(W.is_crowbar()) + if(anchored) + shutdown_computer() + anchored = FALSE + screen_on = FALSE + pixel_x = 0 + pixel_y = 0 + to_chat(user, "You unsecure \the [src].") + else + var/choice = input(user, "Where do you want to place \the [src]?", "Offset selection") in list("North", "South", "West", "East", "This tile", "Cancel") + var/valid = FALSE + switch(choice) + if("North") + valid = TRUE + pixel_y = 32 + if("South") + valid = TRUE + pixel_y = -32 + if("West") + valid = TRUE + pixel_x = -32 + if("East") + valid = TRUE + pixel_x = 32 + if("This tile") + valid = TRUE + + if(valid) + anchored = 1 + screen_on = TRUE + to_chat(user, "You secure \the [src].") + return + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/subtypes/preset_console.dm b/code/modules/modular_computers/computers/subtypes/preset_console.dm new file mode 100644 index 0000000000..d2f409b51e --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/preset_console.dm @@ -0,0 +1,123 @@ +/obj/item/modular_computer/console/preset/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/super(src) + network_card = new/obj/item/weapon/computer_hardware/network_card/wired(src) + +// Engineering +/obj/item/modular_computer/console/preset/engineering/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/power_monitor()) + hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor()) + hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + hard_drive.store_file(new/datum/computer_file/program/atmos_control()) + hard_drive.store_file(new/datum/computer_file/program/rcon_console()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + +// Medical +/obj/item/modular_computer/console/preset/medical/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/suit_sensors()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + hard_drive.store_file(new/datum/computer_file/program/wordprocessor()) + set_autorun("sensormonitor") + +// Research +/obj/item/modular_computer/console/preset/research/install_default_hardware() + ..() + //ai_slot = new/obj/item/weapon/computer_hardware/ai_slot(src) + +/obj/item/modular_computer/console/preset/research/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor()) + hard_drive.store_file(new/datum/computer_file/program/nttransfer()) + hard_drive.store_file(new/datum/computer_file/program/chatclient()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + //hard_drive.store_file(new/datum/computer_file/program/aidiag()) + hard_drive.store_file(new/datum/computer_file/program/email_client()) + hard_drive.store_file(new/datum/computer_file/program/wordprocessor()) + +// Administrator +/obj/item/modular_computer/console/preset/sysadmin/install_default_hardware() + ..() + //ai_slot = new/obj/item/weapon/computer_hardware/ai_slot(src) + +/obj/item/modular_computer/console/preset/sysadmin/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor()) + hard_drive.store_file(new/datum/computer_file/program/nttransfer()) + hard_drive.store_file(new/datum/computer_file/program/chatclient()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + //hard_drive.store_file(new/datum/computer_file/program/aidiag()) + hard_drive.store_file(new/datum/computer_file/program/email_client()) + hard_drive.store_file(new/datum/computer_file/program/email_administration()) + hard_drive.store_file(new/datum/computer_file/program/wordprocessor()) + +// Command +/obj/item/modular_computer/console/preset/command/install_default_hardware() + ..() + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + +/obj/item/modular_computer/console/preset/command/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/chatclient()) + hard_drive.store_file(new/datum/computer_file/program/card_mod()) + hard_drive.store_file(new/datum/computer_file/program/comm()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + hard_drive.store_file(new/datum/computer_file/program/email_client()) + +// Security +/obj/item/modular_computer/console/preset/security/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + hard_drive.store_file(new/datum/computer_file/program/digitalwarrant()) + hard_drive.store_file(new/datum/computer_file/program/wordprocessor()) + +// Civilian +/obj/item/modular_computer/console/preset/civilian/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/chatclient()) + hard_drive.store_file(new/datum/computer_file/program/nttransfer()) + hard_drive.store_file(new/datum/computer_file/program/newsbrowser()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + hard_drive.store_file(new/datum/computer_file/program/email_client()) + hard_drive.store_file(new/datum/computer_file/program/wordprocessor()) + +// ERT +/obj/item/modular_computer/console/preset/ert/install_default_hardware() + ..() + //ai_slot = new/obj/item/weapon/computer_hardware/ai_slot(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + +/obj/item/modular_computer/console/preset/ert/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/nttransfer()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor/ert()) + hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + hard_drive.store_file(new/datum/computer_file/program/comm()) + //hard_drive.store_file(new/datum/computer_file/program/aidiag()) + +// Mercenary +/obj/item/modular_computer/console/preset/mercenary/ + computer_emagged = TRUE + +/obj/item/modular_computer/console/preset/mercenary/install_default_hardware() + ..() + //ai_slot = new/obj/item/weapon/computer_hardware/ai_slot(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + +/obj/item/modular_computer/console/preset/mercenary/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/camera_monitor/hacked()) + hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + //hard_drive.store_file(new/datum/computer_file/program/aidiag()) + +// Merchant +/obj/item/modular_computer/console/preset/merchant/install_default_programs() + ..() + //hard_drive.store_file(new/datum/computer_file/program/merchant()) + hard_drive.store_file(new/datum/computer_file/program/wordprocessor()) diff --git a/code/modules/modular_computers/computers/subtypes/preset_laptop.dm b/code/modules/modular_computers/computers/subtypes/preset_laptop.dm new file mode 100644 index 0000000000..190ba53b27 --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/preset_laptop.dm @@ -0,0 +1,32 @@ +/obj/item/modular_computer/laptop/preset/custom_loadout/cheap/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/(src) + network_card = new/obj/item/weapon/computer_hardware/network_card/(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(src) + battery_module.charge_to_full() + +/obj/item/modular_computer/laptop/preset/custom_loadout/advanced/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/advanced(src) + network_card = new/obj/item/weapon/computer_hardware/network_card/advanced(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(src) + battery_module.charge_to_full() + +/obj/item/modular_computer/laptop/preset/custom_loadout/standard/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/(src) + network_card = new/obj/item/weapon/computer_hardware/network_card/(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(src) + battery_module.charge_to_full() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/subtypes/preset_tablet.dm b/code/modules/modular_computers/computers/subtypes/preset_tablet.dm new file mode 100644 index 0000000000..65c3a47c3c --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/preset_tablet.dm @@ -0,0 +1,28 @@ +/obj/item/modular_computer/tablet/preset/custom_loadout/cheap/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/micro(src) + network_card = new/obj/item/weapon/computer_hardware/network_card(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module/nano(src) + battery_module.charge_to_full() + +/obj/item/modular_computer/tablet/preset/custom_loadout/advanced/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/small(src) + network_card = new/obj/item/weapon/computer_hardware/network_card/advanced(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + card_slot = new/obj/item/weapon/computer_hardware/card_slot(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module(src) + battery_module.charge_to_full() + +/obj/item/modular_computer/tablet/preset/custom_loadout/standard/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/small(src) + network_card = new/obj/item/weapon/computer_hardware/network_card(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module/micro(src) + battery_module.charge_to_full() diff --git a/code/modules/modular_computers/computers/subtypes/preset_telescreen.dm b/code/modules/modular_computers/computers/subtypes/preset_telescreen.dm new file mode 100644 index 0000000000..d0cb86bada --- /dev/null +++ b/code/modules/modular_computers/computers/subtypes/preset_telescreen.dm @@ -0,0 +1,14 @@ +/obj/item/modular_computer/telescreen/preset/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive(src) + network_card = new/obj/item/weapon/computer_hardware/network_card(src) + +/obj/item/modular_computer/telescreen/preset/generic/install_default_programs() + ..() + hard_drive.store_file(new/datum/computer_file/program/chatclient()) + hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) + hard_drive.store_file(new/datum/computer_file/program/email_client()) + set_autorun("cammon") diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm new file mode 100644 index 0000000000..afc02e8414 --- /dev/null +++ b/code/modules/modular_computers/file_system/computer_file.dm @@ -0,0 +1,39 @@ +var/global/file_uid = 0 + +/datum/computer_file/ + var/filename = "NewFile" // Placeholder. No spacebars + var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case + var/size = 1 // File size in GQ. Integers only! + var/obj/item/weapon/computer_hardware/hard_drive/holder // Holder that contains this file. + var/unsendable = 0 // Whether the file may be sent to someone via NTNet transfer or other means. + var/undeletable = 0 // Whether the file may be deleted. Setting to 1 prevents deletion/renaming/etc. + var/uid // UID of this file + +/datum/computer_file/New() + ..() + uid = file_uid + file_uid++ + +/datum/computer_file/Destroy() + if(!holder) + return ..() + + holder.remove_file(src) + // holder.holder is the computer that has drive installed. If we are Destroy()ing program that's currently running kill it. + if(holder.holder2 && holder.holder2.active_program == src) + holder.holder2.kill_program(1) + holder = null + ..() + +// Returns independent copy of this file. +/datum/computer_file/proc/clone(var/rename = 0) + var/datum/computer_file/temp = new type + temp.unsendable = unsendable + temp.undeletable = undeletable + temp.size = size + if(rename) + temp.filename = filename + "(Copy)" + else + temp.filename = filename + temp.filetype = filetype + return temp \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/data.dm b/code/modules/modular_computers/file_system/data.dm new file mode 100644 index 0000000000..7ad48bea54 --- /dev/null +++ b/code/modules/modular_computers/file_system/data.dm @@ -0,0 +1,19 @@ +// /data/ files store data in string format. +// They don't contain other logic for now. +/datum/computer_file/data + var/stored_data = "" // Stored data in string format. + filetype = "DAT" + var/block_size = 250 + var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited. + +/datum/computer_file/data/clone() + var/datum/computer_file/data/temp = ..() + temp.stored_data = stored_data + return temp + +// Calculates file size from amount of characters in saved string +/datum/computer_file/data/proc/calculate_size() + size = max(1, round(length(stored_data) / block_size)) + +/datum/computer_file/data/logfile + filetype = "LOG" diff --git a/code/modules/modular_computers/file_system/news_article.dm b/code/modules/modular_computers/file_system/news_article.dm new file mode 100644 index 0000000000..833ba382e9 --- /dev/null +++ b/code/modules/modular_computers/file_system/news_article.dm @@ -0,0 +1,24 @@ +// /data/ files store data in string format. +// They don't contain other logic for now. +/datum/computer_file/data/news_article + filetype = "XNML" + filename = "Unknown News Entry" + block_size = 5000 // Results in smaller files + do_not_edit = 1 // Editing the file breaks most formatting due to some HTML tags not being accepted as input from average user. + var/server_file_path // File path to HTML file that will be loaded on server start. Example: '/news_articles/space_magazine_1.html'. Use the /news_articles/ folder! + var/archived // Set to 1 for older stuff + var/cover //filename of cover. + +/datum/computer_file/data/news_article/New(var/load_from_file = 0) + ..() + if(server_file_path && load_from_file) + stored_data = file2text(server_file_path) + calculate_size() + + +// NEWS DEFINITIONS BELOW THIS LINE +/* KEPT HERE AS AN EXAMPLE +/datum/computer_file/data/news_article/space/vol_one + filename = "SPACE Magazine vol. 1" + server_file_path = 'news_articles/space_magazine_1.html' +*/ \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm new file mode 100644 index 0000000000..7124bdcd03 --- /dev/null +++ b/code/modules/modular_computers/file_system/program.dm @@ -0,0 +1,210 @@ +// /program/ files are executable programs that do things. +/datum/computer_file/program + filetype = "PRG" + filename = "UnknownProgram" // File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET! + var/required_access = null // List of required accesses to run/download the program. + var/requires_access_to_run = 1 // Whether the program checks for required_access when run. + var/requires_access_to_download = 1 // Whether the program checks for required_access when downloading. + var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact. + var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program. + var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running. + var/obj/item/modular_computer/computer // Device that runs this program. + var/filedesc = "Unknown Program" // User-friendly name of this program. + var/extended_desc = "N/A" // Short description of this program's function. + var/program_icon_state = null // Program-specific screen icon state + var/program_key_state = "standby_key" // Program-specific keyboard icon state + var/program_menu_icon = "newwin" // Icon to use for program's link in main menu + var/requires_ntnet = 0 // Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes. + var/requires_ntnet_feature = 0 // Optional, if above is set to 1 checks for specific function of NTNet (currently NTNET_SOFTWAREDOWNLOAD, NTNET_PEERTOPEER, NTNET_SYSTEMCONTROL and NTNET_COMMUNICATION) + var/ntnet_status = 1 // NTNet status, updated every tick by computer running this program. Don't use this for checks if NTNet works, computers do that. Use this for calculations, etc. + var/usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL + var/network_destination = null // Optional string that describes what NTNet server/system this program connects to. Used in default logging. + var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable. + var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable. + var/computer_emagged = 0 // Set to 1 if computer that's running us was emagged. Computer updates this every Process() tick + var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images! + var/ntnet_speed = 0 // GQ/s - current network connectivity transfer rate + +/datum/computer_file/program/New(var/obj/item/modular_computer/comp = null) + ..() + if(comp && istype(comp)) + computer = comp + +/datum/computer_file/program/Destroy() + computer = null + . = ..() + +/datum/computer_file/program/nano_host() + return computer.nano_host() + +/datum/computer_file/program/clone() + var/datum/computer_file/program/temp = ..() + temp.required_access = required_access + temp.nanomodule_path = nanomodule_path + temp.filedesc = filedesc + temp.program_icon_state = program_icon_state + temp.requires_ntnet = requires_ntnet + temp.requires_ntnet_feature = requires_ntnet_feature + temp.usage_flags = usage_flags + return temp + +// Relays icon update to the computer. +/datum/computer_file/program/proc/update_computer_icon() + if(computer) + computer.update_icon() + +// Attempts to create a log in global ntnet datum. Returns 1 on success, 0 on fail. +/datum/computer_file/program/proc/generate_network_log(var/text) + if(computer) + return computer.add_log(text) + return 0 + +/datum/computer_file/program/proc/is_supported_by_hardware(var/hardware_flag = 0, var/loud = 0, var/mob/user = null) + if(!(hardware_flag & usage_flags)) + if(loud && computer && user) + to_chat(user, "\The [computer] flashes: \"Hardware Error - Incompatible software\".") + return 0 + return 1 + +/datum/computer_file/program/proc/get_signal(var/specific_action = 0) + if(computer) + return computer.get_ntnet_status(specific_action) + return 0 + +// Called by Process() on device that runs us, once every tick. +/datum/computer_file/program/proc/process_tick() + update_netspeed() + return 1 + +/datum/computer_file/program/proc/update_netspeed() + ntnet_speed = 0 + switch(ntnet_status) + if(1) + ntnet_speed = NTNETSPEED_LOWSIGNAL + if(2) + ntnet_speed = NTNETSPEED_HIGHSIGNAL + if(3) + ntnet_speed = NTNETSPEED_ETHERNET + +// Check if the user can run program. Only humans can operate computer. Automatically called in run_program() +// User has to wear their ID or have it inhand for ID Scan to work. +// Can also be called manually, with optional parameter being access_to_check to scan the user's ID +/datum/computer_file/program/proc/can_run(var/mob/living/user, var/loud = 0, var/access_to_check) + // Defaults to required_access + if(!access_to_check) + access_to_check = required_access + if(!access_to_check) // No required_access, allow it. + return 1 + + // Admin override - allows operation of any computer as aghosted admin, as if you had any required access. + if(istype(user, /mob/observer/dead) && check_rights(R_ADMIN, 0, user)) + return 1 + + if(!istype(user)) + return 0 + + var/obj/item/weapon/card/id/I = user.GetIdCard() + if(!I) + if(loud) + to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") + return 0 + + if(access_to_check in I.access) + return 1 + else if(loud) + to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") + +// This attempts to retrieve header data for NanoUIs. If implementing completely new device of different type than existing ones +// always include the device here in this proc. This proc basically relays the request to whatever is running the program. +/datum/computer_file/program/proc/get_header_data() + if(computer) + return computer.get_header_data() + return list() + +// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure. +// When implementing new program based device, use this to run the program. +/datum/computer_file/program/proc/run_program(var/mob/living/user) + if(can_run(user, 1) || !requires_access_to_run) + if(nanomodule_path) + NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src) + NM.using_access = user.GetAccess() + if(requires_ntnet && network_destination) + generate_network_log("Connection opened to [network_destination].") + program_state = PROGRAM_STATE_ACTIVE + return 1 + return 0 + +// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client. +/datum/computer_file/program/proc/kill_program(var/forced = 0) + program_state = PROGRAM_STATE_KILLED + if(network_destination) + generate_network_log("Connection to [network_destination] closed.") + if(NM) + qdel(NM) + NM = null + return 1 + +// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation. +// It returns 0 if it can't run or if NanoModule was used instead. I suggest using NanoModules where applicable. +/datum/computer_file/program/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + if(program_state != PROGRAM_STATE_ACTIVE) // Our program was closed. Close the ui if it exists. + if(ui) + ui.close() + return computer.ui_interact(user) + if(istype(NM)) + NM.ui_interact(user, ui_key, null, force_open) + return 0 + return 1 + + +// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC: +// Topic calls are automagically forwarded from NanoModule this program contains. +// Calls beginning with "PRG_" are reserved for programs handling. +// Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program) +// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE. +/datum/computer_file/program/Topic(href, href_list) + if(..()) + return 1 + if(computer) + return computer.Topic(href, href_list) + +// Relays the call to nano module, if we have one +/datum/computer_file/program/proc/check_eye(var/mob/user) + if(NM) + return NM.check_eye(user) + else + return -1 + +/obj/item/modular_computer/initial_data() + return get_header_data() + +/obj/item/modular_computer/update_layout() + return TRUE + +/datum/nano_module/program + //available_to_ai = FALSE + var/datum/computer_file/program/program = null // Program-Based computer program that runs this nano module. Defaults to null. + +/datum/nano_module/program/New(var/host, var/topic_manager, var/program) + ..() + src.program = program + +/datum/topic_manager/program + var/datum/program + +/datum/topic_manager/program/New(var/datum/program) + ..() + src.program = program + +// Calls forwarded to PROGRAM itself should begin with "PRG_" +// Calls forwarded to COMPUTER running the program should begin with "PC_" +/datum/topic_manager/program/Topic(href, href_list) + return program && program.Topic(href, href_list) + +/datum/computer_file/program/apply_visual(mob/M) + if(NM) + NM.apply_visual(M) + +/datum/computer_file/program/remove_visual(mob/M) + if(NM) + NM.remove_visual(M) diff --git a/code/modules/modular_computers/file_system/program_events.dm b/code/modules/modular_computers/file_system/program_events.dm new file mode 100644 index 0000000000..73386ca198 --- /dev/null +++ b/code/modules/modular_computers/file_system/program_events.dm @@ -0,0 +1,18 @@ +// Events are sent to the program by the computer. +// Always include a parent call when overriding an event. + +// Called when the ID card is removed from computer. ID is removed AFTER this proc. +/datum/computer_file/program/proc/event_idremoved(var/background) + return + +// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss. +/datum/computer_file/program/proc/event_powerfailure(var/background) + kill_program(1) + +// Called when the network connectivity fails. Computer does necessary checks and only calls this when requires_ntnet_feature and similar variables are not met. +/datum/computer_file/program/proc/event_networkfailure(var/background) + kill_program(1) + if(background) + computer.visible_message("\The [computer]'s screen displays an error: \"Network connectivity lost - process [filename].[filetype] (PID [rand(100,999)]) terminated.\"", 1) + else + computer.visible_message("\The [computer]'s screen briefly freezes and then shows: \"FATAL NETWORK ERROR - NTNet connection lost. Please try again later. If problem persists, please contact your system administrator.\"", 1) diff --git a/code/modules/modular_computers/file_system/programs/antagonist/access_decrypter.dm b/code/modules/modular_computers/file_system/programs/antagonist/access_decrypter.dm new file mode 100644 index 0000000000..04bf931593 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/antagonist/access_decrypter.dm @@ -0,0 +1,129 @@ +/datum/computer_file/program/access_decrypter + filename = "nt_accrypt" + filedesc = "NTNet Access Decrypter" + program_icon_state = "hostile" + program_key_state = "security_key" + program_menu_icon = "unlocked" + extended_desc = "This highly advanced script can very slowly decrypt operational codes used in almost any network. These codes can be downloaded to an ID card to expand the available access. The system administrator will probably notice this." + size = 34 + requires_ntnet = 1 + available_on_ntnet = 0 + available_on_syndinet = 1 + nanomodule_path = /datum/nano_module/program/access_decrypter/ + var/message = "" + var/running = FALSE + var/progress = 0 + var/target_progress = 300 + var/datum/access/target_access = null + +/datum/computer_file/program/access_decrypter/kill_program(var/forced) + reset() + ..(forced) + +/datum/computer_file/program/access_decrypter/proc/reset() + running = FALSE + message = "" + progress = 0 + +/datum/computer_file/program/access_decrypter/process_tick() + . = ..() + if(!running) + return + var/obj/item/weapon/computer_hardware/processor_unit/CPU = computer.processor_unit + var/obj/item/weapon/computer_hardware/card_slot/RFID = computer.card_slot + if(!istype(CPU) || !CPU.check_functionality() || !istype(RFID) || !RFID.check_functionality()) + message = "A fatal hardware error has been detected." + return + if(!istype(RFID.stored_card)) + message = "RFID card has been removed from the device. Operation aborted." + return + + progress += CPU.max_idle_programs + if(progress >= target_progress) + reset() + RFID.stored_card.access |= target_access.id + if(ntnet_global.intrusion_detection_enabled) + ntnet_global.add_log("IDS WARNING - Unauthorised access to primary keycode database from device: [computer.network_card.get_network_tag()] - downloaded access codes for: [target_access.desc].") + ntnet_global.intrusion_detection_alarm = 1 + message = "Successfully decrypted and saved operational key codes. Downloaded access codes for: [target_access.desc]" + target_access = null + +/datum/computer_file/program/access_decrypter/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_reset"]) + reset() + return 1 + if(href_list["PRG_execute"]) + if(running) + return 1 + if(text2num(href_list["allowed"])) + return 1 + var/obj/item/weapon/computer_hardware/processor_unit/CPU = computer.processor_unit + var/obj/item/weapon/computer_hardware/card_slot/RFID = computer.card_slot + if(!istype(CPU) || !CPU.check_functionality() || !istype(RFID) || !RFID.check_functionality()) + message = "A fatal hardware error has been detected." + return + if(!istype(RFID.stored_card)) + message = "RFID card is not present in the device. Operation aborted." + return + running = TRUE + target_access = get_access_by_id(href_list["PRG_execute"]) + if(ntnet_global.intrusion_detection_enabled) + ntnet_global.add_log("IDS WARNING - Unauthorised access attempt to primary keycode database from device: [computer.network_card.get_network_tag()]") + ntnet_global.intrusion_detection_alarm = 1 + return 1 + +/datum/nano_module/program/access_decrypter + name = "NTNet Access Decrypter" + var/list/restricted_access_codes = list(access_change_ids, access_network) // access codes that are not hackable due to balance reasons + +/datum/nano_module/program/access_decrypter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(!ntnet_global) + return + var/datum/computer_file/program/access_decrypter/PRG = program + var/list/data = list() + if(!istype(PRG)) + return + data = PRG.get_header_data() + + if(PRG.message) + data["message"] = PRG.message + else if(PRG.running) + data["running"] = 1 + data["rate"] = PRG.computer.processor_unit.max_idle_programs + + // Stolen from DOS traffic generator, generates strings of 1s and 0s + var/percentage = (PRG.progress / PRG.target_progress) * 100 + var/list/strings[0] + for(var/j, j<10, j++) + var/string = "" + for(var/i, i<20, i++) + string = "[string][prob(percentage)]" + strings.Add(string) + data["dos_strings"] = strings + else if(program.computer.card_slot && program.computer.card_slot.stored_card) + var/obj/item/weapon/card/id/id_card = program.computer.card_slot.stored_card + var/list/regions = list() + for(var/i = 1; i <= 7; i++) + var/list/accesses = list() + for(var/access in get_region_accesses(i)) + if (get_access_desc(access)) + accesses.Add(list(list( + "desc" = replacetext(get_access_desc(access), " ", " "), + "ref" = access, + "allowed" = (access in id_card.access) ? 1 : 0, + "blocked" = (access in restricted_access_codes) ? 1 : 0))) + + regions.Add(list(list( + "name" = get_region_accesses_name(i), + "accesses" = accesses))) + data["regions"] = regions + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "access_decrypter.tmpl", "NTNet Access Decrypter", 550, 400, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm new file mode 100644 index 0000000000..0e0a1381bd --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -0,0 +1,108 @@ +/datum/computer_file/program/ntnet_dos + filename = "ntn_dos" + filedesc = "DoS Traffic Generator" + program_icon_state = "hostile" + program_key_state = "security_key" + program_menu_icon = "arrow-4-diag" + extended_desc = "This advanced script can perform denial of service attacks against NTNet quantum relays. The system administrator will probably notice this. Multiple devices can run this program together against same relay for increased effect" + size = 20 + requires_ntnet = 1 + available_on_ntnet = 0 + available_on_syndinet = 1 + nanomodule_path = /datum/nano_module/program/computer_dos/ + var/obj/machinery/ntnet_relay/target = null + var/dos_speed = 0 + var/error = "" + var/executed = 0 + +/datum/computer_file/program/ntnet_dos/process_tick() + dos_speed = 0 + switch(ntnet_status) + if(1) + dos_speed = NTNETSPEED_LOWSIGNAL * NTNETSPEED_DOS_AMPLIFICATION + if(2) + dos_speed = NTNETSPEED_HIGHSIGNAL * NTNETSPEED_DOS_AMPLIFICATION + if(3) + dos_speed = NTNETSPEED_ETHERNET * NTNETSPEED_DOS_AMPLIFICATION + if(target && executed) + target.dos_overload += dos_speed + if(!target.operable()) + target.dos_sources.Remove(src) + target = null + error = "Connection to destination relay lost." + +/datum/computer_file/program/ntnet_dos/kill_program(var/forced) + if(target) + target.dos_sources.Remove(src) + target = null + executed = 0 + + ..(forced) + +/datum/nano_module/program/computer_dos + name = "DoS Traffic Generator" + +/datum/nano_module/program/computer_dos/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(!ntnet_global) + return + var/datum/computer_file/program/ntnet_dos/PRG = program + var/list/data = list() + if(!istype(PRG)) + return + data = PRG.get_header_data() + + if(PRG.error) + data["error"] = PRG.error + else if(PRG.target && PRG.executed) + data["target"] = 1 + data["speed"] = PRG.dos_speed + + // This is mostly visual, generate some strings of 1s and 0s + // Probability of 1 is equal of completion percentage of DoS attack on this relay. + // Combined with UI updates this adds quite nice effect to the UI + var/percentage = PRG.target.dos_overload * 100 / PRG.target.dos_capacity + var/list/strings[0] + for(var/j, j<10, j++) + var/string = "" + for(var/i, i<20, i++) + string = "[string][prob(percentage)]" + strings.Add(string) + data["dos_strings"] = strings + else + var/list/relays[0] + for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays) + relays.Add(R.uid) + data["relays"] = relays + data["focus"] = PRG.target ? PRG.target.uid : null + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "ntnet_dos.tmpl", "DoS Traffic Generator", 400, 250, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/computer_file/program/ntnet_dos/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_target_relay"]) + for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays) + if("[R.uid]" == href_list["PRG_target_relay"]) + target = R + return 1 + if(href_list["PRG_reset"]) + if(target) + target.dos_sources.Remove(src) + target = null + executed = 0 + error = "" + return 1 + if(href_list["PRG_execute"]) + if(target) + executed = 1 + target.dos_sources.Add(src) + if(ntnet_global.intrusion_detection_enabled) + ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [computer.network_card.get_network_tag()]") + ntnet_global.intrusion_detection_alarm = 1 + return 1 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm new file mode 100644 index 0000000000..27e5a26c3f --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm @@ -0,0 +1,39 @@ +/datum/computer_file/program/camera_monitor/hacked + filename = "camcrypt" + filedesc = "Camera Decryption Tool" + nanomodule_path = /datum/nano_module/camera_monitor/hacked + program_icon_state = "hostile" + program_key_state = "security_key" + program_menu_icon = "zoomin" + extended_desc = "This very advanced piece of software uses adaptive programming and large database of cipherkeys to bypass most encryptions used on camera networks. Be warned that system administrator may notice this." + size = 73 // Very large, a price for bypassing ID checks completely. + available_on_ntnet = 0 + available_on_syndinet = 1 + +/datum/computer_file/program/camera_monitor/hacked/process_tick() + ..() + if(program_state != PROGRAM_STATE_ACTIVE) // Background programs won't trigger alarms. + return + + var/datum/nano_module/camera_monitor/hacked/HNM = NM + + // The program is active and connected to one of the station's networks. Has a very small chance to trigger IDS alarm every tick. + if(HNM && HNM.current_network && (HNM.current_network in using_map.station_networks) && prob(0.1)) + if(ntnet_global.intrusion_detection_enabled) + ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network [HNM.current_network] by device with NID [computer.network_card.get_network_tag()]") + ntnet_global.intrusion_detection_alarm = 1 + + +/datum/nano_module/camera_monitor/hacked + name = "Hacked Camera Monitoring Program" + //available_to_ai = FALSE + +/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access) + return 1 + +// The hacked variant has access to all commonly used networks. +/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks) + networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1))) + networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) + networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) + return networks \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm new file mode 100644 index 0000000000..17199c3b18 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -0,0 +1,84 @@ +/datum/computer_file/program/revelation + filename = "revelation" + filedesc = "Revelation" + program_icon_state = "hostile" + program_key_state = "security_key" + program_menu_icon = "home" + extended_desc = "This virus can destroy hard drive of system it is executed on. It may be obfuscated to look like another non-malicious program. Once armed, it will destroy the system upon next execution." + size = 13 + requires_ntnet = 0 + available_on_ntnet = 0 + available_on_syndinet = 1 + nanomodule_path = /datum/nano_module/program/revelation/ + var/armed = 0 + +/datum/computer_file/program/revelation/run_program(var/mob/living/user) + . = ..(user) + if(armed) + activate() + +/datum/computer_file/program/revelation/proc/activate() + if(!computer) + return + + computer.visible_message("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.") + computer.enabled = 0 + computer.update_icon() + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(10, 1, computer.loc) + s.start() + + if(computer.hard_drive) + qdel(computer.hard_drive) + + if(computer.battery_module && prob(25)) + qdel(computer.battery_module) + + if(computer.tesla_link && prob(50)) + qdel(computer.tesla_link) + +/datum/computer_file/program/revelation/Topic(href, href_list) + if(..()) + return 1 + else if(href_list["PRG_arm"]) + armed = !armed + else if(href_list["PRG_activate"]) + activate() + else if(href_list["PRG_obfuscate"]) + var/mob/living/user = usr + var/newname = sanitize(input(user, "Enter new program name: ")) + if(!newname) + return + filedesc = newname + for(var/datum/computer_file/program/P in ntnet_global.available_station_software) + if(filedesc == P.filedesc) + program_menu_icon = P.program_menu_icon + break + return 1 + +/datum/computer_file/program/revelation/clone() + var/datum/computer_file/program/revelation/temp = ..() + temp.armed = armed + return temp + +/datum/nano_module/program/revelation + name = "Revelation Virus" + +/datum/nano_module/program/revelation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = list() + var/datum/computer_file/program/revelation/PRG = program + if(!istype(PRG)) + return + + data = PRG.get_header_data() + + data["armed"] = PRG.armed + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "revelation.tmpl", "Revelation Virus", 400, 250, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm new file mode 100644 index 0000000000..80a250ca6b --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/command/card.dm @@ -0,0 +1,233 @@ +/datum/computer_file/program/card_mod + filename = "cardmod" + filedesc = "ID card modification program" + nanomodule_path = /datum/nano_module/program/card_mod + program_icon_state = "id" + program_key_state = "id_key" + program_menu_icon = "key" + extended_desc = "Program for programming crew ID cards." + required_access = access_change_ids + requires_ntnet = 0 + size = 8 + +/datum/nano_module/program/card_mod + name = "ID card modification program" + var/mod_mode = 1 + var/is_centcom = 0 + var/show_assignments = 0 + +/datum/nano_module/program/card_mod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + data["src"] = "\ref[src]" + data["station_name"] = station_name() + data["manifest"] = data_core ? data_core.get_manifest(0) : null + data["assignments"] = show_assignments + if(program && program.computer) + data["have_id_slot"] = !!program.computer.card_slot + data["have_printer"] = !!program.computer.nano_printer + data["authenticated"] = program.can_run(user) + if(!program.computer.card_slot) + mod_mode = 0 //We can't modify IDs when there is no card reader + else + data["have_id_slot"] = 0 + data["have_printer"] = 0 + data["authenticated"] = 0 + data["mmode"] = mod_mode + data["centcom_access"] = is_centcom + + if(program && program.computer && program.computer.card_slot) + var/obj/item/weapon/card/id/id_card = program.computer.card_slot.stored_card + data["has_id"] = !!id_card + data["id_account_number"] = id_card ? id_card.associated_account_number : null + data["id_rank"] = id_card && id_card.assignment ? id_card.assignment : "Unassigned" + data["id_owner"] = id_card && id_card.registered_name ? id_card.registered_name : "-----" + data["id_name"] = id_card ? id_card.name : "-----" + + data["command_jobs"] = format_jobs(command_positions) + data["engineering_jobs"] = format_jobs(engineering_positions) + data["medical_jobs"] = format_jobs(medical_positions) + data["science_jobs"] = format_jobs(science_positions) + data["security_jobs"] = format_jobs(security_positions) + data["cargo_jobs"] = format_jobs(cargo_positions) + data["civilian_jobs"] = format_jobs(civilian_positions) + data["centcom_jobs"] = format_jobs(get_all_centcom_jobs()) + + data["all_centcom_access"] = is_centcom ? get_accesses(1) : null + data["regions"] = get_accesses() + + if(program.computer.card_slot && program.computer.card_slot.stored_card) + var/obj/item/weapon/card/id/id_card = program.computer.card_slot.stored_card + if(is_centcom) + var/list/all_centcom_access = list() + for(var/access in get_all_centcom_access()) + all_centcom_access.Add(list(list( + "desc" = replacetext(get_centcom_access_desc(access), " ", " "), + "ref" = access, + "allowed" = (access in id_card.access) ? 1 : 0))) + data["all_centcom_access"] = all_centcom_access + else + var/list/regions = list() + for(var/i = 1; i <= 7; i++) + var/list/accesses = list() + for(var/access in get_region_accesses(i)) + if (get_access_desc(access)) + accesses.Add(list(list( + "desc" = replacetext(get_access_desc(access), " ", " "), + "ref" = access, + "allowed" = (access in id_card.access) ? 1 : 0))) + + regions.Add(list(list( + "name" = get_region_accesses_name(i), + "accesses" = accesses))) + data["regions"] = regions + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mod_identification_computer.tmpl", name, 600, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + +/datum/nano_module/program/card_mod/proc/format_jobs(list/jobs) + var/obj/item/weapon/card/id/id_card = program.computer.card_slot ? program.computer.card_slot.stored_card : null + var/list/formatted = list() + for(var/job in jobs) + formatted.Add(list(list( + "display_name" = replacetext(job, " ", " "), + "target_rank" = id_card && id_card.assignment ? id_card.assignment : "Unassigned", + "job" = job))) + + return formatted + +/datum/nano_module/program/card_mod/proc/get_accesses(var/is_centcom = 0) + return null + + +/datum/computer_file/program/card_mod/Topic(href, href_list) + if(..()) + return 1 + + var/mob/user = usr + var/obj/item/weapon/card/id/user_id_card = user.GetIdCard() + var/obj/item/weapon/card/id/id_card + if (computer.card_slot) + id_card = computer.card_slot.stored_card + + var/datum/nano_module/program/card_mod/module = NM + switch(href_list["action"]) + if("switchm") + if(href_list["target"] == "mod") + module.mod_mode = 1 + else if (href_list["target"] == "manifest") + module.mod_mode = 0 + if("togglea") + if(module.show_assignments) + module.show_assignments = 0 + else + module.show_assignments = 1 + if("print") + if(computer && computer.nano_printer) //This option should never be called if there is no printer + if(module.mod_mode) + if(can_run(user, 1)) + var/contents = {"

    Access Report

    + Prepared By: [user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]
    + For: [id_card.registered_name ? id_card.registered_name : "Unregistered"]
    +
    + Assignment: [id_card.assignment]
    + Account Number: #[id_card.associated_account_number]
    + Blood Type: [id_card.blood_type]

    + Access:
    + "} + + var/known_access_rights = get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM) + for(var/A in id_card.access) + if(A in known_access_rights) + contents += " [get_access_desc(A)]" + + if(!computer.nano_printer.print_text(contents,"access report")) + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") + return + else + computer.visible_message("\The [computer] prints out paper.") + else + var/contents = {"

    Crew Manifest

    +
    + [data_core ? data_core.get_manifest(0) : ""] + "} + if(!computer.nano_printer.print_text(contents,text("crew manifest ([])", stationtime2text()))) + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") + return + else + computer.visible_message("\The [computer] prints out paper.") + if("eject") + if(computer && computer.card_slot) + if(id_card) + data_core.manifest_modify(id_card.registered_name, id_card.assignment) + computer.proc_eject_id(user) + if("terminate") + if(computer && can_run(user, 1)) + id_card.assignment = "Terminated" + remove_nt_access(id_card) + callHook("terminate_employee", list(id_card)) + if("edit") + if(computer && can_run(user, 1)) + if(href_list["name"]) + var/temp_name = sanitizeName(input("Enter name.", "Name", id_card.registered_name),allow_numbers=TRUE) + if(temp_name) + id_card.registered_name = temp_name + else + computer.visible_message("[computer] buzzes rudely.") + else if(href_list["account"]) + var/account_num = text2num(input("Enter account number.", "Account", id_card.associated_account_number)) + id_card.associated_account_number = account_num + if("assign") + if(computer && can_run(user, 1) && id_card) + var/t1 = href_list["assign_target"] + if(t1 == "Custom") + var/temp_t = sanitize(input("Enter a custom job assignment.","Assignment", id_card.assignment), 45) + //let custom jobs function as an impromptu alt title, mainly for sechuds + if(temp_t) + id_card.assignment = temp_t + else + var/list/access = list() + if(module.is_centcom) + access = get_centcom_access(t1) + else + var/datum/job/jobdatum + for(var/jobtype in typesof(/datum/job)) + var/datum/job/J = new jobtype + if(ckey(J.title) == ckey(t1)) + jobdatum = J + break + if(!jobdatum) + to_chat(usr, "No log exists for this job: [t1]") + return + + access = jobdatum.get_access() + + remove_nt_access(id_card) + apply_access(id_card, access) + id_card.assignment = t1 + id_card.rank = t1 + + callHook("reassign_employee", list(id_card)) + if("access") + if(href_list["allowed"] && computer && can_run(user, 1)) + var/access_type = text2num(href_list["access_target"]) + var/access_allowed = text2num(href_list["allowed"]) + if(access_type in get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM)) + id_card.access -= access_type + if(!access_allowed) + id_card.access += access_type + if(id_card) + id_card.name = text("[id_card.registered_name]'s ID Card ([id_card.assignment])") + + SSnanoui.update_uis(NM) + return 1 + +/datum/computer_file/program/card_mod/proc/remove_nt_access(var/obj/item/weapon/card/id/id_card) + id_card.access -= get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM) + +/datum/computer_file/program/card_mod/proc/apply_access(var/obj/item/weapon/card/id/id_card, var/list/accesses) + id_card.access |= accesses diff --git a/code/modules/modular_computers/file_system/programs/command/comm.dm b/code/modules/modular_computers/file_system/programs/command/comm.dm new file mode 100644 index 0000000000..b69ba7bc73 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/command/comm.dm @@ -0,0 +1,326 @@ +#define STATE_DEFAULT 1 +#define STATE_MESSAGELIST 2 +#define STATE_VIEWMESSAGE 3 +#define STATE_STATUSDISPLAY 4 +#define STATE_ALERT_LEVEL 5 +/datum/computer_file/program/comm + filename = "comm" + filedesc = "Command and Communications Program" + program_icon_state = "comm" + program_key_state = "med_key" + program_menu_icon = "flag" + nanomodule_path = /datum/nano_module/program/comm + extended_desc = "Used to command and control. Can relay long-range communications. This program can not be run on tablet computers." + required_access = access_heads + requires_ntnet = 1 + size = 12 + usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP + network_destination = "long-range communication array" + var/datum/comm_message_listener/message_core = new + +/datum/computer_file/program/comm/clone() + var/datum/computer_file/program/comm/temp = ..() + temp.message_core.messages = null + temp.message_core.messages = message_core.messages.Copy() + return temp + +/datum/nano_module/program/comm + name = "Command and Communications Program" + //available_to_ai = TRUE + var/current_status = STATE_DEFAULT + var/msg_line1 = "" + var/msg_line2 = "" + var/centcomm_message_cooldown = 0 + var/announcment_cooldown = 0 + var/datum/announcement/priority/crew_announcement = new + var/current_viewing_message_id = 0 + var/current_viewing_message = null + +/datum/nano_module/program/comm/New() + ..() + crew_announcement.newscast = 1 + +/datum/nano_module/program/comm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + if(program) + data["emagged"] = program.computer_emagged + data["net_comms"] = !!program.get_signal(NTNET_COMMUNICATION) //Double !! is needed to get 1 or 0 answer + data["net_syscont"] = !!program.get_signal(NTNET_SYSTEMCONTROL) + if(program.computer) + data["have_printer"] = !!program.computer.nano_printer + else + data["have_printer"] = 0 + else + data["emagged"] = 0 + data["net_comms"] = 1 + data["net_syscont"] = 1 + data["have_printer"] = 0 + + data["message_line1"] = msg_line1 + data["message_line2"] = msg_line2 + data["state"] = current_status + data["isAI"] = issilicon(usr) + data["authenticated"] = is_autenthicated(user) + data["current_security_level"] = security_level + data["current_security_level_title"] = num2seclevel(security_level) + + data["def_SEC_LEVEL_DELTA"] = SEC_LEVEL_DELTA + data["def_SEC_LEVEL_YELLOW"] = SEC_LEVEL_YELLOW + data["def_SEC_LEVEL_ORANGE"] = SEC_LEVEL_ORANGE + data["def_SEC_LEVEL_VIOLET"] = SEC_LEVEL_VIOLET + data["def_SEC_LEVEL_BLUE"] = SEC_LEVEL_BLUE + data["def_SEC_LEVEL_GREEN"] = SEC_LEVEL_GREEN + + var/datum/comm_message_listener/l = obtain_message_listener() + data["messages"] = l.messages + data["message_deletion_allowed"] = l != global_message_listener + data["message_current_id"] = current_viewing_message_id + if(current_viewing_message) + data["message_current"] = current_viewing_message + + if(emergency_shuttle.location()) + data["have_shuttle"] = 1 + if(emergency_shuttle.online()) + data["have_shuttle_called"] = 1 + else + data["have_shuttle_called"] = 0 + else + data["have_shuttle"] = 0 + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "mod_communication.tmpl", name, 550, 420, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + +/datum/nano_module/program/comm/proc/is_autenthicated(var/mob/user) + if(program) + return program.can_run(user) + return 1 + +/datum/nano_module/program/comm/proc/obtain_message_listener() + if(program) + var/datum/computer_file/program/comm/P = program + return P.message_core + return global_message_listener + +/datum/nano_module/program/comm/Topic(href, href_list) + if(..()) + return 1 + var/mob/user = usr + var/ntn_comm = program ? !!program.get_signal(NTNET_COMMUNICATION) : 1 + var/ntn_cont = program ? !!program.get_signal(NTNET_SYSTEMCONTROL) : 1 + var/datum/comm_message_listener/l = obtain_message_listener() + switch(href_list["action"]) + if("sw_menu") + . = 1 + current_status = text2num(href_list["target"]) + if("announce") + . = 1 + if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) + if(user) + var/obj/item/weapon/card/id/id_card = user.GetIdCard() + crew_announcement.announcer = GetNameAndAssignmentFromId(id_card) + else + crew_announcement.announcer = "Unknown" + if(announcment_cooldown) + to_chat(usr, "Please allow at least one minute to pass between announcements") + return TRUE + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|text + if(!input || !can_still_topic()) + return 1 + crew_announcement.Announce(input) + announcment_cooldown = 1 + spawn(600)//One minute cooldown + announcment_cooldown = 0 + if("message") + . = 1 + if(href_list["target"] == "emagged") + if(program) + if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm) + if(centcomm_message_cooldown) + to_chat(usr, "Arrays recycling. Please stand by.") + SSnanoui.update_uis(src) + return + var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text) + if(!input || !can_still_topic()) + return 1 + Syndicate_announce(input, usr) + to_chat(usr, "Message transmitted.") + log_say("[key_name(usr)] has made an illegal announcement: [input]") + centcomm_message_cooldown = 1 + spawn(300)//30 second cooldown + centcomm_message_cooldown = 0 + else if(href_list["target"] == "regular") + if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) + if(centcomm_message_cooldown) + to_chat(usr, "Arrays recycling. Please stand by.") + SSnanoui.update_uis(src) + return + if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs. + to_chat(usr, "No Emergency Bluespace Relay detected. Unable to transmit message.") + return 1 + var/input = sanitize(input("Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text) + if(!input || !can_still_topic()) + return 1 + CentCom_announce(input, usr) + to_chat(usr, "Message transmitted.") + log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]") + centcomm_message_cooldown = 1 + spawn(300) //30 second cooldown + centcomm_message_cooldown = 0 + if("shuttle") + . = 1 + if(is_autenthicated(user) && ntn_cont) + if(href_list["target"] == "call") + var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes") + if(confirm == "Yes" && can_still_topic()) + call_shuttle_proc(usr) + + if(href_list["target"] == "cancel" && !issilicon(usr)) + var/confirm = alert("Are you sure you want to cancel the shuttle?", name, "No", "Yes") + if(confirm == "Yes" && can_still_topic()) + cancel_call_proc(usr) + if("setstatus") + . = 1 + if(is_autenthicated(user) && ntn_cont) + switch(href_list["target"]) + if("line1") + var/linput = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", msg_line1) as text|null, 40), 40) + if(can_still_topic()) + msg_line1 = linput + if("line2") + var/linput = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", msg_line2) as text|null, 40), 40) + if(can_still_topic()) + msg_line2 = linput + if("message") + post_status("message", msg_line1, msg_line2) + if("alert") + post_status("alert", href_list["alert"]) + else + post_status(href_list["target"]) + if("setalert") + . = 1 + if(is_autenthicated(user) && !issilicon(usr) && ntn_cont && ntn_comm) + var/current_level = text2num(href_list["target"]) + var/confirm = alert("Are you sure you want to change alert level to [num2seclevel(current_level)]?", name, "No", "Yes") + if(confirm == "Yes" && can_still_topic()) + var/old_level = security_level + if(!current_level) current_level = SEC_LEVEL_GREEN + if(current_level < SEC_LEVEL_GREEN) current_level = SEC_LEVEL_GREEN + if(current_level > SEC_LEVEL_BLUE) current_level = SEC_LEVEL_BLUE //Cannot engage delta with this + set_security_level(current_level) + if(security_level != old_level) + log_game("[key_name(usr)] has changed the security level to [get_security_level()].") + message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].") + switch(security_level) + if(SEC_LEVEL_GREEN) + feedback_inc("alert_comms_green",1) + if(SEC_LEVEL_YELLOW) + feedback_inc("alert_comms_yellow",1) + if(SEC_LEVEL_ORANGE) + feedback_inc("alert_comms_orange",1) + if(SEC_LEVEL_VIOLET) + feedback_inc("alert_comms_violet",1) + if(SEC_LEVEL_BLUE) + feedback_inc("alert_comms_blue",1) + else + to_chat(usr, "You press button, but red light flashes and nothing happens.")//This should never happen + + current_status = STATE_DEFAULT + if("viewmessage") + . = 1 + if(is_autenthicated(user) && ntn_comm) + current_viewing_message_id = text2num(href_list["target"]) + for(var/list/m in l.messages) + if(m["id"] == current_viewing_message_id) + current_viewing_message = m + current_status = STATE_VIEWMESSAGE + if("delmessage") + . = 1 + if(is_autenthicated(user) && ntn_comm && l != global_message_listener) + l.Remove(current_viewing_message) + current_status = STATE_MESSAGELIST + if("printmessage") + . = 1 + if(is_autenthicated(user) && ntn_comm) + if(program && program.computer && program.computer.nano_printer) + if(!program.computer.nano_printer.print_text(current_viewing_message["contents"],current_viewing_message["title"])) + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") + else + program.computer.visible_message("\The [program.computer] prints out paper.") + + +/datum/nano_module/program/comm/proc/post_status(var/command, var/data1, var/data2) + + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + + if(!frequency) return + + + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + log_admin("STATUS: [key_name(usr)] set status screen message with [src]: [data1] [data2]") + if("alert") + status_signal.data["picture_state"] = data1 + + frequency.post_signal(src, status_signal) + +#undef STATE_DEFAULT +#undef STATE_MESSAGELIST +#undef STATE_VIEWMESSAGE +#undef STATE_STATUSDISPLAY +#undef STATE_ALERT_LEVEL + +/* +General message handling stuff +*/ +var/list/comm_message_listeners = list() //We first have to initialize list then we can use it. +var/datum/comm_message_listener/global_message_listener = new //May be used by admins +var/last_message_id = 0 + +proc/get_comm_message_id() + last_message_id = last_message_id + 1 + return last_message_id + +proc/post_comm_message(var/message_title, var/message_text) + var/list/message = list() + message["id"] = get_comm_message_id() + message["title"] = message_title + message["contents"] = message_text + + for (var/datum/comm_message_listener/l in comm_message_listeners) + l.Add(message) + + //Old console support + for (var/obj/machinery/computer/communications/comm in machines) + if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) + var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) + intercept.name = message_title + intercept.info = message_text + + comm.messagetitle.Add(message_title) + comm.messagetext.Add(message_text) + +/datum/comm_message_listener + var/list/messages + +/datum/comm_message_listener/New() + ..() + messages = list() + comm_message_listeners.Add(src) + +/datum/comm_message_listener/proc/Add(var/list/message) + messages[++messages.len] = message + +/datum/comm_message_listener/proc/Remove(var/list/message) + messages -= list(message) diff --git a/code/modules/nano/modules/alarm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm similarity index 66% rename from code/modules/nano/modules/alarm_monitor.dm rename to code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm index ec43035ed8..cfd9353eee 100644 --- a/code/modules/nano/modules/alarm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm @@ -1,88 +1,134 @@ -/datum/nano_module/alarm_monitor - name = "Alarm monitor" - var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use. - var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user. - -/datum/nano_module/alarm_monitor/all/New() - ..() - alarm_handlers = alarm_manager.all_handlers - -/datum/nano_module/alarm_monitor/engineering/New() - ..() - alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm) - -/datum/nano_module/alarm_monitor/security/New() - ..() - alarm_handlers = list(camera_alarm, motion_alarm) - -/datum/nano_module/alarm_monitor/proc/register_alarm(var/object, var/procName) - for(var/datum/alarm_handler/AH in alarm_handlers) - AH.register_alarm(object, procName) - -/datum/nano_module/alarm_monitor/proc/unregister_alarm(var/object) - for(var/datum/alarm_handler/AH in alarm_handlers) - AH.unregister_alarm(object) - -/datum/nano_module/alarm_monitor/proc/all_alarms() - var/list/all_alarms = new() - for(var/datum/alarm_handler/AH in alarm_handlers) - all_alarms += AH.visible_alarms() - - return all_alarms - -/datum/nano_module/alarm_monitor/proc/major_alarms() - var/list/all_alarms = new() - for(var/datum/alarm_handler/AH in alarm_handlers) - all_alarms += AH.major_alarms() - - return all_alarms - -/datum/nano_module/alarm_monitor/proc/minor_alarms() - var/list/all_alarms = new() - for(var/datum/alarm_handler/AH in alarm_handlers) - all_alarms += AH.minor_alarms() - - return all_alarms - -/datum/nano_module/alarm_monitor/Topic(ref, href_list) - if(..()) - return 1 - if(href_list["switchTo"]) - var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras - if(!C) - return - - usr.switch_to_camera(C) - return 1 - -/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/data[0] - - var/categories[0] - for(var/datum/alarm_handler/AH in alarm_handlers) - categories[++categories.len] = list("category" = AH.category, "alarms" = list()) - for(var/datum/alarm/A in AH.major_alarms()) - var/cameras[0] - var/lost_sources[0] - - if(isAI(user)) - for(var/obj/machinery/camera/C in A.cameras()) - cameras[++cameras.len] = C.nano_structure() - for(var/datum/alarm_source/AS in A.sources) - if(!AS.source) - lost_sources[++lost_sources.len] = AS.source_name - - categories[categories.len]["alarms"] += list(list( - "name" = sanitize(A.alarm_name()), - "origin_lost" = A.origin == null, - "has_cameras" = cameras.len, - "cameras" = cameras, - "lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : "")) - data["categories"] = categories - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) +/datum/computer_file/program/alarm_monitor + filename = "alarmmonitor" + filedesc = "Alarm Monitoring" + nanomodule_path = /datum/nano_module/alarm_monitor/engineering + ui_header = "alarm_green.gif" + program_icon_state = "alert-green" + program_key_state = "atmos_key" + program_menu_icon = "alert" + extended_desc = "This program provides visual interface for the alarm system." + requires_ntnet = 1 + network_destination = "alarm monitoring network" + size = 5 + var/has_alert = 0 + +/datum/computer_file/program/alarm_monitor/process_tick() + ..() + var/datum/nano_module/alarm_monitor/NMA = NM + if(istype(NMA) && NMA.has_major_alarms()) + if(!has_alert) + program_icon_state = "alert-red" + ui_header = "alarm_red.gif" + update_computer_icon() + has_alert = 1 + else + if(has_alert) + program_icon_state = "alert-green" + ui_header = "alarm_green.gif" + update_computer_icon() + has_alert = 0 + return 1 + +/datum/nano_module/alarm_monitor + name = "Alarm monitor" + var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use. + var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user. + //available_to_ai = FALSE + +/datum/nano_module/alarm_monitor/New() + ..() + alarm_handlers = list() + +/datum/nano_module/alarm_monitor/all/New() + ..() + alarm_handlers = alarm_manager.all_handlers + +/datum/nano_module/alarm_monitor/engineering/New() + ..() + alarm_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, power_alarm) + +/datum/nano_module/alarm_monitor/security/New() + ..() + alarm_handlers = list(camera_alarm, motion_alarm) + +/datum/nano_module/alarm_monitor/proc/register_alarm(var/object, var/procName) + for(var/datum/alarm_handler/AH in alarm_handlers) + AH.register_alarm(object, procName) + +/datum/nano_module/alarm_monitor/proc/unregister_alarm(var/object) + for(var/datum/alarm_handler/AH in alarm_handlers) + AH.unregister_alarm(object) + +/datum/nano_module/alarm_monitor/proc/all_alarms() + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.visible_alarms() + + return all_alarms + +/datum/nano_module/alarm_monitor/proc/major_alarms() + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.major_alarms() + + return all_alarms + +// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise. +/datum/nano_module/alarm_monitor/proc/has_major_alarms() + for(var/datum/alarm_handler/AH in alarm_handlers) + if(AH.has_major_alarms()) + return 1 + + return 0 + +/datum/nano_module/alarm_monitor/proc/minor_alarms() + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.minor_alarms() + + return all_alarms + +/datum/nano_module/alarm_monitor/Topic(ref, href_list) + if(..()) + return 1 + if(href_list["switchTo"]) + var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras + if(!C) + return + + usr.switch_to_camera(C) + return 1 + +/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + var/categories[0] + for(var/datum/alarm_handler/AH in alarm_handlers) + categories[++categories.len] = list("category" = AH.category, "alarms" = list()) + for(var/datum/alarm/A in AH.major_alarms()) + var/cameras[0] + var/lost_sources[0] + + if(isAI(user)) + for(var/obj/machinery/camera/C in A.cameras()) + cameras[++cameras.len] = C.nano_structure() + for(var/datum/alarm_source/AS in A.sources) + if(!AS.source) + lost_sources[++lost_sources.len] = AS.source_name + + categories[categories.len]["alarms"] += list(list( + "name" = sanitize(A.alarm_name()), + "origin_lost" = A.origin == null, + "has_cameras" = cameras.len, + "cameras" = cameras, + "lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : "")) + data["categories"] = categories + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state) + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) diff --git a/code/modules/nano/modules/atmos_control.dm b/code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm similarity index 79% rename from code/modules/nano/modules/atmos_control.dm rename to code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm index 3924f65af7..3f88029713 100644 --- a/code/modules/nano/modules/atmos_control.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm @@ -1,86 +1,103 @@ -/datum/nano_module/atmos_control - name = "Atmospherics Control" - var/obj/access = new() - var/emagged = 0 - var/ui_ref - var/list/monitored_alarms = list() - -/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids) - ..() - access.req_access = req_access - access.req_one_access = req_one_access - - if(monitored_alarm_ids) - for(var/obj/machinery/alarm/alarm in machines) - if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids) - monitored_alarms += alarm - // machines may not yet be ordered at this point - monitored_alarms = dd_sortedObjectList(monitored_alarms) - -/datum/nano_module/atmos_control/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["alarm"]) - if(ui_ref) - var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines) - if(alarm) - var/datum/topic_state/TS = generate_state(alarm) - alarm.ui_interact(usr, master_ui = ui_ref, state = TS) - return 1 - -/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) - var/data[0] - var/alarms[0] - var/turf/T = get_turf(nano_host()) - - // TODO: Move these to a cache, similar to cameras - for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines)) - if(!monitored_alarms.len && alarm.alarms_hidden) - continue - alarms[++alarms.len] = list( - "name" = sanitize(alarm.name), - "ref"= "\ref[alarm]", - "danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm), - "x" = alarm.x, - "y" = alarm.y, - "z" = alarm.z) - data["alarms"] = alarms - data["map_levels"] = using_map.get_map_levels(T.z) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state) - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "atmos_control_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "atmos_control_map_header.tmpl") - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - ui_ref = ui - -/datum/nano_module/atmos_control/proc/generate_state(air_alarm) - var/datum/topic_state/air_alarm/state = new() - state.atmos_control = src - state.air_alarm = air_alarm - return state - -/datum/topic_state/air_alarm - var/datum/nano_module/atmos_control/atmos_control = null - var/obj/machinery/alarm/air_alarm = null - -/datum/topic_state/air_alarm/can_use_topic(var/src_object, var/mob/user) - if(has_access(user)) - return STATUS_INTERACTIVE - return STATUS_UPDATE - -/datum/topic_state/air_alarm/href_list(var/mob/user) - var/list/extra_href = list() - extra_href["remote_connection"] = 1 - extra_href["remote_access"] = has_access(user) - - return extra_href - -/datum/topic_state/air_alarm/proc/has_access(var/mob/user) - return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO)) +/datum/computer_file/program/atmos_control + filename = "atmoscontrol" + filedesc = "Atmosphere Control" + nanomodule_path = /datum/nano_module/atmos_control + program_icon_state = "atmos_control" + program_key_state = "atmos_key" + program_menu_icon = "shuffle" + extended_desc = "This program allows remote control of air alarms. This program can not be run on tablet computers." + required_access = access_atmospherics + requires_ntnet = 1 + network_destination = "atmospheric control system" + requires_ntnet_feature = NTNET_SYSTEMCONTROL + usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE + size = 17 + +/datum/nano_module/atmos_control + name = "Atmospherics Control" + var/obj/access = new() + var/emagged = 0 + var/ui_ref + var/list/monitored_alarms = list() + +/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids) + ..() + access.req_access = req_access + access.req_one_access = req_one_access + + if(monitored_alarm_ids) + for(var/obj/machinery/alarm/alarm in machines) + if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids) + monitored_alarms += alarm + // machines may not yet be ordered at this point + monitored_alarms = dd_sortedObjectList(monitored_alarms) + +/datum/nano_module/atmos_control/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["alarm"]) + if(ui_ref) + var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines) + if(alarm) + var/datum/topic_state/TS = generate_state(alarm) + alarm.ui_interact(usr, master_ui = ui_ref, state = TS) + return 1 + +/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + var/alarms[0] + var/turf/T = get_turf(nano_host()) + + // TODO: Move these to a cache, similar to cameras + for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines)) + if(!monitored_alarms.len && alarm.alarms_hidden) + continue + alarms[++alarms.len] = list( + "name" = sanitize(alarm.name), + "ref"= "\ref[alarm]", + "danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm), + "x" = alarm.x, + "y" = alarm.y, + "z" = alarm.z) + data["alarms"] = alarms + data["map_levels"] = using_map.get_map_levels(T.z) + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state) + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. + ui.auto_update_layout = 1 + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "atmos_control_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "atmos_control_map_header.tmpl") + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(0) + ui_ref = ui + +/datum/nano_module/atmos_control/proc/generate_state(air_alarm) + var/datum/topic_state/air_alarm/state = new() + state.atmos_control = src + state.air_alarm = air_alarm + return state + +/datum/topic_state/air_alarm + var/datum/nano_module/atmos_control/atmos_control = null + var/obj/machinery/alarm/air_alarm = null + +/datum/topic_state/air_alarm/can_use_topic(var/src_object, var/mob/user) + if(has_access(user)) + return STATUS_INTERACTIVE + return STATUS_UPDATE + +/datum/topic_state/air_alarm/href_list(var/mob/user) + var/list/extra_href = list() + extra_href["remote_connection"] = 1 + extra_href["remote_access"] = has_access(user) + + return extra_href + +/datum/topic_state/air_alarm/proc/has_access(var/mob/user) + return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO)) diff --git a/code/modules/nano/modules/power_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm similarity index 60% rename from code/modules/nano/modules/power_monitor.dm rename to code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm index ae5dc44f29..32117e845c 100644 --- a/code/modules/nano/modules/power_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm @@ -1,65 +1,113 @@ -/datum/nano_module/power_monitor - name = "Power monitor" - var/list/grid_sensors - var/active_sensor = null //name_tag of the currently selected sensor - -/datum/nano_module/power_monitor/New() - ..() - refresh_sensors() - -/datum/nano_module/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = list() - var/list/sensors = list() - // Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading. - var/obj/machinery/power/sensor/focus = null - var/turf/T = get_turf(nano_host()) - - // Build list of data from sensor readings. - for(var/obj/machinery/power/sensor/S in grid_sensors) - sensors.Add(list(list( - "name" = S.name_tag, - "alarm" = S.check_grid_warning() - ))) - if(S.name_tag == active_sensor) - focus = S - - data["all_sensors"] = sensors - if(focus) - data["focus"] = focus.return_reading_data() - data["map_levels"] = using_map.get_map_levels(T.z) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state) - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "power_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "power_monitor_map_header.tmpl") - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -// Refreshes list of active sensors kept on this computer. -/datum/nano_module/power_monitor/proc/refresh_sensors() - grid_sensors = list() - var/turf/T = get_turf(nano_host()) - var/list/levels = list() - if(T) - levels += using_map.get_map_levels(T.z, FALSE) - for(var/obj/machinery/power/sensor/S in machines) - if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels. - if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen! - warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z") - else - grid_sensors += S - -// Allows us to process UI clicks, which are relayed in form of hrefs. -/datum/nano_module/power_monitor/Topic(href, href_list) - if(..()) - return 1 - if( href_list["clear"] ) - active_sensor = null - if( href_list["refresh"] ) - refresh_sensors() - else if( href_list["setsensor"] ) - active_sensor = href_list["setsensor"] +/datum/computer_file/program/power_monitor + filename = "powermonitor" + filedesc = "Power Monitoring" + nanomodule_path = /datum/nano_module/power_monitor/ + program_icon_state = "power_monitor" + program_key_state = "power_key" + program_menu_icon = "battery-3" + extended_desc = "This program connects to sensors to provide information about electrical systems" + ui_header = "power_norm.gif" + required_access = access_engine + requires_ntnet = 1 + network_destination = "power monitoring system" + size = 9 + var/has_alert = 0 + +/datum/computer_file/program/power_monitor/process_tick() + ..() + var/datum/nano_module/power_monitor/NMA = NM + if(istype(NMA) && NMA.has_alarm()) + if(!has_alert) + program_icon_state = "power_monitor_warn" + ui_header = "power_warn.gif" + update_computer_icon() + has_alert = 1 + else + if(has_alert) + program_icon_state = "power_monitor" + ui_header = "power_norm.gif" + update_computer_icon() + has_alert = 0 + +/datum/nano_module/power_monitor + name = "Power monitor" + var/list/grid_sensors + var/active_sensor = null //name_tag of the currently selected sensor + +/datum/nano_module/power_monitor/New() + ..() + refresh_sensors() + +// Checks whether there is an active alarm, if yes, returns 1, otherwise returns 0. +/datum/nano_module/power_monitor/proc/has_alarm() + for(var/obj/machinery/power/sensor/S in grid_sensors) + if(S.check_grid_warning()) + return 1 + return 0 + +// If PC is not null header template is loaded. Use PC.get_header_data() to get relevant nanoui data from it. All data entries begin with "PC_...." +// In future it may be expanded to other modular computer devices. +/datum/nano_module/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + var/list/sensors = list() + // Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading. + var/obj/machinery/power/sensor/focus = null + var/turf/T = get_turf(nano_host()) + + // Build list of data from sensor readings. + for(var/obj/machinery/power/sensor/S in grid_sensors) + sensors.Add(list(list( + "name" = S.name_tag, + "alarm" = S.check_grid_warning() + ))) + if(S.name_tag == active_sensor) + focus = S + + data["all_sensors"] = sensors + if(focus) + data["focus"] = focus.return_reading_data() + data["map_levels"] = using_map.get_map_levels(T.z) + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state) + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. + ui.auto_update_layout = 1 + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "power_monitor_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "power_monitor_map_header.tmpl") + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +// Refreshes list of active sensors kept on this computer. +/datum/nano_module/power_monitor/proc/refresh_sensors() + grid_sensors = list() + var/turf/T = get_turf(nano_host()) + var/list/levels = list() + if(!T) // Safety check + return + if(T) + levels += using_map.get_map_levels(T.z, FALSE) + for(var/obj/machinery/power/sensor/S in machines) + if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels. + if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen! + warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z") + else + grid_sensors += S + +// Allows us to process UI clicks, which are relayed in form of hrefs. +/datum/nano_module/power_monitor/Topic(href, href_list) + if(..()) + return 1 + if( href_list["clear"] ) + active_sensor = null + . = 1 + if( href_list["refresh"] ) + refresh_sensors() + . = 1 + else if( href_list["setsensor"] ) + active_sensor = href_list["setsensor"] + . = 1 diff --git a/code/modules/nano/modules/rcon.dm b/code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm similarity index 82% rename from code/modules/nano/modules/rcon.dm rename to code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm index 65c1acfe36..d5ee88b670 100644 --- a/code/modules/nano/modules/rcon.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm @@ -1,115 +1,132 @@ -/datum/nano_module/rcon - name = "Power RCON" - var/list/known_SMESs = null - var/list/known_breakers = null - // Allows you to hide specific parts of the UI - var/hide_SMES = 0 - var/hide_SMES_details = 0 - var/hide_breakers = 0 - -/datum/nano_module/rcon/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1, var/datum/topic_state/state = default_state) - FindDevices() // Update our devices list - var/data[0] - - // SMES DATA (simplified view) - var/list/smeslist[0] - for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs) - smeslist.Add(list(list( - "charge" = round(SMES.Percentage()), - "input_set" = SMES.input_attempt, - "input_val" = round(SMES.input_level/1000, 0.1), - "output_set" = SMES.output_attempt, - "output_val" = round(SMES.output_level/1000, 0.1), - "output_load" = round(SMES.output_used/1000, 0.1), - "RCON_tag" = SMES.RCon_tag - ))) - - data["smes_info"] = sortByKey(smeslist, "RCON_tag") - - // BREAKER DATA (simplified view) - var/list/breakerlist[0] - for(var/obj/machinery/power/breakerbox/BR in known_breakers) - breakerlist.Add(list(list( - "RCON_tag" = BR.RCon_tag, - "enabled" = BR.on - ))) - data["breaker_info"] = breakerlist - data["hide_smes"] = hide_SMES - data["hide_smes_details"] = hide_SMES_details - data["hide_breakers"] = hide_breakers - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -// Proc: Topic() -// Parameters: 2 (href, href_list - allows us to process UI clicks) -// Description: Allows us to process UI clicks, which are relayed in form of hrefs. -/datum/nano_module/rcon/Topic(href, href_list) - if(..()) - return - - if(href_list["smes_in_toggle"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_toggle"]) - if(SMES) - SMES.toggle_input() - if(href_list["smes_out_toggle"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_toggle"]) - if(SMES) - SMES.toggle_output() - if(href_list["smes_in_set"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"]) - if(SMES) - var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000 - SMES.set_input(inputset) - if(href_list["smes_out_set"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"]) - if(SMES) - var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000 - SMES.set_output(outputset) - - if(href_list["toggle_breaker"]) - var/obj/machinery/power/breakerbox/toggle = null - for(var/obj/machinery/power/breakerbox/breaker in known_breakers) - if(breaker.RCon_tag == href_list["toggle_breaker"]) - toggle = breaker - if(toggle) - if(toggle.update_locked) - usr << "The breaker box was recently toggled. Please wait before toggling it again." - else - toggle.auto_toggle() - if(href_list["hide_smes"]) - hide_SMES = !hide_SMES - if(href_list["hide_smes_details"]) - hide_SMES_details = !hide_SMES_details - if(href_list["hide_breakers"]) - hide_breakers = !hide_breakers - - -// Proc: GetSMESByTag() -// Parameters: 1 (tag - RCON tag of SMES we want to look up) -// Description: Looks up and returns SMES which has matching RCON tag -/datum/nano_module/rcon/proc/GetSMESByTag(var/tag) - if(!tag) - return - - for(var/obj/machinery/power/smes/buildable/S in known_SMESs) - if(S.RCon_tag == tag) - return S - -// Proc: FindDevices() -// Parameters: None -// Description: Refreshes local list of known devices. -/datum/nano_module/rcon/proc/FindDevices() - known_SMESs = new /list() - for(var/obj/machinery/power/smes/buildable/SMES in machines) - if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon) - known_SMESs.Add(SMES) - - known_breakers = new /list() - for(var/obj/machinery/power/breakerbox/breaker in machines) - if(breaker.RCon_tag != "NO_TAG") - known_breakers.Add(breaker) +/datum/computer_file/program/rcon_console + filename = "rconconsole" + filedesc = "RCON Remote Control" + nanomodule_path = /datum/nano_module/rcon + program_icon_state = "generic" + program_key_state = "rd_key" + program_menu_icon = "power" + extended_desc = "This program allows remote control of power distribution systems. This program can not be run on tablet computers." + required_access = access_engine + requires_ntnet = 1 + network_destination = "RCON remote control system" + requires_ntnet_feature = NTNET_SYSTEMCONTROL + usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE + size = 19 + +/datum/nano_module/rcon + name = "Power RCON" + var/list/known_SMESs = null + var/list/known_breakers = null + // Allows you to hide specific parts of the UI + var/hide_SMES = 0 + var/hide_SMES_details = 0 + var/hide_breakers = 0 + +/datum/nano_module/rcon/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1, var/datum/topic_state/state = default_state) + FindDevices() // Update our devices list + var/list/data = host.initial_data() + + // SMES DATA (simplified view) + var/list/smeslist[0] + for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs) + smeslist.Add(list(list( + "charge" = round(SMES.Percentage()), + "input_set" = SMES.input_attempt, + "input_val" = round(SMES.input_level/1000, 0.1), + "output_set" = SMES.output_attempt, + "output_val" = round(SMES.output_level/1000, 0.1), + "output_load" = round(SMES.output_used/1000, 0.1), + "RCON_tag" = SMES.RCon_tag + ))) + + data["smes_info"] = sortByKey(smeslist, "RCON_tag") + + // BREAKER DATA (simplified view) + var/list/breakerlist[0] + for(var/obj/machinery/power/breakerbox/BR in known_breakers) + breakerlist.Add(list(list( + "RCON_tag" = BR.RCon_tag, + "enabled" = BR.on + ))) + data["breaker_info"] = breakerlist + data["hide_smes"] = hide_SMES + data["hide_smes_details"] = hide_SMES_details + data["hide_breakers"] = hide_breakers + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state) + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +// Proc: Topic() +// Parameters: 2 (href, href_list - allows us to process UI clicks) +// Description: Allows us to process UI clicks, which are relayed in form of hrefs. +/datum/nano_module/rcon/Topic(href, href_list) + if(..()) + return + + if(href_list["smes_in_toggle"]) + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_toggle"]) + if(SMES) + SMES.toggle_input() + if(href_list["smes_out_toggle"]) + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_toggle"]) + if(SMES) + SMES.toggle_output() + if(href_list["smes_in_set"]) + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"]) + if(SMES) + var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000 + SMES.set_input(inputset) + if(href_list["smes_out_set"]) + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"]) + if(SMES) + var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000 + SMES.set_output(outputset) + + if(href_list["toggle_breaker"]) + var/obj/machinery/power/breakerbox/toggle = null + for(var/obj/machinery/power/breakerbox/breaker in known_breakers) + if(breaker.RCon_tag == href_list["toggle_breaker"]) + toggle = breaker + if(toggle) + if(toggle.update_locked) + to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.") + else + toggle.auto_toggle() + if(href_list["hide_smes"]) + hide_SMES = !hide_SMES + if(href_list["hide_smes_details"]) + hide_SMES_details = !hide_SMES_details + if(href_list["hide_breakers"]) + hide_breakers = !hide_breakers + + +// Proc: GetSMESByTag() +// Parameters: 1 (tag - RCON tag of SMES we want to look up) +// Description: Looks up and returns SMES which has matching RCON tag +/datum/nano_module/rcon/proc/GetSMESByTag(var/tag) + if(!tag) + return + + for(var/obj/machinery/power/smes/buildable/S in known_SMESs) + if(S.RCon_tag == tag) + return S + +// Proc: FindDevices() +// Parameters: None +// Description: Refreshes local list of known devices. +/datum/nano_module/rcon/proc/FindDevices() + known_SMESs = new /list() + for(var/obj/machinery/power/smes/buildable/SMES in machines) + if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon) + known_SMESs.Add(SMES) + + known_breakers = new /list() + for(var/obj/machinery/power/breakerbox/breaker in machines) + if(breaker.RCon_tag != "NO_TAG") + known_breakers.Add(breaker) diff --git a/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm new file mode 100644 index 0000000000..af0489a953 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm @@ -0,0 +1,132 @@ +/datum/computer_file/program/supermatter_monitor + filename = "supmon" + filedesc = "Supermatter Monitoring" + nanomodule_path = /datum/nano_module/supermatter_monitor/ + program_icon_state = "smmon_0" + program_key_state = "tech_key" + program_menu_icon = "notice" + extended_desc = "This program connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." + ui_header = "smmon_0.gif" + required_access = access_engine + requires_ntnet = 1 + network_destination = "supermatter monitoring system" + size = 5 + var/last_status = 0 + +/datum/computer_file/program/supermatter_monitor/process_tick() + ..() + var/datum/nano_module/supermatter_monitor/NMS = NM + var/new_status = istype(NMS) ? NMS.get_status() : 0 + if(last_status != new_status) + last_status = new_status + ui_header = "smmon_[last_status].gif" + program_icon_state = "smmon_[last_status]" + if(istype(computer)) + computer.update_icon() + +/datum/nano_module/supermatter_monitor + name = "Supermatter monitor" + var/list/supermatters + var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal. + +/datum/nano_module/supermatter_monitor/Destroy() + . = ..() + active = null + supermatters = null + +/datum/nano_module/supermatter_monitor/New() + ..() + refresh() + +// Refreshes list of active supermatter crystals +/datum/nano_module/supermatter_monitor/proc/refresh() + supermatters = list() + var/turf/T = get_turf(nano_host()) + if(!T) + return + var/valid_z_levels = (GetConnectedZlevels(T.z) & using_map.station_levels) + for(var/obj/machinery/power/supermatter/S in machines) + // Delaminating, not within coverage, not on a tile. + if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/)) + continue + supermatters.Add(S) + + if(!(active in supermatters)) + active = null + +/datum/nano_module/supermatter_monitor/proc/get_status() + . = SUPERMATTER_INACTIVE + for(var/obj/machinery/power/supermatter/S in supermatters) + . = max(., S.get_status()) + +/datum/nano_module/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + if(istype(active)) + var/turf/T = get_turf(active) + if(!T) + active = null + return + var/datum/gas_mixture/air = T.return_air() + if(!istype(air)) + active = null + return + + data["active"] = 1 + data["SM_integrity"] = active.get_integrity() + data["SM_power"] = active.power + data["SM_ambienttemp"] = air.temperature + data["SM_ambientpressure"] = air.return_pressure() + //data["SM_EPR"] = active.get_epr() + if(air.total_moles) + data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01) + data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01) + data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01) + data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01) + data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01) + else + data["SM_gas_O2"] = 0 + data["SM_gas_CO2"] = 0 + data["SM_gas_N2"] = 0 + data["SM_gas_PH"] = 0 + data["SM_gas_N2O"] = 0 + else + var/list/SMS = list() + for(var/obj/machinery/power/supermatter/S in supermatters) + var/area/A = get_area(S) + if(!A) + continue + + SMS.Add(list(list( + "area_name" = A.name, + "integrity" = S.get_integrity(), + "uid" = S.uid + ))) + + data["active"] = 0 + data["supermatters"] = SMS + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400, state = state) + if(host.update_layout()) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/nano_module/supermatter_monitor/Topic(href, href_list) + if(..()) + return 1 + if( href_list["clear"] ) + active = null + return 1 + if( href_list["refresh"] ) + refresh() + return 1 + if( href_list["set"] ) + var/newuid = text2num(href_list["set"]) + for(var/obj/machinery/power/supermatter/S in supermatters) + if(S.uid == newuid) + active = S + return 1 \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/camera.dm b/code/modules/modular_computers/file_system/programs/generic/camera.dm new file mode 100644 index 0000000000..47ac48eb40 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/camera.dm @@ -0,0 +1,186 @@ +// Returns which access is relevant to passed network. Used by the program. +/proc/get_camera_access(var/network) + if(!network) + return 0 + . = using_map.get_network_access(network) + if(.) + return + + switch(network) + if(NETWORK_THUNDER) + return 0 + if(NETWORK_ENGINE,NETWORK_ENGINEERING,NETWORK_ENGINEERING_OUTPOST,NETWORK_ALARM_ATMOS,NETWORK_ALARM_FIRE,NETWORK_ALARM_POWER) + return access_engine + if(NETWORK_MEDICAL) + return access_medical + if(NETWORK_RESEARCH,NETWORK_RESEARCH_OUTPOST) + return access_research + if(NETWORK_MINE,NETWORK_CARGO ) + return access_mailsorting // Cargo office - all cargo staff should have access here. + if(NETWORK_COMMAND,NETWORK_TELECOM) + return access_heads + if(NETWORK_ERT) + return access_cent_specops + + return access_security // Default for all other networks + +/datum/computer_file/program/camera_monitor + filename = "cammon" + filedesc = "Camera Monitoring" + nanomodule_path = /datum/nano_module/camera_monitor + program_icon_state = "cameras" + program_key_state = "generic_key" + program_menu_icon = "search" + extended_desc = "This program allows remote access to the camera system. Some camera networks may have additional access requirements." + size = 12 + available_on_ntnet = 1 + requires_ntnet = 1 + +/datum/nano_module/camera_monitor + name = "Camera Monitoring program" + var/obj/machinery/camera/current_camera = null + var/current_network = null + +/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state) + var/list/data = host.initial_data() + + data["current_camera"] = current_camera ? current_camera.nano_structure() : null + data["current_network"] = current_network + + var/list/all_networks[0] + for(var/network in using_map.station_networks) + all_networks.Add(list(list( + "tag" = network, + "has_access" = can_access_network(user, get_camera_access(network)) + ))) + + all_networks = modify_networks_list(all_networks) + + data["networks"] = all_networks + + if(current_network) + data["cameras"] = camera_repository.cameras_in_network(current_network) + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mod_sec_camera.tmpl", "Camera Monitoring", 900, 800) + // ui.auto_update_layout = 1 // Disabled as with suit sensors monitor - breaks the UI map. Re-enable once it's fixed somehow. + + ui.add_template("mapContent", "sec_camera_map_content.tmpl") + ui.add_template("mapHeader", "mod_sec_camera_map_header.tmpl") + ui.set_initial_data(data) + ui.open() + +// Intended to be overriden by subtypes to manually add non-station networks to the list. +/datum/nano_module/camera_monitor/proc/modify_networks_list(var/list/networks) + return networks + +/datum/nano_module/camera_monitor/proc/can_access_network(var/mob/user, var/network_access) + // No access passed, or 0 which is considered no access requirement. Allow it. + if(!network_access) + return 1 + + return check_access(user, access_security) || check_access(user, network_access) + +/datum/nano_module/camera_monitor/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["switch_camera"]) + var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras + if(!C) + return + if(!(current_network in C.network)) + return + + switch_to_camera(usr, C) + return 1 + + else if(href_list["switch_network"]) + // Either security access, or access to the specific camera network's department is required in order to access the network. + if(can_access_network(usr, get_camera_access(href_list["switch_network"]))) + current_network = href_list["switch_network"] + else + to_chat(usr, "\The [nano_host()] shows an \"Network Access Denied\" error message.") + return 1 + + else if(href_list["reset"]) + reset_current() + usr.reset_view(current_camera) + return 1 + +/datum/nano_module/camera_monitor/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) + //don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras. + if(isAI(user)) + var/mob/living/silicon/ai/A = user + // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. + if(!A.is_in_chassis()) + return 0 + + A.eyeobj.setLoc(get_turf(C)) + A.client.eye = A.eyeobj + return 1 + + set_current(C) + user.machine = nano_host() + user.reset_view(C) + return 1 + +/datum/nano_module/camera_monitor/proc/set_current(var/obj/machinery/camera/C) + if(current_camera == C) + return + + if(current_camera) + reset_current() + + current_camera = C + if(current_camera) + var/mob/living/L = current_camera.loc + if(istype(L)) + L.tracking_initiated() + +/datum/nano_module/camera_monitor/proc/reset_current() + if(current_camera) + var/mob/living/L = current_camera.loc + if(istype(L)) + L.tracking_cancelled() + current_camera = null + +/datum/nano_module/camera_monitor/check_eye(var/mob/user as mob) + if(!current_camera) + return 0 + var/viewflag = current_camera.check_eye(user) + if ( viewflag < 0 ) //camera doesn't work + reset_current() + return viewflag + + +// ERT Variant of the program +/datum/computer_file/program/camera_monitor/ert + filename = "ntcammon" + filedesc = "Advanced Camera Monitoring" + extended_desc = "This program allows remote access to the camera system. Some camera networks may have additional access requirements. This version has an integrated database with additional encrypted keys." + size = 14 + nanomodule_path = /datum/nano_module/camera_monitor/ert + available_on_ntnet = 0 + +/datum/nano_module/camera_monitor/ert + name = "Advanced Camera Monitoring Program" + //available_to_ai = FALSE + +// The ERT variant has access to ERT and crescent cams, but still checks for accesses. ERT members should be able to use it. +/datum/nano_module/camera_monitor/ert/modify_networks_list(var/list/networks) + ..() + networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) + networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) + return networks + +/datum/nano_module/camera_monitor/apply_visual(mob/M) + if(current_camera) + current_camera.apply_visual(M) + else + remove_visual(M) + +/datum/nano_module/camera_monitor/remove_visual(mob/M) + if(current_camera) + current_camera.remove_visual(M) diff --git a/code/modules/modular_computers/file_system/programs/generic/configurator.dm b/code/modules/modular_computers/file_system/programs/generic/configurator.dm new file mode 100644 index 0000000000..c3ce1e358a --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/configurator.dm @@ -0,0 +1,64 @@ +// This is special hardware configuration program. +// It is to be used only with modular computers. +// It allows you to toggle components of your device. + +/datum/computer_file/program/computerconfig + filename = "compconfig" + filedesc = "Computer Configuration Tool" + extended_desc = "This program allows configuration of computer's hardware" + program_icon_state = "generic" + program_key_state = "generic_key" + program_menu_icon = "gear" + unsendable = 1 + undeletable = 1 + size = 4 + available_on_ntnet = 0 + requires_ntnet = 0 + nanomodule_path = /datum/nano_module/program/computer_configurator/ + +/datum/nano_module/program/computer_configurator + name = "NTOS Computer Configuration Tool" + var/obj/item/modular_computer/movable = null + +/datum/nano_module/program/computer_configurator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(program) + movable = program.computer + if(!istype(movable)) + movable = null + + // No computer connection, we can't get data from that. + if(!movable) + return 0 + + var/list/data = list() + + if(program) + data = program.get_header_data() + + var/list/hardware = movable.get_all_components() + + data["disk_size"] = movable.hard_drive.max_capacity + data["disk_used"] = movable.hard_drive.used_capacity + data["power_usage"] = movable.last_power_usage + data["battery_exists"] = movable.battery_module ? 1 : 0 + if(movable.battery_module) + data["battery_rating"] = movable.battery_module.battery.maxcharge + data["battery_percent"] = round(movable.battery_module.battery.percent()) + + var/list/all_entries[0] + for(var/obj/item/weapon/computer_hardware/H in hardware) + all_entries.Add(list(list( + "name" = H.name, + "desc" = H.desc, + "enabled" = H.enabled, + "critical" = H.critical, + "powerusage" = H.power_usage + ))) + + data["hardware"] = all_entries + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "laptop_configuration.tmpl", "NTOS Configuration Utility", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/email_client.dm b/code/modules/modular_computers/file_system/programs/generic/email_client.dm new file mode 100644 index 0000000000..3e2f979bb5 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/email_client.dm @@ -0,0 +1,499 @@ +/datum/computer_file/program/email_client + filename = "emailc" + filedesc = "Email Client" + extended_desc = "This program may be used to log in into your email account." + program_icon_state = "generic" + program_key_state = "generic_key" + program_menu_icon = "mail-closed" + size = 7 + requires_ntnet = 1 + available_on_ntnet = 1 + var/stored_login = "" + var/stored_password = "" + + nanomodule_path = /datum/nano_module/email_client + +// Persistency. Unless you log out, or unless your password changes, this will pre-fill the login data when restarting the program +/datum/computer_file/program/email_client/kill_program() + if(NM) + var/datum/nano_module/email_client/NME = NM + if(NME.current_account) + stored_login = NME.stored_login + stored_password = NME.stored_password + else + stored_login = "" + stored_password = "" + . = ..() + +/datum/computer_file/program/email_client/run_program() + . = ..() + if(NM) + var/datum/nano_module/email_client/NME = NM + NME.stored_login = stored_login + NME.stored_password = stored_password + NME.log_in() + NME.error = "" + NME.check_for_new_messages(1) + +/datum/computer_file/program/email_client/proc/new_mail_notify() + computer.visible_message("\The [computer] beeps softly, indicating a new email has been received.", 1) + +/datum/computer_file/program/email_client/process_tick() + ..() + var/datum/nano_module/email_client/NME = NM + if(!istype(NME)) + return + NME.relayed_process(ntnet_speed) + + var/check_count = NME.check_for_new_messages() + if(check_count) + if(check_count == 2) + new_mail_notify() + ui_header = "ntnrc_new.gif" + else + ui_header = "ntnrc_idle.gif" + +/datum/nano_module/email_client/ + name = "Email Client" + var/stored_login = "" + var/stored_password = "" + var/error = "" + + var/msg_title = "" + var/msg_body = "" + var/msg_recipient = "" + var/datum/computer_file/msg_attachment = null + var/folder = "Inbox" + var/addressbook = FALSE + var/new_message = FALSE + + var/last_message_count = 0 // How many messages were there during last check. + var/read_message_count = 0 // How many messages were there when user has last accessed the UI. + + var/datum/computer_file/downloading = null + var/download_progress = 0 + var/download_speed = 0 + + var/datum/computer_file/data/email_account/current_account = null + var/datum/computer_file/data/email_message/current_message = null + +/datum/nano_module/email_client/proc/log_in() + for(var/datum/computer_file/data/email_account/account in ntnet_global.email_accounts) + if(!account.can_login) + continue + if(account.login == stored_login) + if(account.password == stored_password) + if(account.suspended) + error = "This account has been suspended. Please contact the system administrator for assistance." + return 0 + current_account = account + return 1 + else + error = "Invalid Password" + return 0 + error = "Invalid Login" + return 0 + +// Returns 0 if no new messages were received, 1 if there is an unread message but notification has already been sent. +// and 2 if there is a new message that appeared in this tick (and therefore notification should be sent by the program). +/datum/nano_module/email_client/proc/check_for_new_messages(var/messages_read = FALSE) + if(!current_account) + return 0 + + var/list/allmails = current_account.all_emails() + + if(allmails.len > last_message_count) + . = 2 + else if(allmails.len > read_message_count) + . = 1 + else + . = 0 + + last_message_count = allmails.len + if(messages_read) + read_message_count = allmails.len + + +/datum/nano_module/email_client/proc/log_out() + current_account = null + downloading = null + download_progress = 0 + last_message_count = 0 + read_message_count = 0 + +/datum/nano_module/email_client/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + // Password has been changed by other client connected to this email account + if(current_account) + if(current_account.password != stored_password) + log_out() + error = "Invalid Password" + // Banned. + if(current_account.suspended) + log_out() + error = "This account has been suspended. Please contact the system administrator for assistance." + + if(error) + data["error"] = error + else if(downloading) + data["downloading"] = 1 + data["down_filename"] = "[downloading.filename].[downloading.filetype]" + data["down_progress"] = download_progress + data["down_size"] = downloading.size + data["down_speed"] = download_speed + + else if(istype(current_account)) + data["current_account"] = current_account.login + if(addressbook) + var/list/all_accounts = list() + for(var/datum/computer_file/data/email_account/account in ntnet_global.email_accounts) + if(!account.can_login) + continue + all_accounts.Add(list(list( + "login" = account.login + ))) + data["addressbook"] = 1 + data["accounts"] = all_accounts + else if(new_message) + data["new_message"] = 1 + data["msg_title"] = msg_title + data["msg_body"] = pencode2html(msg_body) + data["msg_recipient"] = msg_recipient + if(msg_attachment) + data["msg_hasattachment"] = 1 + data["msg_attachment_filename"] = "[msg_attachment.filename].[msg_attachment.filetype]" + data["msg_attachment_size"] = msg_attachment.size + else if (current_message) + data["cur_title"] = current_message.title + data["cur_body"] = pencode2html(current_message.stored_data) + data["cur_timestamp"] = current_message.timestamp + data["cur_source"] = current_message.source + data["cur_uid"] = current_message.uid + if(istype(current_message.attachment)) + data["cur_hasattachment"] = 1 + data["cur_attachment_filename"] = "[current_message.attachment.filename].[current_message.attachment.filetype]" + data["cur_attachment_size"] = current_message.attachment.size + else + data["label_inbox"] = "Inbox ([current_account.inbox.len])" + data["label_spam"] = "Spam ([current_account.spam.len])" + data["label_deleted"] = "Deleted ([current_account.deleted.len])" + var/list/message_source + if(folder == "Inbox") + message_source = current_account.inbox + else if(folder == "Spam") + message_source = current_account.spam + else if(folder == "Deleted") + message_source = current_account.deleted + + if(message_source) + data["folder"] = folder + var/list/all_messages = list() + for(var/datum/computer_file/data/email_message/message in message_source) + all_messages.Add(list(list( + "title" = message.title, + "body" = pencode2html(message.stored_data), + "source" = message.source, + "timestamp" = message.timestamp, + "uid" = message.uid + ))) + data["messages"] = all_messages + data["messagecount"] = all_messages.len + else + data["stored_login"] = stored_login + data["stored_password"] = stars(stored_password, 0) + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "email_client.tmpl", "Email Client", 600, 450, state = state) + if(host.update_layout()) + ui.auto_update_layout = 1 + ui.set_auto_update(1) + ui.set_initial_data(data) + ui.open() + +/datum/nano_module/email_client/proc/find_message_by_fuid(var/fuid) + if(!istype(current_account)) + return + + // href_list works with strings, so this makes it a bit easier for us + if(istext(fuid)) + fuid = text2num(fuid) + + for(var/datum/computer_file/data/email_message/message in current_account.all_emails()) + if(message.uid == fuid) + return message + +/datum/nano_module/email_client/proc/clear_message() + new_message = FALSE + msg_title = "" + msg_body = "" + msg_recipient = "" + msg_attachment = null + current_message = null + +/datum/nano_module/email_client/proc/relayed_process(var/netspeed) + download_speed = netspeed + if(!downloading) + return + download_progress = min(download_progress + netspeed, downloading.size) + if(download_progress >= downloading.size) + var/obj/item/modular_computer/MC = nano_host() + if(!istype(MC) || !MC.hard_drive || !MC.hard_drive.check_functionality()) + error = "Error uploading file. Are you using a functional and NTOSv2-compliant device?" + downloading = null + download_progress = 0 + return 1 + + if(MC.hard_drive.store_file(downloading)) + error = "File successfully downloaded to local device." + else + error = "Error saving file: I/O Error: The hard drive may be full or nonfunctional." + downloading = null + download_progress = 0 + return 1 + + +/datum/nano_module/email_client/Topic(href, href_list) + if(..()) + return 1 + var/mob/living/user = usr + check_for_new_messages(1) // Any actual interaction (button pressing) is considered as acknowledging received message, for the purpose of notification icons. + if(href_list["login"]) + log_in() + return 1 + + if(href_list["logout"]) + log_out() + return 1 + + if(href_list["reset"]) + error = "" + return 1 + + if(href_list["new_message"]) + new_message = TRUE + return 1 + + if(href_list["cancel"]) + if(addressbook) + addressbook = FALSE + else + clear_message() + return 1 + + if(href_list["addressbook"]) + addressbook = TRUE + return 1 + + if(href_list["set_recipient"]) + msg_recipient = sanitize(href_list["set_recipient"]) + addressbook = FALSE + return 1 + + if(href_list["edit_title"]) + var/newtitle = sanitize(input(user,"Enter title for your message:", "Message title", msg_title), 100) + if(newtitle) + msg_title = newtitle + return 1 + + // This uses similar editing mechanism as the FileManager program, therefore it supports various paper tags and remembers formatting. + if(href_list["edit_body"]) + var/oldtext = html_decode(msg_body) + oldtext = replacetext(oldtext, "\[editorbr\]", "\n") + + var/newtext = sanitize(replacetext(input(usr, "Enter your message. You may use most tags from paper formatting", "Message Editor", oldtext) as message|null, "\n", "\[editorbr\]"), 20000) + if(newtext) + msg_body = newtext + return 1 + + if(href_list["edit_recipient"]) + var/newrecipient = sanitize(input(user,"Enter recipient's email address:", "Recipient", msg_recipient), 100) + if(newrecipient) + msg_recipient = newrecipient + return 1 + + if(href_list["edit_login"]) + var/newlogin = sanitize(input(user,"Enter login", "Login", stored_login), 100) + if(newlogin) + stored_login = newlogin + return 1 + + if(href_list["edit_password"]) + var/newpass = sanitize(input(user,"Enter password", "Password"), 100) + if(newpass) + stored_password = newpass + return 1 + + if(href_list["delete"]) + if(!istype(current_account)) + return 1 + var/datum/computer_file/data/email_message/M = find_message_by_fuid(href_list["delete"]) + if(!istype(M)) + return 1 + if(folder == "Deleted") + current_account.deleted.Remove(M) + qdel(M) + else + current_account.deleted.Add(M) + current_account.inbox.Remove(M) + current_account.spam.Remove(M) + if(current_message == M) + current_message = null + return 1 + + if(href_list["send"]) + if(!current_account) + return 1 + if((msg_title == "") || (msg_body == "") || (msg_recipient == "")) + error = "Error sending mail: Title or message body is empty!" + return 1 + + var/datum/computer_file/data/email_message/message = new() + message.title = msg_title + message.stored_data = msg_body + message.source = current_account.login + message.attachment = msg_attachment + if(!current_account.send_mail(msg_recipient, message)) + error = "Error sending email: this address doesn't exist." + return 1 + else + error = "Email successfully sent." + clear_message() + return 1 + + if(href_list["set_folder"]) + folder = href_list["set_folder"] + return 1 + + if(href_list["reply"]) + var/datum/computer_file/data/email_message/M = find_message_by_fuid(href_list["reply"]) + if(!istype(M)) + return 1 + + new_message = TRUE + msg_recipient = M.source + msg_title = "Re: [M.title]" + msg_body = "\[editorbr\]\[editorbr\]\[editorbr\]\[br\]==============================\[br\]\[editorbr\]" + msg_body += "Received by [current_account.login] at [M.timestamp]\[br\]\[editorbr\][M.stored_data]" + return 1 + + if(href_list["view"]) + var/datum/computer_file/data/email_message/M = find_message_by_fuid(href_list["view"]) + if(istype(M)) + current_message = M + return 1 + + if(href_list["changepassword"]) + var/oldpassword = sanitize(input(user,"Please enter your old password:", "Password Change"), 100) + if(!oldpassword) + return 1 + var/newpassword1 = sanitize(input(user,"Please enter your new password:", "Password Change"), 100) + if(!newpassword1) + return 1 + var/newpassword2 = sanitize(input(user,"Please re-enter your new password:", "Password Change"), 100) + if(!newpassword2) + return 1 + + if(!istype(current_account)) + error = "Please log in before proceeding." + return 1 + + if(current_account.password != oldpassword) + error = "Incorrect original password" + return 1 + + if(newpassword1 != newpassword2) + error = "The entered passwords do not match." + return 1 + + current_account.password = newpassword1 + stored_password = newpassword1 + error = "Your password has been successfully changed!" + return 1 + + // The following entries are Modular Computer framework only, and therefore won't do anything in other cases (like AI View) + + if(href_list["save"]) + // Fully dependant on modular computers here. + var/obj/item/modular_computer/MC = nano_host() + + if(!istype(MC) || !MC.hard_drive || !MC.hard_drive.check_functionality()) + error = "Error exporting file. Are you using a functional and NTOS-compliant device?" + return 1 + + var/filename = sanitize(input(user,"Please specify file name:", "Message export"), 100) + if(!filename) + return 1 + + var/datum/computer_file/data/email_message/M = find_message_by_fuid(href_list["save"]) + var/datum/computer_file/data/mail = istype(M) ? M.export() : null + if(!istype(mail)) + return 1 + mail.filename = filename + if(!MC.hard_drive || !MC.hard_drive.store_file(mail)) + error = "Internal I/O error when writing file, the hard drive may be full." + else + error = "Email exported successfully" + return 1 + + if(href_list["addattachment"]) + var/obj/item/modular_computer/MC = nano_host() + msg_attachment = null + + if(!istype(MC) || !MC.hard_drive || !MC.hard_drive.check_functionality()) + error = "Error uploading file. Are you using a functional and NTOSv2-compliant device?" + return 1 + + var/list/filenames = list() + for(var/datum/computer_file/CF in MC.hard_drive.stored_files) + if(CF.unsendable) + continue + filenames.Add(CF.filename) + var/picked_file = input(user, "Please pick a file to send as attachment (max 32GQ)") as null|anything in filenames + + if(!picked_file) + return 1 + + if(!istype(MC) || !MC.hard_drive || !MC.hard_drive.check_functionality()) + error = "Error uploading file. Are you using a functional and NTOSv2-compliant device?" + return 1 + + for(var/datum/computer_file/CF in MC.hard_drive.stored_files) + if(CF.unsendable) + continue + if(CF.filename == picked_file) + msg_attachment = CF.clone() + break + if(!istype(msg_attachment)) + msg_attachment = null + error = "Unknown error when uploading attachment." + return 1 + + if(msg_attachment.size > 32) + error = "Error uploading attachment: File exceeds maximal permitted file size of 32GQ." + msg_attachment = null + else + error = "File [msg_attachment.filename].[msg_attachment.filetype] has been successfully uploaded." + return 1 + + if(href_list["downloadattachment"]) + if(!current_account || !current_message || !current_message.attachment) + return 1 + var/obj/item/modular_computer/MC = nano_host() + if(!istype(MC) || !MC.hard_drive || !MC.hard_drive.check_functionality()) + error = "Error downloading file. Are you using a functional and NTOSv2-compliant device?" + return 1 + + downloading = current_message.attachment.clone() + download_progress = 0 + return 1 + + if(href_list["canceldownload"]) + downloading = null + download_progress = 0 + return 1 + + if(href_list["remove_attachment"]) + msg_attachment = null + return 1 \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/file_browser.dm b/code/modules/modular_computers/file_system/programs/generic/file_browser.dm new file mode 100644 index 0000000000..42dfdd622d --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/file_browser.dm @@ -0,0 +1,207 @@ +/datum/computer_file/program/filemanager + filename = "filemanager" + filedesc = "NTOS File Manager" + extended_desc = "This program allows management of files." + program_icon_state = "generic" + program_key_state = "generic_key" + program_menu_icon = "folder-collapsed" + size = 8 + requires_ntnet = 0 + available_on_ntnet = 0 + undeletable = 1 + nanomodule_path = /datum/nano_module/program/computer_filemanager/ + var/open_file + var/error + +/datum/computer_file/program/filemanager/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["PRG_openfile"]) + . = 1 + open_file = href_list["PRG_openfile"] + if(href_list["PRG_newtextfile"]) + . = 1 + var/newname = sanitize(input(usr, "Enter file name or leave blank to cancel:", "File rename")) + if(!newname) + return 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/data/F = new/datum/computer_file/data() + F.filename = newname + F.filetype = "TXT" + HDD.store_file(F) + if(href_list["PRG_deletefile"]) + . = 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_deletefile"]) + if(!file || file.undeletable) + return 1 + HDD.remove_file(file) + if(href_list["PRG_usbdeletefile"]) + . = 1 + var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.portable_drive + if(!RHDD) + return 1 + var/datum/computer_file/file = RHDD.find_file_by_name(href_list["PRG_usbdeletefile"]) + if(!file || file.undeletable) + return 1 + RHDD.remove_file(file) + if(href_list["PRG_closefile"]) + . = 1 + open_file = null + error = null + if(href_list["PRG_clone"]) + . = 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_clone"]) + if(!F || !istype(F)) + return 1 + var/datum/computer_file/C = F.clone(1) + HDD.store_file(C) + if(href_list["PRG_rename"]) + . = 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_rename"]) + if(!file || !istype(file)) + return 1 + var/newname = sanitize(input(usr, "Enter new file name:", "File rename", file.filename)) + if(file && newname) + file.filename = newname + if(href_list["PRG_edit"]) + . = 1 + if(!open_file) + return 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) + if(!F || !istype(F)) + return 1 + if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No")) + return 1 + + var/oldtext = html_decode(F.stored_data) + oldtext = replacetext(oldtext, "\[br\]", "\n") + + var/newtext = sanitize(replacetext(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", oldtext) as message|null, "\n", "\[br\]"), MAX_TEXTFILE_LENGTH) + if(!newtext) + return + + if(F) + var/datum/computer_file/data/backup = F.clone() + HDD.remove_file(F) + F.stored_data = newtext + F.calculate_size() + // We can't store the updated file, it's probably too large. Print an error and restore backed up version. + // This is mostly intended to prevent people from losing texts they spent lot of time working on due to running out of space. + // They will be able to copy-paste the text from error screen and store it in notepad or something. + if(!HDD.store_file(F)) + error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:

    [html_decode(F.stored_data)]

    " + HDD.store_file(backup) + if(href_list["PRG_printfile"]) + . = 1 + if(!open_file) + return 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) + if(!F || !istype(F)) + return 1 + if(!computer.nano_printer) + error = "Missing Hardware: Your computer does not have required hardware to complete this operation." + return 1 + if(!computer.nano_printer.print_text(pencode2html(F.stored_data))) + error = "Hardware error: Printer was unable to print the file. It may be out of paper." + return 1 + if(href_list["PRG_copytousb"]) + . = 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive + if(!HDD || !RHDD) + return 1 + var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_copytousb"]) + if(!F || !istype(F)) + return 1 + var/datum/computer_file/C = F.clone(0) + RHDD.store_file(C) + if(href_list["PRG_copyfromusb"]) + . = 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive + if(!HDD || !RHDD) + return 1 + var/datum/computer_file/F = RHDD.find_file_by_name(href_list["PRG_copyfromusb"]) + if(!F || !istype(F)) + return 1 + var/datum/computer_file/C = F.clone(0) + HDD.store_file(C) + if(.) + SSnanoui.update_uis(NM) + +/datum/nano_module/program/computer_filemanager + name = "NTOS File Manager" + +/datum/nano_module/program/computer_filemanager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + var/datum/computer_file/program/filemanager/PRG + PRG = program + + var/obj/item/weapon/computer_hardware/hard_drive/HDD + var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD + if(PRG.error) + data["error"] = PRG.error + if(PRG.open_file) + var/datum/computer_file/data/file + + if(!PRG.computer || !PRG.computer.hard_drive) + data["error"] = "I/O ERROR: Unable to access hard drive." + else + HDD = PRG.computer.hard_drive + file = HDD.find_file_by_name(PRG.open_file) + if(!istype(file)) + data["error"] = "I/O ERROR: Unable to open file." + else + data["filedata"] = pencode2html(file.stored_data) + data["filename"] = "[file.filename].[file.filetype]" + else + if(!PRG.computer || !PRG.computer.hard_drive) + data["error"] = "I/O ERROR: Unable to access hard drive." + else + HDD = PRG.computer.hard_drive + RHDD = PRG.computer.portable_drive + var/list/files[0] + for(var/datum/computer_file/F in HDD.stored_files) + files.Add(list(list( + "name" = F.filename, + "type" = F.filetype, + "size" = F.size, + "undeletable" = F.undeletable + ))) + data["files"] = files + if(RHDD) + data["usbconnected"] = 1 + var/list/usbfiles[0] + for(var/datum/computer_file/F in RHDD.stored_files) + usbfiles.Add(list(list( + "name" = F.filename, + "type" = F.filetype, + "size" = F.size, + "undeletable" = F.undeletable + ))) + data["usbfiles"] = usbfiles + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "file_manager.tmpl", "NTOS File Manager", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/game.dm b/code/modules/modular_computers/file_system/programs/generic/game.dm new file mode 100644 index 0000000000..b4c0688c29 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/game.dm @@ -0,0 +1,152 @@ +// This file is used as a reference for Modular Computers Development guide on the wiki. It contains a lot of excess comments, as it is intended as explanation +// for someone who may not be as experienced in coding. When making changes, please try to keep it this way. + +// An actual program definition. +/datum/computer_file/program/game + filename = "arcadec" // File name, as shown in the file browser program. + filedesc = "Unknown Game" // User-Friendly name. In this case, we will generate a random name in constructor. + program_icon_state = "game" // Icon state of this program's screen. + program_menu_icon = "script" + extended_desc = "Fun for the whole family! Probably not an AAA title, but at least you can download it on the corporate network.." // A nice description. + size = 5 // Size in GQ. Integers only. Smaller sizes should be used for utility/low use programs (like this one), while large sizes are for important programs. + requires_ntnet = 0 // This particular program does not require NTNet network conectivity... + available_on_ntnet = 1 // ... but we want it to be available for download. + nanomodule_path = /datum/nano_module/arcade_classic/ // Path of relevant nano module. The nano module is defined further in the file. + var/picked_enemy_name + +// Blatantly stolen and shortened version from arcade machines. Generates a random enemy name +/datum/computer_file/program/game/proc/random_enemy_name() + var/name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") + var/name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "Slime", "Lizard Man", "Unicorn") + return "[name_part1] [name_part2]" + +// When the program is first created, we generate a new enemy name and name ourselves accordingly. +/datum/computer_file/program/game/New() + ..() + picked_enemy_name = random_enemy_name() + filedesc = "Defeat [picked_enemy_name]" + +// Important in order to ensure that copied versions will have the same enemy name. +/datum/computer_file/program/game/clone() + var/datum/computer_file/program/game/G = ..() + G.picked_enemy_name = picked_enemy_name + return G + +// When running the program, we also want to pass our enemy name to the nano module. +/datum/computer_file/program/game/run_program() + . = ..() + if(. && NM) + var/datum/nano_module/arcade_classic/NMC = NM + NMC.enemy_name = picked_enemy_name + + +// Nano module the program uses. +// This can be either /datum/nano_module/ or /datum/nano_module/program. The latter is intended for nano modules that are suposed to be exclusively used with modular computers, +// and should generally not be used, as such nano modules are hard to use on other places. +/datum/nano_module/arcade_classic/ + name = "Classic Arcade" + var/player_mana // Various variables specific to the nano module. In this case, the nano module is a simple arcade game, so the variables store health and other stats. + var/player_health + var/enemy_mana + var/enemy_health + var/enemy_name = "Greytide Horde" + var/gameover + var/information + +/datum/nano_module/arcade_classic/New() + ..() + new_game() + +// ui_interact handles transfer of data to NanoUI. Keep in mind that data you pass from here is actually sent to the client. In other words, don't send anything you don't want a client +// to see, and don't send unnecessarily large amounts of data (due to laginess). +/datum/nano_module/arcade_classic/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + data["player_health"] = player_health + data["player_mana"] = player_mana + data["enemy_health"] = enemy_health + data["enemy_mana"] = enemy_mana + data["enemy_name"] = enemy_name + data["gameover"] = gameover + data["information"] = information + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "arcade_classic.tmpl", "Defeat [enemy_name]", 500, 350, state = state) + if(host.update_layout()) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + +// Three helper procs i've created. These are unique to this particular nano module. If you are creating your own nano module, you'll most likely create similar procs too. +/datum/nano_module/arcade_classic/proc/enemy_play() + if((enemy_mana < 5) && prob(60)) + var/steal = rand(2, 3) + player_mana -= steal + enemy_mana += steal + information += "[enemy_name] steals [steal] of your power!" + else if((enemy_health < 15) && (enemy_mana > 3) && prob(80)) + var/healamt = min(rand(3, 5), enemy_mana) + enemy_mana -= healamt + enemy_health += healamt + information += "[enemy_name] heals for [healamt] health!" + else + var/dam = rand(3,6) + player_health -= dam + information += "[enemy_name] attacks for [dam] damage!" + +/datum/nano_module/arcade_classic/proc/check_gameover() + if((player_health <= 0) || player_mana <= 0) + if(enemy_health <= 0) + information += "You have defeated [enemy_name], but you have died in the fight!" + else + information += "You have been defeated by [enemy_name]!" + gameover = 1 + return TRUE + else if(enemy_health <= 0) + gameover = 1 + information += "Congratulations! You have defeated [enemy_name]!" + return TRUE + return FALSE + +/datum/nano_module/arcade_classic/proc/new_game() + player_mana = 10 + player_health = 30 + enemy_mana = 20 + enemy_health = 45 + gameover = FALSE + information = "A new game has started!" + + + +/datum/nano_module/arcade_classic/Topic(href, href_list) + if(..()) // Always begin your Topic() calls with a parent call! + return 1 + if(href_list["new_game"]) + new_game() + return 1 // Returning 1 (TRUE) in Topic automatically handles UI updates. + if(gameover) // If the game has already ended, we don't want the following three topic calls to be processed at all. + return 1 // Instead of adding checks into each of those three, we can easily add this one check here to reduce on code copy-paste. + if(href_list["attack"]) + var/damage = rand(2, 6) + information = "You attack for [damage] damage." + enemy_health -= damage + enemy_play() + check_gameover() + return 1 + if(href_list["heal"]) + var/healfor = rand(6, 8) + var/cost = rand(1, 3) + information = "You heal yourself for [healfor] damage, using [cost] energy in the process." + player_health += healfor + player_mana -= cost + enemy_play() + check_gameover() + return 1 + if(href_list["regain_mana"]) + var/regen = rand(4, 7) + information = "You rest of a while, regaining [regen] energy." + player_mana += regen + enemy_play() + check_gameover() + return 1 \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/news_browser.dm b/code/modules/modular_computers/file_system/programs/generic/news_browser.dm new file mode 100644 index 0000000000..1d4da6d4d5 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/news_browser.dm @@ -0,0 +1,131 @@ +/datum/computer_file/program/newsbrowser + filename = "newsbrowser" + filedesc = "NTNet/ExoNet News Browser" + extended_desc = "This program may be used to view and download news articles from the network." + program_icon_state = "generic" + program_key_state = "generic_key" + program_menu_icon = "contact" + size = 4 + requires_ntnet = 1 + available_on_ntnet = 1 + + nanomodule_path = /datum/nano_module/program/computer_newsbrowser/ + var/datum/computer_file/data/news_article/loaded_article + var/download_progress = 0 + var/download_netspeed = 0 + var/downloading = 0 + var/message = "" + var/show_archived = 0 + +/datum/computer_file/program/newsbrowser/process_tick() + if(!downloading) + return + download_netspeed = 0 + // Speed defines are found in misc.dm + switch(ntnet_status) + if(1) + download_netspeed = NTNETSPEED_LOWSIGNAL + if(2) + download_netspeed = NTNETSPEED_HIGHSIGNAL + if(3) + download_netspeed = NTNETSPEED_ETHERNET + download_progress += download_netspeed + if(download_progress >= loaded_article.size) + downloading = 0 + requires_ntnet = 0 // Turn off NTNet requirement as we already loaded the file into local memory. + SSnanoui.update_uis(NM) + +/datum/computer_file/program/newsbrowser/kill_program() + ..() + requires_ntnet = 1 + loaded_article = null + download_progress = 0 + downloading = 0 + show_archived = 0 + +/datum/computer_file/program/newsbrowser/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_openarticle"]) + . = 1 + if(downloading || loaded_article) + return 1 + + for(var/datum/computer_file/data/news_article/N in ntnet_global.available_news) + if(N.uid == text2num(href_list["PRG_openarticle"])) + loaded_article = N.clone() + downloading = 1 + break + if(href_list["PRG_reset"]) + . = 1 + downloading = 0 + download_progress = 0 + requires_ntnet = 1 + loaded_article = null + if(href_list["PRG_clearmessage"]) + . = 1 + message = "" + if(href_list["PRG_savearticle"]) + . = 1 + if(downloading || !loaded_article) + return + + var/savename = sanitize(input(usr, "Enter file name or leave blank to cancel:", "Save article", loaded_article.filename)) + if(!savename) + return 1 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/data/news_article/N = loaded_article.clone() + N.filename = savename + HDD.store_file(N) + if(href_list["PRG_toggle_archived"]) + . = 1 + show_archived = !show_archived + if(.) + SSnanoui.update_uis(NM) + + +/datum/nano_module/program/computer_newsbrowser + name = "NTNet/ExoNet News Browser" + +/datum/nano_module/program/computer_newsbrowser/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + + var/datum/computer_file/program/newsbrowser/PRG + var/list/data = list() + if(program) + data = program.get_header_data() + PRG = program + else + return + + data["message"] = PRG.message + if(PRG.loaded_article && !PRG.downloading) // Viewing an article. + data["title"] = PRG.loaded_article.filename + data["cover"] = PRG.loaded_article.cover + data["article"] = PRG.loaded_article.stored_data + else if(PRG.downloading) // Downloading an article. + data["download_running"] = 1 + data["download_progress"] = PRG.download_progress + data["download_maxprogress"] = PRG.loaded_article.size + data["download_rate"] = PRG.download_netspeed + else // Viewing list of articles + var/list/all_articles[0] + for(var/datum/computer_file/data/news_article/F in ntnet_global.available_news) + if(!PRG.show_archived && F.archived) + continue + all_articles.Add(list(list( + "name" = F.filename, + "size" = F.size, + "uid" = F.uid, + "archived" = F.archived + ))) + data["all_articles"] = all_articles + data["showing_archived"] = PRG.show_archived + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "news_browser.tmpl", "NTNet/ExoNet News Browser", 575, 750, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() diff --git a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm new file mode 100644 index 0000000000..a0b2194168 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm @@ -0,0 +1,200 @@ +/datum/computer_file/program/ntnetdownload + filename = "ntndownloader" + filedesc = "NTNet Software Download Tool" + program_icon_state = "generic" + program_key_state = "generic_key" + program_menu_icon = "arrowthickstop-1-s" + extended_desc = "This program allows downloads of software from official NT repositories" + unsendable = 1 + undeletable = 1 + size = 4 + requires_ntnet = 1 + requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD + available_on_ntnet = 0 + nanomodule_path = /datum/nano_module/program/computer_ntnetdownload/ + ui_header = "downloader_finished.gif" + var/datum/computer_file/program/downloaded_file = null + var/hacked_download = 0 + var/download_completion = 0 //GQ of downloaded data. + var/download_netspeed = 0 + var/downloaderror = "" + var/list/downloads_queue[0] + +/datum/computer_file/program/ntnetdownload/kill_program() + ..() + downloaded_file = null + download_completion = 0 + download_netspeed = 0 + downloaderror = "" + ui_header = "downloader_finished.gif" + + +/datum/computer_file/program/ntnetdownload/proc/begin_file_download(var/filename) + if(downloaded_file) + return 0 + + var/datum/computer_file/program/PRG = ntnet_global.find_ntnet_file_by_name(filename) + + if(!check_file_download(filename)) + return 0 + + ui_header = "downloader_running.gif" + + if(PRG in ntnet_global.available_station_software) + generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.") + hacked_download = 0 + else if(PRG in ntnet_global.available_antag_software) + generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.") + hacked_download = 1 + else + generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from unspecified server.") + hacked_download = 0 + + downloaded_file = PRG.clone() + +/datum/computer_file/program/ntnetdownload/proc/check_file_download(var/filename) + //returns 1 if file can be downloaded, returns 0 if download prohibited + var/datum/computer_file/program/PRG = ntnet_global.find_ntnet_file_by_name(filename) + + if(!PRG || !istype(PRG)) + return 0 + + // Attempting to download antag only program, but without having emagged computer. No. + if(PRG.available_on_syndinet && !computer_emagged) + return 0 + + if(!computer || !computer.hard_drive || !computer.hard_drive.try_store_file(PRG)) + return 0 + + return 1 + +/datum/computer_file/program/ntnetdownload/proc/abort_file_download() + if(!downloaded_file) + return + generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].") + downloaded_file = null + download_completion = 0 + ui_header = "downloader_finished.gif" + +/datum/computer_file/program/ntnetdownload/proc/complete_file_download() + if(!downloaded_file) + return + generate_network_log("Completed download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].") + if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(downloaded_file)) + // The download failed + downloaderror = "I/O ERROR - Unable to save file. Check whether you have enough free space on your hard drive and whether your hard drive is properly connected. If the issue persists contact your system administrator for assistance." + downloaded_file = null + download_completion = 0 + ui_header = "downloader_finished.gif" + +/datum/computer_file/program/ntnetdownload/process_tick() + if(!downloaded_file) + return + if(download_completion >= downloaded_file.size) + complete_file_download() + if(downloads_queue.len > 0) + begin_file_download(downloads_queue[1]) + downloads_queue.Remove(downloads_queue[1]) + + // Download speed according to connectivity state. NTNet server is assumed to be on unlimited speed so we're limited by our local connectivity + download_netspeed = 0 + // Speed defines are found in misc.dm + switch(ntnet_status) + if(1) + download_netspeed = NTNETSPEED_LOWSIGNAL + if(2) + download_netspeed = NTNETSPEED_HIGHSIGNAL + if(3) + download_netspeed = NTNETSPEED_ETHERNET + download_completion += download_netspeed + +/datum/computer_file/program/ntnetdownload/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_downloadfile"]) + if(!downloaded_file) + begin_file_download(href_list["PRG_downloadfile"]) + else if(check_file_download(href_list["PRG_downloadfile"]) && !downloads_queue.Find(href_list["PRG_downloadfile"]) && downloaded_file.filename != href_list["PRG_downloadfile"]) + downloads_queue += href_list["PRG_downloadfile"] + return 1 + if(href_list["PRG_removequeued"]) + downloads_queue.Remove(href_list["PRG_removequeued"]) + return 1 + if(href_list["PRG_reseterror"]) + if(downloaderror) + download_completion = 0 + download_netspeed = 0 + downloaded_file = null + downloaderror = "" + return 1 + return 0 + +/datum/nano_module/program/computer_ntnetdownload + name = "Network Downloader" + var/obj/item/modular_computer/my_computer = null + +/datum/nano_module/program/computer_ntnetdownload/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(program) + my_computer = program.computer + + if(!istype(my_computer)) + return + + var/list/data = list() + var/datum/computer_file/program/ntnetdownload/prog = program + // For now limited to execution by the downloader program + if(!prog || !istype(prog)) + return + if(program) + data = program.get_header_data() + + // This IF cuts on data transferred to client, so i guess it's worth it. + if(prog.downloaderror) // Download errored. Wait until user resets the program. + data["error"] = prog.downloaderror + if(prog.downloaded_file) // Download running. Wait please.. + data["downloadname"] = prog.downloaded_file.filename + data["downloaddesc"] = prog.downloaded_file.filedesc + data["downloadsize"] = prog.downloaded_file.size + data["downloadspeed"] = prog.download_netspeed + data["downloadcompletion"] = round(prog.download_completion, 0.1) + + data["disk_size"] = my_computer.hard_drive.max_capacity + data["disk_used"] = my_computer.hard_drive.used_capacity + var/list/all_entries[0] + for(var/datum/computer_file/program/P in ntnet_global.available_station_software) + // Only those programs our user can run will show in the list + if(!P.can_run(user) && P.requires_access_to_download) + continue + all_entries.Add(list(list( + "filename" = P.filename, + "filedesc" = P.filedesc, + "fileinfo" = P.extended_desc, + "size" = P.size, + "icon" = P.program_menu_icon + ))) + data["hackedavailable"] = 0 + if(prog.computer_emagged) // If we are running on emagged computer we have access to some "bonus" software + var/list/hacked_programs[0] + for(var/datum/computer_file/program/P in ntnet_global.available_antag_software) + data["hackedavailable"] = 1 + hacked_programs.Add(list(list( + "filename" = P.filename, + "filedesc" = P.filedesc, + "fileinfo" = P.extended_desc, + "size" = P.size, + "icon" = P.program_menu_icon + ))) + data["hacked_programs"] = hacked_programs + + data["downloadable_programs"] = all_entries + + if(prog.downloads_queue.len > 0) + data["downloads_queue"] = prog.downloads_queue + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "ntnet_downloader.tmpl", "NTNet Download Program", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) diff --git a/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm new file mode 100644 index 0000000000..6c67c02c0d --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm @@ -0,0 +1,232 @@ +/datum/computer_file/program/chatclient + filename = "ntnrc_client" + filedesc = "NTNet Relay Chat Client" + program_icon_state = "command" + program_key_state = "med_key" + program_menu_icon = "comment" + extended_desc = "This program allows communication over NTNRC network" + size = 8 + requires_ntnet = 1 + requires_ntnet_feature = NTNET_COMMUNICATION + network_destination = "NTNRC server" + ui_header = "ntnrc_idle.gif" + available_on_ntnet = 1 + nanomodule_path = /datum/nano_module/program/computer_chatclient/ + var/last_message = null // Used to generate the toolbar icon + var/username + var/datum/ntnet_conversation/channel = null + var/operator_mode = 0 // Channel operator mode + var/netadmin_mode = 0 // Administrator mode (invisible to other users + bypasses passwords) + +/datum/computer_file/program/chatclient/New() + username = "DefaultUser[rand(100, 999)]" + +/datum/computer_file/program/chatclient/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["PRG_speak"]) + . = 1 + if(!channel) + return 1 + var/mob/living/user = usr + var/message = sanitize(input(user, "Enter message or leave blank to cancel: "), 512) + if(!message || !channel) + return + channel.add_message(message, username) + + if(href_list["PRG_joinchannel"]) + . = 1 + var/datum/ntnet_conversation/C + for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels) + if(chan.id == text2num(href_list["PRG_joinchannel"])) + C = chan + break + + if(!C) + return 1 + + if(netadmin_mode) + channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others. + return 1 + + if(C.password) + var/mob/living/user = usr + var/password = sanitize(input(user,"Access Denied. Enter password:")) + if(C && (password == C.password)) + C.add_client(src) + channel = C + return 1 + C.add_client(src) + channel = C + if(href_list["PRG_leavechannel"]) + . = 1 + if(channel) + channel.remove_client(src) + channel = null + if(href_list["PRG_newchannel"]) + . = 1 + var/mob/living/user = usr + var/channel_title = sanitizeSafe(input(user,"Enter channel name or leave blank to cancel:"), 64) + if(!channel_title) + return + var/datum/ntnet_conversation/C = new/datum/ntnet_conversation() + C.add_client(src) + C.operator = src + channel = C + C.title = channel_title + if(href_list["PRG_toggleadmin"]) + . = 1 + if(netadmin_mode) + netadmin_mode = 0 + if(channel) + channel.remove_client(src) // We shouldn't be in channel's user list, but just in case... + channel = null + return 1 + var/mob/living/user = usr + if(can_run(usr, 1, access_network)) + if(channel) + var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No") + if(response == "Yes") + if(channel) + channel.remove_client(src) + channel = null + else + return + netadmin_mode = 1 + if(href_list["PRG_changename"]) + . = 1 + var/mob/living/user = usr + var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:"), 20) + if(!newname) + return 1 + if(channel) + channel.add_status_message("[username] is now known as [newname].") + username = newname + + if(href_list["PRG_savelog"]) + . = 1 + if(!channel) + return + var/mob/living/user = usr + var/logname = input(user,"Enter desired logfile name (.log) or leave blank to cancel:") + if(!logname || !channel) + return 1 + var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile() + // Now we will generate HTML-compliant file that can actually be viewed/printed. + logfile.filename = logname + logfile.stored_data = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]" + for(var/logstring in channel.messages) + logfile.stored_data += "[logstring]\[BR\]" + logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]" + logfile.calculate_size() + if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(logfile)) + if(!computer) + // This program shouldn't even be runnable without computer. + CRASH("Var computer is null!") + return 1 + if(!computer.hard_drive) + computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.") + else // In 99.9% cases this will mean our HDD is full + computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.") + if(href_list["PRG_renamechannel"]) + . = 1 + if(!operator_mode || !channel) + return 1 + var/mob/living/user = usr + var/newname = sanitize(input(user, "Enter new channel name or leave blank to cancel:"), 64) + if(!newname || !channel) + return + channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.") + channel.title = newname + if(href_list["PRG_deletechannel"]) + . = 1 + if(channel && ((channel.operator == src) || netadmin_mode)) + qdel(channel) + channel = null + if(href_list["PRG_setpassword"]) + . = 1 + if(!channel || ((channel.operator != src) && !netadmin_mode)) + return 1 + + var/mob/living/user = usr + var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:")) + if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode)) + return 1 + + if(newpassword == "nopassword") + channel.password = "" + else + channel.password = newpassword + +/datum/computer_file/program/chatclient/process_tick() + ..() + if(program_state != PROGRAM_STATE_KILLED) + ui_header = "ntnrc_idle.gif" + if(channel) + // Remember the last message. If there is no message in the channel remember null. + last_message = channel.messages.len ? channel.messages[channel.messages.len - 1] : null + else + last_message = null + return 1 + if(channel && channel.messages && channel.messages.len) + ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif" + else + ui_header = "ntnrc_idle.gif" + +/datum/computer_file/program/chatclient/kill_program(var/forced = 0) + if(channel) + channel.remove_client(src) + channel = null + ..(forced) + +/datum/nano_module/program/computer_chatclient + name = "NTNet Relay Chat Client" + +/datum/nano_module/program/computer_chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(!ntnet_global || !ntnet_global.chat_channels) + return + + var/list/data = list() + if(program) + data = program.get_header_data() + + var/datum/computer_file/program/chatclient/C = program + if(!istype(C)) + return + + data["adminmode"] = C.netadmin_mode + if(C.channel) + data["title"] = C.channel.title + var/list/messages[0] + for(var/M in C.channel.messages) + messages.Add(list(list( + "msg" = M + ))) + data["messages"] = messages + var/list/clients[0] + for(var/datum/computer_file/program/chatclient/cl in C.channel.clients) + clients.Add(list(list( + "name" = cl.username + ))) + data["clients"] = clients + C.operator_mode = (C.channel.operator == C) ? 1 : 0 + data["is_operator"] = C.operator_mode || C.netadmin_mode + + else // Channel selection screen + var/list/all_channels[0] + for(var/datum/ntnet_conversation/conv in ntnet_global.chat_channels) + if(conv && conv.title) + all_channels.Add(list(list( + "chan" = conv.title, + "id" = conv.id + ))) + data["all_channels"] = all_channels + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "ntnet_chat.tmpl", "NTNet Relay Chat Client", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) diff --git a/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm b/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm new file mode 100644 index 0000000000..0efed986ae --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm @@ -0,0 +1,185 @@ +var/global/nttransfer_uid = 0 + +/datum/computer_file/program/nttransfer + filename = "nttransfer" + filedesc = "NTNet P2P Transfer Client" + extended_desc = "This program allows for simple file transfer via direct peer to peer connection." + program_icon_state = "comm_logs" + program_key_state = "generic_key" + program_menu_icon = "transferthick-e-w" + size = 7 + requires_ntnet = 1 + requires_ntnet_feature = NTNET_PEERTOPEER + network_destination = "other device via P2P tunnel" + available_on_ntnet = 1 + nanomodule_path = /datum/nano_module/program/computer_nttransfer/ + + var/error = "" // Error screen + var/server_password = "" // Optional password to download the file. + var/datum/computer_file/provided_file = null // File which is provided to clients. + var/datum/computer_file/downloaded_file = null // File which is being downloaded + var/list/connected_clients = list() // List of connected clients. + var/datum/computer_file/program/nttransfer/remote // Client var, specifies who are we downloading from. + var/download_completion = 0 // Download progress in GQ + var/actual_netspeed = 0 // Displayed in the UI, this is the actual transfer speed. + var/unique_token // UID of this program + var/upload_menu = 0 // Whether we show the program list and upload menu + +/datum/computer_file/program/nttransfer/New() + unique_token = nttransfer_uid + nttransfer_uid++ + ..() + +/datum/computer_file/program/nttransfer/process_tick() + ..() + // Server mode + if(provided_file) + for(var/datum/computer_file/program/nttransfer/C in connected_clients) + // Transfer speed is limited by device which uses slower connectivity. + // We can have multiple clients downloading at same time, but let's assume we use some sort of multicast transfer + // so they can all run on same speed. + C.actual_netspeed = min(C.ntnet_speed, ntnet_speed) + C.download_completion += C.actual_netspeed + if(C.download_completion >= provided_file.size) + C.finish_download() + else if(downloaded_file) // Client mode + if(!remote) + crash_download("Connection to remote server lost") + +/datum/computer_file/program/nttransfer/kill_program(var/forced = 0) + if(downloaded_file) // Client mode, clean up variables for next use + finalize_download() + + if(provided_file) // Server mode, disconnect all clients + for(var/datum/computer_file/program/nttransfer/P in connected_clients) + P.crash_download("Connection terminated by remote server") + downloaded_file = null + ..(forced) + +// Finishes download and attempts to store the file on HDD +/datum/computer_file/program/nttransfer/proc/finish_download() + if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(downloaded_file)) + error = "I/O Error: Unable to save file. Check your hard drive and try again." + finalize_download() + +// Crashes the download and displays specific error message +/datum/computer_file/program/nttransfer/proc/crash_download(var/message) + error = message ? message : "An unknown error has occured during download" + finalize_download() + +// Cleans up variables for next use +/datum/computer_file/program/nttransfer/proc/finalize_download() + if(remote) + remote.connected_clients.Remove(src) + downloaded_file = null + remote = null + download_completion = 0 + + +/datum/nano_module/program/computer_nttransfer + name = "NTNet P2P Transfer Client" + +/datum/nano_module/program/computer_nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(!program) + return + var/datum/computer_file/program/nttransfer/PRG = program + if(!istype(PRG)) + return + + var/list/data = program.get_header_data() + + if(PRG.error) + data["error"] = PRG.error + else if(PRG.downloaded_file) + data["downloading"] = 1 + data["download_size"] = PRG.downloaded_file.size + data["download_progress"] = PRG.download_completion + data["download_netspeed"] = PRG.actual_netspeed + data["download_name"] = "[PRG.downloaded_file.filename].[PRG.downloaded_file.filetype]" + else if (PRG.provided_file) + data["uploading"] = 1 + data["upload_uid"] = PRG.unique_token + data["upload_clients"] = PRG.connected_clients.len + data["upload_haspassword"] = PRG.server_password ? 1 : 0 + data["upload_filename"] = "[PRG.provided_file.filename].[PRG.provided_file.filetype]" + else if (PRG.upload_menu) + var/list/all_files[0] + for(var/datum/computer_file/F in PRG.computer.hard_drive.stored_files) + all_files.Add(list(list( + "uid" = F.uid, + "filename" = "[F.filename].[F.filetype]", + "size" = F.size + ))) + data["upload_filelist"] = all_files + else + var/list/all_servers[0] + for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers) + if(!P.provided_file) + continue + all_servers.Add(list(list( + "uid" = P.unique_token, + "filename" = "[P.provided_file.filename].[P.provided_file.filetype]", + "size" = P.provided_file.size, + "haspassword" = P.server_password ? 1 : 0 + ))) + data["servers"] = all_servers + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "ntnet_transfer.tmpl", "NTNet P2P Transfer Client", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/computer_file/program/nttransfer/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_downloadfile"]) + for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers) + if("[P.unique_token]" == href_list["PRG_downloadfile"]) + remote = P + break + if(!remote || !remote.provided_file) + return + if(remote.server_password) + var/pass = sanitize(input(usr, "Code 401 Unauthorized. Please enter password:", "Password required")) + if(pass != remote.server_password) + error = "Incorrect Password" + return + downloaded_file = remote.provided_file.clone() + remote.connected_clients.Add(src) + return 1 + if(href_list["PRG_reset"]) + error = "" + upload_menu = 0 + finalize_download() + if(src in ntnet_global.fileservers) + ntnet_global.fileservers.Remove(src) + for(var/datum/computer_file/program/nttransfer/T in connected_clients) + T.crash_download("Remote server has forcibly closed the connection") + provided_file = null + return 1 + if(href_list["PRG_setpassword"]) + var/pass = sanitize(input(usr, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none")) + if(!pass) + return + if(pass == "none") + server_password = "" + return + server_password = pass + return 1 + if(href_list["PRG_uploadfile"]) + for(var/datum/computer_file/F in computer.hard_drive.stored_files) + if("[F.uid]" == href_list["PRG_uploadfile"]) + if(F.unsendable) + error = "I/O Error: File locked." + return + provided_file = F + ntnet_global.fileservers.Add(src) + return + error = "I/O Error: Unable to locate file on hard drive." + return 1 + if(href_list["PRG_uploadmenu"]) + upload_menu = 1 + return 0 diff --git a/code/modules/modular_computers/file_system/programs/generic/wordprocessor.dm b/code/modules/modular_computers/file_system/programs/generic/wordprocessor.dm new file mode 100644 index 0000000000..1a4d7a1871 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/generic/wordprocessor.dm @@ -0,0 +1,235 @@ +/datum/computer_file/program/wordprocessor + filename = "wordprocessor" + filedesc = "NanoWord" + extended_desc = "This program allows the editing and preview of text documents." + program_icon_state = "word" + program_key_state = "atmos_key" + size = 4 + requires_ntnet = 0 + available_on_ntnet = 1 + nanomodule_path = /datum/nano_module/program/computer_wordprocessor/ + var/browsing + var/open_file + var/loaded_data + var/error + var/is_edited + +/datum/computer_file/program/wordprocessor/proc/get_file(var/filename) + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return + var/datum/computer_file/data/F = HDD.find_file_by_name(filename) + if(!istype(F)) + return + return F + +/datum/computer_file/program/wordprocessor/proc/open_file(var/filename) + var/datum/computer_file/data/F = get_file(filename) + if(F) + open_file = F.filename + loaded_data = F.stored_data + return 1 + +/datum/computer_file/program/wordprocessor/proc/save_file(var/filename) + var/datum/computer_file/data/F = get_file(filename) + if(!F) //try to make one if it doesn't exist + F = create_file(filename, loaded_data) + return !isnull(F) + var/datum/computer_file/data/backup = F.clone() + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return + HDD.remove_file(F) + F.stored_data = loaded_data + F.calculate_size() + if(!HDD.store_file(F)) + HDD.store_file(backup) + return 0 + is_edited = 0 + return 1 + +/datum/computer_file/program/wordprocessor/proc/create_file(var/newname, var/data = "") + if(!newname) + return + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return + if(get_file(newname)) + return + var/datum/computer_file/data/F = new/datum/computer_file/data() + F.filename = newname + F.filetype = "TXT" + F.stored_data = data + F.calculate_size() + if(HDD.store_file(F)) + return F + +/datum/computer_file/program/wordprocessor/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["PRG_txtrpeview"]) + show_browser(usr,"[open_file][pencode2html(loaded_data)]", "window=[open_file]") + return 1 + + if(href_list["PRG_taghelp"]) + to_chat(usr, "The hologram of a googly-eyed paper clip helpfully tells you:") + var/help = {" + \[br\] : Creates a linebreak. + \[center\] - \[/center\] : Centers the text. + \[h1\] - \[/h1\] : First level heading. + \[h2\] - \[/h2\] : Second level heading. + \[h3\] - \[/h3\] : Third level heading. + \[b\] - \[/b\] : Bold. + \[i\] - \[/i\] : Italic. + \[u\] - \[/u\] : Underlined. + \[small\] - \[/small\] : Decreases the size of the text. + \[large\] - \[/large\] : Increases the size of the text. + \[field\] : Inserts a blank text field, which can be filled later. Useful for forms. + \[date\] : Current station date. + \[time\] : Current station time. + \[list\] - \[/list\] : Begins and ends a list. + \[*\] : A list item. + \[hr\] : Horizontal rule. + \[table\] - \[/table\] : Creates table using \[row\] and \[cell\] tags. + \[grid\] - \[/grid\] : Table without visible borders, for layouts. + \[row\] - New table row. + \[cell\] - New table cell. + \[logo\] - Inserts NT logo image. + \[redlogo\] - Inserts red NT logo image. + \[sglogo\] - Inserts Solgov insignia image."} + + to_chat(usr, help) + return 1 + + if(href_list["PRG_closebrowser"]) + browsing = 0 + return 1 + + if(href_list["PRG_backtomenu"]) + error = null + return 1 + + if(href_list["PRG_loadmenu"]) + browsing = 1 + return 1 + + if(href_list["PRG_openfile"]) + . = 1 + if(is_edited) + if(alert("Would you like to save your changes first?",,"Yes","No") == "Yes") + save_file(open_file) + browsing = 0 + if(!open_file(href_list["PRG_openfile"])) + error = "I/O error: Unable to open file '[href_list["PRG_openfile"]]'." + + if(href_list["PRG_newfile"]) + . = 1 + if(is_edited) + if(alert("Would you like to save your changes first?",,"Yes","No") == "Yes") + save_file(open_file) + + var/newname = sanitize(input(usr, "Enter file name:", "New File") as text|null) + if(!newname) + return 1 + var/datum/computer_file/data/F = create_file(newname) + if(F) + open_file = F.filename + loaded_data = "" + return 1 + else + error = "I/O error: Unable to create file '[href_list["PRG_saveasfile"]]'." + + if(href_list["PRG_saveasfile"]) + . = 1 + var/newname = sanitize(input(usr, "Enter file name:", "Save As") as text|null) + if(!newname) + return 1 + var/datum/computer_file/data/F = create_file(newname, loaded_data) + if(F) + open_file = F.filename + else + error = "I/O error: Unable to create file '[href_list["PRG_saveasfile"]]'." + return 1 + + if(href_list["PRG_savefile"]) + . = 1 + if(!open_file) + open_file = sanitize(input(usr, "Enter file name:", "Save As") as text|null) + if(!open_file) + return 0 + if(!save_file(open_file)) + error = "I/O error: Unable to save file '[open_file]'." + return 1 + + if(href_list["PRG_editfile"]) + var/oldtext = html_decode(loaded_data) + oldtext = replacetext(oldtext, "\[br\]", "\n") + + var/newtext = sanitize(replacetext(input(usr, "Editing file '[open_file]'. You may use most tags used in paper formatting:", "Text Editor", oldtext) as message|null, "\n", "\[br\]"), MAX_TEXTFILE_LENGTH) + if(!newtext) + return + loaded_data = newtext + is_edited = 1 + return 1 + + if(href_list["PRG_printfile"]) + . = 1 + if(!computer.nano_printer) + error = "Missing Hardware: Your computer does not have the required hardware to complete this operation." + return 1 + if(!computer.nano_printer.print_text(pencode2html(loaded_data))) + error = "Hardware error: Printer was unable to print the file. It may be out of paper." + return 1 + +/datum/nano_module/program/computer_wordprocessor + name = "Word Processor" + +/datum/nano_module/program/computer_wordprocessor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + var/datum/computer_file/program/wordprocessor/PRG + PRG = program + + var/obj/item/weapon/computer_hardware/hard_drive/HDD + var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD + if(PRG.error) + data["error"] = PRG.error + if(PRG.browsing) + data["browsing"] = PRG.browsing + if(!PRG.computer || !PRG.computer.hard_drive) + data["error"] = "I/O ERROR: Unable to access hard drive." + else + HDD = PRG.computer.hard_drive + var/list/files[0] + for(var/datum/computer_file/F in HDD.stored_files) + if(F.filetype == "TXT") + files.Add(list(list( + "name" = F.filename, + "size" = F.size + ))) + data["files"] = files + + RHDD = PRG.computer.portable_drive + if(RHDD) + data["usbconnected"] = 1 + var/list/usbfiles[0] + for(var/datum/computer_file/F in RHDD.stored_files) + if(F.filetype == "TXT") + usbfiles.Add(list(list( + "name" = F.filename, + "size" = F.size, + ))) + data["usbfiles"] = usbfiles + else if(PRG.open_file) + data["filedata"] = pencode2html(PRG.loaded_data) + data["filename"] = PRG.is_edited ? "[PRG.open_file]*" : PRG.open_file + else + data["filedata"] = pencode2html(PRG.loaded_data) + data["filename"] = "UNNAMED" + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "word_processor.tmpl", "Word Processor", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() \ No newline at end of file diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm similarity index 79% rename from code/modules/nano/modules/crew_monitor.dm rename to code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm index 319da90715..86ccaa73bc 100644 --- a/code/modules/nano/modules/crew_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm @@ -1,52 +1,69 @@ -/datum/nano_module/crew_monitor - name = "Crew monitor" - -/datum/nano_module/crew_monitor/Topic(href, href_list) - if(..()) return 1 - var/turf/T = get_turf(nano_host()) // TODO: Allow setting any using_map.contact_levels from the interface. - if (!T || !(T.z in using_map.player_levels)) - usr << "Unable to establish a connection: You're too far away from the station!" - return 0 - if(href_list["track"]) - if(isAI(usr)) - var/mob/living/silicon/ai/AI = usr - var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list - if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) - AI.ai_actual_track(H) - return 1 - -/datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/data[0] - var/turf/T = get_turf(nano_host()) - - data["isAI"] = isAI(user) - data["map_levels"] = using_map.get_map_levels(T.z, FALSE) - data["crewmembers"] = list() - for(var/z in (data["map_levels"] | T.z)) // Always show crew from the current Z even if we can't show a map - data["crewmembers"] += crew_repository.health_data(z) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800, state = state) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "crew_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") - if(!(ui.map_z_level in data["map_levels"])) - ui.set_map_z_level(data["map_levels"][1]) - - ui.set_initial_data(data) - ui.open() - - // should make the UI auto-update; doesn't seem to? - ui.set_auto_update(1) - -/*/datum/nano_module/crew_monitor/proc/scan() - for(var/mob/living/carbon/human/H in mob_list) - if(istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/C = H.w_uniform - if (C.has_sensor) - tracked |= C - return 1 +/datum/computer_file/program/suit_sensors + filename = "sensormonitor" + filedesc = "Suit Sensors Monitoring" + nanomodule_path = /datum/nano_module/crew_monitor + program_icon_state = "crew" + program_key_state = "med_key" + program_menu_icon = "heart" + extended_desc = "This program connects to life signs monitoring system to provide basic information on crew health." + required_access = access_medical + requires_ntnet = 1 + network_destination = "crew lifesigns monitoring system" + size = 11 + + + + + +/datum/nano_module/crew_monitor + name = "Crew monitor" + +/datum/nano_module/crew_monitor/Topic(href, href_list) + if(..()) return 1 + var/turf/T = get_turf(nano_host()) // TODO: Allow setting any using_map.contact_levels from the interface. + if (!T || !(T.z in using_map.player_levels)) + usr << "Unable to establish a connection: You're too far away from the station!" + return 0 + if(href_list["track"]) + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list + if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) + AI.ai_actual_track(H) + return 1 + +/datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + var/turf/T = get_turf(nano_host()) + + data["isAI"] = isAI(user) + data["map_levels"] = using_map.get_map_levels(T.z, FALSE) + data["crewmembers"] = list() + for(var/z in (data["map_levels"] | T.z)) // Always show crew from the current Z even if we can't show a map + data["crewmembers"] += crew_repository.health_data(z) + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800, state = state) + + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "crew_monitor_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") + if(!(ui.map_z_level in data["map_levels"])) + ui.set_map_z_level(data["map_levels"][1]) + + ui.set_initial_data(data) + ui.open() + + // should make the UI auto-update; doesn't seem to? + ui.set_auto_update(1) + +/*/datum/nano_module/crew_monitor/proc/scan() + for(var/mob/living/carbon/human/H in mob_list) + if(istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/C = H.w_uniform + if (C.has_sensor) + tracked |= C + return 1 */ \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/research/email_administration.dm b/code/modules/modular_computers/file_system/programs/research/email_administration.dm new file mode 100644 index 0000000000..93ba0bded3 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/research/email_administration.dm @@ -0,0 +1,144 @@ +/datum/computer_file/program/email_administration + filename = "emailadmin" + filedesc = "Email Administration Utility" + extended_desc = "This program may be used to administrate NTNet's emailing service." + program_icon_state = "comm_monitor" + program_key_state = "generic_key" + program_menu_icon = "mail-open" + size = 12 + requires_ntnet = 1 + available_on_ntnet = 1 + nanomodule_path = /datum/nano_module/email_administration + required_access = access_network + + + + +/datum/nano_module/email_administration/ + name = "Email Client" + var/datum/computer_file/data/email_account/current_account = null + var/datum/computer_file/data/email_message/current_message = null + var/error = "" + +/datum/nano_module/email_administration/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + if(error) + data["error"] = error + else if(istype(current_message)) + data["msg_title"] = current_message.title + data["msg_body"] = pencode2html(current_message.stored_data) + data["msg_timestamp"] = current_message.timestamp + data["msg_source"] = current_message.source + else if(istype(current_account)) + data["current_account"] = current_account.login + data["cur_suspended"] = current_account.suspended + var/list/all_messages = list() + for(var/datum/computer_file/data/email_message/message in (current_account.inbox | current_account.spam | current_account.deleted)) + all_messages.Add(list(list( + "title" = message.title, + "source" = message.source, + "timestamp" = message.timestamp, + "uid" = message.uid + ))) + data["messages"] = all_messages + data["messagecount"] = all_messages.len + else + var/list/all_accounts = list() + for(var/datum/computer_file/data/email_account/account in ntnet_global.email_accounts) + if(!account.can_login) + continue + all_accounts.Add(list(list( + "login" = account.login, + "uid" = account.uid + ))) + data["accounts"] = all_accounts + data["accountcount"] = all_accounts.len + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "email_administration.tmpl", "Email Administration Utility", 600, 450, state = state) + if(host.update_layout()) + ui.auto_update_layout = 1 + ui.set_auto_update(1) + ui.set_initial_data(data) + ui.open() + + +/datum/nano_module/email_administration/Topic(href, href_list) + if(..()) + return 1 + + var/mob/user = usr + if(!istype(user)) + return 1 + + // High security - can only be operated when the user has an ID with access on them. + var/obj/item/weapon/card/id/I = user.GetIdCard() + if(!istype(I) || !(access_network in I.access)) + return 1 + + if(href_list["back"]) + if(error) + error = "" + else if(current_message) + current_message = null + else + current_account = null + return 1 + + if(href_list["ban"]) + if(!current_account) + return 1 + + current_account.suspended = !current_account.suspended + ntnet_global.add_log_with_ids_check("EMAIL LOG: SA-EDIT Account [current_account.login] has been [current_account.suspended ? "" : "un" ]suspended by SA [I.registered_name] ([I.assignment]).") + error = "Account [current_account.login] has been [current_account.suspended ? "" : "un" ]suspended." + return 1 + + if(href_list["changepass"]) + if(!current_account) + return 1 + + var/newpass = sanitize(input(user,"Enter new password for account [current_account.login]", "Password"), 100) + if(!newpass) + return 1 + current_account.password = newpass + ntnet_global.add_log_with_ids_check("EMAIL LOG: SA-EDIT Password for account [current_account.login] has been changed by SA [I.registered_name] ([I.assignment]).") + return 1 + + if(href_list["viewmail"]) + if(!current_account) + return 1 + + for(var/datum/computer_file/data/email_message/received_message in (current_account.inbox | current_account.spam | current_account.deleted)) + if(received_message.uid == text2num(href_list["viewmail"])) + current_message = received_message + break + return 1 + + if(href_list["viewaccount"]) + for(var/datum/computer_file/data/email_account/email_account in ntnet_global.email_accounts) + if(email_account.uid == text2num(href_list["viewaccount"])) + current_account = email_account + break + return 1 + + if(href_list["newaccount"]) + var/newdomain = sanitize(input(user,"Pick domain:", "Domain name") as null|anything in using_map.usable_email_tlds) + if(!newdomain) + return 1 + var/newlogin = sanitize(input(user,"Pick account name (@[newdomain]):", "Account name"), 100) + if(!newlogin) + return 1 + + var/complete_login = "[newlogin]@[newdomain]" + if(ntnet_global.does_email_exist(complete_login)) + error = "Error creating account: An account with same address already exists." + return 1 + + var/datum/computer_file/data/email_account/new_account = new/datum/computer_file/data/email_account() + new_account.login = complete_login + new_account.password = GenerateKey() + error = "Email [new_account.login] has been created, with generated password [new_account.password]" + return 1 diff --git a/code/modules/modular_computers/file_system/programs/research/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/research/ntmonitor.dm new file mode 100644 index 0000000000..590837f2b5 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/research/ntmonitor.dm @@ -0,0 +1,102 @@ +/datum/computer_file/program/ntnetmonitor + filename = "ntmonitor" + filedesc = "NTNet Diagnostics and Monitoring" + program_icon_state = "comm_monitor" + program_key_state = "generic_key" + program_menu_icon = "wrench" + extended_desc = "This program monitors the local NTNet network, provides access to logging systems, and allows for configuration changes" + size = 12 + requires_ntnet = 1 + required_access = access_network + available_on_ntnet = 1 + nanomodule_path = /datum/nano_module/computer_ntnetmonitor/ + +/datum/nano_module/computer_ntnetmonitor + name = "NTNet Diagnostics and Monitoring" + //available_to_ai = TRUE + +/datum/nano_module/computer_ntnetmonitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(!ntnet_global) + return + var/list/data = host.initial_data() + + data["ntnetstatus"] = ntnet_global.check_function() + data["ntnetrelays"] = ntnet_global.relays.len + data["idsstatus"] = ntnet_global.intrusion_detection_enabled + data["idsalarm"] = ntnet_global.intrusion_detection_alarm + + data["config_softwaredownload"] = ntnet_global.setting_softwaredownload + data["config_peertopeer"] = ntnet_global.setting_peertopeer + data["config_communication"] = ntnet_global.setting_communication + data["config_systemcontrol"] = ntnet_global.setting_systemcontrol + + data["ntnetlogs"] = ntnet_global.logs + data["ntnetmaxlogs"] = ntnet_global.setting_maxlogcount + + data["banned_nids"] = list(ntnet_global.banned_nids) + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "ntnet_monitor.tmpl", "NTNet Diagnostics and Monitoring Tool", 575, 700, state = state) + if(host.update_layout()) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/nano_module/computer_ntnetmonitor/Topic(href, href_list, state) + var/mob/user = usr + if(..()) + return 1 + if(href_list["resetIDS"]) + if(ntnet_global) + ntnet_global.resetIDS() + return 1 + if(href_list["toggleIDS"]) + if(ntnet_global) + ntnet_global.toggleIDS() + return 1 + if(href_list["toggleWireless"]) + if(!ntnet_global) + return 1 + + // NTNet is disabled. Enabling can be done without user prompt + if(ntnet_global.setting_disabled) + ntnet_global.setting_disabled = 0 + return 1 + + // NTNet is enabled and user is about to shut it down. Let's ask them if they really want to do it, as wirelessly connected computers won't connect without NTNet being enabled (which may prevent people from turning it back on) + if(!user) + return 1 + var/response = alert(user, "Really disable NTNet wireless? If your computer is connected wirelessly you won't be able to turn it back on! This will affect all connected wireless devices.", "NTNet shutdown", "Yes", "No") + if(response == "Yes") + ntnet_global.setting_disabled = 1 + return 1 + if(href_list["purgelogs"]) + if(ntnet_global) + ntnet_global.purge_logs() + return 1 + if(href_list["updatemaxlogs"]) + var/logcount = text2num(input(user,"Enter amount of logs to keep in memory ([MIN_NTNET_LOGS]-[MAX_NTNET_LOGS]):")) + if(ntnet_global) + ntnet_global.update_max_log_count(logcount) + return 1 + if(href_list["toggle_function"]) + if(!ntnet_global) + return 1 + ntnet_global.toggle_function(href_list["toggle_function"]) + return 1 + if(href_list["ban_nid"]) + if(!ntnet_global) + return 1 + var/nid = input(user,"Enter NID of device which you want to block from the network:", "Enter NID") as null|num + if(nid && CanUseTopic(user, state)) + ntnet_global.banned_nids |= nid + return 1 + if(href_list["unban_nid"]) + if(!ntnet_global) + return 1 + var/nid = input(user,"Enter NID of device which you want to unblock from the network:", "Enter NID") as null|num + if(nid && CanUseTopic(user, state)) + ntnet_global.banned_nids -= nid + return 1 diff --git a/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm b/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm new file mode 100644 index 0000000000..28ca1b73f5 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm @@ -0,0 +1,143 @@ +var/warrant_uid = 0 +/datum/datacore/var/list/warrants[] = list() +/datum/data/record/warrant + var/warrant_id + +/datum/data/record/warrant/New() + ..() + warrant_id = warrant_uid++ + + +/datum/computer_file/program/digitalwarrant + filename = "digitalwarrant" + filedesc = "Warrant Assistant" + extended_desc = "Official NTsec program for creation and handling of warrants." + size = 8 + program_icon_state = "warrant" + program_key_state = "security_key" + program_menu_icon = "star" + requires_ntnet = 1 + available_on_ntnet = 1 + required_access = access_security + usage_flags = PROGRAM_ALL + nanomodule_path = /datum/nano_module/program/digitalwarrant/ + +/datum/nano_module/program/digitalwarrant/ + name = "Warrant Assistant" + var/datum/data/record/warrant/activewarrant + +/datum/nano_module/program/digitalwarrant/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + if(activewarrant) + data["warrantname"] = activewarrant.fields["namewarrant"] + data["warrantcharges"] = activewarrant.fields["charges"] + data["warrantauth"] = activewarrant.fields["auth"] + data["type"] = activewarrant.fields["arrestsearch"] + else + var/list/allwarrants = list() + for(var/datum/data/record/warrant/W in data_core.warrants) + allwarrants.Add(list(list( + "warrantname" = W.fields["namewarrant"], + "charges" = "[copytext(W.fields["charges"],1,min(length(W.fields["charges"]) + 1, 50))]...", + "auth" = W.fields["auth"], + "id" = W.warrant_id, + "arrestsearch" = W.fields["arrestsearch"] + ))) + data["allwarrants"] = allwarrants + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "digitalwarrant.tmpl", name, 500, 350, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + +/datum/nano_module/program/digitalwarrant/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["sw_menu"]) + activewarrant = null + + if(href_list["editwarrant"]) + . = 1 + for(var/datum/data/record/warrant/W in data_core.warrants) + if(W.warrant_id == text2num(href_list["editwarrant"])) + activewarrant = W + break + + // The following actions will only be possible if the user has an ID with security access equipped. This is in line with modular computer framework's authentication methods, + // which also use RFID scanning to allow or disallow access to some functions. Anyone can view warrants, editing requires ID. This also prevents situations where you show a tablet + // to someone who is to be arrested, which allows them to change the stuff there. + + var/mob/user = usr + if(!istype(user)) + return + var/obj/item/weapon/card/id/I = user.GetIdCard() + if(!istype(I) || !I.registered_name || !(access_security in I.access)) + to_chat(user, "Authentication error: Unable to locate ID with apropriate access to allow this operation.") + return + + if(href_list["addwarrant"]) + . = 1 + var/datum/data/record/warrant/W = new() + var/temp = sanitize(input(usr, "Do you want to create a search-, or an arrest warrant?") as null|anything in list("search","arrest")) + if(CanInteract(user, default_state)) + if(temp == "arrest") + W.fields["namewarrant"] = "Unknown" + W.fields["charges"] = "No charges present" + W.fields["auth"] = "Unauthorized" + W.fields["arrestsearch"] = "arrest" + if(temp == "search") + W.fields["namewarrant"] = "No location given" + W.fields["charges"] = "No reason given" + W.fields["auth"] = "Unauthorized" + W.fields["arrestsearch"] = "search" + activewarrant = W + + if(href_list["savewarrant"]) + . = 1 + data_core.warrants |= activewarrant + activewarrant = null + + if(href_list["deletewarrant"]) + . = 1 + data_core.warrants -= activewarrant + activewarrant = null + + if(href_list["editwarrantname"]) + . = 1 + var/namelist = list() + for(var/datum/data/record/t in data_core.general) + namelist += t.fields["name"] + var/new_name = sanitize(input(usr, "Please input name") as null|anything in namelist) + if(CanInteract(user, default_state)) + if (!new_name) + return + activewarrant.fields["namewarrant"] = new_name + + if(href_list["editwarrantnamecustom"]) + . = 1 + var/new_name = sanitize(input("Please input name") as null|text) + if(CanInteract(user, default_state)) + if (!new_name) + return + activewarrant.fields["namewarrant"] = new_name + + if(href_list["editwarrantcharges"]) + . = 1 + var/new_charges = sanitize(input("Please input charges", "Charges", activewarrant.fields["charges"]) as null|text) + if(CanInteract(user, default_state)) + if (!new_charges) + return + activewarrant.fields["charges"] = new_charges + + if(href_list["editwarrantauth"]) + . = 1 + + activewarrant.fields["auth"] = "[I.registered_name] - [I.assignment ? I.assignment : "(Unknown)"]" + + if(href_list["back"]) + . = 1 + activewarrant = null diff --git a/code/modules/modular_computers/hardware/_hardware.dm b/code/modules/modular_computers/hardware/_hardware.dm new file mode 100644 index 0000000000..90150bc547 --- /dev/null +++ b/code/modules/modular_computers/hardware/_hardware.dm @@ -0,0 +1,87 @@ +/obj/item/weapon/computer_hardware/ + name = "Hardware" + desc = "Unknown Hardware." + icon = 'icons/obj/modular_components.dmi' + var/obj/item/modular_computer/holder2 = null + var/power_usage = 0 // If the hardware uses extra power, change this. + var/enabled = 1 // If the hardware is turned off set this to 0. + var/critical = 1 // Prevent disabling for important component, like the HDD. + var/hardware_size = 1 // Limits which devices can contain this component. 1: Tablets/Laptops/Consoles, 2: Laptops/Consoles, 3: Consoles only + var/damage = 0 // Current damage level + var/max_damage = 100 // Maximal damage level. + var/damage_malfunction = 20 // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things + var/damage_failure = 50 // "Failure" threshold. When damage exceeds this value the hardware piece will not work at all. + var/malfunction_probability = 10// Chance of malfunction when the component is damaged + +/obj/item/weapon/computer_hardware/attackby(var/obj/item/W as obj, var/mob/living/user as mob) + // Multitool. Runs diagnostics + if(istype(W, /obj/item/device/multitool)) + to_chat(user, "***** DIAGNOSTICS REPORT *****") + diagnostics(user) + to_chat(user, "******************************") + return 1 + // Nanopaste. Repair all damage if present for a single unit. + var/obj/item/stack/S = W + if(istype(S, /obj/item/stack/nanopaste)) + if(!damage) + to_chat(user, "\The [src] doesn't seem to require repairs.") + return 1 + if(S.use(1)) + to_chat(user, "You apply a bit of \the [W] to \the [src]. It immediately repairs all damage.") + damage = 0 + return 1 + // Cable coil. Works as repair method, but will probably require multiple applications and more cable. + if(istype(S, /obj/item/stack/cable_coil)) + if(!damage) + to_chat(user, "\The [src] doesn't seem to require repairs.") + return 1 + if(S.use(1)) + to_chat(user, "You patch up \the [src] with a bit of \the [W].") + take_damage(-10) + return 1 + return ..() + + +// Called on multitool click, prints diagnostic information to the user. +/obj/item/weapon/computer_hardware/proc/diagnostics(var/mob/user) + to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]") + +/obj/item/weapon/computer_hardware/New(var/obj/L) + w_class = hardware_size + if(istype(L, /obj/item/modular_computer)) + holder2 = L + return + +/obj/item/weapon/computer_hardware/Destroy() + holder2 = null + return ..() + +// Handles damage checks +/obj/item/weapon/computer_hardware/proc/check_functionality() + // Turned off + if(!enabled) + return 0 + // Too damaged to work at all. + if(damage > damage_failure) + return 0 + // Still working. Well, sometimes... + if(damage > damage_malfunction) + if(prob(malfunction_probability)) + return 0 + // Good to go. + return 1 + +/obj/item/weapon/computer_hardware/examine(var/mob/user) + . = ..() + if(damage > damage_failure) + to_chat(user, "It seems to be severely damaged!") + else if(damage > damage_malfunction) + to_chat(user, "It seems to be damaged!") + else if(damage) + to_chat(user, "It seems to be slightly damaged.") + +// Damages the component. Contains necessary checks. Negative damage "heals" the component. +/obj/item/weapon/computer_hardware/proc/take_damage(var/amount) + damage += round(amount) // We want nice rounded numbers here. + damage = between(0, damage, max_damage) // Clamp the value. + diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm new file mode 100644 index 0000000000..3b7ea1164b --- /dev/null +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -0,0 +1,79 @@ +// This device is wrapper for actual power cell. I have decided to not use power cells directly as even low-end cells available on station +// have tremendeous capacity in comparsion. Higher tier cells would provide your device with nearly infinite battery life, which is something i want to avoid. +/obj/item/weapon/computer_hardware/battery_module + name = "standard battery" + desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops. It's rating is 750." + icon_state = "battery_normal" + critical = 1 + malfunction_probability = 1 + origin_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1) + var/battery_rating = 750 + var/obj/item/weapon/cell/battery = null + +/obj/item/weapon/computer_hardware/battery_module/advanced + name = "advanced battery" + desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices. It's rating is 1100." + icon_state = "battery_advanced" + origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) + hardware_size = 2 + battery_rating = 1100 + +/obj/item/weapon/computer_hardware/battery_module/super + name = "super battery" + desc = "A very advanced power cell, often used in high-end devices, or as uninterruptable power supply for important consoles or servers. It's rating is 1500." + icon_state = "battery_super" + origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3) + hardware_size = 2 + battery_rating = 1500 + +/obj/item/weapon/computer_hardware/battery_module/ultra + name = "ultra battery" + desc = "A very advanced large power cell. It's often used as uninterruptable power supply for critical consoles or servers. It's rating is 2000." + icon_state = "battery_ultra" + origin_tech = list(TECH_POWER = 5, TECH_ENGINEERING = 4) + hardware_size = 3 + battery_rating = 2000 + +/obj/item/weapon/computer_hardware/battery_module/micro + name = "micro battery" + desc = "A small power cell, commonly seen in most portable microcomputers. It's rating is 500." + icon_state = "battery_micro" + origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) + battery_rating = 500 + +/obj/item/weapon/computer_hardware/battery_module/nano + name = "nano battery" + desc = "A tiny power cell, commonly seen in low-end portable microcomputers. It's rating is 300." + icon_state = "battery_nano" + origin_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1) + battery_rating = 300 + +// This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes. +/obj/item/weapon/computer_hardware/battery_module/lambda + name = "lambda coil" + desc = "A very complex power source compatible with various computers. It is capable of providing power for nearly unlimited duration." + icon_state = "battery_lambda" + hardware_size = 1 + battery_rating = 30000 + +/obj/item/weapon/computer_hardware/battery_module/lambda/New() + ..() + battery = new/obj/item/weapon/cell/infinite(src) + +/obj/item/weapon/computer_hardware/battery_module/diagnostics(var/mob/user) + ..() + to_chat(user, "Internal battery charge: [battery.charge]/[battery.maxcharge] CU") + +/obj/item/weapon/computer_hardware/battery_module/New() + battery = new/obj/item/weapon/cell(src) + battery.maxcharge = battery_rating + battery.charge = 0 + ..() + +/obj/item/weapon/computer_hardware/battery_module/Destroy() + qdel_null(battery) + return ..() + +/obj/item/weapon/computer_hardware/battery_module/proc/charge_to_full() + if(battery) + battery.charge = battery.maxcharge \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm new file mode 100644 index 0000000000..4cf8afc705 --- /dev/null +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -0,0 +1,18 @@ +/obj/item/weapon/computer_hardware/card_slot + name = "RFID card slot" + desc = "Slot that allows this computer to write data on RFID cards. Necessary for some programs to run properly." + power_usage = 10 //W + critical = 0 + icon_state = "cardreader" + hardware_size = 1 + origin_tech = list(TECH_DATA = 2) + + var/obj/item/weapon/card/id/stored_card = null + +/obj/item/weapon/computer_hardware/card_slot/Destroy() + if(holder2 && (holder2.card_slot == src)) + holder2.card_slot = null + if(stored_card) + stored_card.forceMove(get_turf(holder2)) + holder2 = null + return ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm new file mode 100644 index 0000000000..c9aa58d8d1 --- /dev/null +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -0,0 +1,167 @@ +/obj/item/weapon/computer_hardware/hard_drive/ + name = "basic hard drive" + desc = "A small power efficient solid state drive, with 128GQ of storage capacity for use in basic computers where power efficiency is desired." + power_usage = 25 // SSD or something with low power usage + icon_state = "hdd_normal" + hardware_size = 1 + origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) + var/max_capacity = 128 + var/used_capacity = 0 + var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY! + +/obj/item/weapon/computer_hardware/hard_drive/advanced + name = "advanced hard drive" + desc = "A small hybrid hard drive with 256GQ of storage capacity for use in higher grade computers where balance between power efficiency and capacity is desired." + max_capacity = 256 + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + power_usage = 50 // Hybrid, medium capacity and medium power storage + icon_state = "hdd_advanced" + hardware_size = 2 + +/obj/item/weapon/computer_hardware/hard_drive/super + name = "super hard drive" + desc = "A small hard drive with 512GQ of storage capacity for use in cluster storage solutions where capacity is more important than power efficiency." + max_capacity = 512 + origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) + power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. + icon_state = "hdd_super" + hardware_size = 2 + +/obj/item/weapon/computer_hardware/hard_drive/cluster + name = "cluster hard drive" + desc = "A large storage cluster consisting of multiple hard drives for usage in high capacity storage systems. Has capacity of 2048 GQ." + power_usage = 500 + origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4) + max_capacity = 2048 + icon_state = "hdd_cluster" + hardware_size = 3 + +// For tablets, etc. - highly power efficient. +/obj/item/weapon/computer_hardware/hard_drive/small + name = "small hard drive" + desc = "A small highly efficient solid state drive for portable devices." + power_usage = 10 + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + max_capacity = 64 + icon_state = "hdd_small" + hardware_size = 1 + +/obj/item/weapon/computer_hardware/hard_drive/micro + name = "micro hard drive" + desc = "A small micro hard drive for portable devices." + power_usage = 2 + origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) + max_capacity = 32 + icon_state = "hdd_micro" + hardware_size = 1 + +/obj/item/weapon/computer_hardware/hard_drive/diagnostics(var/mob/user) + ..() + // 999 is a byond limit that is in place. It's unlikely someone will reach that many files anyway, since you would sooner run out of space. + to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999") + to_chat(user, "Storage capacity: [used_capacity]/[max_capacity]GQ") + +// Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. +/obj/item/weapon/computer_hardware/hard_drive/proc/store_file(var/datum/computer_file/F) + if(!F || !istype(F)) + return 0 + + if(!can_store_file(F.size)) + return 0 + + if(!check_functionality()) + return 0 + + if(!stored_files) + return 0 + + // This file is already stored. Don't store it again. + if(F in stored_files) + return 0 + + F.holder = src + stored_files.Add(F) + recalculate_size() + return 1 + +// Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. +/obj/item/weapon/computer_hardware/hard_drive/proc/install_default_programs() + store_file(new/datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar + store_file(new/datum/computer_file/program/ntnetdownload(src)) // NTNet Downloader Utility, allows users to download more software from NTNet repository + store_file(new/datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation. + + +// Use this proc to remove file from the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. +/obj/item/weapon/computer_hardware/hard_drive/proc/remove_file(var/datum/computer_file/F) + if(!F || !istype(F)) + return 0 + + if(!stored_files) + return 0 + + if(!check_functionality()) + return 0 + + if(F in stored_files) + stored_files -= F + recalculate_size() + return 1 + else + return 0 + +// Loops through all stored files and recalculates used_capacity of this drive +/obj/item/weapon/computer_hardware/hard_drive/proc/recalculate_size() + var/total_size = 0 + for(var/datum/computer_file/F in stored_files) + total_size += F.size + + used_capacity = total_size + +// Checks whether file can be stored on the hard drive. +/obj/item/weapon/computer_hardware/hard_drive/proc/can_store_file(var/size = 1) + // In the unlikely event someone manages to create that many files. + // BYOND is acting weird with numbers above 999 in loops (infinite loop prevention) + if(stored_files.len >= 999) + return 0 + if(used_capacity + size > max_capacity) + return 0 + else + return 1 + +// Checks whether we can store the file. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file. +/obj/item/weapon/computer_hardware/hard_drive/proc/try_store_file(var/datum/computer_file/F) + if(!F || !istype(F)) + return 0 + var/name = F.filename + "." + F.filetype + for(var/datum/computer_file/file in stored_files) + if((file.filename + "." + file.filetype) == name) + return 0 + return can_store_file(F.size) + + + +// Tries to find the file by filename. Returns null on failure +/obj/item/weapon/computer_hardware/hard_drive/proc/find_file_by_name(var/filename) + if(!check_functionality()) + return null + + if(!filename) + return null + + if(!stored_files) + return null + + for(var/datum/computer_file/F in stored_files) + if(F.filename == filename) + return F + return null + +/obj/item/weapon/computer_hardware/hard_drive/Destroy() + if(holder2 && (holder2.hard_drive == src)) + holder2.hard_drive = null + stored_files = null + return ..() + +/obj/item/weapon/computer_hardware/hard_drive/New() + install_default_programs() + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/nano_printer.dm b/code/modules/modular_computers/hardware/nano_printer.dm new file mode 100644 index 0000000000..2496a6930d --- /dev/null +++ b/code/modules/modular_computers/hardware/nano_printer.dm @@ -0,0 +1,77 @@ +/obj/item/weapon/computer_hardware/nano_printer + name = "nano printer" + desc = "Small integrated printer with paper recycling module." + power_usage = 50 + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + critical = 0 + icon_state = "printer" + hardware_size = 1 + var/stored_paper = 5 + var/max_paper = 10 + +/obj/item/weapon/computer_hardware/nano_printer/diagnostics(var/mob/user) + ..() + to_chat(user, "Paper buffer level: [stored_paper]/[max_paper]") + +/obj/item/weapon/computer_hardware/nano_printer/proc/print_text(var/text_to_print, var/paper_title = null) + if(!stored_paper) + return 0 + if(!enabled) + return 0 + if(!check_functionality()) + return 0 + + var/obj/item/weapon/paper/P = new/obj/item/weapon/paper(get_turf(holder2)) + + // Damaged printer causes the resulting paper to be somewhat harder to read. + if(damage > damage_malfunction) + P.info = stars(text_to_print, 100-malfunction_probability) + else + P.info = text_to_print + if(paper_title) + P.name = paper_title + P.update_icon() + + stored_paper-- + return 1 + +/obj/item/weapon/computer_hardware/nano_printer/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/paper)) + if(stored_paper >= max_paper) + to_chat(user, "You try to add \the [W] into \the [src], but its paper bin is full.") + return + + to_chat(user, "You insert \the [W] into [src].") + qdel(W) + stored_paper++ + else if(istype(W, /obj/item/weapon/paper_bundle)) + var/obj/item/weapon/paper_bundle/B = W + var/num_of_pages_added = 0 + if(stored_paper >= max_paper) + to_chat(user, "You try to add \the [W] into \the [src], but its paper bin is full.") + return + for(var/obj/item/weapon/bundleitem in B) //loop through items in bundle + if(istype(bundleitem, /obj/item/weapon/paper)) //if item is paper (and not photo), add into the bin + B.pages.Remove(bundleitem) + qdel(bundleitem) + num_of_pages_added++ + stored_paper++ + if(stored_paper >= max_paper) //check if the printer is full yet + to_chat(user, "The printer has been filled to full capacity.") + break + if(B.pages.len == 0) //if all its papers have been put into the printer, delete bundle + qdel(W) + else if(B.pages.len == 1) //if only one item left, extract item and delete the one-item bundle + user.drop_from_inventory(B) + user.put_in_hands(B[1]) + qdel(B) + else //if at least two items remain, just update the bundle icon + B.update_icon() + to_chat(user, "You add [num_of_pages_added] papers from \the [W] into \the [src].") + return + +/obj/item/weapon/computer_hardware/nano_printer/Destroy() + if(holder2 && (holder2.nano_printer == src)) + holder2.nano_printer = null + holder2 = null + return ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm new file mode 100644 index 0000000000..ecf0bab6f6 --- /dev/null +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -0,0 +1,100 @@ +var/global/ntnet_card_uid = 1 + +/obj/item/weapon/computer_hardware/network_card/ + name = "basic NTNet network card" + desc = "A basic network card for usage with standard NTNet frequencies." + power_usage = 50 + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 1) + critical = 0 + icon_state = "netcard_basic" + hardware_size = 1 + var/identification_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user. + var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user. + var/long_range = 0 + var/ethernet = 0 // Hard-wired, therefore always on, ignores NTNet wireless checks. + malfunction_probability = 1 + +/obj/item/weapon/computer_hardware/network_card/diagnostics(var/mob/user) + ..() + to_chat(user, "NIX Unique ID: [identification_id]") + to_chat(user, "NIX User Tag: [identification_string]") + to_chat(user, "Supported protocols:") + to_chat(user, "511.m SFS (Subspace) - Standard Frequency Spread") + if(long_range) + to_chat(user, "511.n WFS/HB (Subspace) - Wide Frequency Spread/High Bandiwdth") + if(ethernet) + to_chat(user, "OpenEth (Physical Connection) - Physical network connection port") + +/obj/item/weapon/computer_hardware/network_card/New(var/l) + ..(l) + identification_id = ntnet_card_uid + ntnet_card_uid++ + +/obj/item/weapon/computer_hardware/network_card/advanced + name = "advanced NTNet network card" + desc = "An advanced network card for usage with standard NTNet frequencies. It's transmitter is strong enough to connect even when far away." + long_range = 1 + origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 2) + power_usage = 100 // Better range but higher power usage. + icon_state = "netcard_advanced" + hardware_size = 1 + +/obj/item/weapon/computer_hardware/network_card/wired + name = "wired NTNet network card" + desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection." + ethernet = 1 + origin_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 3) + power_usage = 100 // Better range but higher power usage. + icon_state = "netcard_ethernet" + hardware_size = 3 + +/obj/item/weapon/computer_hardware/network_card/Destroy() + if(holder2 && (holder2.network_card == src)) + holder2.network_card = null + holder2 = null + return ..() + +// Returns a string identifier of this network card +/obj/item/weapon/computer_hardware/network_card/proc/get_network_tag() + return "[identification_string] (NID [identification_id])" + +/obj/item/weapon/computer_hardware/network_card/proc/is_banned() + return ntnet_global.check_banned(identification_id) + +// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection +/obj/item/weapon/computer_hardware/network_card/proc/get_signal(var/specific_action = 0) + if(!holder2) // Hardware is not installed in anything. No signal. How did this even get called? + return 0 + + if(!enabled) + return 0 + + if(!check_functionality() || !ntnet_global || is_banned()) + return 0 + + if(ethernet) // Computer is connected via wired connection. + return 3 + + if(!ntnet_global.check_function(specific_action)) // NTNet is down and we are not connected via wired connection. No signal. + return 0 + + if(holder2) + var/turf/T = get_turf(holder2) + if(!istype(T)) //no reception in nullspace + return 0 + if(T.z in using_map.station_levels) + // Computer is on station. Low/High signal depending on what type of network card you have + if(long_range) + return 2 + else + return 1 + if(T.z in using_map.contact_levels) //not on station, but close enough for radio signal to travel + if(long_range) // Computer is not on station, but it has upgraded network card. Low signal. + return 1 + + return 0 // Computer is not on station and does not have upgraded network card. No signal. + +/obj/item/weapon/computer_hardware/network_card/Destroy() + if(holder2 && (holder2.network_card == src)) + holder2.network_card = null + ..() diff --git a/code/modules/modular_computers/hardware/portable_hard_drive.dm b/code/modules/modular_computers/hardware/portable_hard_drive.dm new file mode 100644 index 0000000000..9a0feb3653 --- /dev/null +++ b/code/modules/modular_computers/hardware/portable_hard_drive.dm @@ -0,0 +1,37 @@ +// These are basically USB data sticks and may be used to transfer files between devices +/obj/item/weapon/computer_hardware/hard_drive/portable/ + name = "basic data crystal" + desc = "Small crystal with imprinted photonic circuits that can be used to store data. Its capacity is 16 GQ." + power_usage = 10 + icon_state = "flashdrive_basic" + hardware_size = 1 + max_capacity = 16 + origin_tech = list(TECH_DATA = 1) + +/obj/item/weapon/computer_hardware/hard_drive/portable/advanced + name = "advanced data crystal" + desc = "Small crystal with imprinted high-density photonic circuits that can be used to store data. Its capacity is 64 GQ." + power_usage = 20 + icon_state = "flashdrive_advanced" + hardware_size = 1 + max_capacity = 64 + origin_tech = list(TECH_DATA = 2) + +/obj/item/weapon/computer_hardware/hard_drive/portable/super + name = "super data crystal" + desc = "Small crystal with imprinted ultra-density photonic circuits that can be used to store data. Its capacity is 256 GQ." + power_usage = 40 + icon_state = "flashdrive_super" + hardware_size = 1 + max_capacity = 256 + origin_tech = list(TECH_DATA = 4) + +/obj/item/weapon/computer_hardware/hard_drive/portable/New() + ..() + stored_files = list() + recalculate_size() + +/obj/item/weapon/computer_hardware/hard_drive/portable/Destroy() + if(holder2 && (holder2.portable_drive == src)) + holder2.portable_drive = null + return ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/processor_unit.dm b/code/modules/modular_computers/hardware/processor_unit.dm new file mode 100644 index 0000000000..9ed7ab40ac --- /dev/null +++ b/code/modules/modular_computers/hardware/processor_unit.dm @@ -0,0 +1,46 @@ +// CPU that allows the computer to run programs. +// Better CPUs are obtainable via research and can run more programs on background. + +/obj/item/weapon/computer_hardware/processor_unit + name = "standard processor" + desc = "A standard CPU used in most computers. It can run up to three programs simultaneously." + icon_state = "cpu_normal" + hardware_size = 2 + power_usage = 50 + critical = 1 + malfunction_probability = 1 + origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2) + + var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description. + +/obj/item/weapon/computer_hardware/processor_unit/small + name = "standard microprocessor" + desc = "A standard miniaturised CPU used in portable devices. It can run up to two programs simultaneously." + icon_state = "cpu_small" + hardware_size = 1 + power_usage = 25 + max_idle_programs = 1 + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + +/obj/item/weapon/computer_hardware/processor_unit/photonic + name = "photonic processor" + desc = "An advanced experimental CPU that uses photonic core instead of regular circuitry. It can run up to five programs simultaneously, but uses a lot of power." + icon_state = "cpu_normal_photonic" + hardware_size = 2 + power_usage = 250 + max_idle_programs = 4 + origin_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 4) + +/obj/item/weapon/computer_hardware/processor_unit/photonic/small + name = "photonic microprocessor" + desc = "An advanced miniaturised CPU for use in portable devices. It uses photonic core instead of regular circuitry. It can run up to three programs simultaneously." + icon_state = "cpu_small_photonic" + hardware_size = 1 + power_usage = 75 + max_idle_programs = 2 + origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3) + +/obj/item/weapon/computer_hardware/processor_unit/Destroy() + if(holder2 && (holder2.processor_unit == src)) + holder2.processor_unit = null + return ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/tesla_link.dm b/code/modules/modular_computers/hardware/tesla_link.dm new file mode 100644 index 0000000000..b23bb963af --- /dev/null +++ b/code/modules/modular_computers/hardware/tesla_link.dm @@ -0,0 +1,14 @@ +/obj/item/weapon/computer_hardware/tesla_link + name = "tesla link" + desc = "An advanced tesla link that wirelessly recharges connected device from nearby area power controller." + critical = 0 + enabled = 1 + icon_state = "teslalink" + hardware_size = 1 + origin_tech = list(TECH_DATA = 2, TECH_POWER = 3, TECH_ENGINEERING = 2) + var/passive_charging_rate = 250 // W + +/obj/item/weapon/computer_hardware/tesla_link/Destroy() + if(holder2 && (holder2.tesla_link == src)) + holder2.tesla_link = null + return ..() \ No newline at end of file diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm new file mode 100644 index 0000000000..ab60291f55 --- /dev/null +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -0,0 +1,308 @@ +// A vendor machine for modular computer portable devices - Laptops and Tablets + +/obj/machinery/lapvend + name = "computer vendor" + desc = "A vending machine with a built-in microfabricator, capable of dispensing various NT-branded computers." + icon = 'icons/obj/vending.dmi' + icon_state = "robotics" + layer = OBJ_LAYER - 0.1 + anchored = 1 + density = 1 + + // The actual laptop/tablet + var/obj/item/modular_computer/laptop/fabricated_laptop = null + var/obj/item/modular_computer/tablet/fabricated_tablet = null + + // Utility vars + var/state = 0 // 0: Select device type, 1: Select loadout, 2: Payment, 3: Thankyou screen + var/devtype = 0 // 0: None(unselected), 1: Laptop, 2: Tablet + var/total_price = 0 // Price of currently vended device. + + // Device loadout + var/dev_cpu = 1 // 1: Default, 2: Upgraded + var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced + var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced + var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range + var/dev_tesla = 0 // 0: None, 1: Standard + var/dev_nanoprint = 0 // 0: None, 1: Standard + var/dev_card = 0 // 0: None, 1: Standard + +// Removes all traces of old order and allows you to begin configuration from scratch. +/obj/machinery/lapvend/proc/reset_order() + state = 0 + devtype = 0 + if(fabricated_laptop) + qdel(fabricated_laptop) + fabricated_laptop = null + if(fabricated_tablet) + qdel(fabricated_tablet) + fabricated_tablet = null + dev_cpu = 1 + dev_battery = 1 + dev_disk = 1 + dev_netcard = 0 + dev_tesla = 0 + dev_nanoprint = 0 + dev_card = 0 + +// Recalculates the price and optionally even fabricates the device. +/obj/machinery/lapvend/proc/fabricate_and_recalc_price(var/fabricate = 0) + total_price = 0 + if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles + if(fabricate) + fabricated_laptop = new(src) + total_price = 99 + switch(dev_cpu) + if(1) + if(fabricate) + fabricated_laptop.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(fabricated_laptop) + if(2) + if(fabricate) + fabricated_laptop.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(fabricated_laptop) + total_price += 299 + switch(dev_battery) + if(1) // Basic(750C) + if(fabricate) + fabricated_laptop.battery_module = new/obj/item/weapon/computer_hardware/battery_module(fabricated_laptop) + if(2) // Upgraded(1100C) + if(fabricate) + fabricated_laptop.battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(fabricated_laptop) + total_price += 199 + if(3) // Advanced(1500C) + if(fabricate) + fabricated_laptop.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(fabricated_laptop) + total_price += 499 + switch(dev_disk) + if(1) // Basic(128GQ) + if(fabricate) + fabricated_laptop.hard_drive = new/obj/item/weapon/computer_hardware/hard_drive(fabricated_laptop) + if(2) // Upgraded(256GQ) + if(fabricate) + fabricated_laptop.hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/advanced(fabricated_laptop) + total_price += 99 + if(3) // Advanced(512GQ) + if(fabricate) + fabricated_laptop.hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/super(fabricated_laptop) + total_price += 299 + switch(dev_netcard) + if(1) // Basic(Short-Range) + if(fabricate) + fabricated_laptop.network_card = new/obj/item/weapon/computer_hardware/network_card(fabricated_laptop) + total_price += 99 + if(2) // Advanced (Long Range) + if(fabricate) + fabricated_laptop.network_card = new/obj/item/weapon/computer_hardware/network_card/advanced(fabricated_laptop) + total_price += 299 + if(dev_tesla) + total_price += 399 + if(fabricate) + fabricated_laptop.tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(fabricated_laptop) + if(dev_nanoprint) + total_price += 99 + if(fabricate) + fabricated_laptop.nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(fabricated_laptop) + if(dev_card) + total_price += 199 + if(fabricate) + fabricated_laptop.card_slot = new/obj/item/weapon/computer_hardware/card_slot(fabricated_laptop) + + return total_price + else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. + if(fabricate) + fabricated_tablet = new(src) + fabricated_tablet.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(fabricated_tablet) + total_price = 199 + switch(dev_battery) + if(1) // Basic(300C) + if(fabricate) + fabricated_tablet.battery_module = new/obj/item/weapon/computer_hardware/battery_module/nano(fabricated_tablet) + if(2) // Upgraded(500C) + if(fabricate) + fabricated_tablet.battery_module = new/obj/item/weapon/computer_hardware/battery_module/micro(fabricated_tablet) + total_price += 199 + if(3) // Advanced(750C) + if(fabricate) + fabricated_tablet.battery_module = new/obj/item/weapon/computer_hardware/battery_module(fabricated_tablet) + total_price += 499 + switch(dev_disk) + if(1) // Basic(32GQ) + if(fabricate) + fabricated_tablet.hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/micro(fabricated_tablet) + if(2) // Upgraded(64GQ) + if(fabricate) + fabricated_tablet.hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/small(fabricated_tablet) + total_price += 99 + if(3) // Advanced(128GQ) + if(fabricate) + fabricated_tablet.hard_drive = new/obj/item/weapon/computer_hardware/hard_drive(fabricated_tablet) + total_price += 299 + switch(dev_netcard) + if(1) // Basic(Short-Range) + if(fabricate) + fabricated_tablet.network_card = new/obj/item/weapon/computer_hardware/network_card(fabricated_tablet) + total_price += 99 + if(2) // Advanced (Long Range) + if(fabricate) + fabricated_tablet.network_card = new/obj/item/weapon/computer_hardware/network_card/advanced(fabricated_tablet) + total_price += 299 + if(dev_nanoprint) + total_price += 99 + if(fabricate) + fabricated_tablet.nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(fabricated_tablet) + if(dev_card) + total_price += 199 + if(fabricate) + fabricated_tablet.card_slot = new/obj/item/weapon/computer_hardware/card_slot(fabricated_tablet) + if(dev_tesla) + total_price += 399 + if(fabricate) + fabricated_tablet.tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(fabricated_tablet) + return total_price + return 0 + + + + + +/obj/machinery/lapvend/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["pick_device"]) + if(state) // We've already picked a device type + return 0 + devtype = text2num(href_list["pick_device"]) + state = 1 + fabricate_and_recalc_price(0) + return 1 + if(href_list["clean_order"]) + reset_order() + return 1 + if((state != 1) && devtype) // Following IFs should only be usable when in the Select Loadout mode + return 0 + if(href_list["confirm_order"]) + state = 2 // Wait for ID swipe for payment processing + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_cpu"]) + dev_cpu = text2num(href_list["hw_cpu"]) + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_battery"]) + dev_battery = text2num(href_list["hw_battery"]) + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_disk"]) + dev_disk = text2num(href_list["hw_disk"]) + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_netcard"]) + dev_netcard = text2num(href_list["hw_netcard"]) + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_tesla"]) + dev_tesla = text2num(href_list["hw_tesla"]) + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_nanoprint"]) + dev_nanoprint = text2num(href_list["hw_nanoprint"]) + fabricate_and_recalc_price(0) + return 1 + if(href_list["hw_card"]) + dev_card = text2num(href_list["hw_card"]) + fabricate_and_recalc_price(0) + return 1 + return 0 + +/obj/machinery/lapvend/attack_hand(var/mob/user) + ui_interact(user) + +/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + if(stat & (BROKEN | NOPOWER | MAINT)) + if(ui) + ui.close() + return 0 + + var/list/data[0] + data["state"] = state + if(state == 1) + data["devtype"] = devtype + data["hw_battery"] = dev_battery + data["hw_disk"] = dev_disk + data["hw_netcard"] = dev_netcard + data["hw_tesla"] = dev_tesla + data["hw_nanoprint"] = dev_nanoprint + data["hw_card"] = dev_card + data["hw_cpu"] = dev_cpu + if(state == 1 || state == 2) + data["totalprice"] = total_price + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "computer_fabricator.tmpl", "Personal Computer Vendor", 500, 400) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + +obj/machinery/lapvend/attackby(obj/item/weapon/W as obj, mob/user as mob) + var/obj/item/weapon/card/id/I = W.GetID() + // Awaiting payment state + if(state == 2) + if(process_payment(I,W)) + fabricate_and_recalc_price(1) + if((devtype == 1) && fabricated_laptop) + if(fabricated_laptop.battery_module) + fabricated_laptop.battery_module.charge_to_full() + fabricated_laptop.forceMove(src.loc) + fabricated_laptop.screen_on = 0 + fabricated_laptop.anchored = 0 + fabricated_laptop.update_icon() + fabricated_laptop.update_verbs() + fabricated_laptop = null + else if((devtype == 2) && fabricated_tablet) + if(fabricated_tablet.battery_module) + fabricated_tablet.battery_module.charge_to_full() + fabricated_tablet.forceMove(src.loc) + fabricated_tablet.update_verbs() + fabricated_tablet = null + ping("Enjoy your new product!") + state = 3 + return 1 + return 0 + return ..() + + +// Simplified payment processing, returns 1 on success. +/obj/machinery/lapvend/proc/process_payment(var/obj/item/weapon/card/id/I, var/obj/item/ID_container) + if(I==ID_container || ID_container == null) + visible_message("\The [usr] swipes \the [I] through \the [src].") + else + visible_message("\The [usr] swipes \the [ID_container] through \the [src].") + var/datum/money_account/customer_account = get_account(I.associated_account_number) + if (!customer_account || customer_account.suspended) + ping("Connection error. Unable to connect to account.") + return 0 + + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!customer_account) + ping("Unable to access account: incorrect credentials.") + return 0 + + if(total_price > customer_account.money) + ping("Insufficient funds in account.") + return 0 + else + customer_account.money -= total_price + var/datum/transaction/T = new() + T.target_name = "Computer Manufacturer (via [src.name])" + T.purpose = "Purchase of [(devtype == 1) ? "laptop computer" : "tablet microcomputer"]." + T.amount = total_price + T.source_terminal = src.name + T.date = current_date_string + T.time = stationtime2text() + customer_account.transaction_log.Add(T) + return 1 \ No newline at end of file diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 3d790b1194..fd2ed900f2 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -100,7 +100,7 @@ return generate_data(check_whitelist, whitelist, blacklist) - var/data[0] + var/list/data = host.initial_data() data["specimen"] = owner.species.name data["gender"] = owner.gender diff --git a/code/modules/nano/modules/nano_module.dm b/code/modules/nano/modules/nano_module.dm index 8ced14f4c5..90c213da1c 100644 --- a/code/modules/nano/modules/nano_module.dm +++ b/code/modules/nano/modules/nano_module.dm @@ -1,16 +1,64 @@ /datum/nano_module var/name - var/host + var/datum/host + var/datum/topic_manager/topic_manager + var/list/using_access -/datum/nano_module/New(var/host) - src.host = host - -/datum/nano_module/Destroy() - host = null - return ..() +/datum/nano_module/New(var/datum/host, var/topic_manager) + ..() + src.host = host.nano_host() + src.topic_manager = topic_manager /datum/nano_module/nano_host() return host ? host : src /datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state) return CanUseTopic(usr, state) == STATUS_INTERACTIVE + +/datum/nano_module/proc/check_eye(var/mob/user) + return -1 + +/datum/nano_module/proc/check_access(var/mob/user, var/access) + if(!access) + return 1 + + if(using_access) + if(access in using_access) + return 1 + else + return 0 + + if(!istype(user)) + return 0 + + var/obj/item/weapon/card/id/I = user.GetIdCard() + if(!I) + return 0 + + if(access in I.access) + return 1 + + return 0 + +/datum/nano_module/Topic(href, href_list) + if(topic_manager && topic_manager.Topic(href, href_list)) + return TRUE + . = ..() + +/datum/nano_module/proc/print_text(var/text, var/mob/user) + var/obj/item/modular_computer/MC = nano_host() + if(istype(MC)) + if(!MC.nano_printer) + to_chat(user, "Error: No printer detected. Unable to print document.") + return + + if(!MC.nano_printer.print_text(text)) + to_chat(user, "Error: Printer was unable to print the document. It may be out of paper.") + else + to_chat(user, "Error: Unable to detect compatible printer interface. Are you running NTOSv2 compatible system?") + +/datum/proc/initial_data() + return list() + +/datum/proc/update_layout() + return FALSE diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 43f98e3361..2b3dc81b99 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -401,6 +401,11 @@ nanoui is used to open and update nano browser uis if(!user.client) return + // An attempted fix to UIs sometimes locking up spamming runtime errors due to src_object being null for whatever reason. + // This hard-deletes the UI, preventing the device that uses the UI from being locked up permanently. + if(!src_object) + del(src) + var/window_size = "" if (width && height) window_size = "size=[width]x[height];" diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index e436497fc5..c41d49aff5 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -90,6 +90,10 @@ var/datum/looping_sound/supermatter/soundloop +/obj/machinery/power/supermatter/New() + ..() + uid = gl_uid++ + /obj/machinery/power/supermatter/Initialize() soundloop = new(list(src), TRUE) return ..() @@ -98,6 +102,34 @@ QDEL_NULL(soundloop) return ..() +/obj/machinery/power/supermatter/proc/get_status() + var/turf/T = get_turf(src) + if(!T) + return SUPERMATTER_ERROR + var/datum/gas_mixture/air = T.return_air() + if(!air) + return SUPERMATTER_ERROR + + if(grav_pulling || exploded) + return SUPERMATTER_DELAMINATING + + if(get_integrity() < 25) + return SUPERMATTER_EMERGENCY + + if(get_integrity() < 50) + return SUPERMATTER_DANGER + + if((get_integrity() < 100) || (air.temperature > CRITICAL_TEMPERATURE)) + return SUPERMATTER_WARNING + + if(air.temperature > (CRITICAL_TEMPERATURE * 0.8)) + return SUPERMATTER_NOTIFY + + if(power > 5) + return SUPERMATTER_NORMAL + return SUPERMATTER_INACTIVE + + /obj/machinery/power/supermatter/proc/explode() message_admins("Supermatter exploded at ([x],[y],[z] - JMP)",0,1) log_game("SUPERMATTER([x],[y],[z]) Exploded. Power:[power], Oxygen:[oxygen], Damage:[damage], Integrity:[get_integrity()]") diff --git a/code/modules/research/designs/circuits.dm b/code/modules/research/designs/circuits.dm index 6c79366e66..28fcff85dd 100644 --- a/code/modules/research/designs/circuits.dm +++ b/code/modules/research/designs/circuits.dm @@ -579,6 +579,13 @@ CIRCUITS BELOW build_path = /obj/item/weapon/circuitboard/shield_cap sort_string = "VAAAC" +/datum/design/circuit/ntnet_relay + name = "NTNet Quantum Relay" + id = "ntnet_relay" + req_tech = list(TECH_DATA = 4) + build_path = /obj/item/weapon/circuitboard/ntnet_relay + sort_string = "WAAAA" + /datum/design/circuit/aicore name = "AI core" id = "aicore" diff --git a/code/modules/research/designs/modular_computer.dm b/code/modules/research/designs/modular_computer.dm new file mode 100644 index 0000000000..5bb19b0be6 --- /dev/null +++ b/code/modules/research/designs/modular_computer.dm @@ -0,0 +1,233 @@ +// Modular computer components +// Hard drives +/datum/design/item/modularcomponent/disk/normal + name = "basic hard drive" + id = "hdd_basic" + req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 100) + build_path = /obj/item/weapon/computer_hardware/hard_drive/ + sort_string = "VBAAA" + +/datum/design/item/modularcomponent/disk/advanced + name = "advanced hard drive" + id = "hdd_advanced" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 200) + build_path = /obj/item/weapon/computer_hardware/hard_drive/advanced + sort_string = "VBAAB" + +/datum/design/item/modularcomponent/disk/super + name = "super hard drive" + id = "hdd_super" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 8000, "glass" = 400) + build_path = /obj/item/weapon/computer_hardware/hard_drive/super + sort_string = "VBAAC" + +/datum/design/item/modularcomponent/disk/cluster + name = "cluster hard drive" + id = "hdd_cluster" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 16000, "glass" = 800) + build_path = /obj/item/weapon/computer_hardware/hard_drive/cluster + sort_string = "VBAAD" + +/datum/design/item/modularcomponent/disk/small + name = "small hard drive" + id = "hdd_small" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 200) + build_path = /obj/item/weapon/computer_hardware/hard_drive/small + sort_string = "VBAAE" + +/datum/design/item/modularcomponent/disk/micro + name = "micro hard drive" + id = "hdd_micro" + req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 100) + build_path = /obj/item/weapon/computer_hardware/hard_drive/micro + sort_string = "VBAAF" + +// Network cards +/datum/design/item/modularcomponent/netcard/basic + name = "basic network card" + id = "netcard_basic" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 1) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 100) + build_path = /obj/item/weapon/computer_hardware/network_card + sort_string = "VBAAG" + +/datum/design/item/modularcomponent/netcard/advanced + name = "advanced network card" + id = "netcard_advanced" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 2) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200) + build_path = /obj/item/weapon/computer_hardware/network_card/advanced + sort_string = "VBAAH" + +/datum/design/item/modularcomponent/netcard/wired + name = "wired network card" + id = "netcard_wired" + req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 3) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 400) + build_path = /obj/item/weapon/computer_hardware/network_card/wired + sort_string = "VBAAI" + +// Data crystals (USB flash drives) +/datum/design/item/modularcomponent/portabledrive/basic + name = "basic data crystal" + id = "portadrive_basic" + req_tech = list(TECH_DATA = 1) + build_type = IMPRINTER + materials = list("glass" = 8000) + build_path = /obj/item/weapon/computer_hardware/hard_drive/portable + sort_string = "VBAAJ" + +/datum/design/item/modularcomponent/portabledrive/advanced + name = "advanced data crystal" + id = "portadrive_advanced" + req_tech = list(TECH_DATA = 2) + build_type = IMPRINTER + materials = list("glass" = 16000) + build_path = /obj/item/weapon/computer_hardware/hard_drive/portable/advanced + sort_string = "VBAAK" + +/datum/design/item/modularcomponent/portabledrive/super + name = "super data crystal" + id = "portadrive_super" + req_tech = list(TECH_DATA = 4) + build_type = IMPRINTER + materials = list("glass" = 32000) + build_path = /obj/item/weapon/computer_hardware/hard_drive/portable/super + sort_string = "VBAAL" + +// Card slot +/datum/design/item/modularcomponent/cardslot + name = "RFID card slot" + id = "cardslot" + req_tech = list(TECH_DATA = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 3000) + build_path = /obj/item/weapon/computer_hardware/card_slot + sort_string = "VBAAM" + +// Nano printer +/datum/design/item/modularcomponent/nanoprinter + name = "nano printer" + id = "nanoprinter" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 3000) + build_path = /obj/item/weapon/computer_hardware/nano_printer + sort_string = "VBAAN" + +// Tesla Link +/datum/design/item/modularcomponent/teslalink + name = "tesla link" + id = "teslalink" + req_tech = list(TECH_DATA = 2, TECH_POWER = 3, TECH_ENGINEERING = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/weapon/computer_hardware/tesla_link + sort_string = "VBAAO" + +// Batteries +/datum/design/item/modularcomponent/battery/normal + name = "standard battery module" + id = "bat_normal" + req_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 2000) + build_path = /obj/item/weapon/computer_hardware/battery_module + sort_string = "VBAAP" + +/datum/design/item/modularcomponent/battery/advanced + name = "advanced battery module" + id = "bat_advanced" + req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 4000) + build_path = /obj/item/weapon/computer_hardware/battery_module/advanced + sort_string = "VBAAQ" + +/datum/design/item/modularcomponent/battery/super + name = "super battery module" + id = "bat_super" + req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 8000) + build_path = /obj/item/weapon/computer_hardware/battery_module/super + sort_string = "VBAAR" + +/datum/design/item/modularcomponent/battery/ultra + name = "ultra battery module" + id = "bat_ultra" + req_tech = list(TECH_POWER = 5, TECH_ENGINEERING = 4) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 16000) + build_path = /obj/item/weapon/computer_hardware/battery_module/ultra + sort_string = "VBAAS" + +/datum/design/item/modularcomponent/battery/nano + name = "nano battery module" + id = "bat_nano" + req_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 2000) + build_path = /obj/item/weapon/computer_hardware/battery_module/nano + sort_string = "VBAAT" + +/datum/design/item/modularcomponent/battery/micro + name = "micro battery module" + id = "bat_micro" + req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 4000) + build_path = /obj/item/weapon/computer_hardware/battery_module/micro + sort_string = "VBAAU" + +// Processor unit +/datum/design/item/modularcomponent/cpu/ + name = "computer processor unit" + id = "cpu_normal" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 8000) + build_path = /obj/item/weapon/computer_hardware/processor_unit + sort_string = "VBAAV" + +/datum/design/item/modularcomponent/cpu/small + name = "computer microprocessor unit" + id = "cpu_small" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 4000) + build_path = /obj/item/weapon/computer_hardware/processor_unit/small + sort_string = "VBAAW" + +/datum/design/item/modularcomponent/cpu/photonic + name = "computer photonic processor unit" + id = "pcpu_normal" + req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 4) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 32000, glass = 8000) + build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic + sort_string = "VBAAX" + +/datum/design/item/modularcomponent/cpu/photonic/small + name = "computer photonic microprocessor unit" + id = "pcpu_small" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 16000, glass = 4000) + build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic/small + sort_string = "VBAAY" diff --git a/html/changelogs/Novacat - modularcomputers.yml b/html/changelogs/Novacat - modularcomputers.yml new file mode 100644 index 0000000000..1e21807f7f --- /dev/null +++ b/html/changelogs/Novacat - modularcomputers.yml @@ -0,0 +1,39 @@ +################################ +# 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 +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Novacat + +# 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, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Ports initial infrastructure for modular computers from Baystation." + - rscadd: "Cameras now have a slight static when viewing through them." + - rscadd: "Adds Digital Warrant Program, to set warrants. Comes with a device." + - rscadd: "Adds Supermatter Monitor program." diff --git a/html/images/redntlogo.png b/html/images/redntlogo.png new file mode 100644 index 0000000000..6c03fa8b60 Binary files /dev/null and b/html/images/redntlogo.png differ diff --git a/icons/NTOS/airestore.png b/icons/NTOS/airestore.png deleted file mode 100644 index d8e5207bfb..0000000000 Binary files a/icons/NTOS/airestore.png and /dev/null differ diff --git a/icons/NTOS/aiupload.png b/icons/NTOS/aiupload.png deleted file mode 100644 index 25a8d8694e..0000000000 Binary files a/icons/NTOS/aiupload.png and /dev/null differ diff --git a/icons/NTOS/alerts.png b/icons/NTOS/alerts.png deleted file mode 100644 index d395428c7c..0000000000 Binary files a/icons/NTOS/alerts.png and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_100.gif b/icons/NTOS/battery_icons/batt_100.gif deleted file mode 100644 index 72f04cff01..0000000000 Binary files a/icons/NTOS/battery_icons/batt_100.gif and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_20.gif b/icons/NTOS/battery_icons/batt_20.gif deleted file mode 100644 index cc56e28214..0000000000 Binary files a/icons/NTOS/battery_icons/batt_20.gif and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_40.gif b/icons/NTOS/battery_icons/batt_40.gif deleted file mode 100644 index 5d03a30c18..0000000000 Binary files a/icons/NTOS/battery_icons/batt_40.gif and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_5.gif b/icons/NTOS/battery_icons/batt_5.gif deleted file mode 100644 index eddcc6ae82..0000000000 Binary files a/icons/NTOS/battery_icons/batt_5.gif and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_60.gif b/icons/NTOS/battery_icons/batt_60.gif deleted file mode 100644 index 2a159b8e3c..0000000000 Binary files a/icons/NTOS/battery_icons/batt_60.gif and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_80.gif b/icons/NTOS/battery_icons/batt_80.gif deleted file mode 100644 index 59efcb225e..0000000000 Binary files a/icons/NTOS/battery_icons/batt_80.gif and /dev/null differ diff --git a/icons/NTOS/battery_icons/batt_none.gif b/icons/NTOS/battery_icons/batt_none.gif deleted file mode 100644 index 64aa24516b..0000000000 Binary files a/icons/NTOS/battery_icons/batt_none.gif and /dev/null differ diff --git a/icons/NTOS/borgcontrol.png b/icons/NTOS/borgcontrol.png deleted file mode 100644 index 63e0815954..0000000000 Binary files a/icons/NTOS/borgcontrol.png and /dev/null differ diff --git a/icons/NTOS/borgupload.png b/icons/NTOS/borgupload.png deleted file mode 100644 index dfb24cecfd..0000000000 Binary files a/icons/NTOS/borgupload.png and /dev/null differ diff --git a/icons/NTOS/camera.png b/icons/NTOS/camera.png deleted file mode 100644 index a9a726b03d..0000000000 Binary files a/icons/NTOS/camera.png and /dev/null differ diff --git a/icons/NTOS/cardcomp.png b/icons/NTOS/cardcomp.png deleted file mode 100644 index e7df0ab207..0000000000 Binary files a/icons/NTOS/cardcomp.png and /dev/null differ diff --git a/icons/NTOS/cloning.png b/icons/NTOS/cloning.png deleted file mode 100644 index 6fa2942505..0000000000 Binary files a/icons/NTOS/cloning.png and /dev/null differ diff --git a/icons/NTOS/comms.png b/icons/NTOS/comms.png deleted file mode 100644 index e089889d93..0000000000 Binary files a/icons/NTOS/comms.png and /dev/null differ diff --git a/icons/NTOS/copyfile.png b/icons/NTOS/copyfile.png deleted file mode 100644 index 50c10b3757..0000000000 Binary files a/icons/NTOS/copyfile.png and /dev/null differ diff --git a/icons/NTOS/deletefile.png b/icons/NTOS/deletefile.png deleted file mode 100644 index ada175fad2..0000000000 Binary files a/icons/NTOS/deletefile.png and /dev/null differ diff --git a/icons/NTOS/drive.png b/icons/NTOS/drive.png deleted file mode 100644 index 69ca021f8b..0000000000 Binary files a/icons/NTOS/drive.png and /dev/null differ diff --git a/icons/NTOS/exocontrol.png b/icons/NTOS/exocontrol.png deleted file mode 100644 index 101f32e44d..0000000000 Binary files a/icons/NTOS/exocontrol.png and /dev/null differ diff --git a/icons/NTOS/file.png b/icons/NTOS/file.png deleted file mode 100644 index 05556e01f8..0000000000 Binary files a/icons/NTOS/file.png and /dev/null differ diff --git a/icons/NTOS/folder.png b/icons/NTOS/folder.png deleted file mode 100644 index 05780bc651..0000000000 Binary files a/icons/NTOS/folder.png and /dev/null differ diff --git a/icons/NTOS/foldermeta.png b/icons/NTOS/foldermeta.png deleted file mode 100644 index 0d7a26b943..0000000000 Binary files a/icons/NTOS/foldermeta.png and /dev/null differ diff --git a/icons/NTOS/genetics.png b/icons/NTOS/genetics.png deleted file mode 100644 index 6f5b2320fc..0000000000 Binary files a/icons/NTOS/genetics.png and /dev/null differ diff --git a/icons/NTOS/medical.png b/icons/NTOS/medical.png deleted file mode 100644 index a3b6a21b54..0000000000 Binary files a/icons/NTOS/medical.png and /dev/null differ diff --git a/icons/NTOS/monitoring.png b/icons/NTOS/monitoring.png deleted file mode 100644 index a94910e48a..0000000000 Binary files a/icons/NTOS/monitoring.png and /dev/null differ diff --git a/icons/NTOS/movefile.png b/icons/NTOS/movefile.png deleted file mode 100644 index 5b31c6c2a8..0000000000 Binary files a/icons/NTOS/movefile.png and /dev/null differ diff --git a/icons/NTOS/ntos.png b/icons/NTOS/ntos.png deleted file mode 100644 index 8b9d735cc9..0000000000 Binary files a/icons/NTOS/ntos.png and /dev/null differ diff --git a/icons/NTOS/operating.png b/icons/NTOS/operating.png deleted file mode 100644 index ab8f65ef7a..0000000000 Binary files a/icons/NTOS/operating.png and /dev/null differ diff --git a/icons/NTOS/pda.png b/icons/NTOS/pda.png deleted file mode 100644 index c6b0bb00fb..0000000000 Binary files a/icons/NTOS/pda.png and /dev/null differ diff --git a/icons/NTOS/power.png b/icons/NTOS/power.png deleted file mode 100644 index b2e4cc837f..0000000000 Binary files a/icons/NTOS/power.png and /dev/null differ diff --git a/icons/NTOS/prison.png b/icons/NTOS/prison.png deleted file mode 100644 index a846fe0041..0000000000 Binary files a/icons/NTOS/prison.png and /dev/null differ diff --git a/icons/NTOS/program.png b/icons/NTOS/program.png deleted file mode 100644 index ac16128763..0000000000 Binary files a/icons/NTOS/program.png and /dev/null differ diff --git a/icons/NTOS/records.png b/icons/NTOS/records.png deleted file mode 100644 index eaaf68e50d..0000000000 Binary files a/icons/NTOS/records.png and /dev/null differ diff --git a/icons/NTOS/research.png b/icons/NTOS/research.png deleted file mode 100644 index 5ebd63aafc..0000000000 Binary files a/icons/NTOS/research.png and /dev/null differ diff --git a/icons/NTOS/server.png b/icons/NTOS/server.png deleted file mode 100644 index 6d96b11413..0000000000 Binary files a/icons/NTOS/server.png and /dev/null differ diff --git a/icons/NTOS/tb_close.png b/icons/NTOS/tb_close.png deleted file mode 100644 index b99a6d8154..0000000000 Binary files a/icons/NTOS/tb_close.png and /dev/null differ diff --git a/icons/NTOS/tcomms.png b/icons/NTOS/tcomms.png deleted file mode 100644 index a63b23c8df..0000000000 Binary files a/icons/NTOS/tcomms.png and /dev/null differ diff --git a/icons/effects/static.dmi b/icons/effects/static.dmi index 6189ae1e33..63f6a1e6f6 100644 Binary files a/icons/effects/static.dmi and b/icons/effects/static.dmi differ diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen_full.dmi index e84b054695..e8602a41ce 100644 Binary files a/icons/mob/screen_full.dmi and b/icons/mob/screen_full.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 0f8d1d245b..ca0c0f9854 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/modular_components.dmi b/icons/obj/modular_components.dmi new file mode 100644 index 0000000000..3784d6992c Binary files /dev/null and b/icons/obj/modular_components.dmi differ diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi new file mode 100644 index 0000000000..e16c2c7be8 Binary files /dev/null and b/icons/obj/modular_console.dmi differ diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi new file mode 100644 index 0000000000..af1883055e Binary files /dev/null and b/icons/obj/modular_laptop.dmi differ diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi new file mode 100644 index 0000000000..5c86d27d89 Binary files /dev/null and b/icons/obj/modular_tablet.dmi differ diff --git a/icons/obj/modular_telescreen.dmi b/icons/obj/modular_telescreen.dmi new file mode 100644 index 0000000000..2b82cdb11f Binary files /dev/null and b/icons/obj/modular_telescreen.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 4910a853a6..218c3a48f3 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -2570,3 +2570,151 @@ window "infowindow" prefix-color = none suffix-color = none +window "text_editor" + elem "text_editor" + type = MAIN + pos = 281,0 + size = 360x488 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = none + is-visible = false + is-disabled = false + is-transparent = false + is-default = false + border = sunken + drop-zone = false + right-click = false + saved-params = "pos;size;is-minimized;is-maximized" + on-size = "" + title = "Text Editor" + titlebar = true + statusbar = true + can-close = true + can-minimize = false + can-resize = false + is-pane = false + is-minimized = false + is-maximized = false + can-scroll = none + icon = "" + image = "" + image-mode = stretch + keep-aspect = false + transparent-color = none + alpha = 255 + macro = "" + menu = "" + on-close = "" + elem "exit" + type = BUTTON + pos = 248,456 + size = 104x24 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = none + is-visible = true + is-disabled = false + is-transparent = false + is-default = false + border = none + drop-zone = false + right-click = false + saved-params = "is-checked" + on-size = "" + text = "Exit without saving" + image = "" + command = "" + is-flat = false + stretch = false + is-checked = false + group = "" + button-type = pushbutton + elem "save" + type = BUTTON + pos = 128,456 + size = 104x24 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = none + is-visible = true + is-disabled = false + is-transparent = false + is-default = false + border = none + drop-zone = false + right-click = false + saved-params = "is-checked" + on-size = "" + text = "Save" + image = "" + command = "" + is-flat = false + stretch = false + is-checked = false + group = "" + button-type = pushbutton + elem "saveexit" + type = BUTTON + pos = 8,456 + size = 104x24 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = none + is-visible = true + is-disabled = false + is-transparent = false + is-default = false + border = none + drop-zone = false + right-click = false + saved-params = "is-checked" + on-size = "" + text = "Save + Exit" + image = "" + command = "" + is-flat = false + stretch = false + is-checked = false + group = "" + button-type = pushbutton + elem "textedit" + type = INPUT + pos = 0,0 + size = 360x448 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = #ffffff + is-visible = true + is-disabled = false + is-transparent = false + is-default = false + border = line + drop-zone = false + right-click = false + saved-params = "" + on-size = "" + command = "" + multi-line = true + is-password = false + no-command = false diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm index 0234821509..6b474e5478 100644 --- a/maps/southern_cross/southern_cross-1.dmm +++ b/maps/southern_cross/southern_cross-1.dmm @@ -316646,7 +316646,7 @@ aaa "aEv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/firealarm{pixel_y = 24},/turf/simulated/floor/tiled/monotile,/area/hangar/two) "aEw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/tiled/monotile,/area/hangar/two) "aEx" = (/obj/machinery/space_heater,/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/turf/simulated/floor/tiled,/area/hangar/two) -"aEy" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_l"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) +"aEy" = (/obj/machinery/ntnet_relay,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) "aEz" = (/turf/simulated/shuttle/wall,/area/shuttle/large_escape_pod1/station) "aEA" = (/turf/simulated/shuttle/wall/no_join,/area/shuttle/large_escape_pod1/station) "aEB" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "large_escape_pod_1_hatch"; locked = 1; name = "Large Escape Pod Hatch 1"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/large_escape_pod1/station) @@ -316703,7 +316703,7 @@ aaa "aFA" = (/obj/effect/floor_decal/borderfloorblack/corner{dir = 8},/obj/effect/floor_decal/industrial/danger/corner{dir = 1},/turf/simulated/floor/tiled,/area/hangar/two) "aFB" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/monotile,/area/hangar/two) "aFC" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/space_heater,/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/turf/simulated/floor/tiled,/area/hangar/two) -"aFD" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) +"aFD" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_l"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) "aFE" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/floor/airless,/area/shuttle/large_escape_pod1/station) "aFF" = (/obj/machinery/atmospherics/unary/cryo_cell{layer = 3.3},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/large_escape_pod1/station) "aFG" = (/obj/structure/bed/roller,/obj/structure/closet/walllocker/emerglocker{pixel_x = 0; pixel_y = 32},/turf/simulated/shuttle/floor/white,/area/shuttle/large_escape_pod1/station) @@ -316751,8 +316751,8 @@ aaa "aGw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/monotile,/area/hangar/two) "aGx" = (/obj/effect/floor_decal/borderfloorblack{dir = 4},/obj/effect/floor_decal/industrial/danger{dir = 4},/turf/simulated/floor/tiled,/area/hangar/two) "aGy" = (/turf/simulated/floor/reinforced,/area/hangar/two) -"aGz" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) -"aGA" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) +"aGz" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) +"aGA" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) "aGB" = (/obj/effect/floor_decal/borderfloorblack{dir = 8},/obj/effect/floor_decal/industrial/danger{dir = 8},/turf/simulated/floor/tiled,/area/hangar/two) "aGC" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/obj/structure/closet/crate,/turf/simulated/floor/tiled,/area/hangar/two) "aGD" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor,/area/shuttle/large_escape_pod1/station) @@ -316828,7 +316828,7 @@ aaa "aHV" = (/obj/machinery/space_heater,/turf/simulated/shuttle/plating,/area/shuttle/shuttle2/start) "aHW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/monotile,/area/hangar/two) "aHX" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/ai_status_display{pixel_x = 32; pixel_y = 0},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/obj/structure/closet/emcloset,/turf/simulated/floor/tiled/steel,/area/hangar/two) -"aHY" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_r"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) +"aHY" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) "aHZ" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor/plating,/area/quartermaster/storage) "aIa" = (/obj/effect/floor_decal/industrial/loading{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/storage) "aIb" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/borderfloor/corner{dir = 4},/obj/effect/floor_decal/corner/brown/bordercorner{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/storage) @@ -317335,7 +317335,7 @@ aaa "aRI" = (/turf/simulated/floor/airless,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aRJ" = (/turf/simulated/shuttle/wall,/area/shuttle/escape_pod3/station) "aRK" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/shuttle/escape_pod3/station) -"aRL" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod3/station) +"aRL" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_r"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) "aRM" = (/turf/simulated/wall,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aRN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aRO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftport) @@ -317351,7 +317351,7 @@ aaa "aRY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) "aRZ" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning/corner,/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) "aSa" = (/turf/simulated/wall,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) -"aSb" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod5/station) +"aSb" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod3/station) "aSc" = (/turf/simulated/shuttle/wall,/area/shuttle/escape_pod5/station) "aSd" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/shuttle/escape_pod5/station) "aSe" = (/turf/simulated/floor/airless,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) @@ -317415,7 +317415,7 @@ aaa "aTk" = (/turf/space,/area/ninja_dojo/arrivals_dock) "aTl" = (/turf/simulated/shuttle/wall,/area/shuttle/escape_pod4/station) "aTm" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/shuttle/escape_pod4/station) -"aTn" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod4/station) +"aTn" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod5/station) "aTo" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/machinery/hologram/holopad,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aTp" = (/obj/machinery/camera/network/first_deck{c_tag = "First Deck - Aft Port Escape Pods"; dir = 8},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/red/border{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aTq" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/hallway/secondary/escape/firstdeck/ep_aftport) @@ -317431,7 +317431,7 @@ aaa "aTA" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) "aTB" = (/obj/machinery/camera/network/first_deck{c_tag = "First Deck - Aft Starboard Escape Pods"; dir = 4},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/red/border{dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) "aTC" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner,/obj/machinery/hologram/holopad,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftstarboard) -"aTD" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod6/station) +"aTD" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod4/station) "aTE" = (/turf/simulated/shuttle/wall,/area/shuttle/escape_pod6/station) "aTF" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/shuttle/escape_pod6/station) "aTG" = (/obj/structure/grille,/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating,/area/shuttle/escape_pod4/station) @@ -323833,7 +323833,7 @@ aaa "dmG" = (/turf/simulated/wall/r_wall,/area/maintenance/locker) "dmH" = (/turf/simulated/shuttle/wall,/area/shuttle/cryo/station) "dmI" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/shuttle/cryo/station) -"dmJ" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) +"dmJ" = (/turf/simulated/shuttle/wall,/obj/structure/shuttle/engine/propulsion/burst{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape_pod6/station) "dmK" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/docking_hallway2) "dmL" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/docking_hallway2) "dmM" = (/obj/structure/closet/emcloset,/turf/simulated/floor/tiled/dark,/area/hallway/secondary/docking_hallway2) @@ -324384,7 +324384,7 @@ aaa "dxl" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "escape_dock_north_starboard_airlock"; name = "interior access button"; pixel_x = -26; pixel_y = 26; req_one_access = list(13)},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) "dxm" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "arrivals_dock_north_airlock"; name = "interior access button"; pixel_x = 26; pixel_y = 26; req_one_access = list(13)},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) "dxn" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1380; icon_state = "door_locked"; id_tag = "arrivals_dock_north_inner"; locked = 1; name = "Arrivals Airlock"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D2/arrivals) -"dxo" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) +"dxo" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) "dxp" = (/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{frequency = 1380; id_tag = "arrivals_dock_north_airlock"; master_tag = "arrivals_dock"; pixel_y = 30; req_one_access = list(13); tag_airlock_mech_sensor = "arrivals_dock_north_mech"; tag_airpump = "arrivals_dock_north_pump"; tag_chamber_sensor = "arrivals_dock_north_sensor"; tag_exterior_door = "arrivals_dock_north_outer"; tag_interior_door = "arrivals_dock_north_inner"; tag_shuttle_mech_sensor = "shuttle_dock_north_mech"},/obj/effect/floor_decal/industrial/loading{icon_state = "loadingarea"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2/arrivals) "dxq" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "arrivals_dock_north_pump"},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2/arrivals) "dxr" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/shield_diffuser,/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "dock3_north_outer"; locked = 1; name = "External Airlock Access"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) @@ -325976,6 +325976,7 @@ aaa "ebR" = (/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/machinery/ai_status_display{pixel_y = -32},/obj/effect/floor_decal/borderfloorwhite,/obj/effect/floor_decal/corner/purple/border,/obj/structure/closet{name = "welding equipment"},/turf/simulated/floor/tiled/white,/area/assembly/robotics) "ebS" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/effect/floor_decal/borderfloorwhite{dir = 1},/obj/effect/floor_decal/corner/purple/border{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/rnd/research) "ebT" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/borderfloorwhite/corner{dir = 1},/obj/effect/floor_decal/corner/purple/bordercorner{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/disposalpipe/junction,/turf/simulated/floor/tiled/white,/area/rnd/research) +"ebU" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) "ebV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/rnd/research) "ebW" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/tiled/white,/area/rnd/research) "ebX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/tiled/white,/area/rnd/research) @@ -326135,7 +326136,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsammamnamoamoamoamoamoamoamoampamaambaeFamqajEafEafFamramsafFafFafFafFafFamramsafFafKajEamtaeFamudWWadLaaaaaaaaaajoajoamvalFakoamwamxalHalHalHamyamzamAamBamCamDamEamBamFamGamHamIamJalIamKamLakIalKamMajwajwaaaaaaaaaaejaiyamNaeZamOamkaiAagmagmagmagmagmagmagmagmagmagmagmagVakfamPaeZdWXdWZdWYdXbdXadXddXcdXbdXbdXfdXedXhdXgdXjdXidXkdXbdXmdXldXnaSNdXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsaltalRamRamSamTamoamUamVamWamXamaambaeFamYamZanaanbanbanbanbanbanbanbanbanbanbanbancandaneaeFanfaioadLaaaaaaaaaajoanganhalFalGanianianialHalHanjanjanjanjanjankanlanmanmannanoanpanqalIalIalIalJalKanransajwaaaaaaaaaaejaiyantaeZanuanvanwanxanxanxanxanxanxanxanxanxanxanxanyanzanAaeZdXpdXrdXqdXqdXsdXudXtdXwdXvdXxdXvdXzdXydXBdXAdXDdXCdXFdXEdXHdXGdXodXIdXKdXJdXMdXLdXKdXNdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsalsaltaltaltaluanDanDalualtaltaltanEaeFanFanGanHanHanIanHanHanJanKanLanManNanNanNanNanOamtaeFanPaioadladlaaaaaaajpanQanRanSanianianTanUanialHanVanWanXanYanZanZaoaaobaocaodaoealIaofalIaogalIalIaohaoiaojajxaaaaaaadFadFaiyaokaeZaolaomaonaonaonaonaooaopaoqaoraosaosaotaosaosaouaovaeZdXOdXQdXPdXRapiatLdXSapidXUdXWdXVdXXaSNaSNdXYaSNaZYdXZcfodXHdYadXodYbdYcdXJdXMdXLdXKdYddXodXodYfdYedXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaakLatTatTakLakLakLakLaoxaoxaoyaoyaoyaoyaoyaeFaeFaeFaeFaeFaeFaeFaeFaozahcaoAaeFaoBaoBaoBaeFaeFaeFaeFafMaoCaoDadlaaaaaaajpaoEaoFaoGaoHaoIaoJaoKanialHanjaoLaoMaoNanZanZaoOaoPaoQaoRaoSaoTaoUaoVaoWaoXalIaoYaoZapaajxaaaaaaadFapbapcapdaeZaeZaeZaikapeapeapeaikapfaikapgaikaeZaeZaeZaeZaeZaeZaeZaphaphaphaphaphdYgdYgalralralralralralrdYidYhalralrdXZdYjdYkdWHdXodYldXKdXJdXMdXLdXKdYldXodYmdYodYndXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaakLatTatTakLakLakLakLaoxaoxaoyaoyaoyaoyaoyaeFaeFaeFaeFaeFaeFaeFaeFaozahcaoAaeFaoBaoBaoBaeFaeFaeFaeFafMaoCaoDadlaaaaaaajpaoEaoFaoGaoHaoIaoJaoKanialHanjaoLaoMaoNaEyanZaoOaoPaoQaoRaoSaoTaoUaoVaoWaoXalIaoYaoZapaajxaaaaaaadFapbapcapdaeZaeZaeZaikapeapeapeaikapfaikapgaikaeZaeZaeZaeZaeZaeZaeZaphaphaphaphaphdYgdYgalralralralralralrdYidYhalralrdXZdYjdYkdWHdXodYldXKdXJdXMdXLdXKdYldXodYmdYodYndXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafakLakLapjapkaplapmapnakLapoapoappapqaprapsaptapuapvapwapxapyapyapzapuapAapAapBapCapDapEapFapCapGafMadlapHapIapJadlaaaaaaajpapKapLapManiapNapOapNanialHanjanjanjanjanjapPapQapQapQapRapSapTapUapVapWapXalIapYapZaqaajxaaaaaaadFaqbaghaqcaqdaqeaqfaqgaqhaqiaqjaqgaqkaqlaqlaqmaqnaqoaqoaqpaqqaqraqmaqsaqtaquaqvaqwaqxaqxalraqydYpaqAaqBaqCalOdYqatMalrdYtdYsdXodXodXodYudYwdYvdYydYxdYAdYzdXodYBdYDdYCdYFdYEdYGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaakLakLaqDaqDapkaqEaqFaqFaqGaqHaqIaqJaqKaqLaqMaqNapuapvaqOaqPapyapyapyapuaqQaqQaqRaqSaqTaqUaqVapCaqWaqXaqYaqZaraarbadlaaaaaaajoarcardareaniarfargarfanialHarhariarjarkarlarmarnarkaroarparqarrarsartaruarvalIarwapZarxajwaaaaaaadFaryaghaghaghaghagharzarAarBarCarDarEarFarFaqmarGarHaqoarIaqqaqqaqmarJarKarLdYHarNarOarPdYIarRarRarRarRarRarRalOalralrdYKdYJdXodYLdYNdYMaShdYOdYRdYQaShdYSdYUdYTdYWdYVdXodXodXodXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaakLarSapkakLakLakLakLakLakLarTarUarUarUarVarWarXapuarYapyaqParZasaasbapuascasdaseapCasfasgashapCasiasjaskaslasmasnadlasoasoaspasqasrajSamxarfargarfanialHalHalHalHalHalHalHalHalHalHalHalIalIalIamHassastalIasuasvaswasxasyasyadFaszaghasAasAasAasAaqgasBasCasDaqgasEasFasGaqmasHasIasJarIasKaqqaqmasLasMasNasOasOasOaphalralralralralralralOalPalrdYXdYYdXHdZadYZdZcdZbdZedZddZfdZddZgdZddZhdZddZjdZidZldZkdZndZmdXoaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -326148,11 +326149,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaakLakLapkapkapkapkaqDaqDaqDaqDaqDazVazWazWazXaxVayQayRayRazYayRayRayVaxVazZaAaaAaaAbazbazbaAcaAcaAcaAcaAcaAcaAcaAdaybaaaaaaaAeaAfaAgaAhauAazrazqaAjaAiauAaAnaAoaApaAkaAraAsaAtaAuaAvaAwaAxaAyaAzaAAaABaACaAzaADaAEaAFaAGaaaaaaayxaAHazBaAIaAIaAIaAIaAJaAKaALaAMaANaAOaAPaAPayDaAQaARaASazNaATaAUayDaAVaAWaAXaAYaAZaBaaBbeaKaBdaBdaBearRarRarRalralrdXodXodXodXoeaLeaNeaMeaPeaOeaReaQeaPeaSeaTdYTdYTeaUdXodXodXodXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaafaafakLakLaBfaBfaBgaBhaBiaBjaBkaBlaxTaBmaBmaBmaxVayQaBnayRaBoayRaBpaBqaxVaBraBsaBsaBtaBtaBtaBtaBtaBtaBtaBtaBuaBvaBwaybaaaaaaaBxaByaBzaBAaBDaAqaAmaBCaBBaBGaBHaBIaBJaBJaBKaBJaBEaBFaAvaBNaBOaBPaBQaBRaBSaBTaAzaBUaBVaBWaBXaaaaaaayxaBYazBaAIaBZaCaaCaayyaCbaCcaCdayyaqkaqlaqlayDaCeaCfayDaCgaARaChayDaCiaCjaCkaClaCmaCnaCnalraCoalOaCpaCqaCralralraafaaaaaaaaadXodXodXoeaVeaXeaWdYyeaYebaeaZdXodZbdZbdZbebbdXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaakLakLaBfaCsaCsaCsaCsaCtaCtaCsaCsaCuaCsaCsaCsaCsaCsaCsaCsaCsaCsaCvaCwaCxaCyaBtaCzaCAaCBaCCaCDaCEaBtaybaCFaCGaybaaaaaaaBxaCHaCIaCJauAaBLaBMaCZaCKaCLaCPaCQaCRaCSaCTaCUaCVaCWaAvaCXaCYaDbaDadVsaDcaDdaAzaDeaDfaDgaBXaaaaaaayxaDhaDiaAIaDjaDjaDjaDkaDlaDlaDlaDkaDmaDkaDnaDkaDjaDjaDjaDjaDjaDjaDjazUazUazUazUazUaDoaDoalralralralravpavpalraaaaaaaaaaaaaaaaaaaaadXodYldXKdXKdYydXKdXKdYldXoebcebeebddXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaDpaDqaDraDsaDtaDuaDvaDwaDxaDtaDyaDzaDAaDBaDCaDDaDEaDFaDGaDHaDIaDJaDKaDLaDMaDMaDMaDNaBtaDOaDPaybaybaaaaaaaBxaDQaCMaDSaCNaCNaykaykaykaykaDUaDVaDWaDXaDYaDZaEaaEbaEcaEdaEeaEfaAzaEgaEhaAzaAzaEiaEjaEkaBXaaaaaaayxayxaElaEmaDjaEnaEoaEpaEpaEpaEpaEqaEraEsaEtaEuaEuaEvaEuaEuaEwaExaDjaEyaEzaEzaEzaEAaEBaEBaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaadXodYbdZBdXKdYydXKdXKdYddXodXodYfdYedXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaEFaEGaEHaEHaEIaEJaEJaEKaELaEMaENaENaEOaEPaEQaERaESaETaEUaEVaEWaEXaEYaEZaDMaDMaFaaFbaDOaDPaFcaaaaaaaaaaAeaFdaFeaFfaFgauHauHaFhaFhaDTaFiaFjaCUaCUaCUaFkaCVaFlaFmaFnaFoaFpaAzaAzaAzaAzaFqaFraFsaFtaAGaaaaaaaaaaFuaElaFvaDjaFwaFxaFyaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFAaFBaFCaDjaFDaFEaFFaFGaFHaFIaFJaFKaFLaFMaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaadXoebfdXKdXKdYydXKdXKebgdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFPaFQaFQaFQaFQaFQaFPaFRaFSaEPaEPaFTaEPaEPaFUaFVaFWaFXaFYaFZaGaaDMaGbaGcaGdaGeaBtaDOaDPaFcaaaaaaaaaaAeaAeaGfaFfaFfaGgaDTauHaFhaDTaGhaGiaGjaGkaCUaGlaGmaGnaAvaGoaGpaGpaGqaAzaGraGsaGtaFraGuaAGaAGaaaaaaaaaaFuaElaGvaDjaEnaGwaGxaGyaGzaGAaGyaGyaGyaGyaGyaGzaGAaGyaGBaGwaGCaDjaFDaFEaGDaFJaFJaFJaFJaFJaFJaFJaGEaGFaEDaaaaaaaaaaaaaaaaaaaaaaaadXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFQaFQaFQaFQaFQaFQaFQaFRaGGaEPaEPaFTaEPaEPaGHaCxaGIaGJaGKaGLaGMaGNaGOaGPaGQaGRaBtaybaGSaFcaaaaaaaaaaaaaBxaFfaFfaFfaFfaGTauHauHauHaGUauHaGVaGWaGXaCUaGYaGZaHaaHbaHcaHdaAvaAvaHeaHfaHgaHhaGtaBXaaaaaaaaaaaaaFuaElaHiaDjaHjaGwaGxaGyaHkaHkaHlaGyaGyaGyaHlaHkaHkaGyaGBaGwaHmaDjaFDaFEaHnaHoaHpaHqaHraHsaHtaHuaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaHvaFOaFQaFQaFQaFQaFQaFQaFQaHwaHxaHxaHxaFTaEPaEPaHyaCxaHzaHAaHBaEWaEWaGLaHCaEWaEWaEWaEWaHDazhaybaybaaaaaaaaaaBxaBxaFfaFfaFfaFfaFgaHEaHFaHFaHFaHGaHHaHIaHJaHKaHLaAvaAvaAvaAvaAvaFqaGtaFraGtaGtaBXaBXaaaaaaaaaayxayxaElaDkaDjaHMaHNaGxaGyaHOaHPaHQaHRaHSaHTaHUaHVaHOaGyaGBaHWaHXaDjaHYaEzaEzaEzaEAaEzaEzaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaDpaDqaDraDsaDtaDuaDvaDwaDxaDtaDyaDzaDAaDBaDCaDDaDEaDFaDGaDHaDIaDJaDKaDLaDMaDMaDMaDNaBtaDOaDPaybaybaaaaaaaBxaDQaCMaDSaCNaCNaykaykaykaykaDUaDVaDWaDXaDYaDZaEaaEbaEcaEdaEeaEfaAzaEgaEhaAzaAzaEiaEjaEkaBXaaaaaaayxayxaElaEmaDjaEnaEoaEpaEpaEpaEpaEqaEraEsaEtaEuaEuaEvaEuaEuaEwaExaDjaFDaEzaEzaEzaEAaEBaEBaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaadXodYbdZBdXKdYydXKdXKdYddXodXodYfdYedXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaEFaEGaEHaEHaEIaEJaEJaEKaELaEMaENaENaEOaEPaEQaERaESaETaEUaEVaEWaEXaEYaEZaDMaDMaFaaFbaDOaDPaFcaaaaaaaaaaAeaFdaFeaFfaFgauHauHaFhaFhaDTaFiaFjaCUaCUaCUaFkaCVaFlaFmaFnaFoaFpaAzaAzaAzaAzaFqaFraFsaFtaAGaaaaaaaaaaFuaElaFvaDjaFwaFxaFyaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFAaFBaFCaDjaGzaFEaFFaFGaFHaFIaFJaFKaFLaFMaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaadXoebfdXKdXKdYydXKdXKebgdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFPaFQaFQaFQaFQaFQaFPaFRaFSaEPaEPaFTaEPaEPaFUaFVaFWaFXaFYaFZaGaaDMaGbaGcaGdaGeaBtaDOaDPaFcaaaaaaaaaaAeaAeaGfaFfaFfaGgaDTauHaFhaDTaGhaGiaGjaGkaCUaGlaGmaGnaAvaGoaGpaGpaGqaAzaGraGsaGtaFraGuaAGaAGaaaaaaaaaaFuaElaGvaDjaEnaGwaGxaGyaGAaHYaGyaGyaGyaGyaGyaGAaHYaGyaGBaGwaGCaDjaGzaFEaGDaFJaFJaFJaFJaFJaFJaFJaGEaGFaEDaaaaaaaaaaaaaaaaaaaaaaaadXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFQaFQaFQaFQaFQaFQaFQaFRaGGaEPaEPaFTaEPaEPaGHaCxaGIaGJaGKaGLaGMaGNaGOaGPaGQaGRaBtaybaGSaFcaaaaaaaaaaaaaBxaFfaFfaFfaFfaGTauHauHauHaGUauHaGVaGWaGXaCUaGYaGZaHaaHbaHcaHdaAvaAvaHeaHfaHgaHhaGtaBXaaaaaaaaaaaaaFuaElaHiaDjaHjaGwaGxaGyaHkaHkaHlaGyaGyaGyaHlaHkaHkaGyaGBaGwaHmaDjaGzaFEaHnaHoaHpaHqaHraHsaHtaHuaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaHvaFOaFQaFQaFQaFQaFQaFQaFQaHwaHxaHxaHxaFTaEPaEPaHyaCxaHzaHAaHBaEWaEWaGLaHCaEWaEWaEWaEWaHDazhaybaybaaaaaaaaaaBxaBxaFfaFfaFfaFfaFgaHEaHFaHFaHFaHGaHHaHIaHJaHKaHLaAvaAvaAvaAvaAvaFqaGtaFraGtaGtaBXaBXaaaaaaaaaayxayxaElaDkaDjaHMaHNaGxaGyaHOaHPaHQaHRaHSaHTaHUaHVaHOaGyaGBaHWaHXaDjaRLaEzaEzaEzaEAaEzaEzaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLakLaCsaEEaFOaFQaFQaFQaFQaFQaFQaFQaHZaHZaHZaIaaFTaEPaEPaIbaESaIcaHAaIdaIeaIfaDHaIgaESaDOaIhaIiaAcazhaIjaybaaaaaaaaaaaaaBxaBxaFfaFfaFfaFfaIkaIlaImaInazlaIoaIpaIqaIraIsaItaIuaIvaIwaIxaHgaHgaHhaGtaBXaBXaaaaaaaaaaaaayxaIyaElaDjaDjaDjaIzaGxaGyaIAaIBaICaIDaIEaIEaIFaIEaHOaGyaGBaIGaDjaDjalralralralralralralralralralralralralraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCOaEEaFOaFQaFQaFQaFQaFQaFQaFQaIHaIIaIJaIIaIKaENaENaILaIMaINaIOaIPaIQaIRaIQaISaITaDOaIhaAcaAcaIUaIVaybaaaaaaaaaaaaaaaaBxaBxaFfaIWaIXaIYaIZaJaaJbaJcaJdaJeaJfaJgaJhaJiaJjaJkaJlaJmaJnaJoaGtaBXaBXaaaaaaaaaaaaaaaayxaJpaJqaDkaDjaJraGwaGxaGyaJsaJtaJuaJvaJwaJwaJwaJwaJxaGyaGBaGwaJyaDjaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaDRaJzaFOaFQaFQaFQaFQaFQaFQaFQaFRaEPaEPaJAaFTaJBaJCaJDaJEaJFaJGaJHaJIaJJaJKaJLaESaDOaJMaJNaAcazhaJOaybaaaaaaaaaaabaaaaaaaBxaBxaAeaJPaJQaJRaJSaInazlaIoaJTaJUaJVaJWaJXaJYaJZaKaaKbaKcaAGaBXaBXaaaaaaaabaaaaaaaaaayxaKdaElaKeaDjaJraGwaGxaGyaHOaKfaKgaKhaJwaKiaKjaKkaKlaGyaGBaGwaJyaDjaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaKmaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -326170,13 +326171,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaFcaQzaQAaQBaQCaQDaQDaQEaQFaQGaQHaQDaQIaQDaQJaQKaQLaQMaQNaQKaQOaQPaQQaQRaQSaQKaQTaQUaQVaQVaQWaQXaQYaQZaFuaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaagaadaadabcaagaagaadaadaafaagaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaabaaaaaaaaaaMfazgazgaybaRaaRbaRbaRcaRdaReaRfaRgaRhaRbaRiaRjaRkaRlaRmaRjaRnaRjaRoaRpaRqaRraRsaRtaRjaRjaRuayxazBazBaPIaaaaaaaaaaabaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaafaadaadaadaafaaeaagaadaadaadaafaaaaafaagaadaadaadaadaafaaeaaaaMfaMfaMfaMfaLOaLOaLOaRvaRwaRxaRyaRzaRAaRzaRzaRBaKvaRCaKwaKxaRDaRDaRDaRDaREaRFaRGaRHaLOaLOaLOaPIaPIaPIaPIaafaafaadaadaadaadaKmaaaaadaafaadaadaadaadaadaadaadaaaaaeaKmaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaRIaRJaRJaRKaRJaRLaRMaRNaROaRMaRPaRQaRRaRzaRSaRTaRCaRUaRSaRDaRVaRWaRWaREaRYaRZaSaaSbaScaSdaScaScaSeaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaRIaRJaRJaRKaRJaSbaRMaRNaROaRMaRPaRQaRRaRzaRSaRTaRCaRUaRSaRDaRVaRWaRWaREaRYaRZaSaaTnaScaSdaScaScaSeaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaaaaaaaaaaSfaaaaaaaaaaaaaaaaSfaaaaaaaaaaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaSgbEoaSiaSjaSkaSlaSmaSnaRMaSoaSpaSqaSraRSaSsaStaKTaKRaRDaSuaRVaSvaSwaSxaSydgEaSAaSBaSCaSDaSEaSeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaRJaRJaRKaRJaRLaRMaSFaSGaRyaRzaRzaRzaRzaRSaSHaSIaSJaSKaSLaSMebkaSOaREaSPaSQaSaaSbaScaSdaScaScaSeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaRJaRJaRKaRJaSbaRMaSFaSGaRyaRzaRzaRzaRzaRSaSHaSIaSJaSKaSLaSMebkaSOaREaSPaSQaSaaTnaScaSdaScaScaSeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSRaRyaRyaRyaRyaRyaRyaSSaSTaRyaSUaSVaSWaSXaSYaSZaTaaTbaTcaTdaTeaTfaTgaREaThaTiaREaREaREaREaREaREaTjaaaaaaaaaaTkaaaaaaaaaaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaTlaTlaTmaTlaTnaRMaToaTpaTqaTraTbaTbaTbaTsaTbaTtaTuaTvaTwaTxaTyaTzaTAaTBaTCaSaaTDaTEaTFaTEaTEaSeaaaaaaaaaaTkaaaaaaaaaaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaTlaTlaTmaTlaTDaRMaToaTpaTqaTraTbaTbaTbaTsaTbaTtaTuaTvaTwaTxaTyaTzaTAaTBaTCaSadmJaTEaTFaTEaTEaSeaaaaaaaaaaTkaaaaaaaaaaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaTGaTHaTIaTJaTKaTLaTMaTNaRyaTOaTPaTQaTRaRnaTSaTTaTUaTcaTdaTVaTWaTXaREaTYaTZaUaaUbaUcaUdaUeaUfaSeaaaaaaaaaaTkaaaaaaaaaaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaTlaTlaTmaTlaTnaRMaUgaUhaRydnCaKRaUjaUkaUlaUmaUnaUmaUoaUkaUpaUqaUraREaUsaUtaSaaTDaTEaTFaTEaTEaSeaaaaaaaaaaTkaTkaTkaTkaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRIaTlaTlaTmaTlaTDaRMaUgaUhaRydnCaKRaUjaUkaUlaUmaUnaUmaUoaUkaUpaUqaUraREaUsaUtaSadmJaTEaTFaTEaTEaSeaaaaaaaaaaTkaTkaTkaTkaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUuaUvaUvaUvaUvaUvaRyaUwaUwaRMaUxaUkaUkaUkaUyaUzaUAaUzaUBaUkaUCaUCaUCaREaUDaUEaREaUvaUvaUvaUvaUvaUuaaaaTkaTkaTkaTkaTkaTkaTkaTkaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUFaUGaUHaUFaUIaUJaUKaULaUMaUNaUOaUPaUQaURaUSaUTaUUaUVaUWaUXaUYaULaUYaUZaUMaVaaVbaVcaVdaUFaVeaVfaUFaTkaTkaTkaTkaTkaTkaTkaTkaTkaTkaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaSfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVgaVhaViaVjaVkaVlaVmaVnaVoaVpaVqaVraVraVraVraVsaVtaVuaVraVraVraVraVvaVwaVxaVyaVmaVlaVzaVAaVBaVCaVDaTkaTkaTkaTkaTkaTkaTkaTkaTkaTkaTkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -326449,14 +326450,14 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrdkTdkUdiMdkVdkWdkXdjsdkYdjsdjsdkZdjsdkvdladlbdlzdlddkxdledlfdlgdiMdlhcUKdlidixdhudhudixdljdlkdixdlldhudixdixdlmdixdlndixdlodlpdlqdhxdlrdlsdixdjAdjAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrcAYdltdiMdludjsdlvdjsdkYdlwdlxdlydmpdlAdlBdlCdlDdlDdlEdlFdlGdlHdiMdfkdlIdlJdlKdlLdlMdlNdlOdlPdlQdlRddzdlSdixdlTdlUdlVdixdlWdlWdlXdlYdlZdmadmbdmcdmdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrcUrcUrcUrcUrcUrcUrdmediMdiMdmfdmgdmhdkYdmidlxdmjdmpdmkdmldmjdmmdmndkxdmodYrdmqdiMdmrdmsdmtdmudmvdmwdmxdmydmzdmAdmBdmCdmDdixdixdixdixdixdixdixdixdixdmEdmFdmFdmFdmGdmGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdmJdmKdmLdmMdiMdmNdmOdmOdmPdmQdiMdiMdiMdiMdiMdiMdiMdiMdiMdiMdiMdiMdmRdmSdcLdmTdmUdmUdmUdmUdmUdmUdmUdmUdmUdmUdmUdmVdmWdmVdmXdmYdmZdnadmVdnbdncdmFdnddnednfaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdxodmKdmLdmMdiMdmNdmOdmOdmPdmQdiMdiMdiMdiMdiMdiMdiMdiMdiMdiMdiMdiMdmRdmSdcLdmTdmUdmUdmUdmUdmUdmUdmUdmUdmUdmUdmUdmVdmWdmVdmXdmYdmZdnadmVdnbdncdmFdnddnednfaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdrgdrgdrgdnidnidmKdnjdnkdnkdnldnkdnmdnndnodnpdnqdnrdnsdntdnudnvdnwdnxdnydnzdnAdnBdfkcUKdVAdmUdnDdnEdnFdnGdnHdnIdmUdnJdnKdmUdmXdmXdmXdmXdmXdmXdmXdmXdnLdnMdnNdnMdnOdnfaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmIdnPdnQdnRdnRdnSdmIdnTdnUdnVdnWdnXdnYdnZdoadobdocdoddoedofdogdohdoidojdokdoldomdomdomdondoodopdmUdmUdmUdoqdordosdotdoudovdowdmUdoxdoydozdoAdoBdoCdoDdmXdnbdnMdmFdoEdoFdnfaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdoGdoHdoHdoIdoJdoKdoLdoMdoNdoOdoPdoQdoRdoPdoPdoOdoSdoTdoUdoVdoWdoXdoYdoZdpadpbdoYdfkdpcdpddmUdpedpfdpgdphdpidpjdmUdpkdnKdmUdpldpmdpndpodppdpqdprdmXdnbdpsdmFdmFdmGdmGaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdptdoHdoHdoIdoJdoKdoLdpudpvdoOdpwdpxdpydpzdpAdoOdpBdpBdpCdpBdpDdpEdpFdpGdpFdpHdpIdpJdpcdpKdmUdmUdmUdmUdpLdmUdmUdmUdmUdmUdmUdpMdpmdpndpNdpOdpmdpPdmXdpQdnMdVtdpRdmGaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmIdpSdpTdpUdpUdnSdmIdmKdpVdpudpWdoPdpXdpYdpZdpXdpXdqadqbdqcdqddqcdqedpEdqfdqgdqhdpFdqidfkdpcdqjdqkdqldqmdqndqodqpdqqdqrdqsdqtdqudqvdqvdqvdqwdqxdqxdqydqzdqAdqBecBdqCdnfaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdqDdqDdqDdnidnidmKdqEdpudqFdoPdqGdqHdqIdqJdqKdoOdqLdqMdqNdqcdqOdpEdqPdqQdqRdpFdqidfkdqSdqjdqkdqldqTdqUdqUdqVdqWdqUdqXdqUdqYdqZdradrbdqYdqUdrcdqUdmXdrddrednMdrfdnfaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdxodmKdrhdridrjdoOdrkdrldrmdrndrodoOdrpdrqdrrdqcdrsdpEdrtdrudrvdrwdrxdfkdrydrzdrAdrBdrCdrDdrEdqUdqWdrFdrGdrGdrHdrGdrIdrIdrJdrIdrIdmXdmXdrKdrLdnMdrMdnfaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHebUdmKdrhdridrjdoOdrkdrldrmdrndrodoOdrpdrqdrrdqcdrsdpEdrtdrudrvdrwdrxdfkdrydrzdrAdrBdrCdrDdrEdqUdqWdrFdrGdrGdrHdrGdrIdrIdrJdrIdrIdmXdmXdrKdrLdnMdrMdnfaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmKdmKdmKdmKdmKdmKdmKdrNdrOdpWdoPdrPdrQdrRdrSdrTdoOdrUdqcdrVdrWdrXdpEdrYdrZdsadpFdqidfkcUKdsbdscdsddqTdsedsfdqUdqWdsgdrGdshdsidsjdrIdskdsldsmdrIdsndmXdsodspdmGdmGdmGaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmKdsqdsrdqFdoPdssdpxdssdstdsudoOdsvdqcdswdqcdsxdpEdsydszdsAdpFdsBdsCcTAdsDdscdsEdsFdsGdsHdqUdsIdsJdrGdsKdsLdsMdrIdsNdsOdsPdrIdsQdmXdsRdsSdmGaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsTdsTdsTdsTdsTaaaaaaaaaaaaaaaaaadmKdsUdsVdoXdoOdsWdsXdsYdssdsZdtadtbdtcdtddtcdtedpEdpEdpEdpEdtfdtgdthdtidtjdtgdtkdtldtmdsHdtndqUdsJdrGdtodtpdtqdrIdtrdtsdttdrIdsndmXdtudtvdmGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/southern_cross/southern_cross-6.dmm b/maps/southern_cross/southern_cross-6.dmm index da134489ba..ea991b7090 100644 --- a/maps/southern_cross/southern_cross-6.dmm +++ b/maps/southern_cross/southern_cross-6.dmm @@ -1,3 +1,4 @@ +<<<<<<< HEAD "aa" = (/turf/space,/area/space) "ab" = (/turf/unsimulated/wall,/area/space) "ac" = (/obj/structure/window/reinforced,/turf/unsimulated/wall,/area/space) @@ -2499,3 +2500,2505 @@ aaaaRfababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} +======= +"aa" = (/turf/space,/area/space) +"ab" = (/turf/unsimulated/wall,/area/space) +"ac" = (/obj/structure/window/reinforced,/turf/unsimulated/wall,/area/space) +"ad" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/wall,/area/space) +"ae" = (/turf/simulated/floor/holofloor/desert,/area/holodeck/source_desert) +"af" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_desert) +"ag" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/wall,/area/space) +"ah" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"ai" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aj" = (/obj/structure/table/rack/holorack,/obj/item/clothing/under/dress/dress_saloon,/obj/item/clothing/head/pin/flower,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_theatre) +"ak" = (/obj/effect/landmark/costume,/obj/structure/table/rack/holorack,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_theatre) +"al" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"am" = (/obj/structure/flora/pottedplant{icon_state = "plant-10"},/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) +"an" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) +"ao" = (/turf/simulated/floor/holofloor/reinforced,/area/holodeck/source_wildlife) +"ap" = (/turf/simulated/floor/holofloor/reinforced,/area/holodeck/source_plating) +"aq" = (/obj/effect/floor_decal/corner/red/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"ar" = (/obj/effect/floor_decal/corner/red{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"as" = (/obj/effect/floor_decal/corner/red/full{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"at" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"au" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"av" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_emptycourt) +"aw" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/wall,/area/space) +"ax" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_desert) +"ay" = (/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"az" = (/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aA" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_theatre) +"aB" = (/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"aC" = (/obj/machinery/door/window/holowindoor{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) +"aD" = (/obj/effect/landmark{name = "Holocarp Spawn"},/turf/simulated/floor/holofloor/reinforced,/area/holodeck/source_wildlife) +"aE" = (/obj/effect/floor_decal/corner/red{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"aF" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"aG" = (/obj/effect/floor_decal/corner/red{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"aH" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood/corner,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aI" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aJ" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aK" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood/corner{dir = 8},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aL" = (/obj/machinery/door/window/holowindoor{dir = 1; name = "Jury Box"},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"aM" = (/obj/structure/window/reinforced/holowindow{dir = 1},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"aN" = (/obj/structure/window/reinforced/holowindow{dir = 4},/obj/structure/window/reinforced/holowindow{dir = 1},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"aO" = (/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"aP" = (/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) +"aQ" = (/obj/machinery/door/window/holowindoor{dir = 8; name = "Red Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_emptycourt) +"aR" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 4},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aS" = (/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) +"aT" = (/obj/effect/decal/cleanable/dirt,/obj/structure/holostool,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) +"aU" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) +"aV" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aW" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 6},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"aX" = (/obj/effect/decal/cleanable/dirt,/obj/effect/floor_decal/spline/fancy/wood{dir = 1},/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) +"aY" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_theatre) +"aZ" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"ba" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet/corners{dir = 5},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bb" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/obj/structure/bed/chair/holochair{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bc" = (/obj/structure/window/reinforced/holowindow{dir = 4},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"bd" = (/obj/structure/window/reinforced/holowindow,/obj/machinery/door/window/holowindoor{dir = 1; name = "Court Reporter's Box"},/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"be" = (/obj/structure/table/woodentable/holotable,/obj/structure/window/reinforced/holowindow,/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"bf" = (/obj/structure/table/woodentable/holotable,/obj/structure/window/reinforced/holowindow,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"bg" = (/obj/structure/table/woodentable/holotable,/obj/structure/window/reinforced/holowindow,/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"bh" = (/obj/structure/window/reinforced/holowindow,/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 1; icon_state = "right"; name = "Witness Box"},/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) +"bi" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 4},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bj" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) +"bk" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_theatre) +"bl" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bm" = (/obj/effect/floor_decal/carpet{dir = 1},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bn" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bo" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bp" = (/obj/effect/floor_decal/carpet{dir = 8},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bq" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/structure/bed/chair/holochair{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"br" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bs" = (/obj/effect/floor_decal/carpet{dir = 1},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bt" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bu" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 8},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bv" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bw" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bx" = (/obj/structure/table/woodentable/holotable,/obj/effect/floor_decal/carpet{dir = 8},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"by" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bz" = (/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bA" = (/obj/structure/table/woodentable/holotable,/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bB" = (/obj/effect/floor_decal/corner/green{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"bC" = (/obj/effect/floor_decal/corner/green{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"bD" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bE" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 5},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bF" = (/obj/effect/decal/cleanable/dirt,/obj/effect/floor_decal/spline/fancy/wood,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) +"bG" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bH" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bI" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bJ" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood/corner{dir = 1},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bK" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 1},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bL" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 1},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bM" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood/corner{dir = 4},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bN" = (/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bO" = (/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 8; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_emptycourt) +"bP" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bQ" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bR" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bS" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bT" = (/obj/structure/flora/pottedplant{icon_state = "plant-06"},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_theatre) +"bU" = (/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 6},/obj/effect/floor_decal/carpet{dir = 10},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) +"bV" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bW" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/obj/structure/bed/chair/holochair{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bX" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bY" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"bZ" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) +"ca" = (/obj/effect/floor_decal/corner/green/full,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"cb" = (/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"cc" = (/obj/effect/floor_decal/corner/green/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) +"cd" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/wall,/area/space) +"ce" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/wall,/area/space) +"cf" = (/turf/simulated/floor/holofloor/space,/area/holodeck/source_space) +"cg" = (/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) +"ch" = (/obj/structure/flora/pottedplant{icon_state = "plant-06"},/turf/simulated/floor/holofloor/wood,/area/holodeck/source_meetinghall) +"ci" = (/turf/simulated/floor/holofloor/wood,/area/holodeck/source_meetinghall) +"cj" = (/obj/effect/floor_decal/corner/red/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"ck" = (/obj/effect/floor_decal/corner/red{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cl" = (/obj/structure/holohoop,/obj/effect/floor_decal/corner/red{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cm" = (/obj/effect/floor_decal/corner/red/full{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cn" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"co" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cp" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_basketball) +"cq" = (/turf/simulated/floor/holofloor/beach/sand,/area/holodeck/source_beach) +"cr" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/obj/effect/floor_decal/corner/red/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cs" = (/obj/structure/table/holotable,/obj/item/clothing/head/helmet/thunderdome,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/under/color/red,/obj/item/weapon/holo/esword/red,/obj/effect/floor_decal/corner/red{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"ct" = (/obj/structure/table/holotable,/obj/effect/floor_decal/corner/red/full{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cu" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cv" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cw" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_thunderdomecourt) +"cx" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"cy" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"cz" = (/obj/effect/landmark{name = "Holocarp Spawn Random"},/turf/simulated/floor/holofloor/space,/area/holodeck/source_space) +"cA" = (/obj/structure/flora/grass/both,/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) +"cB" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 9},/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"cC" = (/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 1},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"cD" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 6},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"cE" = (/obj/effect/floor_decal/corner/red{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cF" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cG" = (/obj/effect/floor_decal/corner/red{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"cH" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/holofloor/beach/sand,/area/holodeck/source_beach) +"cI" = (/obj/effect/floor_decal/corner/red{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cJ" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cK" = (/obj/effect/floor_decal/corner/red{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"cL" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"cM" = (/obj/structure/flora/tree/pine,/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) +"cN" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_meetinghall) +"cO" = (/obj/machinery/door/window/holowindoor{dir = 8; name = "Red Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_basketball) +"cP" = (/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/holofloor/beach/sand,/area/holodeck/source_beach) +"cQ" = (/obj/effect/overlay/palmtree_l,/obj/effect/overlay/coconut,/turf/simulated/floor/holofloor/beach/sand,/area/holodeck/source_beach) +"cR" = (/obj/machinery/door/window/holowindoor{dir = 8; name = "Red Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_thunderdomecourt) +"cS" = (/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 2; icon_state = "right"; name = "Red Corner"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"cT" = (/obj/structure/window/reinforced/holowindow,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"cU" = (/obj/structure/flora/tree/dead,/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) +"cV" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_meetinghall) +"cW" = (/turf/simulated/floor/holofloor/lino,/area/holodeck/source_meetinghall) +"cX" = (/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 6},/obj/effect/floor_decal/carpet{dir = 9},/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"cY" = (/obj/item/weapon/beach_ball,/turf/simulated/floor/holofloor/beach/sand,/area/holodeck/source_beach) +"cZ" = (/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"da" = (/obj/effect/floor_decal/corner/red/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"db" = (/obj/effect/floor_decal/corner/red{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dc" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dd" = (/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"de" = (/obj/structure/flora/grass/green,/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) +"df" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dg" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 1},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dh" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"di" = (/obj/effect/floor_decal/corner/red/full,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dj" = (/obj/effect/floor_decal/corner/red{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dk" = (/obj/item/weapon/beach_ball/holoball,/obj/effect/floor_decal/corner/red{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dl" = (/obj/effect/floor_decal/corner/red/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dm" = (/obj/item/weapon/inflatable_duck,/turf/simulated/floor/holofloor/beach/sand,/area/holodeck/source_beach) +"dn" = (/obj/structure/window/reinforced/holowindow/disappearing,/obj/effect/floor_decal/corner/red/full,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"do" = (/obj/structure/window/reinforced/holowindow/disappearing,/obj/effect/floor_decal/corner/red{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dp" = (/obj/structure/window/reinforced/holowindow/disappearing,/obj/effect/floor_decal/corner/red/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dq" = (/obj/effect/floor_decal/corner/red{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dr" = (/obj/effect/floor_decal/corner/blue/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"ds" = (/obj/effect/floor_decal/corner/blue/full{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dt" = (/obj/effect/floor_decal/corner/green{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"du" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 8},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dv" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dw" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dx" = (/obj/effect/floor_decal/corner/green/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dy" = (/obj/effect/floor_decal/corner/green{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dz" = (/obj/effect/floor_decal/corner/green/full{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dA" = (/obj/structure/window/reinforced/holowindow/disappearing{dir = 1},/obj/effect/floor_decal/corner/green/full{dir = 8},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dB" = (/obj/structure/window/reinforced/holowindow/disappearing{dir = 1},/obj/effect/floor_decal/corner/green{dir = 5},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dC" = (/obj/structure/window/reinforced/holowindow/disappearing{dir = 1},/obj/effect/floor_decal/corner/green/full{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dD" = (/obj/effect/floor_decal/corner/blue/full,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dE" = (/obj/effect/floor_decal/corner/blue/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dF" = (/obj/effect/floor_decal/corner/green{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dG" = (/obj/effect/floor_decal/corner/green{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dH" = (/obj/effect/floor_decal/corner/green{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dI" = (/obj/effect/floor_decal/corner/green{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"dJ" = (/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dK" = (/obj/effect/floor_decal/corner/green/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_boxingcourt) +"dL" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) +"dM" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet{dir = 8},/area/holodeck/source_meetinghall) +"dN" = (/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dO" = (/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 8; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_basketball) +"dP" = (/turf/unsimulated/beach/sand{icon_state = "beach"},/area/holodeck/source_beach) +"dQ" = (/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 8; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_thunderdomecourt) +"dR" = (/obj/structure/window/reinforced/holowindow{dir = 1},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"dS" = (/obj/machinery/door/window/holowindoor{dir = 1; name = "Green Corner"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"dT" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dU" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dV" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 6},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_meetinghall) +"dW" = (/turf/simulated/floor/holofloor/beach/water,/area/holodeck/source_beach) +"dX" = (/obj/effect/floor_decal/corner/green/full,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dY" = (/obj/structure/holohoop{dir = 1},/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"dZ" = (/obj/effect/floor_decal/corner/green/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) +"ea" = (/obj/structure/table/holotable,/obj/effect/floor_decal/corner/green/full,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"eb" = (/obj/structure/table/holotable,/obj/item/clothing/head/helmet/thunderdome,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/under/color/green,/obj/item/weapon/holo/esword/green,/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"ec" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/obj/effect/floor_decal/corner/green/full{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_thunderdomecourt) +"ed" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) +"ee" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/wall,/area/space) +"ef" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/centcom/specops) +"eg" = (/obj/structure/table/rack,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/obj/item/ammo_casing/rocket,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"eh" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT"; name = "Assault Weapon Storage"; p_open = 0},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ei" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ej" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ek" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/rocket,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"el" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/automatic/z8,/obj/item/weapon/gun/projectile/automatic/z8,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"em" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/assetprotection,/obj/item/weapon/rig/ert/assetprotection,/obj/item/weapon/rig/ert/assetprotection,/obj/item/weapon/rig/ert/assetprotection,/obj/item/weapon/rig/ert/assetprotection,/obj/item/weapon/rig/ert/assetprotection,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"en" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/sniperrifle,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"eo" = (/obj/structure/table/rack,/obj/item/weapon/melee/energy/sword/blue,/obj/item/weapon/melee/energy/sword/blue,/obj/item/weapon/melee/energy/sword/blue,/obj/item/weapon/melee/energy/sword/blue,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ep" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/automatic/l6_saw,/obj/item/ammo_magazine/m545saw,/obj/item/ammo_magazine/m545saw,/obj/item/ammo_magazine/m545saw,/obj/item/ammo_magazine/m545saw,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"eq" = (/obj/structure/table/rack,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"er" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/laser,/obj/item/weapon/gun/energy/laser,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"es" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m9mmp90,/obj/item/ammo_magazine/m9mmp90,/obj/item/ammo_magazine/m9mmp90,/obj/item/ammo_magazine/m9mmp90,/obj/item/weapon/gun/projectile/automatic/p90,/obj/item/weapon/gun/projectile/automatic/p90,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"et" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/xray,/obj/item/weapon/gun/energy/xray,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"eu" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"ev" = (/obj/machinery/deployable/barrier,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ew" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ex" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ey" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/gun/energy/ionrifle,/obj/structure/window/reinforced{dir = 1},/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ez" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/ionrifle/pistol,/obj/item/weapon/gun/energy/ionrifle/pistol,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eA" = (/obj/machinery/computer/teleporter,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eB" = (/obj/machinery/teleport/station,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eC" = (/obj/machinery/teleport/hub,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eD" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eE" = (/obj/machinery/mech_recharger,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eF" = (/obj/machinery/mech_recharger,/obj/mecha/combat/gygax/dark,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eG" = (/obj/structure/table/reinforced,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eH" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eI" = (/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eJ" = (/obj/structure/table/steel_reinforced,/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion,/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eK" = (/obj/structure/table/steel_reinforced,/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster,/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eL" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/item/weapon/storage/belt/security/tactical/bandolier,/obj/item/weapon/storage/belt/security/tactical/bandolier,/obj/item/weapon/storage/belt/security/tactical/bandolier,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eM" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"eN" = (/obj/item/weapon/bikehorn/rubberducky,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"eO" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"eP" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT"; name = "Assault Armor Storage"; p_open = 0},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"eQ" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/gun/launcher/grenade,/obj/item/weapon/gun/launcher/grenade,/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eR" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eS" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/storage/box/shotgunammo,/obj/item/weapon/storage/box/shotgunammo,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eT" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eU" = (/obj/item/weapon/storage/box/flashshells,/obj/item/weapon/storage/box/flashshells,/obj/item/weapon/storage/box/stunshells,/obj/item/weapon/storage/box/stunshells,/obj/item/weapon/storage/box/beanbags,/obj/item/weapon/storage/box/beanbags,/obj/structure/window/reinforced,/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eV" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/taser,/obj/item/weapon/gun/energy/taser,/obj/item/weapon/gun/energy/taser,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eW" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/item/clothing/glasses/night{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/night{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/night{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/night{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/night{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/night{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/sunglasses/sechud/tactical{pixel_x = -2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses/sechud/tactical{pixel_x = -2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses/sechud/tactical{pixel_x = -2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses/sechud/tactical{pixel_x = -2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses/sechud/tactical{pixel_x = -2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses/sechud/tactical{pixel_x = -2; pixel_y = -2},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eX" = (/obj/structure/closet/wardrobe/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eY" = (/obj/machinery/vending/cola{name = "hacked Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"eZ" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fa" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fb" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fc" = (/obj/structure/table/standard,/obj/item/weapon/towel,/obj/item/weapon/towel,/obj/item/weapon/towel,/obj/item/weapon/towel,/obj/random/soap,/obj/random/soap,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fd" = (/obj/structure/urinal{pixel_y = 32},/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fe" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/window/reinforced/tinted,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"ff" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fg" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/obj/structure/window/reinforced/tinted,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fh" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fi" = (/obj/structure/table/steel_reinforced,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fj" = (/obj/item/mecha_parts/mecha_equipment/teleporter,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fk" = (/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun,/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fl" = (/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fm" = (/obj/structure/table/rack,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fn" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/emps{pixel_x = 4; pixel_y = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/storage/box/frags,/obj/item/weapon/storage/box/smokes,/obj/item/weapon/storage/box/smokes,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fo" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/item/ammo_magazine/m9mmt/rubber,/obj/item/ammo_magazine/m9mmt/rubber,/obj/item/ammo_magazine/m9mmt/rubber,/obj/item/ammo_magazine/m9mmt/rubber,/obj/item/ammo_magazine/m9mmt/rubber,/obj/item/ammo_magazine/m9mmt/rubber,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fp" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/automatic/wt550,/obj/item/weapon/gun/projectile/automatic/wt550,/obj/item/weapon/gun/projectile/automatic/wt550,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fq" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/item/ammo_magazine/m9mmt,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fr" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fs" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_drop_pouches,/obj/item/clothing/accessory/storage/black_drop_pouches,/obj/item/clothing/accessory/storage/black_drop_pouches,/obj/item/clothing/accessory/storage/black_drop_pouches,/obj/item/clothing/accessory/storage/black_drop_pouches,/obj/item/clothing/accessory/storage/black_drop_pouches,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ft" = (/obj/structure/table/reinforced,/obj/item/weapon/shield_diffuser,/obj/item/weapon/shield_diffuser,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fu" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/obj/item/weapon/shield_diffuser,/obj/item/weapon/shield_diffuser,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fv" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"fw" = (/obj/effect/landmark{name = "Commando"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fx" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fy" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fz" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fA" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) +"fB" = (/obj/structure/table/bench/padded,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fC" = (/obj/machinery/door/airlock,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fD" = (/obj/item/mecha_parts/mecha_equipment/tool/extinguisher,/obj/item/mecha_parts/mecha_equipment/tool/rcd,/obj/item/weapon/pickaxe/diamonddrill,/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fE" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/item/weapon/rig/ert/security,/obj/item/weapon/rig/ert/security,/obj/item/weapon/rig/ert/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fF" = (/obj/structure/table/rack,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fG" = (/obj/structure/table/rack,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/holster/hip,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fH" = (/obj/structure/table/rack,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/armpit,/obj/effect/floor_decal/industrial/outline/blue,/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fI" = (/obj/structure/table/reinforced,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/wrench,/obj/effect/floor_decal/industrial/outline/blue,/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fJ" = (/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fK" = (/obj/machinery/porta_turret{anchored = 0; check_records = 0; enabled = 0; req_one_access = list(103); use_power = 0},/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fL" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fM" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fN" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"fO" = (/obj/mecha/working/hoverpod,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fP" = (/obj/mecha/working/ripley/firefighter,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fQ" = (/obj/mecha/medical/odysseus/loaded,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fR" = (/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,/obj/item/mecha_parts/mecha_equipment/tool/cable_layer,/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"fS" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/item/ammo_magazine/m45/rubber,/obj/item/ammo_magazine/m45/rubber,/obj/item/ammo_magazine/m45/rubber,/obj/item/ammo_magazine/m45/rubber,/obj/item/ammo_magazine/m45/rubber,/obj/item/ammo_magazine/m45/flash,/obj/item/ammo_magazine/m45/flash,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/obj/item/ammo_magazine/m45,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fT" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/item/weapon/gun/projectile/sec,/obj/item/weapon/gun/projectile/sec,/obj/item/weapon/gun/projectile/sec,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fU" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/handcuffs{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fV" = (/obj/item/weapon/material/knife/tacknife/combatknife,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fW" = (/obj/machinery/vending/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fX" = (/obj/structure/table/rack,/obj/item/taperoll/police,/obj/item/taperoll/police,/obj/item/taperoll/police,/obj/item/taperoll/police,/obj/item/taperoll/police,/obj/item/taperoll/police,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fY" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"fZ" = (/obj/structure/table/rack,/obj/item/clothing/accessory/holster/leg,/obj/item/clothing/accessory/holster/leg,/obj/item/clothing/accessory/holster/leg,/obj/item/clothing/accessory/holster/leg,/obj/item/clothing/accessory/holster/leg,/obj/item/clothing/accessory/holster/leg,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ga" = (/obj/machinery/door/airlock/centcom{icon_state = "door_locked"; locked = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gb" = (/obj/structure/table/glass,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gc" = (/obj/structure/toilet{dir = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"gd" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"ge" = (/obj/structure/sign/warning/secure_area/armory,/turf/simulated/shuttle/wall/dark/hard_corner,/area/centcom/specops) +"gf" = (/obj/structure/sign/warning/secure_area,/turf/simulated/shuttle/wall/dark/hard_corner,/area/centcom/specops) +"gg" = (/obj/effect/floor_decal/corner/red{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gh" = (/obj/effect/floor_decal/corner/red{dir = 5},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gi" = (/obj/effect/floor_decal/corner/red{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gj" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gk" = (/obj/effect/floor_decal/corner/purple{dir = 6},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gl" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/device/flash,/obj/item/device/flash,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gm" = (/obj/structure/table/rack,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gn" = (/obj/structure/table/reinforced,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/wrench,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"go" = (/obj/structure/table/reinforced,/obj/item/weapon/stamp/centcomm,/obj/item/weapon/pen,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gp" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gq" = (/obj/structure/table/reinforced,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/crowbar,/obj/item/device/radio/off,/obj/item/device/radio/off,/obj/item/device/radio/off,/obj/item/device/radio/off,/obj/item/device/radio/off,/obj/item/device/radio/off,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gr" = (/obj/machinery/door/airlock,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gs" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"gt" = (/obj/effect/floor_decal/corner/yellow,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gu" = (/obj/effect/floor_decal/corner/yellow{dir = 10},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gv" = (/obj/effect/floor_decal/corner/yellow{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gw" = (/obj/effect/floor_decal/corner/white,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gx" = (/obj/effect/floor_decal/corner/white{dir = 10},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gy" = (/obj/effect/floor_decal/corner/white{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gz" = (/obj/structure/table/reinforced,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gA" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donut,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gB" = (/obj/structure/table/reinforced,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gC" = (/obj/structure/table/rack,/obj/item/weapon/storage/backpack/security,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/gloves/purple,/obj/item/clothing/glasses/science,/obj/item/weapon/storage/backpack/security,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/gloves/purple,/obj/item/clothing/glasses/science,/obj/item/weapon/reagent_containers/spray/cleaner{pixel_x = 6; pixel_y = 3},/obj/item/weapon/reagent_containers/spray/cleaner{pixel_x = 6; pixel_y = 3},/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gD" = (/obj/item/weapon/mop,/obj/structure/mopbucket,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gE" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket{amount_per_transfer_from_this = 50},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gF" = (/obj/structure/sign/greencross{desc = "White cross in a green field, you can get medical aid here."; name = "First-Aid"},/turf/simulated/shuttle/wall/dark/hard_corner,/area/centcom/specops) +"gG" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"gH" = (/turf/simulated/shuttle/wall/dark/no_join,/area/centcom/specops) +"gI" = (/obj/item/weapon/circuitboard/aiupload,/obj/item/weapon/circuitboard/borgupload,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/aiModule/nanotrasen,/obj/item/weapon/aiModule/reset,/obj/item/weapon/aiModule/freeformcore,/obj/item/weapon/aiModule/protectStation,/obj/item/weapon/aiModule/quarantine,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/obj/item/weapon/aiModule/safeguard,/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gJ" = (/obj/machinery/vending/assist,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gK" = (/obj/machinery/vending/tool,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gL" = (/obj/machinery/vending/engivend,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gM" = (/obj/machinery/vending/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gN" = (/obj/structure/table/rack,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gO" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gP" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/pillbottles,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gQ" = (/obj/machinery/chemical_dispenser/full,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gR" = (/obj/machinery/chem_master,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gS" = (/obj/machinery/chemical_dispenser/ert,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gT" = (/obj/machinery/vending/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gU" = (/obj/item/clothing/glasses/hud/health{pixel_x = 4; pixel_y = 4},/obj/item/clothing/glasses/hud/health{pixel_x = 2; pixel_y = 2},/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gV" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/table/rack,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gW" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gX" = (/obj/structure/table/reinforced,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"gY" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/response_ship/start) +"gZ" = (/turf/simulated/shuttle/wall/dark{join_group = "shuttle_ert"},/area/shuttle/response_ship/start) +"ha" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/weapon/rig/ert/engineer,/obj/item/weapon/rig/ert/engineer,/obj/item/weapon/rig/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hb" = (/obj/structure/closet/crate/medical,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"hc" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"hd" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced,/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/weapon/rig/ert/medical,/obj/item/weapon/rig/ert/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"he" = (/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hf" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hg" = (/obj/structure/table/rack,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hh" = (/obj/structure/closet/crate/internals{name = "Mask Crate"},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hi" = (/obj/machinery/cell_charger,/obj/structure/table/reinforced,/obj/effect/floor_decal/industrial/outline/blue,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hj" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/response_ship/start) +"hk" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating/airless,/area/shuttle/response_ship/start) +"hl" = (/obj/machinery/computer/security/telescreen{desc = ""; name = "Spec. Ops. Monitor"; network = list("NETWORK_ERT"); pixel_y = 26},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hm" = (/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hn" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"ho" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/obj/structure/bed/chair,/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hp" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0},/obj/machinery/light{dir = 4},/obj/structure/bed/chair,/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hq" = (/turf/simulated/shuttle/wall/dark{hard_corner = 1; join_group = "shuttle_ert"},/area/shuttle/response_ship/start) +"hr" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/clothing/accessory/storage/brown_drop_pouches,/obj/item/clothing/accessory/storage/brown_drop_pouches,/obj/item/clothing/accessory/storage/brown_drop_pouches,/obj/item/clothing/accessory/storage/brown_drop_pouches,/obj/item/clothing/accessory/storage/brown_drop_pouches,/obj/item/clothing/accessory/storage/brown_drop_pouches,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hs" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/table/rack,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_drop_pouches,/obj/item/clothing/accessory/storage/white_drop_pouches,/obj/item/clothing/accessory/storage/white_drop_pouches,/obj/item/clothing/accessory/storage/white_drop_pouches,/obj/item/clothing/accessory/storage/white_drop_pouches,/obj/item/clothing/accessory/storage/white_drop_pouches,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ht" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating/airless,/area/shuttle/response_ship/start) +"hu" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hv" = (/obj/machinery/computer/shuttle_control/web/ert{icon_state = "flightcomp_center"; dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hw" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hx" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "response_shuttle"; pixel_x = 0; pixel_y = -25; tag_door = "response_shuttle_door"},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hy" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "response_shuttle_door"; locked = 1; name = "Forward Docking Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hz" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "response_base_door"; locked = 1},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"hA" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "response_base"; name = "docking port controller"; pixel_x = 0; pixel_y = -25; req_one_access = list(103); tag_door = "response_base_door"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"hB" = (/obj/structure/reagent_dispensers/watertank,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hC" = (/obj/structure/table/steel_reinforced,/obj/machinery/cell_charger,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hD" = (/obj/item/stack/material/glass{amount = 50},/obj/item/stack/material/glass{amount = 50},/obj/item/stack/material/glass{amount = 50},/obj/item/stack/material/glass{amount = 50},/obj/item/stack/material/steel{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/material/steel{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/material/steel{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/material/steel{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/material/plasteel{amount = 50},/obj/item/stack/material/plasteel{amount = 50},/obj/item/stack/material/plasteel{amount = 50},/obj/item/stack/material/plasteel{amount = 50},/obj/item/stack/material/glass/reinforced{amount = 50},/obj/item/stack/material/glass/reinforced{amount = 50},/obj/item/stack/material/glass/reinforced{amount = 50},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hE" = (/obj/machinery/pipedispenser/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hF" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hG" = (/obj/structure/table/reinforced,/obj/item/device/defib_kit,/obj/item/device/defib_kit,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/tool/screwdriver,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hH" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/syringes,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hI" = (/obj/item/roller,/obj/item/roller{pixel_y = 8},/obj/item/roller{pixel_y = 16},/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hJ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/masks,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hK" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced,/obj/structure/table/rack,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hL" = (/obj/structure/table/rack,/obj/item/rig_module/device/rcd,/obj/item/rig_module/device/rcd,/obj/item/rig_module/device/plasmacutter,/obj/item/rig_module/device/plasmacutter,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hM" = (/obj/structure/table/rack,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/chem_dispenser/injector,/obj/item/rig_module/chem_dispenser/injector,/obj/item/rig_module/device/healthscanner,/obj/item/rig_module/device/healthscanner,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hN" = (/obj/structure/table/rack,/obj/item/rig_module/mounted/egun,/obj/item/rig_module/mounted/egun,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hO" = (/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/item/weapon/storage/box/trackimp,/obj/item/weapon/storage/box/cdeathalarm_kit,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hP" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/command,/obj/item/clothing/head/helmet/ert/command,/obj/item/weapon/storage/backpack/ert/commander,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hQ" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/weapon/stamp/centcomm,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hR" = (/obj/item/device/radio/intercom/specops{pixel_y = -21},/obj/machinery/computer/communications,/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hS" = (/obj/structure/flight_right{icon_state = "right"; dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hT" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hU" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hV" = (/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/response_ship/start) +"hW" = (/obj/structure/reagent_dispensers/fueltank,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hX" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/taperoll/engineering,/obj/item/taperoll/engineering,/obj/item/taperoll/engineering,/obj/item/taperoll/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hY" = (/obj/structure/table/steel_reinforced,/obj/item/taperoll/atmos,/obj/item/taperoll/atmos,/obj/item/taperoll/atmos,/obj/item/weapon/pickaxe/drill,/obj/item/weapon/pickaxe/drill,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"hZ" = (/obj/machinery/pipedispenser/disposal/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ia" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/device/flash,/obj/item/device/flash,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ib" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/pill_bottle/tramadol,/obj/item/weapon/storage/pill_bottle/tramadol,/obj/item/weapon/storage/pill_bottle/tramadol,/obj/item/weapon/storage/pill_bottle/dylovene,/obj/item/weapon/storage/pill_bottle/dylovene,/obj/item/weapon/storage/pill_bottle/dylovene,/obj/item/weapon/storage/pill_bottle/dermaline,/obj/item/weapon/storage/pill_bottle/dermaline,/obj/item/weapon/storage/pill_bottle/dermaline,/obj/item/weapon/storage/pill_bottle/spaceacillin,/obj/item/weapon/storage/pill_bottle/dexalin_plus,/obj/item/weapon/storage/pill_bottle/dexalin_plus,/obj/item/weapon/storage/pill_bottle/dexalin_plus,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ic" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"id" = (/obj/structure/closet/crate/medical,/obj/item/weapon/surgical/circular_saw,/obj/item/weapon/surgical/surgicaldrill,/obj/item/weapon/surgical/bonegel{pixel_x = 4; pixel_y = 3},/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/scalpel,/obj/item/weapon/surgical/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/surgical/hemostat{pixel_y = 4},/obj/item/weapon/surgical/cautery{pixel_y = 4},/obj/item/weapon/surgical/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/nanopaste,/obj/item/weapon/tank/anesthetic,/obj/item/clothing/mask/breath/medical,/obj/item/clothing/mask/surgical,/obj/item/clothing/mask/surgical,/obj/item/weapon/autopsy_scanner,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ie" = (/obj/machinery/iv_drip,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"if" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ig" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ih" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/response_ship/start) +"ii" = (/obj/item/weapon/storage/box,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ij" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ik" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical/emt,/obj/item/weapon/storage/belt/medical/emt,/obj/item/weapon/storage/belt/medical/emt,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"il" = (/obj/structure/table/reinforced,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/wrench,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"im" = (/obj/structure/table/reinforced,/obj/item/weapon/pinpointer/advpinpointer,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"in" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; dir = 8; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/specops) +"io" = (/obj/machinery/shield_gen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ip" = (/obj/machinery/shield_gen/external,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iq" = (/obj/machinery/power/emitter,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ir" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"is" = (/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"it" = (/obj/machinery/portable_atmospherics/canister/air,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iu" = (/obj/machinery/shieldwallgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iv" = (/obj/machinery/shieldgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iw" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/bodybags,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"ix" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iy" = (/obj/machinery/shield_capacitor,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iz" = (/obj/item/weapon/extinguisher,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iA" = (/obj/structure/table/reinforced,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/spray/sterilizine,/obj/item/weapon/reagent_containers/spray/sterilizine,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iB" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/combat{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/combat,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iC" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/fire{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/fire,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iD" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/toxin{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/toxin,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iE" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/adv{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/adv,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iF" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/o2,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iG" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/regular,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iH" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/clotting{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/clotting,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iI" = (/obj/structure/table/reinforced,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iJ" = (/obj/structure/table/rack,/obj/item/rig_module/device/drill,/obj/item/rig_module/device/drill,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/maneuvering_jets,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iK" = (/obj/structure/table/rack,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iL" = (/obj/structure/table/rack,/obj/item/rig_module/grenade_launcher,/obj/item/rig_module/grenade_launcher,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iM" = (/obj/structure/closet/crate,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"iN" = (/obj/machinery/autolathe{desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; hacked = 1; name = "Unlocked Autolathe"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"iO" = (/obj/structure/table/reinforced,/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iP" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iQ" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/hand_tele,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) +"iR" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "CREED"; name = "Ready Room"; p_open = 0},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/specops) +"iS" = (/obj/structure/sign/warning/docking_area,/turf/unsimulated/wall,/area/centcom/command) +"iT" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/command) +"iU" = (/obj/machinery/door/airlock/external,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"iV" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"iW" = (/turf/unsimulated/wall,/area/centcom/command) +"iX" = (/turf/unsimulated/wall,/area/centcom/suppy) +"iY" = (/turf/simulated/shuttle/wall,/area/centcom/evac) +"iZ" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; dir = 8; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/evac) +"ja" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/suppy) +"jb" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod1/centcom) +"jc" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod2/centcom) +"jd" = (/turf/simulated/shuttle/wall,/area/supply/dock) +"je" = (/turf/unsimulated/wall,/area/centcom/main_hall) +"jf" = (/obj/structure/window/reinforced,/turf/simulated/shuttle/wall/dark/no_join,/area/supply/dock) +"jg" = (/turf/unsimulated/wall,/area/tdome) +"jh" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/main_hall) +"ji" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "CREED"; name = "Ready Room"; p_open = 0},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"jj" = (/turf/unsimulated/wall,/area/centcom/creed) +"jk" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/creed) +"jl" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor,/area/supply/dock) +"jm" = (/turf/simulated/shuttle/floor,/area/supply/dock) +"jn" = (/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor,/area/supply/dock) +"jo" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"jp" = (/obj/structure/closet/secure_closet/hydroponics,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"jq" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"jr" = (/turf/unsimulated/wall{icon = 'icons/obj/doors/Doormaint.dmi'; icon_state = "door_closed"; name = "Sealed Door"},/area/centcom/bar) +"js" = (/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/command) +"jt" = (/obj/machinery/computer/card/centcom,/obj/item/weapon/card/id/centcom,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"ju" = (/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jv" = (/obj/structure/table/rack,/obj/item/weapon/storage/secure/briefcase,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/backpack/satchel,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jw" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/shuttle/floor,/area/supply/dock) +"jx" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/supply/dock) +"jy" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/centcom/evac) +"jz" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/centcom/evac) +"jA" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/centcom/evac) +"jB" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"jC" = (/obj/machinery/chem_master/condimaster,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"jD" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"jE" = (/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 9},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jF" = (/obj/structure/bed/chair/comfy/teal,/obj/effect/floor_decal/carpet{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jG" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jH" = (/obj/structure/table/wooden_reinforced,/obj/machinery/computer/security/telescreen{name = "Spec. Ops. Monitor"; network = list("ERT")},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jI" = (/obj/structure/bed/chair/office/dark,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jJ" = (/obj/machinery/computer/pod{id = "NTrasen"; name = "Hull Door Control"},/obj/item/device/radio/intercom/specops{pixel_y = -21},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jK" = (/obj/structure/closet/secure_closet/hos,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jL" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/supply/dock) +"jM" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 1},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating/airless,/area/centcom/evac) +"jN" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 1"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"jO" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 2"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"jP" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"jQ" = (/obj/structure/table/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/red,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"jR" = (/obj/structure/closet/chefcloset,/obj/item/glass_jar,/obj/item/device/retail_scanner/civilian,/obj/item/weapon/soap/nanotrasen,/obj/item/device/destTagger{pixel_x = 4; pixel_y = 3},/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"jS" = (/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"jT" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"jU" = (/obj/structure/bed/chair/comfy/teal{dir = 4},/obj/effect/floor_decal/carpet{dir = 8},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jV" = (/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jW" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/bananapeel,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jX" = (/obj/structure/bed/chair/comfy/teal{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"jY" = (/obj/structure/table/wooden_reinforced,/obj/machinery/button/remote/blast_door{name = "Spec Ops Ready Room"; pixel_y = 15; req_access = list(11); id = "CREED"},/obj/machinery/button/remote/blast_door{name = "Mech Storage"; icon_state = "doorctrl0"; pixel_y = 0; req_access = list(11); id = "ASSAULT"},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"jZ" = (/obj/structure/table/wooden_reinforced,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"ka" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "supply_shuttle"; pixel_x = 25; pixel_y = 0; req_one_access = list(13,31); tag_door = "supply_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/supply/dock) +"kb" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/table/rack,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/shuttle/plating,/area/centcom/evac) +"kc" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/centcom/evac) +"kd" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"ke" = (/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"kf" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_1_recovery"; pixel_x = -25; pixel_y = 25; req_one_access = list(13); tag_door = "escape_pod_1_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"kg" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_2_recovery"; pixel_x = -25; pixel_y = 25; req_one_access = list(13); tag_door = "escape_pod_2_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"kh" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/plating,/area/centcom/evac) +"ki" = (/obj/machinery/door/blast/regular{id = "thunderdomegen"; name = "General Supply"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"kj" = (/turf/unsimulated/floor{icon_state = "asteroid"},/area/centcom/main_hall) +"kk" = (/obj/structure/mopbucket,/obj/item/weapon/mop,/turf/simulated/shuttle/plating,/area/centcom/evac) +"kl" = (/turf/simulated/shuttle/plating,/area/centcom/evac) +"km" = (/obj/machinery/door/airlock/maintenance_hatch{req_access = list(101)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"kn" = (/turf/simulated/shuttle/floor,/area/centcom/evac) +"ko" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/turf/simulated/shuttle/floor,/area/centcom/evac) +"kp" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/structure/closet/secure_closet/personal,/turf/simulated/shuttle/floor,/area/centcom/evac) +"kq" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/closet/secure_closet/personal,/turf/simulated/shuttle/floor,/area/centcom/evac) +"kr" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/shuttle/plating,/area/centcom/evac) +"ks" = (/obj/structure/table/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/vest,/obj/item/clothing/head/helmet/swat,/obj/item/weapon/gun/energy/laser,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"kt" = (/obj/machinery/door/blast/regular{id = "thunderdomehea"; name = "Heavy Supply"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"ku" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdome2) +"kv" = (/obj/effect/landmark{name = "tdome2"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdome2) +"kw" = (/obj/machinery/door/blast/regular{id = "thunderdomeaxe"; name = "Axe Supply"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"kx" = (/obj/structure/table/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/melee/energy/axe,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"ky" = (/obj/machinery/door/airlock/centcom{name = "Courthouse"; opacity = 1},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/command) +"kz" = (/obj/machinery/door/airlock/centcom{name = "Administrative Office"; opacity = 1; req_access = list(108)},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"kA" = (/mob/living/simple_mob/animal/passive/dog/corgi/puppy/Bockscar,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"kB" = (/obj/machinery/telecomms/relay/preset/centcom,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"kC" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/turf/simulated/shuttle/floor,/area/supply/dock) +"kD" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/supply/dock) +"kE" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/shuttle/plating,/area/centcom/evac) +"kF" = (/obj/machinery/vending/engineering,/turf/simulated/shuttle/plating,/area/centcom/evac) +"kG" = (/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/shuttle/plating,/area/centcom/evac) +"kH" = (/obj/structure/table/standard,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdome2) +"kI" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"kJ" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/storage/briefcase,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"kK" = (/turf/simulated/shuttle/wall/hard_corner,/area/supply/dock) +"kL" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/evac) +"kM" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod7/centcom) +"kN" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod8/centcom) +"kO" = (/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 10},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"kP" = (/obj/structure/bed/chair/comfy/teal{dir = 1},/obj/effect/floor_decal/carpet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"kQ" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) +"kR" = (/obj/structure/bed/chair/office/dark{dir = 1},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"kS" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/wall/no_join,/area/supply/dock) +"kT" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_7_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 7"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"kU" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_7_recovery"; pixel_x = -26; pixel_y = 26; req_one_access = list(13); tag_door = "escape_pod_7_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"kV" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_8_recovery"; pixel_x = 26; pixel_y = -26; req_one_access = list(13); tag_door = "escape_pod_8_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"kW" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_8_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 8"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"kX" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"},/turf/simulated/shuttle/plating/airless/carry,/area/supply/dock) +"kY" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry,/area/supply/dock) +"kZ" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/shuttle/plating/airless/carry,/area/supply/dock) +"la" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome) +"lb" = (/obj/machinery/door/blast/regular{id = "thunderdome"; name = "Thunderdome Blast Door"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"lc" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"ld" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"le" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/main_hall) +"lf" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"lg" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; dir = 8; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/command) +"lh" = (/turf/simulated/shuttle/wall/hard_corner,/area/centcom/evac) +"li" = (/obj/structure/table/standard,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"lj" = (/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"lk" = (/obj/machinery/igniter,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"ll" = (/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"lm" = (/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"ln" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"lo" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"lp" = (/obj/machinery/smartfridge,/turf/unsimulated/wall,/area/centcom/bar) +"lq" = (/obj/structure/closet/secure_closet/bar,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"lr" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/transport1/centcom) +"ls" = (/turf/simulated/shuttle/wall,/area/shuttle/transport1/centcom) +"lt" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/shuttle/plating,/area/shuttle/transport1/centcom) +"lu" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/command) +"lv" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/shuttle/plating,/area/centcom/evac) +"lw" = (/turf/simulated/shuttle/wall/dark/no_join,/area/centcom/evac) +"lx" = (/obj/structure/closet/secure_closet/security,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"ly" = (/obj/structure/closet{name = "Evidence Closet"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"lz" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"lA" = (/obj/structure/table/rack,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"lB" = (/obj/structure/shuttle/window,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/centcom/evac) +"lC" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor,/area/centcom/evac) +"lD" = (/turf/simulated/shuttle/plating,/area/shuttle/large_escape_pod2/centcom) +"lE" = (/obj/structure/bed/chair{dir = 4},/obj/effect/landmark{name = "tdomeadmin"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"lF" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"lG" = (/obj/structure/bed/chair{dir = 8},/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"lH" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"lI" = (/obj/machinery/porta_turret/crescent,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"lJ" = (/obj/machinery/porta_turret/crescent,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"lK" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/transport1/centcom) +"lL" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating/airless,/area/shuttle/transport1/centcom) +"lM" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"lN" = (/obj/structure/bed/chair,/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"lO" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/simulated/shuttle/floor/yellow,/area/shuttle/transport1/centcom) +"lP" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/shuttle/floor/yellow,/area/shuttle/transport1/centcom) +"lQ" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Centcom"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"lR" = (/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"lS" = (/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"lT" = (/obj/machinery/computer/security/telescreen,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"lU" = (/obj/machinery/computer/security/telescreen,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"lV" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"lW" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"lX" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"lY" = (/obj/structure/reagent_dispensers/watertank/high,/obj/item/weapon/reagent_containers/glass/bucket,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"lZ" = (/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"ma" = (/obj/structure/table/marble,/obj/item/weapon/reagent_containers/glass/beaker,/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/reagentgrinder,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mb" = (/obj/machinery/door/airlock/freezer,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"mc" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"md" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"me" = (/obj/machinery/computer/rcon,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mf" = (/obj/machinery/computer/station_alert/all,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mg" = (/obj/machinery/computer/power_monitor,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mh" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mi" = (/obj/machinery/door/airlock/external{frequency = 1380; glass = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_bay_door"; locked = 1; name = "Transport Airlock"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mj" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mk" = (/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"ml" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mm" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mn" = (/obj/machinery/computer/shuttle_control/centcom,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mo" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access = list(1)},/turf/simulated/shuttle/plating,/area/centcom/evac) +"mp" = (/obj/machinery/door/airlock/glass_security{name = "Security Processing"; req_access = list(1)},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"mq" = (/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"mr" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"ms" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"mt" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mu" = (/obj/machinery/biogenerator,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mv" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mw" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/fryer,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mx" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 8},/obj/machinery/computer/supplycomp/control,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"my" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mz" = (/obj/machinery/computer/robotics,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"mA" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating/airless,/area/shuttle/transport1/centcom) +"mB" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mC" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mD" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 9},/turf/simulated/shuttle/floor/yellow,/area/shuttle/transport1/centcom) +"mE" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/shuttle/floor/yellow,/area/shuttle/transport1/centcom) +"mF" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle"; pixel_x = 0; pixel_y = -25; tag_door = "centcom_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mG" = (/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"mH" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"mI" = (/obj/machinery/computer/pod{id = "thunderdomeaxe"; name = "Thunderdome Axe Supply"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"mJ" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"mK" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"mL" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/closet/secure_closet/freezer/fridge,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mM" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/grill,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mN" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mO" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"mP" = (/obj/machinery/button/remote/blast_door{id = "crescent_thunderdome"; name = "Thunderdome Access"; pixel_x = 6; pixel_y = -24; req_access = list(101)},/obj/machinery/button/remote/blast_door{id = "crescent_vip_shuttle"; name = "VIP Shuttle Access"; pixel_x = 6; pixel_y = -34; req_access = list(101)},/obj/machinery/button/remote/blast_door{id = "crescent_checkpoint_access"; name = "Crescent Checkpoint Access"; pixel_x = -6; pixel_y = -24; req_access = list(101)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"mQ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 26; pixel_y = 0; tag_door = "centcom_shuttle_bay_door"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"mR" = (/obj/machinery/computer/card,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"mS" = (/obj/machinery/computer/secure_data,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"mT" = (/obj/machinery/computer/pod{id = "thunderdomegen"; name = "Thunderdome General Supply"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"mU" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/oven,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mV" = (/obj/structure/table/standard{name = "plastic table frame"},/obj/item/weapon/material/knife/machete/hatchet,/obj/item/weapon/material/knife/machete/hatchet,/obj/item/weapon/material/minihoe,/obj/item/weapon/material/minihoe,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mW" = (/obj/machinery/smartfridge/drying_rack,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mX" = (/obj/structure/table/standard{name = "plastic table frame"},/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mY" = (/obj/machinery/door/airlock/centcom{name = "Maintenance Access"; opacity = 1; req_access = list(106)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"mZ" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"na" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "large_escape_pod_2_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 02"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"nb" = (/obj/machinery/computer/pod{id = "thunderdomehea"; name = "Thunderdome Heavy Supply"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"nc" = (/obj/item/weapon/tool/wrench,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"nd" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"ne" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"nf" = (/obj/machinery/atmospherics/pipe/vent{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"ng" = (/obj/machinery/door/airlock/centcom{name = "Thunderdome"; opacity = 1; req_access = list(101)},/obj/machinery/door/blast/regular{id = "crescent_thunderdome"; name = "Thunderdome"},/turf/unsimulated/floor{icon_state = "steel"},/area/tdome) +"nh" = (/obj/machinery/seed_storage/garden,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"ni" = (/obj/machinery/honey_extractor,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nj" = (/obj/machinery/vending/hydronutrients,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nk" = (/obj/machinery/computer/secure_data,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nl" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nm" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"nn" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"no" = (/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"np" = (/obj/machinery/computer/shuttle_control/web/shuttle2{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"nq" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nr" = (/obj/machinery/computer/med_data,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"ns" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "CREED"; name = "Ready Room"; p_open = 0},/turf/simulated/shuttle/floor,/area/centcom/evac) +"nt" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "large_escape_pod_2_recovery"; pixel_x = -25; pixel_y = 25; req_one_access = list(13); tag_door = "large_escape_pod_2_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"nu" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"nv" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent{pixel_x = 1},/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"nw" = (/obj/machinery/atmospherics/valve{dir = 4},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"nx" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/effect/wingrille_spawn/reinforced/crescent,/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"ny" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"nz" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"nA" = (/obj/machinery/camera/network/thunder{c_tag = "Thunderdome Arena"; invisibility = 101},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"nB" = (/obj/machinery/flasher{id = "flash"; name = "Thunderdome Flash"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"nC" = (/obj/machinery/seed_extractor,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nD" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nE" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/candy,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nF" = (/obj/machinery/door/blast/regular{id = "CentComPort"; name = "Security Doors"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"nG" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"nH" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nI" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"nJ" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/mob/living/silicon/decoy{name = "A.L.I.C.E."},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"nK" = (/obj/structure/filingcabinet/filingcabinet,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"nL" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nM" = (/obj/machinery/door/airlock/external,/turf/simulated/shuttle/floor,/area/centcom/evac) +"nN" = (/obj/machinery/computer/pod{id = "thunderdome"; name = "Thunderdome Blast Door Control"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"nO" = (/obj/item/weapon/extinguisher,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"nP" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"nQ" = (/obj/structure/table/marble,/obj/item/weapon/storage/box/glasses/square,/obj/item/weapon/storage/box/glasses/square,/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nR" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/icecream_vat,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nS" = (/obj/machinery/computer/security,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nT" = (/obj/machinery/computer/shuttle_control/web/shuttle1,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"nU" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1443; listening = 0; name = "Spec Ops Intercom"; pixel_y = 22},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"nV" = (/obj/machinery/door/window{dir = 2; name = "AI Core Door"; req_access = list(109)},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"nW" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/machinery/turretid{pixel_x = 0; pixel_y = 28; req_access = list(101)},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/command) +"nX" = (/obj/machinery/computer/crew,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"nY" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 0; pixel_y = -26; tag_door = "admin_shuttle_bay_door"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) +"nZ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "large_escape_pod_1_recovery"; pixel_x = -25; pixel_y = -25; req_one_access = list(13); tag_door = "large_escape_pod_1_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"oa" = (/obj/item/stack/medical/ointment,/obj/item/stack/medical/ointment,/obj/item/stack/medical/ointment,/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"ob" = (/obj/structure/table/marble,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/material/kitchen/rollingpin,/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"oc" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"od" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/condiment/enzyme,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"oe" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/cereal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"of" = (/obj/structure/table/reinforced,/obj/item/weapon/card/id/gold/captain/spare,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"og" = (/obj/structure/table/reinforced,/obj/item/device/pda/captain,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) +"oh" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_bay_door"; locked = 1},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/command) +"oi" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "large_escape_pod_1_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 01"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"oj" = (/obj/structure/table/standard,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/bruise_pack,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"ok" = (/obj/machinery/computer/arcade,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"ol" = (/obj/effect/floor_decal/spline/plain{dir = 4},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"om" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/vending/dinnerware,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"on" = (/obj/structure/flora/pottedplant/stoutbush,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/main_hall) +"oo" = (/obj/structure/table/reinforced,/obj/machinery/computer/skills,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"op" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"oq" = (/obj/machinery/account_database{name = "CentComm Accounts database"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"or" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"os" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"ot" = (/turf/simulated/shuttle/plating,/area/shuttle/cryo/centcom) +"ou" = (/obj/structure/table/standard,/obj/item/weapon/towel,/obj/item/weapon/towel,/obj/item/weapon/towel,/obj/item/weapon/towel,/obj/random/soap,/obj/random/soap,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"ov" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"ow" = (/obj/structure/toilet,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"ox" = (/turf/simulated/shuttle/plating,/area/shuttle/large_escape_pod1/centcom) +"oy" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"oz" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"oA" = (/obj/structure/flora/pottedplant,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"oB" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"oC" = (/obj/machinery/telecomms/broadcaster/preset_cent,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"oD" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Centcom"},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"oE" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"oF" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Centcom"},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"oG" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"oH" = (/obj/structure/extinguisher_cabinet{pixel_x = 28; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"oI" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"oJ" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"oK" = (/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) +"oL" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/spesslaw,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"oM" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/stuffing,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"oN" = (/obj/machinery/telecomms/hub/preset_cent,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"oO" = (/obj/machinery/computer/card,/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"oP" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine,/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"oQ" = (/obj/machinery/computer/communications,/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) +"oR" = (/turf/simulated/shuttle/wall/dark,/area/shuttle/administration/centcom) +"oS" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"oT" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/electrical,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"oU" = (/obj/machinery/computer/rdservercontrol{badmin = 1; name = "Master R&D Server Controller"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"oV" = (/obj/machinery/vending/boozeomat,/turf/simulated/shuttle/wall/dark,/area/shuttle/administration/centcom) +"oW" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"oX" = (/obj/machinery/vending/cigarette,/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"oY" = (/obj/machinery/microwave,/obj/structure/table/reinforced,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"oZ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle"; pixel_x = -25; pixel_y = 0; req_one_access = list(101); tag_door = "admin_shuttle_hatch"},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"pa" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"pb" = (/obj/item/device/multitool,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/structure/table/reinforced,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pc" = (/obj/item/weapon/storage/toolbox/mechanical,/obj/structure/table/reinforced,/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pd" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cryostorage_shuttle_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock Cryostorage"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"pe" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "cryostorage_shuttle_recovery"; pixel_x = -26; pixel_y = 26; req_one_access = list(13); tag_door = "cryostorage_shuttle_recovery_hatch"},/turf/simulated/shuttle/floor,/area/centcom/evac) +"pf" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"},/turf/simulated/shuttle/floor,/area/centcom/evac) +"pg" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/mechanical,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) +"ph" = (/obj/machinery/telecomms/receiver/preset_cent,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"pi" = (/obj/machinery/telecomms/bus/preset_cent,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"pj" = (/obj/machinery/telecomms/relay/preset/southerncross/transit,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"pk" = (/obj/machinery/telecomms/processor/preset_cent,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"pl" = (/obj/machinery/telecomms/server/presets/centcomm,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"pm" = (/obj/machinery/r_n_d/server/centcom,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"pn" = (/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"po" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"pp" = (/obj/structure/table/standard,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pq" = (/obj/machinery/cell_charger,/obj/structure/table/reinforced,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pr" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake/filled,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"ps" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/meatsteak,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"pt" = (/obj/machinery/door/window/northright,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pu" = (/obj/structure/table/reinforced,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pv" = (/obj/item/weapon/flame/lighter/zippo,/obj/structure/table/reinforced,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pw" = (/obj/item/weapon/storage/fancy/cigarettes,/obj/structure/table/reinforced,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"px" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"py" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pz" = (/obj/item/stack/material/glass{amount = 50},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pA" = (/obj/item/stack/material/steel{amount = 50},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"pB" = (/obj/machinery/door/airlock{name = "Unisex Showers"},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"pC" = (/obj/structure/table/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/vest,/obj/item/clothing/head/helmet/swat,/obj/item/weapon/gun/energy/laser,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"pD" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdome1) +"pE" = (/obj/effect/landmark{name = "tdome1"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdome1) +"pF" = (/obj/structure/table/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/weapon/melee/energy/axe,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"pG" = (/obj/structure/table/glass,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/main_hall) +"pH" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"pI" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"pJ" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"pK" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/soylenviridians,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"pL" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"pM" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/candiedapple,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"pN" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"pO" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"pP" = (/turf/unsimulated/wall,/area/centcom/bar) +"pQ" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"pR" = (/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"pS" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 9},/obj/structure/bed/padded,/obj/item/weapon/bedsheet/captain,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"pT" = (/obj/effect/floor_decal/carpet{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"pU" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"pV" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access = list(105)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"pW" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"pX" = (/turf/unsimulated/wall,/area/centcom/living) +"pY" = (/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"pZ" = (/obj/item/weapon/stool/padded,/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"qa" = (/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{pixel_x = 2; pixel_y = 6},/obj/structure/table/standard,/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"qb" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/administration/centcom) +"qc" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating/airless,/area/shuttle/administration/centcom) +"qd" = (/obj/machinery/vending/snack,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qe" = (/obj/item/weapon/stool,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qf" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qg" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qh" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qi" = (/obj/machinery/robotic_fabricator,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qj" = (/obj/machinery/autolathe{desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; hacked = 1; name = "Thunderdome Autolathe"},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qk" = (/obj/structure/dispenser,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"ql" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"qm" = (/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"qn" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = -1},/obj/structure/curtain/open/shower,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"qo" = (/obj/machinery/door/airlock,/turf/simulated/shuttle/floor,/area/centcom/evac) +"qp" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"qq" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qr" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/bloodsoup,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qs" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/bar) +"qt" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/obj/structure/table/standard,/obj/item/weapon/melee/classic_baton,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"qu" = (/obj/effect/floor_decal/carpet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"qv" = (/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 6},/obj/structure/closet/secure_closet/personal,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"qw" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/living) +"qx" = (/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/structure/table/standard,/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"qy" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/administration/centcom) +"qz" = (/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"qA" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/shuttle/floor,/area/centcom/evac) +"qB" = (/turf/unsimulated/wall,/area/shuttle/trade) +"qC" = (/obj/structure/table/standard,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdome1) +"qD" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qE" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/amanita_pie,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qF" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{pixel_x = 4; pixel_y = -2},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qG" = (/obj/structure/bed/chair/wood/wings,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"qH" = (/obj/machinery/light,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qI" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qJ" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/simulated/shuttle/plating,/area/shuttle/administration/centcom) +"qK" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/shuttle/trade) +"qL" = (/obj/structure/table/standard,/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/shuttle/trade) +"qM" = (/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"qN" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qO" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qP" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/snacks/beetsoup,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qQ" = (/obj/machinery/smartfridge,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"qR" = (/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"qS" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"qT" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"qU" = (/obj/machinery/vending/boozeomat,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"qV" = (/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_alc/full,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"qW" = (/obj/structure/device/piano{dir = 4},/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"qX" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"qY" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod4/centcom) +"qZ" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod6/centcom) +"ra" = (/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/shuttle/trade) +"rb" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/shuttle/trade) +"rc" = (/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/drinks/glass2/square,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"rd" = (/obj/machinery/door/airlock/glass{icon_state = "door_locked"; locked = 1; name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"re" = (/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"rf" = (/obj/structure/table/marble,/obj/item/weapon/book/manual/barman_recipes,/obj/item/weapon/reagent_containers/glass/rag,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"rg" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"rh" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/snacks/tofukabob,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"ri" = (/turf/unsimulated/wall{icon = 'icons/obj/doors/Doormaint.dmi'; icon_state = "door_closed"; name = "Sealed Door"},/area/centcom/main_hall) +"rj" = (/obj/structure/table/marble,/obj/item/clothing/under/suit_jacket,/obj/item/clothing/accessory/wcoat,/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"rk" = (/obj/machinery/vending/cola,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"rl" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"rm" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"rn" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/snacks/poppypretzel,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"ro" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{pixel_x = 4; pixel_y = -2},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/bar) +"rp" = (/obj/machinery/floor_light,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/bar) +"rq" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"rr" = (/obj/effect/floor_decal/industrial/hatch/yellow,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"rs" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"rt" = (/obj/machinery/dna_scannernew,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"ru" = (/obj/machinery/computer/cloning,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"rv" = (/obj/machinery/clonepod,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"rw" = (/obj/machinery/computer/scan_consolenew,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"rx" = (/obj/machinery/computer/shuttle_control/administration,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"ry" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_4_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 4"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"rz" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_4_recovery"; pixel_x = -26; pixel_y = 26; req_one_access = list(13); tag_door = "escape_pod_4_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"rA" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_6_recovery"; pixel_x = 26; pixel_y = -26; req_one_access = list(13); tag_door = "escape_pod_6_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"rB" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_6_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 6"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"rC" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/weapon/gun/energy/gun/burst,/obj/item/weapon/gun/energy/gun/burst,/obj/item/weapon/gun/energy/ionrifle/pistol,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rD" = (/obj/structure/table/standard,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/clothing/glasses/sunglasses,/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rE" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rF" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/syndie_kit/chameleon,/obj/item/weapon/storage/box/syndie_kit/clerical,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rG" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"rH" = (/obj/machinery/door/airlock/glass{name = "Bar"},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"rI" = (/obj/machinery/floor_light,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/bar) +"rJ" = (/obj/structure/sink{pixel_y = 16},/obj/structure/mirror{pixel_x = 0; pixel_y = 32},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"rK" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor,/area/centcom/evac) +"rL" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/shotgunammo/large,/obj/item/weapon/storage/box/stunshells/large,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rM" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rN" = (/obj/machinery/computer/shuttle_control{name = "Beruang control console"; req_access = list(160); shuttle_tag = "Trade"},/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"rO" = (/obj/structure/closet/crate,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/shuttle/trade) +"rP" = (/turf/unsimulated/floor{icon_state = "dark"},/area/shuttle/trade) +"rQ" = (/obj/structure/table/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/green,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"rR" = (/obj/machinery/door/airlock/centcom{name = "Bridge Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"rS" = (/obj/machinery/door/airlock/glass_centcom{name = "Bridge Access"; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"rT" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"rU" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"rV" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{pixel_x = 4; pixel_y = -2},/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/obj/item/weapon/flame/candle,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"rW" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"rX" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"rY" = (/obj/structure/table/reinforced,/obj/machinery/librarycomp,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"rZ" = (/obj/structure/bookcase,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sa" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor,/area/centcom/evac) +"sb" = (/obj/structure/table/rack,/obj/item/clothing/suit/storage/vest/heavy/merc,/obj/item/clothing/suit/storage/vest/heavy,/obj/item/clothing/suit/storage/vest,/obj/item/clothing/head/helmet,/obj/item/clothing/head/helmet,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sc" = (/obj/structure/frame/computer,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sd" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/shuttle/trade) +"se" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"sf" = (/obj/machinery/media/jukebox,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"sg" = (/obj/machinery/vending/cola{name = "hacked Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"sh" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"si" = (/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{pixel_x = -6},/obj/structure/table/standard,/obj/effect/floor_decal/corner/yellow/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/living) +"sj" = (/obj/machinery/door/window/northright{icon_state = "right"; dir = 2},/obj/machinery/light{dir = 8},/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sk" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/surgery,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sl" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sm" = (/obj/structure/table/standard,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sn" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod3/centcom) +"so" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod5/centcom) +"sp" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/shuttle/trade) +"sq" = (/obj/machinery/door/airlock/multi_tile/glass{dir = 4; req_access = list(160)},/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sr" = (/obj/structure/table/woodentable{dir = 5},/obj/item/device/flashlight/lamp/green,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"ss" = (/obj/machinery/floor_light,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/bar) +"st" = (/obj/machinery/light{dir = 8},/obj/structure/bed/padded,/obj/item/weapon/bedsheet/hos,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"su" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 3"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"sv" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_3_recovery"; pixel_x = -26; pixel_y = 26; req_one_access = list(13); tag_door = "escape_pod_3_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"sw" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/centcom/evac) +"sx" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_5_recovery"; pixel_x = 26; pixel_y = -26; req_one_access = list(13); tag_door = "escape_pod_5_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"sy" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 5"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"sz" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{pixel_y = 3},/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"sA" = (/obj/structure/table/standard,/obj/item/weapon/soap/deluxe,/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"sB" = (/obj/structure/table/standard,/obj/item/clothing/accessory/permit,/obj/item/clothing/accessory/permit,/obj/item/clothing/accessory/permit,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sC" = (/obj/structure/closet/wardrobe/white,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sD" = (/obj/structure/closet/wardrobe/green,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sE" = (/obj/structure/closet/wardrobe/grey,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"sF" = (/obj/machinery/button/remote/blast_door{id = "tradestationshutters"; name = "warehouse control"; pixel_x = -30; req_access = list(160)},/turf/unsimulated/floor{icon_state = "dark"},/area/shuttle/trade) +"sG" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"sH" = (/obj/structure/toilet{dir = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"sI" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"sJ" = (/obj/machinery/vending/medical,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sK" = (/obj/machinery/chem_master,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sL" = (/obj/machinery/chemical_dispenser/ert,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) +"sM" = (/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"sN" = (/obj/machinery/door/blast/shutters{dir = 8; id = "tradestationshutters"; name = "Warehouse Shutters"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/shuttle/trade) +"sO" = (/obj/structure/table/standard,/obj/random/soap,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bar) +"sP" = (/obj/structure/sign/double/barsign,/turf/unsimulated/wall,/area/centcom/bar) +"sQ" = (/obj/structure/sign/directions/cargo{dir = 8},/obj/structure/sign/directions/security{dir = 8; pixel_y = -10},/obj/structure/sign/directions/engineering{dir = 8; pixel_y = 10},/turf/unsimulated/wall,/area/centcom/main_hall) +"sR" = (/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"sS" = (/obj/structure/sign/directions/medical{dir = 4},/obj/structure/sign/directions/evac{pixel_y = 10},/turf/unsimulated/wall,/area/centcom/main_hall) +"sT" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/machinery/button/remote/blast_door{desc = "A remote control switch for port-side blast doors."; id = "CentComPort"; name = "Security Doors"; pixel_x = -25; pixel_y = -25; req_access = list(101)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"sU" = (/obj/machinery/door/airlock/glass{icon_state = "door_locked"; locked = 1; name = "Central Access"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"sV" = (/obj/machinery/turretid{pixel_x = -28; pixel_y = -28; req_access = list(101)},/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"sW" = (/obj/machinery/vending/snack,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"sX" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"sY" = (/obj/machinery/vending/cola,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"sZ" = (/obj/machinery/vending/cigarette,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) +"ta" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"tb" = (/obj/machinery/door/airlock{name = "Restroom"},/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"tc" = (/obj/structure/table/bench/steel,/obj/effect/landmark{name = "Trader"},/turf/unsimulated/floor{icon_state = "dark"},/area/shuttle/trade) +"td" = (/obj/effect/landmark{name = "Trader"},/turf/unsimulated/floor{icon_state = "dark"},/area/shuttle/trade) +"te" = (/obj/structure/table/glass,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"tf" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"tg" = (/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"th" = (/obj/structure/table/reinforced,/obj/item/frame/light,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"ti" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"tj" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/mechanical,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"tk" = (/obj/item/weapon/tool/crowbar,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"tl" = (/obj/machinery/computer/crew,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tm" = (/obj/machinery/bodyscanner{dir = 8},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tn" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"to" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tp" = (/obj/machinery/atmospherics/unary/cryo_cell{layer = 3.3},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tq" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer"},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tr" = (/obj/machinery/button/remote/blast_door{id = "tradestationshutters"; name = "warehouse control"; pixel_x = 30; req_access = list(160)},/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"ts" = (/turf/unsimulated/floor{icon_state = "white"},/area/centcom/main_hall) +"tt" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tu" = (/obj/machinery/iv_drip,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tv" = (/obj/structure/bed/roller,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tw" = (/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = -4; pixel_y = 0},/obj/item/weapon/tool/wrench,/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tx" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"ty" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tz" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tA" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"tB" = (/obj/machinery/door/airlock/silver{name = "Toilet"},/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"tC" = (/obj/structure/closet/wardrobe/pink,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tD" = (/obj/structure/closet/wardrobe/yellow,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tE" = (/obj/structure/closet/wardrobe/mixed,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tF" = (/obj/structure/closet/wardrobe/pjs,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tG" = (/obj/structure/closet/wardrobe/suit,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tH" = (/obj/structure/closet/wardrobe/xenos,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tI" = (/obj/structure/closet/wardrobe/black,/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"tJ" = (/obj/item/frame/light,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"tK" = (/obj/machinery/chem_master,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tL" = (/obj/structure/closet/secure_closet/bar{req_access = list(25)},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"tM" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tN" = (/obj/machinery/chemical_dispenser/full,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/table/standard,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tO" = (/obj/machinery/chemical_dispenser/ert,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/table/standard,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tP" = (/obj/structure/closet/secure_closet/medical_wall/pills{pixel_y = 32},/obj/structure/table/glass,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tQ" = (/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/obj/machinery/atmospherics/portables_connector,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tR" = (/obj/machinery/atmospherics/unary/cryo_cell,/obj/effect/floor_decal/corner/blue{dir = 5},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"tS" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tT" = (/obj/structure/toilet{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/shuttle/trade) +"tU" = (/turf/unsimulated/wall,/area/centcom/security) +"tV" = (/turf/unsimulated/wall,/area/centcom/medical) +"tW" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -30; pixel_y = 0},/obj/structure/table/standard,/obj/item/device/defib_kit,/obj/item/device/defib_kit,/obj/machinery/recharger,/obj/item/weapon/tool/screwdriver,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tX" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tY" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"tZ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "trade_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 25; pixel_y = 0; tag_door = "trade_shuttle_bay_door"},/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"ua" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ub" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uc" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/effect/floor_decal/corner/orange/full{dir = 8},/obj/item/weapon/reagent_containers/glass/bucket,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ud" = (/obj/structure/table/reinforced,/obj/item/weapon/material/minihoe,/obj/item/device/analyzer/plant_analyzer,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ue" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uf" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ug" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uh" = (/obj/structure/closet/secure_closet/security,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ui" = (/obj/structure/closet/secure_closet/security,/obj/effect/floor_decal/corner/red{dir = 5},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uj" = (/obj/structure/closet/secure_closet/security,/obj/effect/floor_decal/corner/red/full{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uk" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/medical) +"ul" = (/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"um" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer"},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"un" = (/obj/machinery/atmospherics/unary/cryo_cell,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uo" = (/obj/machinery/iv_drip,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"up" = (/obj/structure/table/glass,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uq" = (/obj/structure/table/standard,/obj/item/weapon/surgical/hemostat,/obj/item/weapon/surgical/cautery,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"ur" = (/obj/structure/table/standard,/obj/item/stack/medical/advanced/bruise_pack,/obj/item/weapon/surgical/retractor,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"us" = (/obj/structure/table/standard,/obj/item/weapon/surgical/circular_saw{pixel_y = 8},/obj/item/weapon/surgical/scalpel,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"ut" = (/obj/structure/table/standard,/obj/item/weapon/surgical/surgicaldrill,/obj/item/weapon/autopsy_scanner,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; name = "Surgery Cleaner"; pixel_x = 2; pixel_y = 2},/obj/item/weapon/surgical/FixOVein,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uu" = (/obj/structure/closet/crate/medical,/obj/item/weapon/surgical/circular_saw,/obj/item/weapon/surgical/surgicaldrill,/obj/item/weapon/surgical/bonegel{pixel_x = 4; pixel_y = 3},/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/scalpel,/obj/item/weapon/surgical/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/surgical/hemostat{pixel_y = 4},/obj/item/weapon/surgical/cautery{pixel_y = 4},/obj/item/weapon/surgical/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/nanopaste,/obj/item/weapon/tank/anesthetic,/obj/item/clothing/mask/breath/medical,/obj/item/clothing/mask/surgical,/obj/item/clothing/mask/surgical,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uv" = (/obj/machinery/door/airlock/hatch{name = "Cockpit"; req_access = list(109)},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uw" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/bodybags,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"ux" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uy" = (/obj/machinery/clonepod,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uz" = (/obj/machinery/computer/cloning,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uA" = (/obj/machinery/dna_scannernew,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uB" = (/obj/structure/closet{name = "Prisoner's Locker"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uC" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/security) +"uD" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"uE" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uF" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uG" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uH" = (/obj/structure/table/standard,/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/bonegel,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uI" = (/obj/machinery/iv_drip,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uJ" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uK" = (/obj/machinery/computer/crew,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uL" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uM" = (/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uN" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uO" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uP" = (/obj/machinery/door/airlock/medical{name = "Morgue"; req_access = list(6)},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uQ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "trade_shuttle_bay_door"; locked = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/shuttle/trade) +"uR" = (/obj/machinery/optable,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uS" = (/obj/machinery/computer/operating,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"uT" = (/obj/machinery/computer/operating,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uU" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"uV" = (/obj/structure/morgue,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uW" = (/obj/structure/morgue{icon_state = "morgue1"; dir = 8},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"uX" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/shuttle/merchant/home) +"uY" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "trade_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"uZ" = (/turf/simulated/shuttle/wall/dark,/area/shuttle/merchant/home) +"va" = (/obj/machinery/vending/hydronutrients,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vb" = (/obj/machinery/vending/hydroseeds,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vc" = (/obj/structure/table/reinforced,/obj/item/clothing/head/greenbandana,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vd" = (/obj/machinery/computer/security,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ve" = (/obj/machinery/bodyscanner{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vf" = (/obj/machinery/body_scanconsole,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vg" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vh" = (/obj/machinery/vending/wallmed1{pixel_y = -30},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vi" = (/obj/structure/closet/secure_closet/medical2,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vj" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/box/masks{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/box/gloves{pixel_x = 3; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire{layer = 2.9; pixel_x = 2; pixel_y = 3},/obj/item/weapon/storage/firstaid/adv{pixel_x = -2},/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"vk" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 0},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"vl" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/fire{pixel_x = -2; pixel_y = 4},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"vm" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/toxin{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"vn" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"vo" = (/obj/structure/table/standard,/obj/item/weapon/clipboard,/obj/item/weapon/pen,/obj/item/weapon/stamp/captain,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"vp" = (/obj/machinery/computer/shuttle,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"vq" = (/obj/structure/table/standard,/obj/item/weapon/storage/lockbox,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"vr" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"vs" = (/obj/structure/table/standard,/obj/item/device/radio/off,/obj/item/weapon/paper_bin,/turf/simulated/shuttle/floor/black,/area/centcom/evac) +"vt" = (/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"vu" = (/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"vv" = (/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"vw" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "trade_shuttle"; pixel_x = -25; pixel_y = 0; req_one_access = list(101); tag_door = "trade_shuttle_hatch"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vx" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vy" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/shuttle/plating/airless,/area/shuttle/merchant/home) +"vz" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/merchant/home) +"vA" = (/obj/machinery/door/window/brigdoor{dir = 4; name = "Security"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vB" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) +"vC" = (/obj/structure/table/glass,/obj/machinery/reagentgrinder,/obj/effect/floor_decal/corner/paleblue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vD" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/shuttle/plating,/area/centcom/evac) +"vE" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vF" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/rd,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vG" = (/obj/structure/table/standard,/obj/machinery/chemical_dispenser/bar_alc/full,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vH" = (/obj/structure/table/standard,/obj/machinery/microwave,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vI" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"vJ" = (/obj/structure/bed/chair,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"vK" = (/obj/structure/flora/pottedplant{icon_state = "plant-22"},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"vL" = (/obj/machinery/sleep_console{dir = 8},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vM" = (/obj/machinery/sleeper{dir = 4},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"vN" = (/turf/space,/obj/structure/shuttle/engine/propulsion{dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/merchant/home) +"vO" = (/obj/structure/table/bench/steel,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vP" = (/obj/structure/closet/secure_closet/brig,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vQ" = (/obj/structure/table/reinforced,/obj/item/weapon/book/codex/corp_regs,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"vR" = (/obj/machinery/door/airlock/glass_security{name = "Security Lobby"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) +"vS" = (/obj/machinery/door/airlock/glass{name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/medical) +"vT" = (/obj/structure/closet/secure_closet/chemical,/obj/effect/floor_decal/corner/paleblue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vU" = (/obj/structure/table/glass,/obj/item/stack/material/phoron,/obj/effect/floor_decal/corner/paleblue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vV" = (/obj/machinery/door/airlock/glass{name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vW" = (/obj/machinery/sleeper{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vX" = (/obj/machinery/sleep_console,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vY" = (/obj/structure/closet/wardrobe/white,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"vZ" = (/obj/machinery/clonepod,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"wa" = (/obj/machinery/computer/cloning,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"wb" = (/obj/machinery/dna_scannernew,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"wc" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"wd" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"we" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wf" = (/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wg" = (/obj/machinery/door/airlock/silver{name = "Sleeping"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wh" = (/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"wi" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"wj" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"wk" = (/obj/machinery/atm{pixel_x = -32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wl" = (/obj/machinery/suit_cycler/syndicate,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wm" = (/obj/machinery/bodyscanner{dir = 8},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wn" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wo" = (/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/box/masks{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/box/gloves{pixel_x = 3; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire{layer = 2.9; pixel_x = 2; pixel_y = 3},/obj/item/weapon/storage/firstaid/adv{pixel_x = -2},/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/structure/closet/medical_wall{pixel_y = 32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wp" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wq" = (/obj/structure/table/reinforced,/obj/item/device/taperecorder,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"wr" = (/obj/structure/table/reinforced,/obj/item/weapon/book/codex/corp_regs,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ws" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/pill_bottle/dice,/obj/item/weapon/deck/cards,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"wt" = (/obj/machinery/door/airlock/glass_security{name = "Spaceport Security Airlock"; req_access = list(63)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"wu" = (/obj/structure/table/bench/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"wv" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"ww" = (/obj/structure/closet/wardrobe/pjs,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wx" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 8},/obj/item/weapon/pen{pixel_y = 4},/obj/machinery/light,/obj/structure/table/glass,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wy" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/hos,/obj/structure/sign/poster{pixel_y = -32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wz" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"wA" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/glasses/square,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"wB" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 32},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"wC" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/inflatable_duck,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wD" = (/obj/structure/table/steel_reinforced,/obj/item/stack/material/mhydrogen,/obj/item/stack/material/diamond,/obj/item/stack/material/sandstone,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wE" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/rig/internalaffairs,/obj/item/clothing/head/helmet/space/void/wizard,/obj/item/clothing/suit/space/void/wizard,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wF" = (/obj/structure/table/steel_reinforced,/obj/random/tool,/obj/random/tool,/obj/random/tool,/obj/random/tool,/obj/random/tool,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wG" = (/obj/structure/table/steel_reinforced,/obj/random/toolbox,/obj/random/toolbox,/obj/random/toolbox,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wH" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"wI" = (/obj/vehicle/train/engine,/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wJ" = (/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"wK" = (/obj/machinery/door/airlock/glass_medical{name = "Medical Bay"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wL" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wM" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/merchant/home) +"wN" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/red,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"wO" = (/obj/structure/closet/walllocker/emerglocker{pixel_y = -32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wP" = (/obj/machinery/button/remote/blast_door{id = "tradestarshutters"; name = "remote shutter control"; pixel_x = 30; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wQ" = (/obj/structure/table/steel_reinforced,/obj/random/firstaid,/obj/random/firstaid,/obj/random/firstaid,/obj/random/firstaid,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wR" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wS" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wT" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wU" = (/obj/structure/table/steel_reinforced,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/weapon/weldpack,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wV" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"wW" = (/obj/vehicle/train/trolley,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wX" = (/obj/machinery/light,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wY" = (/obj/machinery/vending/medical{pixel_y = -32; req_access = null},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"wZ" = (/obj/machinery/door/airlock/glass_security{name = "Security Processing"; req_access = list(1)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xa" = (/obj/structure/table/bench/padded,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) +"xb" = (/obj/structure/morgue,/obj/effect/floor_decal/corner/blue/full{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xc" = (/obj/effect/floor_decal/corner/blue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xd" = (/obj/structure/morgue{icon_state = "morgue1"; dir = 8},/obj/effect/floor_decal/corner/blue/full{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xe" = (/obj/machinery/door/airlock/multi_tile/glass{dir = 4; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xf" = (/obj/structure/table/steel_reinforced,/obj/random/medical,/obj/random/medical,/obj/random/medical,/obj/random/medical,/obj/structure/window/reinforced,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xg" = (/obj/machinery/door/window/southleft{name = "Cargo Hold"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xh" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/coin/uranium,/obj/item/weapon/coin/silver,/obj/item/weapon/coin/platinum,/obj/item/weapon/coin/phoron,/obj/item/weapon/coin/iron,/obj/item/weapon/coin/gold,/obj/item/weapon/coin/diamond,/obj/structure/window/reinforced,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xi" = (/obj/machinery/door/window/southright{name = "Cargo Hold"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xj" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/hyper,/obj/item/weapon/cell/potato,/obj/structure/window/reinforced,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xk" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"xl" = (/obj/structure/table/standard,/obj/item/clothing/gloves/sterile/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/surgical/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/surgical/scalpel,/obj/item/weapon/surgical/surgicaldrill,/obj/item/weapon/surgical/circular_saw,/obj/item/stack/nanopaste,/obj/item/weapon/surgical/hemostat{pixel_y = 4},/obj/item/weapon/surgical/cautery{pixel_y = 4},/obj/item/weapon/surgical/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/medical/advanced/bruise_pack,/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/bonegel{pixel_x = 4; pixel_y = 3},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xm" = (/obj/machinery/iv_drip,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xn" = (/obj/structure/table/glass,/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xo" = (/obj/structure/morgue,/obj/effect/floor_decal/corner/blue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xp" = (/obj/structure/morgue{icon_state = "morgue1"; dir = 8},/obj/effect/floor_decal/corner/blue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xq" = (/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"xr" = (/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"xs" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xt" = (/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xu" = (/obj/machinery/door/airlock/multi_tile/glass,/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"xv" = (/obj/structure/closet/crate/secure/weapon,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xw" = (/obj/machinery/computer/arcade/orion_trail,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xx" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xy" = (/obj/structure/table/glass,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xz" = (/obj/effect/floor_decal/corner/paleblue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xA" = (/obj/structure/closet/secure_closet/personal/patient,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xB" = (/obj/effect/floor_decal/corner/blue{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xC" = (/obj/structure/filingcabinet/chestdrawer{desc = "A large drawer filled with autopsy reports."; name = "Autopsy Reports"},/obj/effect/floor_decal/corner/blue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xD" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 8},/obj/item/weapon/pen{pixel_y = 4},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xE" = (/obj/structure/table/steel_reinforced,/obj/machinery/newscaster{pixel_x = 32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xF" = (/obj/structure/toilet,/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) +"xG" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/light/small,/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) +"xH" = (/obj/structure/mirror{pixel_x = 0; pixel_y = 28},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) +"xI" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{pixel_y = 3},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) +"xJ" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xK" = (/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"xL" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xM" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xN" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donkpockets,/obj/item/weapon/storage/box/donkpockets,/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 30},/obj/effect/floor_decal/corner/orange{dir = 6},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xO" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xP" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xQ" = (/obj/structure/bed/chair/office/light{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xR" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{dir = 4; name = "Security"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"xS" = (/obj/structure/table/standard,/obj/item/roller,/obj/item/roller{pixel_y = 8},/obj/item/roller{pixel_y = 16},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xT" = (/obj/structure/table/glass,/obj/machinery/computer/med_data/laptop,/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xU" = (/obj/item/device/camera{name = "Autopsy Camera"; pixel_x = -2; pixel_y = 7},/obj/item/weapon/paper_bin{pixel_y = -6},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = -9},/obj/item/weapon/pen/blue{pixel_x = 3; pixel_y = -5},/obj/structure/table/standard,/obj/effect/floor_decal/corner/blue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"xV" = (/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"xW" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"xX" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_mob/animal/passive/dog/tamaskan/Spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"xY" = (/obj/machinery/door/airlock/silver{name = "Toilet"},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) +"xZ" = (/obj/machinery/door/airlock/silver{name = "Restroom"},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) +"ya" = (/obj/structure/undies_wardrobe,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yb" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yc" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/obj/structure/largecrate/animal/cat,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yd" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/structure/largecrate/animal/cow,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"ye" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/structure/closet/crate/freezer/rations,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yf" = (/obj/structure/table/rack,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/item/device/kit/paint/ripley/death,/obj/item/device/kit/paint/ripley/flames_blue,/obj/item/device/kit/paint/ripley/flames_red,/obj/item/device/kit/paint/ripley,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yg" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/structure/closet/crate/secure/loot,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yh" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/structure/largecrate/hoverpod,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yi" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/obj/mecha/working/ripley/mining,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yj" = (/obj/machinery/door/window/westright{name = "Storefront"; req_access = list(160)},/obj/structure/table/marble,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "trade"; name = "Shop Shutters"; opacity = 0},/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"yk" = (/obj/structure/bed/chair/office/dark{dir = 8},/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"yl" = (/obj/machinery/computer/arcade/battle,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ym" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/effect/floor_decal/corner/orange{dir = 10},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"yn" = (/obj/structure/table/reinforced,/obj/machinery/microwave,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"yo" = (/obj/item/device/camera{desc = "A one use - polaroid camera. 30 photos left."; name = "detectives camera"; pictures_left = 30; pixel_x = 2; pixel_y = 3},/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"yp" = (/obj/item/weapon/storage/box/evidence,/obj/item/weapon/folder/red,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"yq" = (/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"yr" = (/obj/structure/closet{name = "Evidence Closet"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"ys" = (/obj/machinery/computer/card,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/security) +"yt" = (/obj/machinery/smartfridge/chemistry,/turf/unsimulated/wall,/area/centcom/medical) +"yu" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"yv" = (/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/obj/structure/table/standard,/obj/effect/floor_decal/corner/blue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"yw" = (/obj/effect/floor_decal/corner/blue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"yx" = (/obj/item/weapon/autopsy_scanner,/obj/item/weapon/surgical/scalpel,/obj/structure/table/standard,/obj/effect/floor_decal/corner/blue/full{dir = 4},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"yy" = (/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"yz" = (/obj/machinery/computer/shuttle_control/merchant,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yA" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"yB" = (/obj/machinery/door/airlock/command{name = "Bridge"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yC" = (/obj/structure/noticeboard{pixel_y = 32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yD" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/obj/structure/largecrate/animal/corgi,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yE" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/largecrate/animal/corgi,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yF" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/closet/crate/internals,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yG" = (/obj/structure/table/rack,/obj/effect/floor_decal/industrial/warning,/obj/item/device/kit/paint/gygax/darkgygax,/obj/item/device/kit/paint/gygax/recitence,/obj/item/device/kit/paint/durand,/obj/item/device/kit/paint/durand/phazon,/obj/item/device/kit/paint/durand/seraph,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yH" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/closet/crate/secure/loot,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yI" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/largecrate/hoverpod,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yJ" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/mecha/working/ripley/firefighter,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yK" = (/obj/machinery/door/window/westleft{name = "Storefront"; req_access = list(160)},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "trade"; name = "Shop Shutters"; opacity = 0},/obj/structure/table/marble,/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"yL" = (/obj/machinery/door/airlock/medical,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"yM" = (/obj/machinery/computer/arcade/battle,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yN" = (/obj/structure/table/steel_reinforced,/obj/machinery/button/remote/blast_door{id = "tradebridgeshutters"; name = "remote shutter control"; pixel_x = 30; req_access = list(150)},/obj/structure/flora/pottedplant{icon_state = "plant-09"; name = "Esteban"; pixel_y = 8},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yO" = (/obj/machinery/vending/assist{contraband = null; name = "Old Vending Machine"; products = list(/obj/item/device/assembly/prox_sensor = 5, /obj/item/device/assembly/signaler = 4, /obj/item/device/assembly/infra = 4, /obj/item/device/assembly/prox_sensor = 4, /obj/item/weapon/handcuffs = 8, /obj/item/device/flash = 4, /obj/item/weapon/cartridge/signal = 4, /obj/item/clothing/glasses/sunglasses = 4)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yP" = (/obj/structure/closet{name = "custodial"},/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/mop,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yQ" = (/obj/machinery/vending/sovietsoda,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yR" = (/obj/machinery/light,/obj/structure/table/standard,/obj/item/weapon/soap,/obj/item/weapon/towel{color = "#0000FF"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yS" = (/obj/structure/sign/poster{pixel_y = -32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yT" = (/obj/machinery/door/airlock/multi_tile/glass{dir = 2; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yU" = (/obj/machinery/door/window/westleft{name = "Storefront"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yV" = (/obj/machinery/button/remote/blast_door{id = "trade"; name = "Shop Shutters"; pixel_x = 0; pixel_y = -26},/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"yW" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/head/bearpelt,/obj/item/clothing/head/bowler,/obj/item/clothing/head/caphat/cap,/obj/item/clothing/head/beaverhat,/obj/item/clothing/head/beret/centcom,/obj/item/clothing/head/beret/sec,/obj/item/clothing/head/collectable/kitty,/obj/item/clothing/head/collectable/kitty,/obj/item/clothing/head/collectable/kitty,/obj/item/clothing/head/collectable/rabbitears,/obj/item/clothing/head/collectable/rabbitears,/obj/item/clothing/head/collectable/rabbitears,/obj/item/clothing/head/collectable/petehat,/obj/item/clothing/head/collectable/pirate,/obj/item/clothing/head/collectable/wizard,/obj/item/clothing/head/collectable/xenom,/obj/item/clothing/head/cowboy_hat,/obj/item/clothing/head/pin/flower/violet,/obj/item/clothing/head/pin/flower/blue,/obj/item/clothing/head/pin/flower/orange,/obj/item/clothing/head/pin/flower/pink,/obj/item/clothing/head/justice,/obj/item/clothing/head/justice/blue,/obj/item/clothing/head/justice/green,/obj/item/clothing/head/justice/pink,/obj/item/clothing/head/justice/yellow,/obj/item/clothing/head/philosopher_wig,/obj/item/clothing/head/plaguedoctorhat,/obj/item/clothing/head/xenos,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"yX" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"yY" = (/turf/unsimulated/wall,/area/centcom/terminal) +"yZ" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"za" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"zb" = (/obj/machinery/vending/boozeomat{req_access = null},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zc" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zd" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"ze" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/under/cheongsam,/obj/item/clothing/under/hosformalmale,/obj/item/clothing/under/hosformalfem,/obj/item/clothing/under/harness,/obj/item/clothing/under/gladiator,/obj/item/clothing/under/ert,/obj/item/clothing/under/schoolgirl,/obj/item/clothing/under/redcoat,/obj/item/clothing/under/sexymime,/obj/item/clothing/under/sexyclown,/obj/item/clothing/under/soviet,/obj/item/clothing/under/space,/obj/item/clothing/under/swimsuit/stripper/mankini,/obj/item/clothing/under/suit_jacket/female,/obj/item/clothing/under/rank/psych/turtleneck,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/under/syndicate/tacticool,/obj/item/clothing/under/syndicate/tacticool,/obj/item/clothing/under/dress/sailordress,/obj/item/clothing/under/dress/redeveninggown,/obj/item/clothing/under/dress/dress_saloon,/obj/item/clothing/under/dress/blacktango,/obj/item/clothing/under/dress/blacktango/alt,/obj/item/clothing/under/dress/dress_orange,/obj/item/clothing/under/dress/maid/janitor,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zf" = (/obj/machinery/door/airlock/glass{name = "Dock"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) +"zg" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table/steel_reinforced,/obj/item/weapon/contraband/poster,/obj/item/weapon/contraband/poster,/obj/item/weapon/contraband/poster,/obj/item/weapon/contraband/poster,/obj/item/weapon/contraband/poster,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zh" = (/obj/machinery/door/window/northleft{name = "Cargo Hold"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zi" = (/obj/structure/table/steel_reinforced,/obj/random/plushie,/obj/random/plushie,/obj/random/plushie,/obj/random/plushie,/obj/random/plushie,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zj" = (/obj/machinery/door/window/northright{name = "Cargo Hold"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zk" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/blue,/obj/item/clothing/gloves/brown,/obj/item/clothing/gloves/captain,/obj/item/clothing/gloves/combat,/obj/item/clothing/gloves/green,/obj/item/clothing/gloves/grey,/obj/item/clothing/gloves/light_brown,/obj/item/clothing/gloves/purple,/obj/item/clothing/gloves/rainbow,/obj/item/clothing/gloves/swat,/obj/item/clothing/gloves/white,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zl" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 2; start_pressure = 740.5},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zm" = (/obj/structure/closet/walllocker/emerglocker{pixel_y = 32},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zn" = (/obj/machinery/autolathe{desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; hacked = 1; name = "Unlocked Autolathe"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zo" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/terminal) +"zp" = (/obj/machinery/button/remote/blast_door{id = "tradeportshutters"; name = "remote shutter control"; pixel_x = 30; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zq" = (/obj/structure/table/steel_reinforced,/obj/random/contraband,/obj/random/contraband,/obj/random/contraband,/obj/random/contraband,/obj/random/contraband,/obj/random/contraband,/obj/item/weapon/bikehorn,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zr" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zs" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zt" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zu" = (/obj/machinery/door/airlock/glass{icon_state = "door_locked"; locked = 1; name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"zv" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/meter,/obj/structure/largecrate/animal/cat,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zw" = (/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zx" = (/obj/machinery/vending/medical,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zy" = (/obj/structure/flora/pottedplant/orientaltree,/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zz" = (/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zA" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/adv{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/adv,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zB" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/toxin{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/toxin{pixel_x = 0; pixel_y = 0},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zC" = (/obj/structure/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/paleblue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zD" = (/obj/structure/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/paleblue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zE" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/o2{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/o2{pixel_x = 0; pixel_y = 0},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zF" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/fire{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/fire{pixel_x = 0; pixel_y = 0},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zG" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/emergency,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zH" = (/obj/effect/floor_decal/corner/paleblue,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zI" = (/obj/effect/floor_decal/corner/paleblue{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zJ" = (/obj/structure/closet/secure_closet/medical_wall{name = "O- Blood Locker"; pixel_x = 0; pixel_y = -32},/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/effect/floor_decal/corner/paleblue{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zK" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"zL" = (/obj/structure/closet/wardrobe/captain,/obj/item/weapon/gun/projectile/revolver/mateba,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zM" = (/obj/machinery/light{dir = 1},/obj/structure/bookcase,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zN" = (/obj/structure/bed/chair/comfy/black,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zO" = (/obj/structure/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"zP" = (/obj/machinery/photocopier,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"zQ" = (/obj/structure/table/steel_reinforced,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zR" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/lipstick/black,/obj/item/weapon/lipstick/jade,/obj/item/weapon/lipstick/purple,/obj/item/weapon/lipstick,/obj/item/weapon/lipstick/random,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zS" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/armpit,/obj/item/clothing/accessory/holster/hip,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/webbing,/obj/item/clothing/accessory/storage/webbing,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/scarf/white,/obj/item/clothing/accessory/scarf/lightblue,/obj/item/clothing/accessory/scarf/red,/obj/item/clothing/accessory/scarf/purple,/obj/item/clothing/accessory/armband/science,/obj/item/clothing/accessory/armband/med,/obj/item/clothing/accessory/armband/engine,/obj/item/clothing/accessory/armband/cargo,/obj/item/clothing/accessory/armband,/obj/item/clothing/accessory/medal/nobel_science,/obj/item/clothing/accessory/medal/silver,/obj/item/clothing/accessory/medal/gold,/obj/item/clothing/accessory/medal/bronze_heart,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zT" = (/obj/effect/floor_decal/corner/paleblue/full{dir = 4},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zU" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/suit/hgpirate,/obj/item/clothing/suit/imperium_monk,/obj/item/clothing/suit/leathercoat,/obj/item/clothing/suit/justice,/obj/item/clothing/suit/justice,/obj/item/clothing/suit/justice,/obj/item/clothing/suit/justice,/obj/item/clothing/suit/justice,/obj/item/clothing/suit/pirate,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zV" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/closet/crate/solar,/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"zW" = (/obj/effect/floor_decal/corner/paleblue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zX" = (/obj/effect/floor_decal/corner/paleblue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zY" = (/obj/machinery/door/airlock/glass_medical{id_tag = "MedbayFoyer"; name = "Medbay"; req_access = list(5)},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"zZ" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/paleblue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Aa" = (/obj/structure/bed/chair/office/light{dir = 8},/obj/effect/floor_decal/corner/paleblue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Ab" = (/obj/structure/table/standard,/obj/item/roller,/obj/item/roller{pixel_y = 8},/obj/item/roller{pixel_y = 16},/obj/effect/floor_decal/corner/paleblue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Ac" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/paleblue/full,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Ad" = (/obj/structure/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/paleblue/full{dir = 4},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Ae" = (/obj/structure/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/paleblue/full,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Af" = (/obj/machinery/computer/crew,/obj/effect/floor_decal/corner/paleblue/full,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Ag" = (/turf/unsimulated/floor{icon_state = "asteroid"},/area/centcom/terminal) +"Ah" = (/turf/unsimulated/wall{icon = 'icons/obj/doors/Doormaint.dmi'; icon_state = "door_closed"; name = "Sealed Door"},/area/centcom/terminal) +"Ai" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/terminal) +"Aj" = (/obj/structure/closet/emcloset,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/terminal) +"Ak" = (/obj/structure/sign/directions/cargo{dir = 1},/obj/structure/sign/directions/security{dir = 1; pixel_y = -10},/obj/structure/sign/directions/engineering{dir = 1; pixel_y = 10},/turf/unsimulated/wall,/area/centcom/terminal) +"Al" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"Am" = (/obj/machinery/door/airlock/command{name = "Captain's Quarters"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"An" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 8},/obj/item/weapon/pen{pixel_y = 4},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"Ao" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/escape/centcom) +"Ap" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"Aq" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"Ar" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"As" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) +"At" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/obj/machinery/atm{pixel_x = -32},/obj/machinery/meter,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Au" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "trade2_control"; pixel_x = -22; pixel_y = -32; req_one_access = list(150)},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Av" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 10},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Aw" = (/obj/structure/table/standard,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/head/helmet/space/void/merc,/obj/item/clothing/head/helmet/space/void/merc,/obj/item/clothing/head/helmet/space/void/merc,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Ax" = (/obj/structure/table/standard,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Ay" = (/obj/structure/table/standard,/obj/item/stack/material/steel{amount = 2},/obj/item/stack/material/steel{amount = 2},/obj/item/stack/material/glass{amount = 15},/obj/item/stack/material/glass{amount = 15},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Az" = (/obj/structure/sign/directions/medical{dir = 1; pixel_y = -10},/obj/structure/sign/directions/science{dir = 1},/turf/unsimulated/wall,/area/centcom/terminal) +"AA" = (/obj/machinery/door/airlock/glass{name = "Dock"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AB" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AC" = (/obj/effect/floor_decal/corner/white/full{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AD" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/captain,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AE" = (/obj/structure/table/glass,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AF" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AG" = (/obj/machinery/light,/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"AH" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"AI" = (/obj/structure/flora/pottedplant{icon_state = "plant-10"},/turf/simulated/floor/carpet,/area/shuttle/merchant/home) +"AJ" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "trade2_shuttle_inner"; locked = 1; name = "Ship Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AK" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "trade2_shuttle_inner"; locked = 1; name = "Ship Hatch"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AL" = (/obj/machinery/vending/engivend,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AM" = (/obj/machinery/vending/tool,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AN" = (/obj/effect/floor_decal/industrial/warning/cee{icon_state = "warningcee"; dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"AO" = (/obj/effect/floor_decal/industrial/warning/cee{icon_state = "warningcee"; dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"AP" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AQ" = (/obj/effect/floor_decal/corner/white/diagonal{icon_state = "corner_white_diagonal"; dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AR" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AS" = (/obj/structure/table/standard,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"AT" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1331; id_tag = "trade2_vent"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1331; id_tag = "trade2_control"; pixel_x = -24; req_access = list(150); tag_airpump = "trade2_vent"; tag_chamber_sensor = "trade2_sensor"; tag_exterior_door = "trade2_shuttle_outer"; tag_interior_door = "trade2_shuttle_inner"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AU" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "trade2_sensor"; pixel_x = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1331; id_tag = "trade2_vent"},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AV" = (/obj/structure/table/standard,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"AW" = (/obj/structure/grille,/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) +"AX" = (/obj/effect/floor_decal/industrial/warning/corner,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"AY" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "trade2_shuttle_outer"; locked = 1; name = "Ship Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"AZ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "trade2_control"; pixel_x = 24; req_one_access = list(150)},/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "trade2_shuttle_outer"; locked = 1; name = "Ship Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) +"Ba" = (/obj/structure/table/standard,/obj/machinery/ai_status_display{pixel_y = 32},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bb" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bc" = (/obj/effect/floor_decal/industrial/loading{icon_state = "loadingarea"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bd" = (/obj/effect/floor_decal/industrial/loading{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Be" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bf" = (/obj/machinery/light{dir = 8},/obj/structure/bed/chair/shuttle{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bg" = (/obj/machinery/light{dir = 8},/obj/structure/closet/emcloset,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bh" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/structure/closet/emcloset,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bi" = (/obj/structure/grille,/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) +"Bj" = (/obj/structure/grille,/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) +"Bk" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bl" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bm" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/status_display{pixel_x = 0; pixel_y = -32},/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) +"Bn" = (/obj/structure/bed/chair/shuttle{dir = 1},/obj/machinery/status_display{pixel_x = 0; pixel_y = -32},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Bo" = (/obj/effect/floor_decal/industrial/warning,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bp" = (/obj/effect/floor_decal/industrial/warning,/obj/effect/floor_decal/sign/dock/one,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bq" = (/obj/structure/table/standard,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Br" = (/obj/structure/lattice,/turf/space,/area/space) +"Bs" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space,/area/space) +"Bt" = (/obj/structure/sign/warning/docking_area,/turf/unsimulated/wall,/area/centcom/terminal) +"Bu" = (/obj/structure/table/standard,/obj/effect/floor_decal/industrial/warning/corner,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bv" = (/obj/structure/closet/emcloset,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bw" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Bx" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"By" = (/turf/simulated/shuttle/wall,/area/shuttle/escape/centcom) +"Bz" = (/obj/structure/shuttle/window,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) +"BA" = (/obj/effect/floor_decal/industrial/warning,/obj/effect/floor_decal/sign/dock/two,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BB" = (/obj/effect/floor_decal/corner/white{dir = 6; icon_state = "corner_white"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BC" = (/obj/effect/floor_decal/corner/white{dir = 5},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BD" = (/obj/effect/floor_decal/corner/white{icon_state = "corner_white"; dir = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BE" = (/turf/simulated/shuttle/wall/hard_corner,/area/shuttle/escape/centcom) +"BF" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"BG" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"BH" = (/obj/machinery/computer/shuttle_control/emergency,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"BI" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"BJ" = (/obj/effect/floor_decal/corner/white,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BK" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/wizard_station) +"BL" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"BM" = (/obj/effect/floor_decal/corner/white{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BN" = (/obj/effect/floor_decal/corner/white{dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BO" = (/obj/machinery/computer/security,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"BP" = (/obj/structure/bed/chair/shuttle{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"BQ" = (/obj/structure/bed/chair/shuttle{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"BR" = (/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"BS" = (/obj/structure/bed/chair/shuttle{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"BT" = (/obj/machinery/computer/crew,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"BU" = (/obj/machinery/chemical_dispenser/bar_soft/full,/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"BV" = (/obj/item/weapon/reagent_containers/food/drinks/bottle/pwine{pixel_x = -4; pixel_y = 10},/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"BW" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"BX" = (/obj/machinery/door/airlock/external{icon_state = "door_locked"; locked = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"BY" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"BZ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_shuttle"; pixel_x = 0; pixel_y = -25; req_one_access = list(13); tag_door = "escape_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Ca" = (/obj/machinery/hologram/holopad,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Cb" = (/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Cc" = (/obj/machinery/computer/arcade/battle,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Cd" = (/obj/machinery/computer/arcade/orion_trail,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Ce" = (/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"Cf" = (/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"Cg" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{on = 0; pixel_x = -3; pixel_y = 8},/obj/item/toy/figure/ninja,/turf/unsimulated/floor{icon_state = "lino"},/area/wizard_station) +"Ch" = (/obj/structure/bed,/obj/item/weapon/bedsheet/rd,/turf/unsimulated/floor{icon_state = "lino"},/area/wizard_station) +"Ci" = (/obj/structure/AIcore/deactivated,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Cj" = (/obj/structure/bed/chair/wood/wings,/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = 30},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Ck" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Cl" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Cm" = (/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"Cn" = (/obj/structure/mirror{pixel_x = -28},/turf/unsimulated/floor{icon_state = "lino"},/area/wizard_station) +"Co" = (/turf/unsimulated/floor{icon_state = "lino"},/area/wizard_station) +"Cp" = (/obj/structure/table/woodentable,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/item/weapon/ore/slag{desc = "Well at least Arthur doesn't have to share now..."; name = "pet rock"},/turf/unsimulated/floor{icon_state = "lino"},/area/wizard_station) +"Cq" = (/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = 30},/obj/structure/bedsheetbin,/obj/structure/table/woodentable,/turf/unsimulated/floor{icon_state = "lino"},/area/wizard_station) +"Cr" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Cs" = (/obj/machinery/door/airlock/glass_command{name = "Escape Shuttle Cockpit"; req_access = list(19)},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Ct" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Cu" = (/obj/structure/table/woodentable,/obj/item/device/radio/headset,/obj/item/weapon/spacecash/c500,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Cv" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Cw" = (/obj/item/weapon/reagent_containers/food/snacks/spellburger{pixel_y = 8},/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "white"},/area/wizard_station) +"Cx" = (/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Cy" = (/obj/structure/undies_wardrobe,/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Cz" = (/turf/simulated/shuttle/wall/no_join,/area/shuttle/escape/centcom) +"CA" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 3},/obj/item/weapon/extinguisher,/obj/item/weapon/tool/crowbar,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"CB" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"CC" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CD" = (/obj/structure/table/woodentable,/obj/item/device/paicard,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CE" = (/obj/structure/table/woodentable,/obj/item/weapon/book/codex/corp_regs,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CF" = (/obj/machinery/door/airlock/hatch,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CG" = (/obj/machinery/door/airlock/hatch,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CH" = (/obj/item/weapon/antag_spawner/technomancer_apprentice,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CI" = (/obj/structure/table/woodentable,/obj/item/clothing/shoes/boots/workboots,/obj/item/clothing/under/technomancer,/obj/item/clothing/head/technomancer,/obj/item/weapon/storage/box/syndie_kit/chameleon,/obj/item/weapon/storage/box/syndie_kit/chameleon,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CJ" = (/obj/machinery/door/airlock/external{icon_state = "door_locked"; locked = 1},/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"CK" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_dock_airlock"; locked = 1; name = "Arrivals Airlock"; req_access = list(13)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"CL" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"CM" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CN" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/wizard_station) +"CO" = (/obj/machinery/vending/hydroseeds,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/wizard_station) +"CP" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"CQ" = (/obj/effect/landmark/start{name = "wizard"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CR" = (/obj/item/weapon/reagent_containers/food/snacks/cheesewedge,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CS" = (/obj/structure/table/woodentable,/obj/machinery/librarycomp{pixel_y = 6},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CT" = (/obj/machinery/media/jukebox,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"CU" = (/obj/machinery/vending/hydronutrients,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/wizard_station) +"CV" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/under/psysuit,/obj/item/clothing/suit/wizrobe/psypurple,/obj/item/clothing/head/wizard/amp,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"CW" = (/mob/living/simple_mob/animal/passive/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CX" = (/obj/structure/flora/pottedplant{icon_state = "plant-24"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CY" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"CZ" = (/obj/structure/bed/chair/shuttle{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Da" = (/obj/structure/bed/chair/shuttle{dir = 4},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Db" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/bed/chair/shuttle{dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Dc" = (/obj/machinery/photocopier,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Dd" = (/obj/structure/bookcase,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"De" = (/obj/structure/flora/pottedplant{icon_state = "plant-08"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Df" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/shoes/sandal/marisa{desc = "A set of fancy shoes that are as functional as they are comfortable."; name = "Gentlemans Shoes"},/obj/item/clothing/under/gentlesuit,/obj/item/clothing/suit/wizrobe/gentlecoat,/obj/item/clothing/head/wizard/cap,/obj/item/weapon/staff/gentcane,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dg" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dh" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/staff/broom,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Di" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/red,/obj/item/clothing/shoes/sandal,/obj/item/clothing/head/wizard/red,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dj" = (/obj/structure/bed/chair/shuttle{dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Dk" = (/obj/structure/bed/chair/shuttle{dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Dl" = (/obj/machinery/the_singularitygen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dm" = (/obj/machinery/crystal,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Dn" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Do" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/arrow/quill,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Dp" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/stock_parts/matter_bin/super,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dq" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"Dr" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_dock"; name = "docking port controller"; pixel_x = 25; pixel_y = 0; req_one_access = list(13); tag_door = "centcom_dock_airlock"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Ds" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"Dt" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Du" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dv" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dw" = (/obj/machinery/computer/message_monitor,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dx" = (/obj/structure/frame/computer,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Dy" = (/obj/structure/table/steel_reinforced,/obj/item/stack/telecrystal,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Dz" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DA" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/head/philosopher_wig,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DB" = (/obj/structure/flora/pottedplant{icon_state = "plant-04"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DC" = (/obj/structure/sign/electricshock,/turf/simulated/shuttle/wall/dark/hard_corner,/area/wizard_station) +"DD" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"DE" = (/obj/machinery/computer/shuttle,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DF" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DG" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"DH" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DI" = (/obj/machinery/computer/power_monitor,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DJ" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/obj/machinery/computer/station_alert/all,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DK" = (/obj/structure/table/steel_reinforced,/obj/item/device/mmi/radio_enabled,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DL" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/material/knife/ritual,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DM" = (/obj/structure/flora/pottedplant{icon_state = "plant-03"},/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DN" = (/obj/structure/reagent_dispensers/watertank,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"DO" = (/obj/machinery/power/port_gen/pacman,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"DP" = (/obj/structure/table/steel_reinforced,/obj/item/xenos_claw,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DQ" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/coin/diamond,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DR" = (/obj/structure/table/steel_reinforced,/obj/item/broken_device,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"DS" = (/obj/structure/table/steel_reinforced,/obj/item/organ/internal/stack,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DT" = (/obj/machinery/floodlight,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"DU" = (/obj/machinery/mecha_part_fabricator,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DV" = (/obj/structure/table/steel_reinforced,/obj/machinery/cell_charger,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DW" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/book/manual/ripley_build_and_repair,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DX" = (/obj/item/device/suit_cooling_unit,/obj/structure/table/steel_reinforced,/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = 30},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DY" = (/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = 30},/obj/item/target,/obj/effect/floor_decal/industrial/outline/yellow,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"DZ" = (/obj/item/target/syndicate,/obj/effect/floor_decal/industrial/outline/yellow,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ea" = (/obj/structure/table/steel_reinforced,/obj/item/toy/sword,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Eb" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/table/steel_reinforced,/obj/item/weapon/gun/energy/laser/practice,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ec" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access = list(1)},/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) +"Ed" = (/obj/machinery/door/airlock/glass_medical{name = "Escape Shuttle Infirmary"; req_access = list(5)},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Ee" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Ef" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/book/manual/engineering_hacking,/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Eg" = (/obj/effect/floor_decal/industrial/warning/corner,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Eh" = (/obj/effect/floor_decal/industrial/warning,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Ei" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ej" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/obj/item/target,/obj/effect/floor_decal/industrial/outline/yellow,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ek" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) +"El" = (/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) +"Em" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) +"En" = (/obj/machinery/atmospherics/unary/cryo_cell{layer = 3.3},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Eo" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Ep" = (/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Eq" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = -4; pixel_y = 0},/obj/item/weapon/tool/wrench,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Er" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/box/masks{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/box/gloves{pixel_x = 3; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire{layer = 2.9; pixel_x = 2; pixel_y = 3},/obj/item/weapon/storage/firstaid/adv{pixel_x = -2},/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"Es" = (/obj/item/robot_parts/r_arm,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"Et" = (/obj/item/robot_parts/l_leg,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"Eu" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/book/manual/robotics_cyborgs,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ev" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ew" = (/obj/machinery/power/emitter{anchored = 1; desc = "It is a heavy duty industrial laser used in a very non-industrial way."; name = "teleport defender"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Ex" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Ey" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"Ez" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EA" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 5},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EB" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"EC" = (/obj/item/robot_parts/r_leg,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"ED" = (/obj/item/robot_parts/chest,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EE" = (/obj/item/robot_parts/l_arm,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EF" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"EG" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"EH" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EI" = (/obj/structure/target_stake,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EJ" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EK" = (/obj/machinery/light,/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) +"EL" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"EM" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"EN" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"EO" = (/obj/machinery/sleep_console{dir = 4},/obj/machinery/light,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"EP" = (/obj/machinery/sleeper{dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"EQ" = (/obj/structure/AIcore,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"ER" = (/obj/structure/flora/pottedplant{icon_state = "plant-20"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"ES" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"ET" = (/obj/effect/floor_decal/industrial/warning,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EU" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EV" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/shuttle/escape/centcom) +"EW" = (/obj/effect/decal/mecha_wreckage/phazon,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EX" = (/obj/item/robot_parts/head,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) +"EY" = (/obj/item/weapon/firstaid_arm_assembly,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"EZ" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/syndicate_elite/mothership) +"Fa" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating/airless,/area/shuttle/escape/centcom) +"Fb" = (/obj/item/weapon/bucket_sensor,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Fc" = (/obj/item/weapon/farmbot_arm_assembly,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Fd" = (/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Fe" = (/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Ff" = (/obj/machinery/computer/teleporter,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Fg" = (/obj/machinery/teleport/station,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Fh" = (/obj/machinery/teleport/hub,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Fi" = (/obj/effect/floor_decal/industrial/warning,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) +"Fj" = (/turf/unsimulated/wall,/area/ninja_dojo/dojo) +"Fk" = (/turf/unsimulated/wall,/area/beach) +"Fl" = (/turf/unsimulated/mineral,/area/ninja_dojo/dojo) +"Fm" = (/turf/unsimulated/beach/sand{density = 1; opacity = 1},/area/beach) +"Fn" = (/turf/simulated/mineral,/area/ninja_dojo/dojo) +"Fo" = (/turf/unsimulated/floor{dir = 2; icon = 'icons/turf/snow_new.dmi'; icon_state = "snow"; name = "snow"},/area/ninja_dojo/dojo) +"Fp" = (/obj/effect/floor_decal/asteroid,/turf/unsimulated/floor{dir = 2; icon = 'icons/turf/snow_new.dmi'; icon_state = "snow"; name = "snow"},/area/ninja_dojo/dojo) +"Fq" = (/turf/unsimulated/beach/sand,/area/beach) +"Fr" = (/obj/structure/signpost,/turf/unsimulated/beach/sand,/area/beach) +"Fs" = (/obj/structure/closet,/turf/unsimulated/beach/sand,/area/beach) +"Ft" = (/turf/simulated/shuttle/wall/voidcraft/green,/area/ninja_dojo/start) +"Fu" = (/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/beach) +"Fv" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/beach) +"Fw" = (/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/beach) +"Fx" = (/obj/item/target/alien,/turf/unsimulated/floor{icon = 'icons/turf/flooring/wood.dmi'; icon_state = "wood_broken2"},/area/ninja_dojo/dojo) +"Fy" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Fz" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/flame/candle,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"FA" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/material/sword/katana,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"FB" = (/obj/machinery/space_heater,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"FC" = (/obj/item/target,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"FD" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/ninja_dojo/start) +"FE" = (/turf/simulated/shuttle/wall/voidcraft/blue,/area/ninja_dojo/start) +"FF" = (/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand,/area/beach) +"FG" = (/obj/item/target/syndicate,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"FH" = (/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 9},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"FI" = (/obj/effect/floor_decal/carpet{dir = 1},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"FJ" = (/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 5},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"FK" = (/obj/effect/wingrille_spawn/reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/ninja_dojo/dojo) +"FL" = (/obj/effect/landmark{name = "endgame_exit"},/turf/unsimulated/beach/sand,/area/beach) +"FM" = (/obj/machinery/teleport/hub,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/ninja_dojo/dojo) +"FN" = (/obj/machinery/teleport/station,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/ninja_dojo/dojo) +"FO" = (/obj/machinery/computer/teleporter,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/ninja_dojo/dojo) +"FP" = (/obj/effect/floor_decal/carpet{dir = 8},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"FQ" = (/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"FR" = (/obj/effect/floor_decal/carpet{dir = 4},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"FS" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/ninja_dojo/dojo) +"FT" = (/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/ninja_dojo/start) +"FU" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/machinery/atmospherics/pipe/tank/air{dir = 2; start_pressure = 740.5},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"FV" = (/obj/machinery/computer/teleporter,/turf/simulated/shuttle/plating,/area/ninja_dojo/start) +"FW" = (/obj/machinery/teleport/station,/turf/simulated/shuttle/plating,/area/ninja_dojo/start) +"FX" = (/obj/machinery/teleport/hub,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/shuttle/plating,/area/ninja_dojo/start) +"FY" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/obj/structure/table/steel_reinforced,/obj/machinery/cell_charger,/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"FZ" = (/obj/structure/table/standard,/turf/unsimulated/beach/sand,/area/beach) +"Ga" = (/obj/structure/table/standard,/obj/item/clothing/under/color/rainbow,/obj/item/clothing/glasses/sunglasses,/obj/item/clothing/head/collectable/petehat{pixel_y = 5},/turf/unsimulated/beach/sand,/area/beach) +"Gb" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Gc" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Dooruranium.dmi'},/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Gd" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Dooruranium.dmi'},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/ninja_dojo/dojo) +"Ge" = (/obj/machinery/door/airlock/voidcraft/vertical{frequency = 1331; id_tag = "ninja_shuttle_outer"; name = "Ship External Hatch"; req_access = list(150)},/obj/machinery/door/blast/regular{density = 0; dir = 8; icon_state = "pdoor0"; id = "blastninja"; name = "Outer Airlock"; opacity = 0},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gf" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "ninja_shuttle_sensor"; pixel_x = 0; pixel_y = 28},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gg" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/meter,/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"Gh" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gi" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"Gj" = (/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gk" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/storage/firstaid/adv{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/combat,/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gl" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/snacks/chips,/turf/unsimulated/beach/sand,/area/beach) +"Gm" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/turf/unsimulated/beach/sand,/area/beach) +"Gn" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand,/area/beach) +"Go" = (/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Gp" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1331; id_tag = "ninja_shuttle"; pixel_x = 0; pixel_y = -25; req_access = list(150)},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "ninja_shuttle_pump"},/obj/machinery/button/remote/blast_door{id = "blastninja"; name = "ship lockdown control"; pixel_x = -25},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gq" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/door/airlock/voidcraft/vertical{frequency = 1331; id_tag = "ninja_shuttle_inner"; name = "Ship Internal Hatch"; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gr" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "ninja_shuttle"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gs" = (/obj/structure/table/steel_reinforced,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"Gt" = (/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 10},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"Gu" = (/obj/effect/floor_decal/carpet,/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"Gv" = (/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/ninja_dojo/dojo) +"Gw" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"Gx" = (/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/machinery/computer/security,/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"Gy" = (/turf/unsimulated/floor{icon = 'icons/turf/flooring/wood.dmi'; icon_state = "wood_broken1"},/area/ninja_dojo/dojo) +"Gz" = (/obj/structure/table/steel_reinforced,/obj/item/device/paicard,/obj/item/device/pda/syndicate,/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"GA" = (/obj/structure/bed/chair/comfy/black,/turf/simulated/shuttle/floor/voidcraft/dark,/area/ninja_dojo/start) +"GB" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/storage/toolbox/syndicate{pixel_x = -1; pixel_y = 3},/obj/machinery/button/remote/blast_door{id = "ninjawindow"; name = "remote shutter control"; pixel_x = 0; pixel_y = -25; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"GC" = (/obj/structure/table/bench/wooden,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"GD" = (/obj/structure/flight_right{dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"GE" = (/obj/machinery/computer/shuttle_control/web/ninja{icon_state = "flightcomp_center"; dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"GF" = (/obj/structure/flight_left{dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) +"GG" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/obj/item/toy/plushie/mouse{desc = "A plushie of a small fuzzy rodent."; name = "Woodrat"},/turf/unsimulated/beach/sand,/area/beach) +"GH" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/turf/unsimulated/beach/sand,/area/beach) +"GI" = (/obj/machinery/vending/coffee,/turf/unsimulated/beach/sand,/area/beach) +"GJ" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Dooruranium.dmi'},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"GK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "ninjawindow"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/ninja_dojo/start) +"GL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "ninjawindow"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/ninja_dojo/start) +"GM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "ninjawindow"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/ninja_dojo/start) +"GN" = (/obj/item/clothing/head/collectable/paper,/turf/unsimulated/beach/sand,/area/beach) +"GO" = (/obj/structure/flora/tree/pine,/turf/unsimulated/floor{dir = 2; icon = 'icons/turf/snow_new.dmi'; icon_state = "snow"; name = "snow"},/area/ninja_dojo/dojo) +"GP" = (/obj/structure/flora/ausbushes/palebush,/turf/unsimulated/floor{dir = 2; icon = 'icons/turf/snow_new.dmi'; icon_state = "snow"; name = "snow"},/area/ninja_dojo/dojo) +"GQ" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/unsimulated/floor{dir = 2; icon = 'icons/turf/snow_new.dmi'; icon_state = "snow"; name = "snow"},/area/ninja_dojo/dojo) +"GR" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "asteroid"},/area/ninja_dojo/dojo) +"GS" = (/turf/unsimulated/floor{icon_state = "asteroid"},/area/ninja_dojo/dojo) +"GT" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/unsimulated/floor{icon_state = "asteroid"},/area/ninja_dojo/dojo) +"GU" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{dir = 2; icon = 'icons/turf/snow_new.dmi'; icon_state = "snow"; name = "snow"},/area/ninja_dojo/dojo) +"GV" = (/turf/unsimulated/floor{icon_state = "sandwater"},/area/beach) +"GW" = (/turf/unsimulated/beach/coastline{density = 1; opacity = 1},/area/beach) +"GX" = (/turf/unsimulated/beach/coastline,/area/beach) +"GY" = (/turf/unsimulated/beach/water{density = 1; opacity = 1},/area/beach) +"GZ" = (/turf/unsimulated/beach/water,/area/beach) +"Ha" = (/obj/structure/table/wooden_reinforced,/obj/machinery/recharger{pixel_y = 0},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hb" = (/obj/structure/table/wooden_reinforced,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hc" = (/turf/unsimulated/wall{icon = 'icons/obj/doors/Dooruranium.dmi'; icon_state = "door_closed"; name = "Sealed Door"},/area/ninja_dojo/dojo) +"Hd" = (/obj/structure/table/glass,/obj/item/clothing/mask/balaclava/tactical{pixel_x = 2; pixel_y = 2},/obj/item/clothing/mask/balaclava,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"He" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/fortunecookie,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hf" = (/obj/structure/table/glass,/obj/item/clothing/mask/balaclava,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hg" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hh" = (/obj/structure/table/glass,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hi" = (/obj/structure/toilet{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"Hj" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"Hk" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"Hl" = (/obj/structure/table/bench/wooden,/obj/effect/landmark{name = "ninjastart"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hm" = (/obj/effect/landmark{name = "ninjastart"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hn" = (/obj/structure/window/reinforced/tinted{dir = 1},/obj/structure/table/glass,/obj/item/weapon/towel{color = "#FF6666"; name = "light red towel"},/obj/item/weapon/towel{color = "#FF6666"; name = "light red towel"},/obj/random/soap,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"Ho" = (/obj/machinery/recharger{pixel_y = 0},/obj/structure/table/steel_reinforced,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hp" = (/obj/structure/table/wooden_reinforced,/obj/item/device/radio/uplink,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hq" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"Hr" = (/obj/item/weapon/rig/light/stealth,/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Hs" = (/obj/item/device/suit_cooling_unit,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Ht" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Dooruranium.dmi'},/turf/unsimulated/floor{icon_state = "white"},/area/ninja_dojo/dojo) +"Hu" = (/obj/machinery/door/morgue,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) +"Hv" = (/obj/structure/closet/crate,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Hw" = (/obj/item/broken_device,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"Hx" = (/turf/unsimulated/floor{icon_state = "white"},/area/ninja_dojo/dojo) +"Hy" = (/obj/machinery/door/morgue,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"Hz" = (/obj/structure/table/steel_reinforced,/obj/item/rig_module/chem_dispenser/ninja,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"HA" = (/obj/structure/bed/chair/office/dark,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"HB" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/storage/toolbox/syndicate{pixel_x = -1; pixel_y = 3},/obj/random/tech_supply,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"HC" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"HD" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = -1},/obj/structure/curtain/open/shower/medical,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja_dojo/dojo) +"HE" = (/obj/structure/table/steel_reinforced,/obj/machinery/cell_charger,/obj/random/powercell,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"HF" = (/obj/structure/table/steel_reinforced,/obj/item/rig_module/mounted/energy_blade,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"HG" = (/obj/structure/table/steel_reinforced,/obj/item/rig_module/fabricator/energy_net,/obj/item/rig_module/vision/multi,/turf/unsimulated/floor{icon_state = "dark"},/area/ninja_dojo/dojo) +"HH" = (/obj/machinery/sleeper{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/ninja_dojo/dojo) +"HI" = (/obj/machinery/sleep_console,/turf/unsimulated/floor{icon_state = "white"},/area/ninja_dojo/dojo) +"HJ" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/adv{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/adv,/turf/unsimulated/floor{icon_state = "white"},/area/ninja_dojo/dojo) +"HK" = (/turf/unsimulated/wall,/area/syndicate_station) +"HL" = (/obj/machinery/space_heater,/turf/unsimulated/floor{icon = 'icons/turf/flooring/wood.dmi'; icon_state = "wood_broken3"},/area/ninja_dojo/dojo) +"HM" = (/turf/unsimulated/wall,/area/syndicate_mothership/elite_squad) +"HN" = (/turf/unsimulated/wall,/area/skipjack_station) +"HO" = (/turf/unsimulated/wall,/area/prison/solitary) +"HP" = (/obj/structure/table/rack,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HQ" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/storage/toolbox/emergency{pixel_x = -3; pixel_y = -3},/obj/item/weapon/storage/toolbox/emergency{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/storage/toolbox/emergency{pixel_x = -3; pixel_y = -3},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HR" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/plasmastun,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HS" = (/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HT" = (/obj/structure/table/rack,/obj/machinery/recharger/wallcharger{pixel_x = 5; pixel_y = 32},/obj/item/weapon/material/knife/tacknife/combatknife,/obj/item/weapon/material/knife/tacknife/combatknife,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HU" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle,/obj/machinery/recharger/wallcharger{pixel_x = 5; pixel_y = 32},/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HV" = (/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"HW" = (/obj/mecha/combat/marauder/mauler,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"HX" = (/obj/machinery/mech_recharger,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"HY" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/automatic/sts35,/obj/item/weapon/gun/projectile/automatic/sts35,/obj/item/ammo_magazine/m545,/obj/item/ammo_magazine/m545,/obj/item/ammo_magazine/m545,/obj/item/ammo_magazine/m545,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"HZ" = (/turf/simulated/shuttle/wall/dark,/area/shuttle/syndicate_elite/mothership) +"Ia" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/syndicate_elite/mothership) +"Ib" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/syndicate_elite/mothership) +"Ic" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/syndicate_station/start) +"Id" = (/turf/simulated/mineral,/area/space) +"Ie" = (/turf/simulated/mineral,/area/skipjack_station) +"If" = (/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"Ig" = (/obj/machinery/embedded_controller/radio/docking_port_multi{child_names_txt = "Airlock One;Airlock Two;Airlock Three;Airlock Four"; child_tags_txt = "escape_dock_north_airlock;escape_dock_south_airlock;escape_dock_snorth_airlock;escape_dock_ssouth_airlock"; frequency = 1380; id_tag = "escape_dock"; pixel_y = -32; req_one_access = list(13)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Ih" = (/obj/structure/table/standard,/obj/item/device/paicard,/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Ii" = (/obj/effect/decal/cleanable/cobweb2{icon_state = "cobweb1"},/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Ij" = (/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Ik" = (/obj/structure/bed,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/prison/solitary) +"Il" = (/obj/effect/landmark{name = "prisonwarp"},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/prison/solitary) +"Im" = (/obj/structure/table/rack,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"In" = (/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Io" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Ip" = (/mob/living/silicon/decoy{icon_state = "ai-malf"; name = "GLaDOS"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Iq" = (/obj/structure/window/reinforced,/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 1},/turf/simulated/floor/airless,/area/shuttle/syndicate_elite/mothership) +"Ir" = (/obj/structure/inflatable,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Is" = (/obj/item/weapon/ore,/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"It" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Iu" = (/obj/structure/table/rack,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Iv" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/handcuffs{pixel_x = 4; pixel_y = 2},/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/smokes,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Iw" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/obj/item/clothing/accessory/storage/white_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Ix" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1213; listening = 1; name = "Syndicate Ops Intercom"; pixel_y = 26; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Iy" = (/obj/machinery/door/airlock/glass_security{name = "Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{id = "syndicate_elite_mech_room"; name = "Mech Room Door"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"Iz" = (/obj/effect/wingrille_spawn/reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_mothership/elite_squad) +"IA" = (/turf/simulated/shuttle/wall/dark/no_join,/area/shuttle/syndicate_elite/mothership) +"IB" = (/obj/effect/landmark{name = "Syndicate-Commando-Bomb"},/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"IC" = (/obj/structure/inflatable,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"ID" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"IE" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/glasses/square{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"IF" = (/obj/item/weapon/tray{pixel_y = 5},/obj/structure/table/standard,/obj/item/weapon/material/knife/butch,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"IG" = (/obj/structure/table/rack,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"IH" = (/obj/structure/table/rack,/obj/item/device/binoculars,/obj/item/device/binoculars,/obj/item/device/binoculars,/obj/item/device/binoculars,/obj/item/device/binoculars,/obj/item/device/binoculars,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"II" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"IJ" = (/obj/machinery/embedded_controller/radio/docking_port_multi{child_names_txt = "Airlock One;Airlock Two"; child_tags_txt = "arrivals_dock_north_airlock;arrivals_dock_south_airlock"; frequency = 1380; id_tag = "arrivals_dock"; pixel_y = -32},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"IK" = (/obj/effect/wingrille_spawn/reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_station) +"IL" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"IM" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_mothership/elite_squad) +"IN" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_mothership/elite_squad) +"IO" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "syndicate_elite"; name = "Side Hull Door"; opacity = 0},/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"IP" = (/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"IQ" = (/obj/effect/decal/cleanable/cobweb2{icon_state = "spiderling"; name = "dead spider"},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"IR" = (/obj/structure/table/standard,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"IS" = (/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"IT" = (/obj/item/weapon/ore,/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"IU" = (/obj/structure/table/rack,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"IV" = (/obj/structure/table/rack,/obj/item/weapon/pinpointer/shuttle/merc,/obj/item/weapon/pinpointer/shuttle/merc,/obj/item/weapon/pinpointer/shuttle/merc,/obj/item/weapon/pinpointer/shuttle/merc,/obj/item/weapon/pinpointer/shuttle/merc,/obj/item/weapon/pinpointer/shuttle/merc,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"IW" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"IX" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"IY" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/syndicate_mothership/elite_squad) +"IZ" = (/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"Ja" = (/obj/item/weapon/ore,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jb" = (/obj/structure/urinal{pixel_y = 32},/obj/item/weapon/soap/syndie,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"Jc" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"Jd" = (/obj/structure/toilet,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"Je" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jf" = (/obj/item/weapon/gun/energy/sonic,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jg" = (/obj/structure/closet/crate,/obj/item/clothing/under/vox/vox_casual,/obj/item/clothing/under/vox/vox_casual,/obj/item/clothing/under/vox/vox_casual,/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jh" = (/obj/structure/closet/crate,/obj/item/clothing/accessory/storage/vox,/obj/item/clothing/accessory/storage/vox,/obj/item/clothing/accessory/storage/vox,/obj/item/clothing/accessory/storage/vox,/obj/item/clothing/accessory/storage/vox,/obj/item/clothing/accessory/storage/vox,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Ji" = (/obj/structure/closet/crate,/obj/item/clothing/gloves/vox,/obj/item/clothing/gloves/vox,/obj/item/clothing/gloves/vox,/obj/item/clothing/gloves/vox,/obj/item/clothing/gloves/vox,/obj/item/clothing/gloves/vox,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/shoes/magboots/vox,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jj" = (/obj/item/weapon/gun/launcher/spikethrower,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jk" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jl" = (/obj/structure/table/rack,/obj/item/clothing/suit/storage/vest/heavy/merc{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/storage/vest/heavy/merc{pixel_x = -2; pixel_y = -2},/obj/item/clothing/suit/storage/vest/heavy/merc,/obj/item/clothing/suit/storage/vest/heavy/merc,/obj/item/clothing/suit/storage/vest/heavy/merc,/obj/item/clothing/suit/storage/vest/heavy/merc,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Jm" = (/obj/effect/landmark{name = "Syndicate-Commando"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"Jn" = (/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) +"Jo" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"Jp" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"Jq" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"Jr" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"Js" = (/obj/structure/mirror/raider{pixel_x = -32},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"Jt" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"Ju" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"Jv" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jw" = (/obj/item/clothing/glasses/night/vox,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jx" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/darkmatter,/obj/item/weapon/gun/energy/darkmatter,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Jy" = (/obj/machinery/door/airlock/centcom{name = "Storage"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Jz" = (/obj/machinery/door/airlock/centcom{icon_state = "door_locked"; locked = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"JA" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/turf/unsimulated/floor{icon = 'icons/turf/flooring/wood.dmi'; icon_state = "wood_broken1"},/area/skipjack_station) +"JB" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"JC" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"JD" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/green,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"JE" = (/obj/structure/table/standard,/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"JF" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"JG" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{dir = 4; pixel_x = -28; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"JH" = (/obj/machinery/shower{dir = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/skipjack_station) +"JI" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"JJ" = (/obj/item/weapon/gun/energy/plasmastun,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"JK" = (/obj/item/weapon/gun/launcher/crossbow,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"JL" = (/obj/fiftyspawner/rods,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"JM" = (/obj/item/clothing/mask/gas/swat/vox,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"JN" = (/obj/structure/table/rack,/obj/item/clothing/mask/gas/swat/vox,/obj/item/clothing/mask/gas/swat/vox,/obj/item/clothing/mask/gas/swat/vox,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"JO" = (/obj/structure/table/standard,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"JP" = (/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"JQ" = (/obj/structure/reagent_dispensers/beerkeg/fakenuke{desc = "Something seems off about this bomb."; name = "\improper Nuclear Fission Explosive"},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"JR" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"JS" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"JT" = (/obj/structure/curtain/open/shower/security,/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = -1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"JU" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"JV" = (/obj/structure/curtain/open/shower/security,/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = -1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"JW" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"JX" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"JY" = (/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"JZ" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 9},/obj/effect/floor_decal/carpet{dir = 5},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/skipjack_station) +"Ka" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"Kb" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"Kc" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{icon_state = "white"},/area/skipjack_station) +"Kd" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/skipjack_station) +"Ke" = (/obj/effect/landmark{name = "Syndicate-Uplink"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Kf" = (/obj/machinery/door/airlock/centcom{name = "Armory"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Kg" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/glasses/square{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"Kh" = (/obj/structure/table/reinforced,/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"Ki" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"Kj" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"Kk" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"Kl" = (/obj/machinery/computer/pod{id = "syndicate_elite"; name = "Hull Door Control"},/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"Km" = (/obj/machinery/computer/syndicate_elite_shuttle,/turf/simulated/shuttle/floor/skipjack,/area/shuttle/syndicate_elite/mothership) +"Kn" = (/turf/unsimulated/floor{icon = 'icons/turf/flooring/wood.dmi'; icon_state = "wood_broken3"},/area/skipjack_station) +"Ko" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/skipjack_station) +"Kp" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{icon_state = "steel_dirty"},/area/skipjack_station) +"Kq" = (/turf/unsimulated/floor{icon_state = "steel_dirty"},/area/skipjack_station) +"Kr" = (/obj/item/xenos_claw,/obj/item/organ/internal/brain/vox,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"Ks" = (/obj/item/weapon/ore,/turf/unsimulated/floor{name = "plating"; icon_state = "asteroid_dug"},/area/skipjack_station) +"Kt" = (/obj/effect/landmark{name = "Nuclear-Bomb"},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/syndicate_station) +"Ku" = (/obj/structure/table/reinforced,/obj/item/weapon/tray{pixel_y = 5},/obj/effect/landmark{name = "Nuclear-Code"},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"Kv" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"Kw" = (/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"Kx" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/shuttle/syndicate_elite/mothership) +"Ky" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "syndicate_elite"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate_elite/mothership) +"Kz" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{icon = 'icons/turf/flooring/wood.dmi'; icon_state = "wood_broken2"},/area/skipjack_station) +"KA" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 10},/obj/effect/floor_decal/carpet{dir = 6},/turf/unsimulated/floor{dir = 2; icon_state = "carpet"},/area/skipjack_station) +"KB" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"KC" = (/obj/structure/table/rack,/obj/item/clothing/glasses/thermal/plain/monocle,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"KD" = (/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"KE" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"KF" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"KG" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"KH" = (/obj/structure/table/rack,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"KI" = (/obj/structure/table/rack,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"KJ" = (/obj/structure/closet/secure_closet/freezer/kitchen{req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"KK" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka{pixel_x = 3; pixel_y = 12},/obj/item/weapon/reagent_containers/food/drinks/bottle/wine{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"KL" = (/obj/structure/table/standard,/obj/item/weapon/towel{color = "#ff0000"; name = "red towel"},/obj/item/weapon/towel{color = "#ff0000"; name = "red towel"},/obj/item/weapon/towel{color = "#ff0000"; name = "red towel"},/obj/item/weapon/towel{color = "#ff0000"; name = "red towel"},/obj/item/weapon/towel{color = "#ff0000"; name = "red towel"},/obj/item/weapon/soap/syndie,/obj/item/weapon/soap/syndie,/turf/simulated/floor/tiled/freezer,/area/syndicate_station) +"KM" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"KN" = (/obj/structure/toilet{dir = 8},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"KO" = (/turf/simulated/floor/airless,/area/shuttle/syndicate_elite/mothership) +"KP" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/blue,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"KQ" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"KR" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/hop,/turf/unsimulated/floor{icon_state = "wood"},/area/skipjack_station) +"KS" = (/obj/item/weapon/ore,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"KT" = (/obj/item/clothing/head/xenos,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"KU" = (/obj/machinery/door/airlock/centcom{name = "Suit Storage"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"KV" = (/obj/machinery/door/airlock/centcom{name = "Kitchen"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_station) +"KW" = (/obj/machinery/door/airlock{name = "Restroom"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_station) +"KX" = (/obj/effect/wingrille_spawn/reinforced,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/skipjack_station) +"KY" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"KZ" = (/obj/item/weapon/storage/box,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"La" = (/obj/item/clothing/mask/gas/swat{desc = "A close-fitting mask clearly not made for a human face."; name = "\improper alien mask"},/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"Lb" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/mask/gas/syndicate,/obj/item/clothing/head/helmet/space/void/merc,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Lc" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/green,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/green,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Ld" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Le" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"Lf" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"Lg" = (/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"Lh" = (/obj/item/weapon/storage/box/syndie_kit/clerical,/obj/structure/table/standard,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"Li" = (/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"Lj" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/hos,/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"Lk" = (/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"Ll" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"Lm" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Ln" = (/obj/effect/decal/cleanable/cobweb2{icon_state = "spiderling"; name = "dead spider"},/turf/unsimulated/floor{icon_state = "steel_dirty"},/area/skipjack_station) +"Lo" = (/obj/structure/table/rack,/obj/item/weapon/tank/vox,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"Lp" = (/obj/item/pizzabox/meat,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"Lq" = (/obj/structure/table/rack,/obj/item/weapon/storage/briefcase/inflatable,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Lr" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/blue,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/blue,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Ls" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/med,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/med,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Lt" = (/obj/machinery/vending/cola{name = "hacked Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Lu" = (/obj/structure/bed/chair/comfy/black,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"Lv" = (/obj/effect/landmark{name = "Syndicate-Spawn"},/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"Lw" = (/obj/structure/table/standard,/obj/item/device/radio/headset/syndicate/alt,/obj/item/device/radio/headset/syndicate/alt,/obj/item/device/radio/headset/syndicate/alt,/obj/item/device/radio/headset/syndicate/alt,/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"Lx" = (/obj/structure/bed/chair,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"Ly" = (/obj/item/weapon/tank/vox,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"Lz" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/orange,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/orange,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LA" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/engie,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/engie,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LB" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LC" = (/obj/machinery/door/airlock/centcom{name = "Barracks"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"LD" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"LE" = (/obj/structure/table/glass,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"LF" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"LG" = (/obj/machinery/door/airlock/centcom{name = "Barracks"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"LH" = (/obj/structure/table/standard,/obj/item/device/flashlight/lamp{pixel_x = 4; pixel_y = 8},/obj/item/clothing/glasses/sunglasses/prescription,/obj/item/clothing/glasses/sunglasses/prescription,/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"LI" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"LJ" = (/obj/structure/table/steel,/obj/item/device/pda/syndicate,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"LK" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"LL" = (/obj/machinery/portable_atmospherics/canister/phoron,/obj/item/weapon/tank/vox,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"LM" = (/obj/item/clothing/head/philosopher_wig,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"LN" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LO" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/red,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/red,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LP" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LQ" = (/obj/structure/table/glass,/obj/item/device/paicard,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"LR" = (/obj/structure/table/standard,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 8},/obj/item/weapon/pen{pixel_y = 4},/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"LS" = (/obj/structure/table/steel,/obj/item/device/radio/uplink,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"LT" = (/obj/item/weapon/gun/launcher/pneumatic,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"LU" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_station) +"LV" = (/obj/structure/table/standard,/obj/item/device/pda/syndicate,/turf/unsimulated/floor{icon_state = "lino"},/area/syndicate_station) +"LW" = (/obj/item/weapon/storage/box/syndie_kit/spy,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"LX" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/skipjack_station) +"LY" = (/obj/structure/ore_box,/turf/unsimulated/floor{icon_state = "asteroid"},/area/skipjack_station) +"LZ" = (/obj/structure/table/rack,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Ma" = (/obj/structure/table/rack,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/obj/item/weapon/tank/emergency/oxygen/double,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Mb" = (/obj/structure/table/rack,/obj/item/weapon/rig/merc/empty,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Mc" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Md" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/space) +"Me" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Mf" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 8},/turf/space,/area/space) +"Mg" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/turf/space,/area/space) +"Mh" = (/obj/machinery/door/airlock/external{frequency = 1331; id_tag = "merc_base_hatch"; req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Mi" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/turf/space,/area/space) +"Mj" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Mk" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Ml" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Mm" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_station) +"Mn" = (/obj/structure/window/reinforced{dir = 4},/turf/space,/area/space) +"Mo" = (/obj/structure/window/reinforced{dir = 8},/turf/space,/area/space) +"Mp" = (/turf/simulated/shuttle/wall/voidcraft/red,/area/syndicate_station/start) +"Mq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Mr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Ms" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Mt" = (/turf/simulated/wall/skipjack,/area/skipjack_station/start) +"Mu" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_west_control"; req_one_access = list(150)},/turf/simulated/wall/skipjack,/area/skipjack_station/start) +"Mv" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_closed"; id_tag = "vox_northwest_lock"; locked = 0; req_access = list(150)},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Mw" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_closed"; id_tag = "vox_northeast_lock"; locked = 0; req_access = list(150)},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Mx" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_east_control"; req_access = list(150)},/turf/simulated/wall/skipjack,/area/skipjack_station/start) +"My" = (/obj/structure/table/standard,/obj/random/projectile,/turf/unsimulated/floor{icon_state = "steel"},/area/skipjack_station) +"Mz" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "smindicate"; name = "Outer Airlock"; opacity = 0},/obj/machinery/door/airlock/voidcraft{frequency = 1331; id_tag = "merc_shuttle_outer"; name = "Ship External Access"; req_access = list(150)},/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"MA" = (/obj/structure/table/steel,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MB" = (/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MC" = (/obj/machinery/autolathe{hacked = 1; name = "hacked autolathe"},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MD" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/floor/airless,/area/syndicate_station/start) +"ME" = (/obj/structure/shuttle/engine/router{icon_state = "router"; dir = 8},/turf/simulated/floor/airless,/area/syndicate_station/start) +"MF" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/syndicate_station/start) +"MG" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_west_vent"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MH" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_west_sensor"; pixel_x = 25},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"ML" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_east_sensor"; pixel_x = -25},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MM" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MN" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/turf/simulated/shuttle/wall/voidcraft/red,/area/syndicate_station/start) +"MO" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "merc_shuttle_pump"},/obj/machinery/button/remote/blast_door{id = "smindicate"; name = "ship lockdown control"; pixel_x = -25},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"MP" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "merc_shuttle_pump"},/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "merc_shuttle_sensor"; pixel_x = 28; pixel_y = 8},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1331; id_tag = "merc_shuttle"; pixel_x = 24; pixel_y = -2; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"MQ" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/shuttle/wall/voidcraft/red,/area/syndicate_station/start) +"MR" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 10},/turf/simulated/shuttle/wall/voidcraft/red,/area/syndicate_station/start) +"MS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"MT" = (/obj/machinery/atmospherics/pipe/tank/air,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MU" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MV" = (/obj/machinery/recharger/wallcharger{pixel_x = -25},/obj/structure/table/steel,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MW" = (/obj/machinery/light{dir = 4},/obj/structure/table/rack,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"MX" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/syndicate_station/start) +"MY" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/obj/machinery/meter,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"MZ" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "vox_west_vent"; tag_exterior_door = "vox_northwest_lock"; frequency = 1331; id_tag = "vox_west_control"; tag_interior_door = "vox_southwest_lock"; pixel_x = 24; req_access = list(150); tag_chamber_sensor = "vox_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "vox_west_vent"},/obj/machinery/light/small,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Na" = (/obj/structure/flight_left,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nb" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nc" = (/obj/structure/flight_right,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nd" = (/obj/machinery/computer/shuttle_control/web/heist,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Ne" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/head/pirate,/obj/item/clothing/glasses/thermal/plain/monocle,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nf" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1331; id_tag = "skipjack_shuttle"; pixel_x = -24; req_access = list(150); tag_airpump = "vox_east_vent"; tag_chamber_sensor = "vox_east_sensor"; tag_exterior_door = "vox_northeast_lock"; tag_interior_door = "vox_southeast_lock"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "vox_east_vent"},/obj/machinery/light/small,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Ng" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/obj/machinery/meter,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Nh" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "merc_shuttle"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Ni" = (/obj/machinery/atmospherics/pipe/manifold/visible{icon_state = "map"; dir = 8},/obj/machinery/door/airlock/voidcraft/vertical{frequency = 1331; id_tag = "merc_shuttle_inner"; name = "Ship External Access"; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Nj" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "merc_shuttle_pump"},/obj/machinery/light/small,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Nk" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "merc_shuttle_pump"},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Nl" = (/obj/machinery/door/airlock/voidcraft/vertical{frequency = 1331; id_tag = "merc_shuttle_inner"; name = "Ship External Access"; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Nm" = (/obj/machinery/atmospherics/pipe/manifold4w/visible,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "merc_shuttle"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Nn" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"No" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/meter,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Np" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Nq" = (/obj/machinery/recharger/wallcharger{pixel_x = -25},/obj/structure/table/steel,/obj/item/weapon/storage/box/frags,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Nr" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_closed"; id_tag = "vox_southwest_lock"; locked = 0; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Ns" = (/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nt" = (/obj/machinery/light/small{dir = 8},/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nu" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nv" = (/obj/machinery/light/small{dir = 4},/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Nw" = (/obj/machinery/button/remote/blast_door{id = "skipjackshutters"; name = "remote shutter control"; req_access = list(150)},/turf/simulated/wall/skipjack,/area/skipjack_station/start) +"Nx" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_closed"; id_tag = "vox_southeast_lock"; locked = 0; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Ny" = (/obj/machinery/porta_turret/ai_defense,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Nz" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/turf/simulated/shuttle/wall/voidcraft/red,/area/syndicate_station/start) +"NA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"NB" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/wall/voidcraft/red,/area/syndicate_station/start) +"NC" = (/obj/structure/table/steel,/obj/effect/spawner/newbomb/timer/syndicate,/obj/item/weapon/tool/screwdriver,/obj/item/device/assembly/signaler{pixel_y = 2},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"ND" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NE" = (/obj/machinery/light/small{dir = 8},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"NF" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"NG" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry,/area/skipjack_station/start) +"NH" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "vox_west_control"; pixel_x = -22; req_one_access = list(150)},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"NI" = (/obj/structure/table/rack,/obj/item/weapon/material/harpoon,/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/random/rigsuit,/obj/random/multiple/voidsuit,/obj/random/multiple/voidsuit,/obj/random/energy,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"NJ" = (/obj/structure/table/rack,/obj/random/rigsuit,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"NK" = (/obj/structure/table/rack,/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/random/multiple/voidsuit,/obj/random/multiple/voidsuit,/obj/random/energy,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"NL" = (/obj/structure/table/rack,/obj/item/clothing/mask/breath,/obj/machinery/light/small{dir = 8},/obj/random/multiple/voidsuit,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"NM" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "vox_east_control"; pixel_x = 22; req_access = list(150)},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"NN" = (/obj/structure/frame/computer,/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NO" = (/obj/machinery/computer/security/nuclear,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NP" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NQ" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/security/tactical/bandolier,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NR" = (/obj/structure/table/steel,/obj/item/weapon/storage/toolbox/syndicate/powertools,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NS" = (/obj/structure/table/steel,/obj/item/weapon/gun/projectile/pistol,/obj/item/ammo_magazine/m9mm,/obj/item/weapon/gun/projectile/pistol,/obj/item/ammo_magazine/m9mm,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NT" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NU" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NV" = (/obj/machinery/light,/obj/structure/closet/syndicate/suit{name = "suit closet"},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NW" = (/obj/machinery/light,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NX" = (/obj/machinery/button/remote/blast_door{id = "syndieshutters_telebay"; name = "remote shutter control"; pixel_x = 0; pixel_y = -25; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"NY" = (/obj/machinery/door/blast/regular{dir = 4; id = "syndieshutters_telebay"; name = "Outer Airlock"},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"NZ" = (/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Oa" = (/obj/machinery/teleport/station,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Ob" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Oc" = (/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Od" = (/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/obj/structure/table/steel,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Oe" = (/obj/item/seeds/potatoseed,/obj/item/seeds/potatoseed,/obj/item/seeds/ambrosiavulgarisseed,/obj/item/weapon/material/minihoe,/obj/item/weapon/beartrap,/obj/structure/table/steel,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Of" = (/obj/machinery/vending/hydroseeds,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Og" = (/obj/structure/table/rack,/obj/item/weapon/melee/energy/sword/pirate,/obj/item/clothing/suit/space/pirate,/obj/item/clothing/suit/space/pirate,/obj/item/weapon/tank/oxygen,/obj/item/weapon/pinpointer/shuttle/heist,/obj/item/weapon/pinpointer/shuttle/heist,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Oh" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/clothing/shoes/magboots,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Oi" = (/obj/machinery/washing_machine,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Oj" = (/obj/structure/table/standard,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/flame/lighter/zippo,/obj/item/clothing/gloves/yellow,/obj/item/stack/material/steel{amount = 50},/obj/item/stack/material/glass{amount = 50},/obj/item/weapon/card/emag,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Ok" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Ol" = (/obj/structure/table/steel_reinforced,/obj/machinery/button/remote/blast_door{id = "syndieshutters"; name = "remote shutter control"; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Om" = (/obj/structure/bed/chair/comfy/red{icon_state = "comfychair_preview"; dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"On" = (/obj/machinery/light{dir = 4},/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Oo" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/structure/bed/chair/comfy/red{dir = 4; icon_state = "comfychair_preview"},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Op" = (/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Oq" = (/obj/machinery/light{dir = 4},/obj/structure/bed/chair/comfy/red{icon_state = "comfychair_preview"; dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Or" = (/obj/machinery/door/airlock/voidcraft{req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Os" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Ot" = (/obj/machinery/teleport/hub,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Ou" = (/obj/structure/table/rack,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Ov" = (/obj/structure/table/rack,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Ow" = (/obj/structure/table/rack,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Ox" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/simulated/mineral,/area/space) +"Oy" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Oz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OC" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"OE" = (/obj/item/robot_parts/head,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"OG" = (/obj/structure/flight_right{icon_state = "right"; dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"OH" = (/obj/machinery/turretid{pixel_x = 32; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"OI" = (/obj/structure/bed/chair/comfy/red{dir = 4; icon_state = "comfychair_preview"},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"OJ" = (/obj/structure/bed/chair/comfy/red{icon_state = "comfychair_preview"; dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"OK" = (/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"OL" = (/obj/machinery/turretid{pixel_x = 0; pixel_y = 32; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"OM" = (/obj/structure/table/rack,/obj/item/device/aicard,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"ON" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/space,/area/space) +"OO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OP" = (/obj/item/robot_parts/l_leg,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OQ" = (/obj/machinery/computer/shuttle_control/web/syndicate{dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"OR" = (/obj/structure/bed/chair/comfy/red{icon_state = "comfychair_preview"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"OS" = (/obj/machinery/door/airlock/voidcraft/vertical{req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"OT" = (/mob/living/simple_mob/animal/passive/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"OU" = (/obj/machinery/door/airlock/voidcraft/vertical{req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"OV" = (/obj/machinery/telecomms/allinone{intercept = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"OW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OX" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OY" = (/obj/machinery/floodlight,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"OZ" = (/obj/item/device/suit_cooling_unit,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Pa" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/crossbow,/obj/item/stack/rods{amount = 10},/obj/machinery/light/small{dir = 8},/obj/item/weapon/beartrap,/obj/item/weapon/beartrap,/obj/item/weapon/beartrap,/obj/item/weapon/beartrap,/obj/item/weapon/beartrap,/obj/item/weapon/beartrap,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Pb" = (/obj/structure/table/rack,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/grenade/spawnergrenade/manhacks,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Pc" = (/obj/structure/table/steel,/obj/machinery/recharger,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Pd" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Pe" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Pf" = (/obj/item/robot_parts/robot_suit,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Pg" = (/obj/structure/flight_left{icon_state = "left"; dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Ph" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Pi" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Pj" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Pk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Pl" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"Pm" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Pn" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Po" = (/obj/structure/table/steel,/obj/item/clothing/glasses/regular,/obj/item/clothing/glasses/regular,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Pp" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"Pq" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Pr" = (/obj/item/weapon/tool/wrench,/obj/item/weapon/mop,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Ps" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/item/weapon/tool/crowbar,/obj/item/device/suit_cooling_unit,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Pt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Pu" = (/obj/structure/table/steel_reinforced,/obj/machinery/recharger,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Pv" = (/obj/structure/bed/chair/comfy/red,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Pw" = (/obj/machinery/vending/assist{contraband = null; name = "AntagCorpVend"; products = list(/obj/item/device/assembly/prox_sensor = 5, /obj/item/device/assembly/signaler = 4, /obj/item/device/assembly/infra = 4, /obj/item/device/assembly/prox_sensor = 4, /obj/item/weapon/handcuffs = 8, /obj/item/device/flash = 4, /obj/item/weapon/cartridge/signal = 4, /obj/item/clothing/glasses/sunglasses = 4)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Px" = (/obj/machinery/atmospherics/unary/cryo_cell,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Py" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/syndicate{pixel_x = -1; pixel_y = 3},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Pz" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/utility/full,/obj/item/device/multitool,/obj/machinery/light/small,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"PA" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/utility/full,/obj/item/device/multitool,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"PB" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"PC" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"PD" = (/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"PE" = (/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"PF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"PG" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"PH" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"PI" = (/obj/structure/table/steel,/obj/item/weapon/deck/cards,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"PJ" = (/obj/machinery/bodyscanner{dir = 8},/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"PK" = (/obj/machinery/light/small{dir = 1},/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"PL" = (/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"PM" = (/obj/structure/toilet{dir = 4},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"PN" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"PO" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"PP" = (/obj/structure/frame/computer,/obj/machinery/light,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"PQ" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"PR" = (/obj/structure/closet/crate/freezer/rations,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"PS" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"PT" = (/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"PU" = (/obj/machinery/light{dir = 1},/obj/structure/table/steel,/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/item/device/defib_kit/compact/combat/loaded,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"PV" = (/obj/structure/closet/secure_closet/medical_wall{pixel_y = 32; req_access = list(150)},/obj/item/bodybag,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = -4; pixel_y = 8},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 4; pixel_y = 7},/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/storage/firstaid/combat,/obj/item/weapon/storage/firstaid/clotting,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"PW" = (/obj/machinery/atmospherics/pipe/manifold/visible{icon_state = "map"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"PX" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"PY" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating/airless,/area/skipjack_station/start) +"PZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Qa" = (/obj/structure/table/steel,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Qb" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"Qc" = (/obj/machinery/door/airlock/voidcraft{req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Qd" = (/obj/machinery/door/window{dir = 8; name = "Cell"; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Qe" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qf" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qg" = (/obj/machinery/atmospherics/portables_connector{icon_state = "map_connector"; dir = 4},/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qh" = (/obj/structure/table/steel,/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/regular,/obj/machinery/atmospherics/pipe/manifold/visible,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/adv,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qi" = (/obj/machinery/atmospherics/unary/freezer{icon_state = "freezer_0"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qj" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/centcom/evac) +"Qk" = (/obj/structure/table/standard,/obj/item/weapon/handcuffs/legcuffs,/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"Ql" = (/obj/structure/table/standard,/obj/item/weapon/deck/cards,/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"Qm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) +"Qn" = (/obj/machinery/light/small,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start) +"Qo" = (/obj/structure/table/standard,/obj/item/weapon/surgical/circular_saw{pixel_y = 8},/obj/item/weapon/surgical/hemostat,/obj/item/weapon/surgical/scalpel,/obj/item/stack/medical/advanced/bruise_pack,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"Qp" = (/obj/structure/toilet{dir = 4},/obj/machinery/flasher{id = "syndieflash"; pixel_x = -28; pixel_y = 0},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"Qq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Qr" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Qs" = (/obj/machinery/light{dir = 4},/obj/machinery/button/flasher{id = "syndieflash"; name = "Flasher"; pixel_x = 27; pixel_y = 0},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"Qt" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window{dir = 8; name = "Surgery"; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qu" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qv" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table/steel,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"Qw" = (/mob/living/simple_mob/animal/passive/tindalos,/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"Qx" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"Qy" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"Qz" = (/obj/structure/table/standard,/obj/item/weapon/surgical/cautery,/obj/item/weapon/surgical/retractor,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"QA" = (/obj/structure/closet{name = "custodial"},/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"QB" = (/obj/structure/mopbucket,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"QC" = (/obj/structure/table/steel,/obj/item/weapon/material/knife{pixel_x = -6},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = 9},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = 4},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = -1},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"QD" = (/obj/item/device/radio/electropack,/obj/structure/table/steel,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) +"QE" = (/obj/machinery/button/remote/blast_door{id = "syndieshutters_infirmary"; name = "remote shutter control"; pixel_x = -25},/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QF" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/steel,/obj/item/stack/medical/advanced/bruise_pack,/obj/item/stack/nanopaste,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QG" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/closet/secure_closet/medical_wall{pixel_x = 32; pixel_y = 0; req_access = list(150)},/obj/item/weapon/tank/anesthetic,/obj/item/clothing/mask/breath/medical,/obj/item/clothing/mask/surgical,/obj/item/clothing/gloves/sterile/latex,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QH" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"QI" = (/obj/item/weapon/bedsheet/rainbow,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"QJ" = (/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"QK" = (/obj/item/weapon/bedsheet/hos,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"QL" = (/obj/structure/table/standard,/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/bonegel,/obj/item/weapon/surgical/FixOVein,/obj/item/stack/nanopaste,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"QM" = (/obj/machinery/bodyscanner{dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QN" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QO" = (/obj/structure/table/steel,/obj/item/stack/medical/splint,/obj/item/stack/medical/splint,/obj/item/weapon/storage/belt/medical/emt,/obj/item/weapon/storage/belt/medical/emt,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QP" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/steel,/obj/item/weapon/storage/firstaid/surgery,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QQ" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QR" = (/obj/machinery/iv_drip,/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"QS" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/machinery/turretid{pixel_x = 32; req_access = list(150)},/obj/machinery/turretid{pixel_x = 32; req_access = list(150)},/turf/simulated/floor/airless,/area/syndicate_station/start) +"QT" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"QU" = (/obj/item/weapon/bedsheet/orange,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"QV" = (/obj/item/weapon/bedsheet/green,/obj/machinery/light/small{dir = 4},/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"QW" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"QX" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/adv{pixel_x = 1},/obj/item/weapon/storage/firstaid/toxin{pixel_x = 3; pixel_y = 3},/obj/machinery/light/small{dir = 4},/obj/structure/closet/secure_closet/medical_wall{pixel_x = 32; pixel_y = 0; req_access = list(150)},/obj/item/weapon/storage/firstaid/fire{pixel_x = 1},/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/regular,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) +"QY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "syndieshutters_infirmary"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"QZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "syndieshutters_infirmary"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Ra" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "syndieshutters_infirmary"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"Rb" = (/obj/item/weapon/bedsheet/rd,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"Rc" = (/obj/item/pizzabox/meat,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"Rd" = (/obj/item/weapon/bedsheet/clown,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) +"Re" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/space) +"Rf" = (/turf/unsimulated/wall{icon = 'icons/misc/title.dmi'; icon_state = "title"},/area/space) +"Rg" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/simulated/mineral,/area/space) + +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacabacacacacacacacacacacabacacacacacacacacacacabacacacacacacacacacacabacacacacacacacacacacabacacacacacacacacacacabacacacacacacacacacacabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaeafaeaeaeaeaeaeagahaiahaiahahaiahaiahagajakakakakakakakakakagalalalalalalalalamanagaoaoaoaoaoaoaoaoaoaoagapapapapapapapapapapagaqarararararasatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaeaeaeaeaeaeaxaeagayazayazayazayazayazagaAaAaAaAaAaAaAaAaAaAagaBaBaBaBaBaBaBaBaCanagaoaDaoaoaoaoaoaoaDaoagapapapapapapapapapapagaEaFaFaFaFaFaGatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaxaeaeaeaeaeaeaeaeagazayaHaIaJaIaJaKazayagaAaAaAaAaAaAaAaAaAaAagaLaMaNaBalaOalaBaPanagaoaoaoaoaoaoaoaoaoaoagapapapapapapapapapapagaEaFaFaFaFaFaGaQavavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaeaeaeafaeaeaeaeagazayaRaSaTaTaUaVaWaXagaYaYaYaYaYaYaYaYaYaZagbabbbcbdbebfbgbhaPanagaoaoaoaDaoaoaDaoaoaoagapapapapapapapapapapagaEaFaFaFaFaFaGatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeafaeaeaeafaeaeaeagayazbiaUbjbjaUaUaUaUagbkbkblbmbmbmbmbnbkboagbpbqbcbrbsbsbsbtaPanagaoaoaoaoaoaoaoaoaoaoagapapapapapapapapapapagaEaFaFaFaFaFaGatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaeaeaeaeaeaeaeaeagayazbiaUbjbjaUaUaUaUagbkbkbubvbvbvbvbwbkboagbpbqbcbxbybzbybAaPanagaoaoaoaoaoaoaoaoaoaoagapapapapapapapapapapagbBaFaFaFaFaFbCatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaeaeaeaxaeaeaeafagazayaRaSaTaTaUbDbEbFagbkbkbubvbvbvbvbwbkboagbpbqbcbGbHbzbHbIaPanagaoaoaoaDaoaoaDaoaoaoagapapapapapapapapapapagbBaFaFaFaFaFbCatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaxaeaeaeaeaeaeaeagazaybJbKbLbKbLbMazayagbkbkbubvbvbvbvbwbkboagbpbqbcbpbzbzbzbNaCanagaoaoaoaoaoaoaoaoaoaoagapapapapapapapapapapagbBaFaFaFaFaFbCbOavavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaeaeaeaeaeaeaeaeaeaeagayazayazayazayazazayagbkbkbPbQbQbQbQbRbkbSagbpbqbcbGbHbHbHbIaPanagaoaDaoaoaoaoaoaoaDaoagapapapapapapapapapapagbBaFaFaFaFaFbCatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadafaeaeaeaxaeaeaeaeaxagahaiahaiahahaiahaiahagbTbkbkbkbkbkbkbkbkbUagbVbWbcbXbYbYbYbZamanagaoaoaoaoaoaoaoaoaoaoagapapapapapapapapapapagcacbcbcbcbcbccatauavawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcdcdcdcdcdcdcdcdcdcdabcdcdcdcdcdcdcdcdcdcdabcdcdcdcdcdcdcdcdcdcdabcecececececececececeabcecececececececececeabcecececececececececeabcecececececececececeabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfcfcfcfcfcfcfcfagcgcgcgcgcgcgcgcgcgcgagchciciciciciciciciciagcjckcjclcmckcmcncocpagcqcqcqcqcqcqcqcqcqcqagcrcscscscscsctcucvcwagcxcxcycycycycycycycyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfczcfcfcfcfczcfagcgcAcgcgcgcgcAcgcgcgagcicicBcCcCcCcDciciciagcEcFcEcFcGcFcGcncocpagcqcqcHcqcqcqcqcqcqcqagcIcJcJcJcJcJcKcucvcwagcycycycycLcLcLcycycyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfcfcfcfcfcfcfcfagcgcgcgcgcgcgcgcgcMcgagcicicNcNcNcNcNciciciagcEcFckckckcFcGcOcpcpagcqcqcqcqcqcqcPcQcqcqagcIcJcJcJcJcJcKcRcwcwagcycycycScTcTcTcycycyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfczcfcfcfcfczcfcfcfagcgcgcUcgcMcgcgcgcgcgagcVcWcWcWcWcWcWcWcWcXagcEcFcFcFcFcFcGcncocpagcqcqcqcqcYcqcqcqcqcqagcIcJcJcJcJcJcKcucvcwagcycLcZdadbdbdcddcLcyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfcfcfcfcfcfcfcfagcgcgcgdecgcgcgcgdecgagcVdfdgdgdgdgdgdhcWcWagdidjdjdkdjdjdlcncocpagcqcqcqcqcqcqcqdmcqcqagdndodododododpcucvcwagcycLcZdqdrdsdtddcLcyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfcfcfcfcfcfcfcfagcgcgcgcgcgcgcgcgcgcgagcVdudvdvdvdvdvdwcWcWagdxdydydydydydzcncocpagcqcqcqcqcqcqcqcqcqcqagdAdBdBdBdBdBdCcucvcwagcycLcZdqdDdEdtddcLcyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfczcfcfcfcfczcfagcgcgcgcgcAcgcUcgcgcAagcVdudvdvdvdvdvdwcWcXagdFcFcFcFcFcFdGcncocpagcqcqcqcqcqcqcqcqcqcqagdHcJcJcJcJcJdIcucvcwagcycLcZdcdJdJdKddcLcyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfcfcfcfcfcfcfcfagdLcgcgcgcgdLcgcgcgcgagcVdudvdvdvdvdvdMcWcWagdFcFdNdNdNcFdGdOcpcpagdPdPdPdPdPdPdPdPdPdPagdHcJcJcJcJcJdIdQcwcwagcycycydRdRdRdScycycyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfczcfcfcfcfczcfcfcfagcgdecgcUcgcgdecgcUcgagcVdTdUdUdUdUdUdVcWcWagdFcFdFcFdGcFdGcncocpagdWdWdWdWdWdWdWdWdWdWagdHcJcJcJcJcJdIcucvcwagcycycycLcLcLcycycycyawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcfcfcfcfcfcfcfcfcfcfagcgcgcgcgdLcgcgcgcgdLagcVcWcWcWcWcWcWcWcWcWagdXdNdXdYdZdNdZcncocpagdWdWdWdWdWdWdWdWdWdWageaebebebebebeccucvcwagcycycycycycycycyededawaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeeeeeeeeeeeeeeeeeeeeabeeeeeeeeeeeeeeeeeeeeabeeeeeeeeeeeeeeeeeeeeabeeeeeeeeeeeeeeeeeeeeabeeeeeeeeeeeeeeeeeeeeabeeeeeeeeeeeeeeeeeeeeabeeeeeeeeeeeeeeeeeeeeabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefefefefefefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefegeheieieiehejefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefekeheieieiehelefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefefeieieiefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefemeheieieiehenefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeoeheieieiehepefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefefeieieiefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeqeheieieieherefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeseheieieiehetefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefefefefefefefefefefefefefehehehefefefefefefefefefefefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeueueueuefeueueueuefevevewewewewexeyezefeAeBeCeieieDewewefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeEeueueEefeFeueueEefeieieieieieieieieGefeweweHeieieDewewefaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeIeueueIefeJeueueKefeieieieieieieieieLefeweweweieiewewewefaaaaaaefefefefefefefefefefefefeMeNeOefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefePePefefefePePefefeQeReSeTeUeVeieieWefeweweHeieieDewewefaaaaaaefeXeXeXeYeZfafbeffcfdeffefffgefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeffheueufifjfkeueufleffmfnfofpfqfreieifsefftftfueieieDewewefaaaaaaeffvfvfvfwewewewefffffffffffffefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeueueueueueueueufxefeieieieieieieieifyeffzfzeffAfAeffzfzefefefefeffBfBfBewewewewfCffffffffffffefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeueueueueueueueufDefeieieieieieieieifEeffFfGfHeieifIfJfKefeweweweffvfvfvfweweweweffLffeffMeffNefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeEfOeEfPeEfQeueufReffSfTfUfVfWfXeieifYeffZeieieieieieifKefgaefgaefeXeXeXewewgbgbeffLffefgcefgcefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeffzfzfzfzfzefgdgdefeffzfzfzfzfzgefAfAgeefeieieieieieieieigfeieieiefefefeffAfAefefefefefefefefefefefefefefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieieieieieieieieieieieieieieiggghghgieieieigjgjgjgjeieifAeieieifAeieieieieieieieieieieieieieieigkefewglgmefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieieieieieieieieieieieieieieieieieieieieieigngogpgqeieifzeieieifzeieieieieieieieieieieieieieieigkgrewewgsefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieieieieigtgugugveieieieieieigwgxgxgyeieieigpgzgAgBeieifAeieieifAeieieieieieieieieieieieieieieigkefgCgDgEefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeffzfzfzfzfzeffAfAefeffzfzfzfzfzgFfAfAgFefeieigGgGgGgGeieiefeieieiefgHgHgHgHgHgHgHgHgHgHgHgHgHgHeieiefefefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefgIgJgKgLgMgNeieigOefgPgQgRgSgTgUeieigVefgWeieieieieieigXefeieieiefeugYgZgZgZgZgZgZgZgZgZgZeugHeieifzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieieieieieieieihaefhbhceihceieieieihdefhehffJeieihghhhiefeieieiefeuhjhkhlhmhmhmhmhnhohphqgZgHeieifzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieieieieieieieihrefeieieieieieieieihseffzfzeffAfAeffzfzefeieieiefeuhjhthuhvhwhmhmhmhmhmhxhyhzhAeiefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieihBhChDhEeieihFefeieihGhHhIhJeieihKefhLhMhNeieihOhPhQefeieieiefeuhjhthRhShThUhUhmhmhVhqgZgHefefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefeieihWhXhYhZeieiiaefeieiibicidieeieiiaefewewifeieieDewigefeieieiefeuihgZgZgZgZgZgZgZgZgZgZeugHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefiieieieieieieieiijefeieieieieieieieiikefileweweieiewewimefeieieiefefininininininininininininefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefioipiqirisitiuewivefeieieieieieieieiiwefewewifeieieDewixefeieieiefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefiyiyiqirisitiuizivefiAiBiCiDiEiFiGiHiIefiJiKiLiMiNiOiPiQefeieieiefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefeffAefefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefiRiRiRefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiSiTiUiTiSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiWiViViViWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaiXiXiXiXiXiXiXiXiXiXiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYiZiZiZiYiZiZiZiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaiXjajajajajajajajajaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYjbjbjbiYjcjcjciYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPpPpPpPpPpPaaaaaaaaaaaapPpPpPpPpPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaiXjajajdjdjdjdjdjajaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYjbjbjbiYjcjcjciYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaajgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPpPjpjpjpjqpPjrpPpPpPpPpPpPjBjBjCpPjrpPpPjejejejejejejeaaaaaaaaaaaaaaaaaaaaaaaaaaiTiViViViTaaaaaaaaaaaaaaaaiXjajdjdjfjfjfjdjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYjbjbjbiYjcjcjciYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaajgjojojojojojojojojojojojojojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPpPjDjqjqjqjqjqjqjqpPjRjSjSpPjTjTjTjTjTjTpPkjkjjekIkIkIjeaaaaaaaaaaaaiWiWiTiTiTiTiWiWjiiWjijjjjjkjkjkjjjjaaaaiXjajdjljmjmjmjnjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYiYjbjbjbiYjcjcjciYiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjgjgjojojgjgjgjgjgjgjgjgjgjgjojojgjgjgaaaaaaaaaaaaaaaaaaaaaaaaaapPjqjqldldldldldjqjqlpjSjSjSpPlqlWjTjTjTlXpPkjkjlekIkIkIjeaaaaaaaaaaaaiWjsjsjsjsjsjsiWiViViVjjjtjujujujvjjaaaaiXjajdjmjmjwjwjwjxjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYjyjzjzjzjAiYiYjbjbjbiYjcjcjciYiYjyjzjzjzjAiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojojojPjojojQjQjQjQjQjojgjojojojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPlYjqldldldldldjqjqlZjSjSmapPpPpPpPmbpPpPpPkjkjlekIkIkIjeaaaaaaaaaaaaiWjsjEjFjFjGjsiTiViViVjkjHjIjJjujKjjaaaaiXjajdjmjmjmjmjmjLjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYjMjMjMjMjMiYiYiYjNiYiYiYjOiYiYiYjMjMjMjMjMiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgjgjgjgkikikikikikijgjgjgjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPmtjqjqjqjqjqjqjqmuqsmvjSjSjSmwmMmLjSmNmUqskjkjlekIkIkIjeaaaaaaaaaaaaiWjsjUjVjWjXjsiTiViViVjkjYjZjZjujujjaaaaiXjajdjmjmjmjmkajdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkbkckckckciYkdkekfkekekekgkekdiYkckckckckhiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukukukvkvkukukukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPmVmXmWninhnjmtjqnCqsnDjSjSjSjSjSjSjSjSnEqskjkjjekIkIkIjeaaaaaaaaaaaaiWjsjUjVjVjXjsiWiViViVjjjujujujujujjaaaaiXjajdjmjmjmjmjmjLjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkkklklklklkmkeknkokpknkqkoknkekmklklklklkriYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukvkvkHkHkvkvkukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPpPpPpPpPpPpPqslZqsqsnDjSjSnRnQocobodjSoeqskjkjjekIkIkIjejeaaaaaaaaaaiWjsjUjVjVjXjskyiViViVkzjujujujukBjjaaaaiXjajdjmjmkCkCkCkDjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkEklklklkliYkeknkokpknkqkoknkeiYkFklklklkGiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukvkvkHkHkvkvkukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPokpRolpPpPjSjSjSjSjSjSjSjSomqskjkjlekIkIkIonjeaaaaaaaaaaiWjsjUjVjVjXjsiWiViViVjjjukAjujujujjaaaaiXjajdjljmjmjmjnjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalhiYiYiYiYiYiYkeknkokpknkqkoknkeiYiYiYiYiYiYlhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukukukvkvkukukukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPozpRoloApPqsoBpPjSoMoLpsprpPpPkjkjlekIkIkIpGjeaaaaaaaaaaiWjsjUjVkJjXjsiTiViViVjkjZjZjZjujujjaaaaiXjajdkKjmjmjmkKjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLkMkMkMkMkMiYkeknkokpknkqkoknkeiYkNkNkNkNkNkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukukukvkvkukukukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPpRpRolpIpHpJjqpKjSjSjSjSpLpMqskjkjlekIkIkIonjeaaaaaaaaaaiWjskOkPkPkQjsiTiViViVjkjZkRjujujujjaaaaiXjajdjdkSkSkSjdjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLkMkMkMkMkMkTkUknknknknknknknkVkWkNkNkNkNkNkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgjglajgjgjgjgjglblblblblblbjgjgjgjgjglcjgjgaaaaaaaaaaaaaaaaaaaaaaaaaapPpPpPpPpPpPpNpRolpQpOqqqpqDqrqFqEqOqNqPqskjkjlekIkIkIjejeaaaaaaaaaaiWjsjsjsjsjsjsiWiViViVjjjujujujujujjaaaaiXjajakXkYkYkYkZjajaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLkMkMkMkMkMiYkekekekeknkekekekeiYkNkNkNkNkNkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgliljljljjglklllllllllllllllllkjglmlmlmlnjgaaaaaaaaaaaaaaaaaaaaaaaaaapPqQsRsRsRqRozpRolpIqSpJjqqTmtqTmtqTmtqTpPlelejekIkIkIjejejejejejejejeiWiWiWiTiTiTiWlfiTlfiWiWiWiWiWiWiWiWiWiWlglglglglglglglglglglglglgiWaaaaaaaaaaaaaaaaaaQjiYiYiYiYiYiYiYiYiYiYiYiYiYkeknkeiYiYiYiYiYiYiYiYiYiYiYiYiYQjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgliljljlElFlllllllllllllllllllllFlGlmlmlHjgaaaaaaaaaaaaaaaaaaaaaaaaaapPqUsRqVsRrcozpRoljqqpjqqpjqqpjqqpjqqpjqrdkIkIkIkIkIkIjekIkIkIkIkIkIkIiWiWiWiViViViViViViViViViViViWiWiWiViViSlrlslsltltltlslslslslslsluiWaaaaaaaaaaaaaaaaaakLlvkllvlwlxlylzlAlBlAlAlAiYlBlClBiYkllDlDlDlDlDlDlDlDlDlDlDkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgliljlTlElFlllllllllllllllllllllFlGlUlmlVjgaaaaaaaaaaaaaaaaaaaaaaaaaapPtLsRresRrcozpRolqpjqqpjqqpjqqpjqqpjqqpqskIkIkIkIkIkIjekIkIkIkIkIkIkIiWiWlJiViViViViViViViViViViVlJiWiWiViViTlKlLlMlMlNlMlOlPlslQlRlslsiWaaaaaaaaaaaaaaaaaakLklklkllBlSlSlSlSlBlSlSlSiYkeknkeiYlDlDlDlDlDlDlDlDlDlDlDlDkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgmqljljlElFlllllllllllllllllllllFlGlmlmmrjgaaaaaaaaaaaaaaaaaaaaaaaaaapPrfsRsRsIrcozpRoljqqpjqqpjqpIrhrgqqqpjqrdkIkIkIkIkIkIjekIkIkIkIkIkIkIiTiViViViVmcmdmemfmgmdmhiViViViViWiViVmimjmkmkmkmkmkmkmkmlmkmmmnltiWaaaaaaaaaaaaaaaaaakLlvklklmolSlSlSlSmplSlSlSiYkeknkeiYlDlDlDlDlDlDlDlDlDlDlDlDkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqBqBqBqBqBqBqBqBqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgmIljlTlElFlllllllllllllllllllllFlGlUlmmJjgjejejejejejejeaaaajejerijepPrjsRrcrcqRozpRoloArkrmrlqppQrornpJjqqppPlelejekIkIkIjekIkIkIkIkIkIkIiTiViViVmxmdmdmymdmymdmdmziViViViWiViViTlrmAmBmBmCmBmDmElsmFmGlslsiWaaaaaaaaaaaaaaaaaakLklklkllBmHlSlSmHlBlSlSlSiYkeknkeiYlDlDlDlDlDlDlDlDlDlDlDlDkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqKqLqBqMqMqBqLqKqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgmTljljlElFlllllllllllllllllllllFlGlmlmlmjgkIkIkIkIkIkIjejejejejhjhjhpPpPpRozozozpRpRpRrprprprppPpPpPpPpPrqpPpPkjkjjekIkIkIjekIkIkIkIkIkIkIiTiViVmcmdmdmdmOmPmOmdmdmdmhiViViWiVmQiWlKlslsltltltlslslslslslsluiWaaaaaaaaaaaaaaaaaakLlvkllvlwmRlSlSmSlBlAlAlAiYkeknkeiYkllDlDlDlDlDlDlDlDlDlDlDkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBrararbqMqMrbraraqBqBqBqBqBqBqBqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgnbljncljndllllllnenflllllllllllFlmlmlmlmngkIkIkIkIkIkIjerrlerGkIkIkIkIrHpRpRpRpRpRpRpRrIrIrIrIpPjTjTjTjTjTrJpPkjkjjekIkIkIjejejejejejemYjeiWiViVmdmdmdmOmZmZmZmOmdmdmdiViViWiViViWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiTiSQjlhiYiYlBiYiYmpmpiYiYiYlBiYiYkeknkeiYiYlBiYiYiYnanaiYiYlBiYlhQjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqBqBqBqMqMqBqBqBqBrCqMrDrEqMrFqBqBqBqBqBqBqBqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgljljnvnwnxnynynynznAnBlllllllllFlmlmlmlmjgkIkIkIkIkIkIrRrrrSrGkIkIkIkIqspRpRpRpRpRqGpRrIrIrIrIpPrTpPrUpPjTjTpPkjkjjekIkIkIkIlekIkIjekIkIkIlfiViVnknlmOmZnmnnnonpmOnqnriViVlfiViViViViViViViViViViViViViViViViViViViVjiiTiViViTiYnsknlBkekekekekekekekekdlBkekeknkekelBkdkekekentkekekekenulBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqKqLqBqMqMqBqLqKqBrLqMqMqMrMrNqBrOrPrOrPrOrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgnNljljnOndllllllnPnflllllllllllFlmlmlmlmngkIkIkIkIkIkIjerrlerGkIkIkIkIrHpRrWrVserWsrsfssrIrIrIpPsGpPsHpPsOpPpPkjkjlekIkIkIkInFkIkInGkIkIkIiTiViVnHmdmOnIiWnJiWnKmOmdnLiViViTiViViViViViViViViViViViViViViViViViViViVjiiUiViViUnMnsknnMknknknknknknknknknlCknknknknknlCknknknknknknknknknnulBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBrararbqMqMrbraraqBsbqMqMqMqMscqBsdrPsdrPsdrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgoaljljlElFlllllllllllllllllllllFlGlmlmlmjgkIkIkIkIkIkIjejejejekIkIkIjepPpPqsqsqsqssPpPqsqsqsqspPpPpPpPpPpPpPkjkjkjlekIkIkIkIlekIkIjekIkIkIlfiViVnSnlmOnTnUnVnWmZmOnqnXiViVlfiViViViViViVnYiViViViViViViViViViViViViVjiiWiViViWiYnsknlBkekekekekekekekekdlBkekeknkekelBkdkekekenZkekekekenulBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqBqBqBqBqBqBqMqMqBqBqBqBspspsqqMspspqBrPrPrPrPrPrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgojljlTlElFlllllllllllllllllllllFlGlUlmmJjglelelelejejejekjkjlekIkIkIjekjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjlekIkIkIjejelelejelemsleiWiViVmdmdmdmOofmOogmOmdmdmdiViViWiWiWiWiWiWiWiWohohiWiWiWiWiWiWiWiWiWiWiWiWiWiWiTiSQjlhiYiYlBiYiYlwlwiYiYiYlwiYiYkeknkeiYiYlBiYiYiYoioiiYiYlBiYlhQjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBszsAszqBsBsBqMqMsCsDsEqBqMqMqMqMqMqMqBsFrPrPrPrPrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgoyljljlElFlllllllllllllllllllllFlGlmlmmrjgkjkjkjkjkjkjkjkjjesQkIkIkIsSjekjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjkjjejekIkIkIleoooplolololooqiTiViVormdmdmdmOmOmOmdmdmdosiViViWlulululululululululululululululululululululuiWaaaaaakLotototototototiYouovlwowiYkeknkeiYoxoxoxoxoxoxoxoxoxoxoxklkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBsMsMsMqBqMrPrPrPrPrPqMqMqMrPrPrPrPqMsNrPrPrPrPrPrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgoJljlTlElFlllllllllllllllllllllFlGlUlmoKjglelelelejelelelejejhkIkIkIjhjejejejejelelelelelelelelelelelelejelelelejejhkIkIkIlemKsTlolololooCiTiViViVoDmdmdoEmdoEmdmdoFiViViViWlulululululululululululululululululululululuiWaaaaaakLotototototototiYoGoHlwoIiYkeknkeiYoxoxoxoxoxoxoxoxoxoxoxoxkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBtasMsMtbqMtctctctctcqMqMqMrPtdtdrPqMsNrPrPrPrPrPrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgoTljljlElFlllllllllllllllllllllFlGlmlmmJjgkIkIkIkIkIkIkIkIsUkIkIjhkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkInGkIkIkIkIjesVlololololooNiTiViViViVormdoOoPoQmdosiViViViViWlululululuoRoRoRoRoRoSoSoRoRoRoRoRlululululuiWaaaaaakLotototototototiYknknknkniYkeknkeiYoxoxoxoxoxoxoxoxoxoxoxoxkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBtasMsMqBqMrPrPrPrPrPqMqMqMrPrPrPrPtrqBsdrPrOrPsdrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgpgljljljjglklllllllllllllllllkjglmlmlmlmjgkIkIkIkIkIkIkIkIjekIkIjhkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIjekIkIkIkIjelolololololooUiWiWlJiViViViViViViViViViViVlJiWiWlulululuoRoVoWoXoYoRoZpaoRpbpcoRoRoRoRlululuiWaaaaaakLotototototototpdpeknknknpfkeknkeiYoxoxoxoxoxoxoxoxoxoxoxoxkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBtAqBtBqBtCtDtEtFtGtHtIqBqMqMqMqMqMqMqBrOrPrOrPrOrPqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaajgjglajgjgjgjgjglblblblblblbjgjgjgjgjgjgjgjgkIkIkIkIkIkIkIkIsUkIkIjhkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkIkInGkIkIkIkIjephpipjpkpllopmiWiWiWiViViViViViViViViViViViWiWiWlululuoRoRpnpnpnpnoRpopooRpnpnpppqoRoRoRluluiWaaaaaakLotototototototpdknknknknpfkeknkeiYoxoxoxoxoxoxoxoxoxoxoxklkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqBqBtTqBqBqBqBqBqBqBqBqBqBqBsqqMqBqBqBqBqBqBqBqBqBqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgpCktpDpDpDpEpEpDpDpDkwpFjgaaaaaajelelelejejelelelejejhkIkIkIjhjelelelejejelelelesUlelelejejelelejelelelejejhkIkIkIjejejejejejejejeiWiWiWiWiWiWiWlfiTlfiWiWiWiWiWiWiWluluoRoRoRptpupvpwoRpxpnpypnpnpnpnpzpAoRluluiWaaaaaakLotototototototiYlwlwpBlwiYkeknkeiYlwlwlwlwlwlwlwlwlwlwlwlwlwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqBqBaaaaaaaaaaaaaaaaaaqBqMtZqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgpCktpDpDpDpEpEpDpDpDkwpFjgaaaaaajekIkIkItejekjkjkjjejetftftfjejekjkjkjjekIkIkIkIkIkIkIkItgjekjkjkjkjkjkjjejekIkIkIjejeaaaaaaaaaaaaaaaapXpSpTpUpVpWpWpWpXpYpZqapZpYiWluluqbqcqdpnqeqeqeoRpnpnoRqfqgqhqiqjqkoRluluiWaaaaaakLotototototototiYqlqmqmqniYkeknkeqoknknknknknknknknknknknknlwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBqMqMqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgpCktpDpEpEqCqCpEpEpDkwpFjgaaaaaajekIkIkIkIjekjkjkjkjjekIkIkIjekjkjkjkjjethtitikIkIkIkIkItgjekjkjkjkjkjkjkjlekIkIkIjeaaaaaaaaaaaaaaaaaapXqtquqvpXpWpWpWqwpYpZqxpZpYiWluluqyqcpnpnpnpnpnpypnpnoRoRoRoRoRoRoRoRluluiWaaaaaakLotototototototiYqlqzqmqniYlBlClBiYqAkoqAkoqAkoqAkoqAkoqAkolwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqBuQuQqBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgpCktpDpEpEqCqCpEpEpDkwpFjgaaaaaajejejekIkIlekjkjkjkjlekIkIkIlekjkjkjkjlekIkIkIkIkIkIkIkItjjelelejejejejejejejejejejeaaaaaaaaaaaaaaaaaapXpXpXpXpXpWpWpWqwpYpYpYpYpYiWluluoRoRpnpnpnqHpnoRpnpnpnqIqJlululululululuiWaaaaaaQjiYiYiYiYiYiYiYiYiYiYlwiYiYkeknkeiYiYiYiYiYiYiYiYiYiYiYiYiYQjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauXuYuYuXaaaaaaaauZuZuZuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgpCktpDpDpDpEpEpDpDpDkwpFjgaaaaaajelojekIkIlekjkjkjlelekIkIkIlelekjkjkjlekIkItkkIkIkIkIkIjejetstststsjeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapXpSpTpUpVpWpWpWpYpYpYpYqWpZiWlululuoRoRoRoRoRoRoRpxpnqXpnqJlululululululuiWaaaaaaaaaaaaaakLqYqYqYqYqYiYkdkekekeknkekekekdiYqZqZqZqZqZkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZuZuZuZuZvtvuvvuZaaaaaaaaaauZuZvwvxuZuZaaaauZuZuZuZvyvzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgjgjgjgkikikikikikijgjgabjgaaaaaajelojelololekjkjkjlekIkIkIkIkIlekjkjkjlekIkIkIkIkIkIkIkIjetststststsjeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapXrsquqvpXpWpWpWpYpYpYpYpYpYiWluluoRoRrtrurvrtrwoRpnpnpnrxqJlululululululuiWaaaaaaaaaaaaaakLqYqYqYqYqYryrzknknknknknknknrArBqZqZqZqZqZkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuXvEvFuZvGvHvIvJvKuZuZaaaaaauZuZuXuYuYuXuZvtvvuXvLvMuZvyvNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojojojPjojorQrQrQrQrQjojgaaaaaaaaaajejejelololekjkjkjjekIkIkIkIkIjekjkjkjletJkIkIkIkIkIkIkIjetststststsjeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapXpXpXpXpXpWpWpWqwpYpYpYpYpYiWluluqbqcpnpnpnpnpnpypnpnoRoRoRoRoRoRoRoRluluiWaaaaaaaaaaaaaakLqYqYqYqYqYiYkeknrKrKrKrKrKknkeiYqZqZqZqZqZkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawdwewfwfwgwfwfwhwiwjuZuZvtvuvvuZuZwkwfwfwluZwmwnwowfwpuZvyvNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjgjgjgjgjgjgjgjgjgjgjgjgjgjgaaaaaaaaaajelolololojekjkjkjlekIkIkIkIkIlekjkjkjjekIkIkIkIkIkIkIkIjejejejejejejeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapXpSpTpUpVpWpWpWqwpYpZqxpZpYiWluluqyqcrXpnpnpnpnoRpnpnpnpnpnoRpnrYrZoRluluiWaaaaaaaaaaaaaaiYiYiYiYiYiYiYkeknsasasasasaknkeiYiYiYiYiYiYiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawvwwwxwyuZwfwfwzwAwBuZwCwDwEwFwGwHwIwJwJwfwKwfwfwfwfwLuZvywMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajelololojejekjkjkjlelekIkIkIlelekjkjkjjejekIkIkIkIkIkIkIjeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapXrsquqvpXpWsgshpXpYpZsipZpYiWluluoRoRoRsjskslsmoRpxslslslpnpypnpnpnoRluluiWaaaaaaaaaaaaaakLsnsnsnsnsniYkeknsasasasasaknkeiYsososososokLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZuZuZuZuZwOwfwfwPuZwQwRwSwTwUwVwWwJwJwfwKwfwXwYwfwfuZuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajejejejejekjkjkjkjkjlekIkIkIlekjkjkjkjkjjejejejerijejejejeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapXpXpXpXpXpXpXpXpXpXpXpXpXpXiWlululuoRoRpnpnpnpnoRpnslslslpnoRstoRoRoRluluiWaaaaaaaaaaaaaakLsnsnsnsnsnsusvknswswswswswknsxsysososososokLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZuZxewfuZuXxfxgxhxixjxkwWwJwfwOuXuZuZuXxlxmuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUjekIkIkIjetVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiWlulululuoRoRsJsKsLoRpnpnpnpnpnoRoRoRoRlululuiWaaaaaaaaaaaaaakLsnsnsnsnsniYkeknknknknknknknkeiYsososososokLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZxqxruZuZuZuZuZuZuZuZxswfwfwfwfxtwfwfwfwfuZuZxuwfuXuZxvxvuZuZuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuaubuatUucudueueuetUufugubububtUuhuhuiujtUlIkIkIkIlIuktKtNtMtOtKtPtVtPtQtRtRunumupuouotVuqurusuttVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiWlululululuoRoRoRoRoRoRoRoRoRoRoRoRlululululuiWaaaaaaaaaaaaaaiYiYiYiYiYiYiYsWsXkekeknkekesYsZiYiYiYiYiYiYiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZxDxEuZxFuZxGxHxIuXuZxJwfwJwJwJwJwJwJwJwJwJwfwJwfxKxLwJwJwfuZvyvzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuBubuBtUubububububuCufufuDubububububububtUkIkIkIkIkIukululululululululuEuFuFuFuGululultVuHululuItVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiWlulululululululululululululululululululululuiWaaaaaaaaaaaaaaaaiYtlqmtmtniYiYiYiYkeknkeiYiYiYiYtotptptqiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxVxWwJxXuZxYuXuZxZuZyauZybwJwJycydyeyfygyhyiwJwJwJwJyjykwJwJwfuZvyvNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuaubuatUubububububuCubububububtUububububtUkIkIkIkIkIukvCvUvTvTxzxzytulululululululululyLululuRuStVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiWlulululululululululululululululululululululuiWaaaaaaaaaaaaaaaaiYttqmqmqmtutulBkdkeknkekdlBtvtwtxtytytziYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayyyzyAwJyBwfwfwfwfyCwfwfwfwJwJyDyEyFyGyHyIyJwJwJwJwJyKwJwJwJwfuZvyvNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuCubuCtUububvavbvctUubvdubububtUtUtUtUtUtUjezflezfjetVtVukukukuktVtVuIulvevfululululzxtVvgvhulvitVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWiWaaaaaaaaaaaaaaaalBqmqmqmqmqmqmtSkeknknknketSqmqmqmqmqmqmlBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZyMyNuZyOyPyQyRySwfyTwfwfwJwJwJwJwJwJwJwJwJwfwJwfyUwfyVwJwpuZvywMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUububububububtUuCuCtUugufubububvAvBvBvBvBtUjekIkIkIjetVzyzzzzzzzzzytVulululululzAzBultVtVtVtVtVtVtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYtWqmqmtXtYqmlBkeknknknkelBqmqmqmqmqmqmiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZyZzauZuZuZuZuZuZuZuXzbwfwfwfwfwXwfwfwfwfuZuZxuwfuXuZzczduZuZuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUubvOvOvOububuCvPvPuCufufubububvQvBvBvBvBvRkIkIkIkIkIvSululzCzDululvVululvWvXulzEzFultVvYvZwawbwctVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQjuuqmqmtvqmqmiYiYlBuvlBiYiYuwuxqmuyuzuAQjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZuZxewfuZuXzgzhzizjzkwHzlwJwfzmuXuZuZuZwfznuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUubwqwrwsububwtububwtububububwuufvBvBvBvBuClIkIkIkIlIukululzCzDululukulululululxSzGulyLululululultVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQjuJqmqmtXtYqmiYuKuLuMuNuOiYlwlwuPlwlwlwQjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZuZuZuZwfzmwfwfzpuZzqzrzsztyWwVzvwJwJwfzwwfxtwfwfwfuZuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUubvOvOvOububwtububwtubububububwNvBvBvBvBvRkIkIkIkIkIvSululzCzDululvVululvWvXulululzHtVtVtVyLtVtVtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYuTqmqmqmqmqmiYuMuUuMuUuMiYuVqmqmqmuWlwiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazKzLzMzNuZwfwfwhzOzPuZzQzRzSzezUxkzVwJwJwfzwwfwfwfwfwfuZvyvzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUububububububtUuCuCtUuCuCwZuCuCuCxaxaxavBtUkIkIkIkIkItVzIululululzHtVzIzHzJxzxzxzxzzTtVxbxcxcxcxdtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYiYvjvkvlvmvniYvovpvqvrvsiYuVqmqmqmuWiYiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAlwfwfwfAmwfwfAnApApuZuZAqArAsuZuZAtAuAvwfuZAwAxAywfwpuZvyvNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuCubuCtUububububugtUubububububtUtUuCuCuCtUlolololokItVzWululululzXxnzWzXtVukukzYukuktVxoulululxptVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYiYiYiYiYiYiYvDvDvDvDvDiYiYiYiYiYiYiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuXADAEuZAFwfAGAHAIuZuZaaaaaauZuZuXAJAKuXuZAqAsuZALAMuZvyvNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuaubuatUububububxwtUububufububtUububububxxkIkIkIkIkIukzZulzCzDulzXxyAazXtVxAulululxAtVxBulululxCtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauZuZuZuZuZuZAqArAsuZaaaaaaaaaauZuZATAUuZuZaaaauZuZuZuZvywMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuBubuBtUxMubububxNtUubxOufxPubwZubububxQxRkIlolololoukAbulzCzDulzXxTzWzXtVulululululyLululuRulxUtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauXAYAZuXaaaaaaaauZuZuZuZuZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUuaubuatUylugubymyntUyoypyqwqyrtUububysuDuCkIkIkIkIkIukAcxzAdAexzzTtVAfzTtVyuulyuulyutVyvywywywyxtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUtUjezfzfzfjetVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVtVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYAgAgAgAgAgAgAgAgAgAgAgAgAgyYAgAgAgAgAgAgzojhkIkIkIjhzoAgAgAgAgAgAgyYAgAgAgAgAgAgAgAgAgAgAgAgyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYAgAgAgAgAgAgAgAgAgAgAgAgAgyYAgAgAgAgAgAgzolIkIkIkIlIzoAgAgAgAgAgAgyYAgAgAgAgAgAgAgAgAgAgAgAgyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYAgAgAgAgAgAgAgAgAgAgyYyYAhyYyYAgAgAgAgAgzojhkIkIkIjhzoAgAgAgAgAgyYyYAhyYyYAgAgAgAgAgAgAgAgAgyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYzozozozozozoyYzozoyYyYAiAiAjyYyYzozozoyYAkzoyXyXyXzoAzyYzozozoyYyYAjAiAiyYyYzozozozozoyYyYyYyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYyXyXyXyXyXyXyXyXyXzuyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXzuyXyXyXyXyXyXyXyXyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYyXyXyXyXyXyXyXyXyXyYyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyYyXyXyXyXyXyXyXyXyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaBKBKBKBLBKBKBKaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYyXyXyXyXyXyXIgyXyXzuyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXyXzuyXIJyXyXyXyXyXyXyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaBKBLBKBKBUBVBWBKBKBLBKaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYzozozozozozoyYzozoyYyYAAAAAAyYyYzoyYzozozozozoyYzozozozozoyYzoyYyYAAAAAAyYyYzoyYzozozozozozoyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaBKBKBKCcCdBKCeCfCfBKCgChBKBKBKaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoyXyXyXyXCrzoaaaaBraaaaaaaaaaaaaaaaaaBraaaazoCryXyXyXCrzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaBKBKCjCkClClBKCmCfCfBKCnCoCpCqBKBKaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXyXBwzoaaaaBraaaaaaaaaaaaaaaaaaBraaaazoBxyXyXyXBwzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaBKBKCtCuCvClClBKCwCfCfBKCxCxCxCxCyBKBKaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoABACyXyXyYaaaaBraaaaaaaaaaaaaaaaaaBraaaayYyXBJBCBNyXyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaBKCCCDCECvClClCFCxCxCxCGCxCxCxCHCxCIBKaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBXAOANCJAPBByXBwzoaaaaBraaByBzBzBzBzBzByaaBraaaazoBxyXAQyXBwzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaBKBKClCMCMClClClBKCNCxCOBKCPCxCQCxCxCRBKBKaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoARBMyXyXzoaaaaBrByBEASBGBHBIAVBEByBraaaazoyXBMBCBDyXzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaBLCSClClClClClCTBKCNCxCUBKCVCxCxCWCxCxCXBLaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXyXBwzoaaaaBrByBOBPBQBRBQBSBTByBraaaazoBxyXyXyXBwzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBKBKBKDcDdClDeDdBKBKBKCGBKBKBKDfDgCxDhDiBKBKBKaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBtyYzozozoyYyYyYyYyYyXyXyXyXyXyYBrBrBrBzBRBRBZCaCbBRBRBzBrBrBryYyXyXyXyXyXyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBKCxBKBKBKCFBKBKBKDlDmDnDoDpBKBKBKCGBKBKBKDqBKaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXyXBwzoaaaaaaByBRBRBECiBEBRBRByaaaaaazoBxyXyXyXBwzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBLDtCxDuDvCxDwDxBKDyDnCxDzDABKDBDnCxDnDCDDDqBLaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoAByXyXCrzoaaaaByBECsAWBEByBEAWCsBEByaaaazoCryXyXyXCrzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBLDECxDFCxCxCxCxCGDnCxBKCxDnCGCxCxCxCxDGDqDqBLaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBXAOANCJAPyXAXzozozozoCzCABRBRCBBaCBBRBRCACzzozozozoAByXAXzozozozoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBLDHCxDnDnCxDIDJBKDKDnCxDnDLBKDMDnCxDnBKDNDOBLaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoARyXBbCKyXBcCKCLBRBRBRBRBRBRBRBRBRCLCKyXBcCKAPyXBbCJAOANBXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBKCxBKBKBKCGBKBKBKDPDQDnDRDSBKBKBKCGBKBKBKDTBKaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXBbCKBdyXCKCLBRBRBRBRBRBRBRBRBRCLCKBdyXCKAPyXBezozozozoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaBKBKBKDUDVCxDWDXBKBKBKCGBKBKBKDYDZCxEaEbBKBKBKaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBtyYzozozoyYyYyYyYyYyXyXyXBezozozozoCzBfBRCZDaBRCZDaBRDbCzzozozozoARyXyXBvzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaBLEeCxCxCxCxCxEfBKEgEhEiBKEjCxCxCxCxCxCxBLaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXyXBvzoaaaaBzDjBRCZDaBRCZDaBRDkBzaaaazoBvyXyXyXyXzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaBKBKDqEsDqEtCxEuBKEvEwExBKDZCxEyEzEAEBBKBKaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoAByXyXDryYaaaaBzDjBRCZDaCaCZDaBRDkBzaaaayYyXyXyXyXyXzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaBKDqECEDEECxCxCGEFCxEGCGCxCxEHEIEJEBBKaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBXAOANCJAPyXyXBvzoaaaaBzDjBRCZDaBRCZDaBRDkBzaaaazoBvyXyXyXyXzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaBKBKEQDqDqCxERBKEvCxExBKDnCxESETEUBKBKaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoARyXAXzozozozoCzBgBRCZDaBRCZDaBRBhCzzozozozoAByXyXBvzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaBKBKEWEXCxEYBKBKCGBKBKDnCxEBEBBKBKaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXBbCKyXBcCKCLBRBRBRBRBRBRBRBRBRCLCKyXBcCKAPyXAXzozozozoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaBKBKBKFbFcBKCxCxCxBKFdFeBKBKBKaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBtyYzozozoyYyYyYyYyYyXyXyXBbCKBdyXCKCLBRBRBRBRBRBRBRBRBRCLCKBdyXCKAPyXBbCJAOANBXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaBKBLBKBKFfFgFhBKBKBLBKaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXBezozozozoCzAWEcAWByBiBjEdBiBjCzzozozozoARyXBezozozozoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaBKBKBKBLBKBKBKaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoAByXyXCrzoaaaaByEkElEmByEnEoEpEqErByaaaazoCryXyXyXCrzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBXAOANCJAPyXyXBwzoBrBrByEkElEmByBkBlEpEpEpByBrBrzoBxyXyXyXBwzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozozozoARyXyXyXyYaaaaByEkEKBmByELEMBnEOEPByaaaayYyXyXyXyXyXyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsBsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBvyXyXyXBwzoaaaaByEVEVBEByByByBEEVEVByaaaazoBxyXyXyXBwzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoyXAXBpBoBqzoaaaaByAoAoByFaFaFaByAoAoByaaaazoBuBoBAABCrzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayYyYzoCJCJBtyYaaaaaaaaaaByAoAoAoByaaaaaaaaaayYBtCJCJzoyYyYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBFCYBYzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBFCYBYzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoDsFiENzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoDsFiENzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazozoBXBXzoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazoBXBXzozoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFlFlFlFlFlFlFlFlFlFlFlFlFlFlFlFlFlFlFkFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFlFnFnFnFoFpFoFoFoFoFoFoFoFoFnFnFnFnFkFmFqFqFrFqFqFqFsFsFsFqFqFsFsFsFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFlFnFoFoFoFoFoFtFoFoFoFtFoFoFnFnFnFnFkFmFuFqFqFqFqFqFqFqFqFqFqFqFqFqFqFqFqFqFvFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFjFjFjFjFjFjFjFjFjFjFnFoFoFpFoFoFoFtFoFoFoFtFoFoFoFnFnFnFkFmFqFqFqFqFqFqFqFqFqFqFqFqFqFwFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFxFyFyFzFAFzFyFyFBFjFoFpFoFoFoFoFoFtFoFoFoFtFoFoFoFoFnFnFkFmFqFqFqFqFqFqFqFqFqFqFqFqFqFuFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFCFyFyFyFyFyFyFyFyFjFoFoFoFoFoFoFoFtFDFEFDFtFoFoFoFoFoFnFkFmFqFqFqFqFFFwFqFqFqFqFqFqFqFqFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFjFjFjFjFjFGFyFHFIFIFIFJFyFyFjFjFKFKFjFoFtFDFtFtFtFtFtFDFtFoFpFoFoFkFmFqFqFqFqFqFLFLFqFqFqFqFqFqFqFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFMFNFOFjFyFyFyFPFQFQFQFRFyFyFyFjFSFSFjFtFtFTFUFVFWFXFYFTFtFtFoFoFoFkFmFqFqFqFqFLFZGaFLFqFqFqFqFqFqFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjGbGbGbGcFyFyFyFPFQFQFQFRFyFyFyGdFSFSGdGeGfFtGgGhGhGhGiGjGkFtFoFoFoFkFmFqFqFqFqFLGlGmFLFqFqFFFqGnFqFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjGoGoGoFjFyFyFyFPFQFQFQFRFyFyFyFjFSFSFjFtGpGqGrGjGjGjGjGjGsFtFoFoFoFkFmFqFqFqFqFqFLFLFqFqFqFqFqFqFqFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFjFjFjFjFjFyFyGtGuGuGuGvFyFyFjFjFKFKFjFtFTFTGwGjGjGjGxFTFTFtFoFoFpFkFmFqFqFwFqFqFqFqFqFqFqFqFqFqFqFqFqFuFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFjFyFyFyFyFyFyFyGyFyFjFoFoFoFoFoFtFTGzGjGAGjGBFTFtFoFoFoFoFkFmFqFqFFFwFqFqFqFqFqFqFqFqFqFqFqFqFwFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFjGCGCGCFyFyFyGCGCGCFjFoFoFpFoFoFoFtFtGDGEGFFtFtFoFoFoFoFoFkFmFqFqFqFqFqFqFqGGFqGHFqGHFqGIFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFjFjFjFjFKGJFKFjFjFjFjFoFoFoFoFoFoFoFtGKGLGMFtFoFoFoFoFoFoFkFmFqFqFqGNFqFqFqFqFqFqFqFqFqFqFqFqFqFqFqFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoGOFoFoFoFoGPGQGRGSGTGUGPFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkFmGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVFmFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGTGUFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGWGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGWFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGTGUFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFpFoFoFoFoFoGQGRGSGTGUFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGTGUFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGTGUFoGOFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGTGUFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoGOFoFoFoGQGRGSGTGUFoFoFoFoFoFoFoFoFoFoFpFoFoFoFoFoFoGOFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGSFjFjFKFKFKFjFjFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFoFoFoFoFoFoFoGQGRGSGSFjHaFyFyFyHbFjFoFoFoFoFoFoFoFoFoFoFoFoFoFoFoFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFjFjFjFKFKFKFKFjFKGJFKFjFyFyGCFyFyFjFKFjFjFjFKFjFjFjFjFjFjFjFjFjFjFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHcFyFyFyFyFyFyFyFyFyFyHdFjFyGCHeGCFyFjHfHgFjHgHhFjHiHjHkFjaaaaaaaaaaFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHcFyFyFyFyFyFyFyFyFyFyFyFjFyFyHlFyFyFjFyHmFjHmFyFjHnHjHjFjaaaaaaaaaaFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjFKGcFKFjHoFyFyFyFyFyFyFjHpFyFyFyHbFjFyFyFjFyFyFjHqHjHjFjaaaaaaaaaaFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjHrGoHsFjFKHtFKFjFyFyFyFjFKFjHuFjFKFjFjHuFjHuFjFjFjHjHjFjaaaaaaaaaaFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjHvGoHwFjHxHxHxFjFyFyFyFyFyFyFyFyFyFyFyFyFyFyFyFyHyHjHjFjaaaaaaaaaaFkGYGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjHzHAHBFjHxHxHxFjFyFyFyFyFyFyFyFyFyFyFyFyFyFyFyFyFjHCHDFjaaaaaaaaaaFkGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYFkaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFjHEHFHGFjHHHIHJFjHcFjHcFjHKHKHKHKHKHKHKHKFyFyFBHLHMHMHMHMHMHMHMHMHMHMHMabababababababababababababababababababababaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababHNHNHNHNHNHNHNHNHNHNHNHNHNababababababababababHOHOHOHOHOHOHOHOHOHOHOHOHOababHKHKHPHQHRHSHTHUHKHKHKHKHKHMHVHWHXHWHXHWHXHWHXHMaaaaaaaaHZEZIaIbHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIeIeIeIfHNMyMyIhHNIiIjIjHNIeIdIdIdIdIdIdIdIdIdIdHOIkIlHOIkIlHOIkIlHOIkIlHOIdIdHKImInInInInInInIoHKHKIpHKHMHVHVHVHVHVHVHVHVHVHMaaaaaaaaHZIqIqIqHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIeIfIfIfIrIjIjIjHNIjIjIsItIeIeIeIdIdIdIdIdIdIdIdHOHOHOHOHOHOHOHOHOHOHOHOHOIdIdHKIuInInIvIwInInIoHKInInIxHMHMHMHMHMIyHMHMHMHMHMHMHMIzHMIAIBIBIBIAaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIeIeIfIfICIfIjIjIDIjIjIjHNIEIFIeIeIdIdIdIdIdIdIdHOIkIlHOIkIlHOIkIlHOIkIlHOIdIdHKIGInInIHIIInInHYHKIKIKIKHMHVHVHVHVHVHVHVHVHVHVHVILIMINIOIPIPIPHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdIeIeIfHNIQIjIjHNIjIjIjHNIRISITIeIeHNHNHNHNHNHNHOHOHOHOHOHOHOHOHOHOHOHOHOIdIdHKIUInInIVIWInInIXHKInInInIYHVHVHVHVHVHVHVHVHVHVHVILIMINIOIPIPIPHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdIdIeIeHNIjIjIjHNIjIjIjHNIZISISItIeJaJbJcJdHNJeJfJgJhJiJjJkabIdIdIdIdIdIdIdIdHKJlInInInInInInIXHKInInInIYJmJmJmJnJnJnJmJmJmHMHMHMIzHMIAJoIPJpIAaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNHNHNHNHNHNHNHNIjIjIjJqISISISJrHNJsJtJtJuHNJvItJwItItItJxabIdIdIdIdIdIdIdHKHKIKIKHKJyJyHKIKIKHKHKJzJzHMHMHMHMHMHMHMHMHMHMHMIdIdIdaaHZJoIPJpHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNJAJBJCJBJDJEHNIjIjIjHNISISISJFHNJGJtJtJHHNJIJJJKJLJwJMJNabIdIdIdIdIdHKHKHKInInInInInInInInInHKInInInHKJOJPJQJRJSHKJTJUJVHKHKHKIdaaHZJWIPJWHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNJXJYJXJYJXJZHNIjIjIjHNKaKbKcHNHNHNIDHNHNHNHNHNKdKdKdHNHNabIdIdIdIdIdHKInHKInInInKeInInInInInKfInInInHKKgJPJPJPKhHKKiKiKiKjKkHKIdaaHZKlIPKmHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNJYKnJYJYJYKoKpIjIjIjHNHNHNHNHNIjIjIjIjItKpKqKrIfIfKsIfIeabIdIdIdIdIdHKKtHKInInInInInInInInInKfInInInHKKuJPJPJPKvHKKwKiKiHKHKHKIdaaHZKxKyKxHZaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNJXJYJXJYKzKAHNIjIjIjIjIjIjIjIjIjIjIjIjIjKBKqIfKCKDKEIfIeabIdIdIdIdIdHKHKHKInKFKGInInInInKHKIHKInInInHKKJJPJPJPKKHKKLKiKiKMKNHKIdaaaaHZKOHZaaaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNKPJBKQJBKRJBHNKqIjIjIjIjIjIjIjIjIjHNHNHNIeKSKqIfIfIfKTIeabIdIdIdIdIdIdIdHKHKIKIKHKKUKUHKIKIKHKHKInInHKHKHKKVHKHKHKHKKWHKHKHKHKIdaaaaaaaaaaaaaaIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdIdHNHNHNHNHNHNHNHNKXKYKXHNHNHNHNHNHNHNHNIeIeIeIeKZIfIfIfLaIeabIdIdIdIdIdIdIdIdHKLbInInInInInInLcHKLdInInIKLeLfLgLgLhHKLiLiLjLjLjHKHKIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdHNHNIiIjIjKqKqHNLkLkLkLkLlHNLmIjIjIjLnHNHNIeIeIeIfLoKDKDLpIeabIdIdIdIdIdIdIdIdHKLbInInLqLrInInLsHKLtInInHKLgLgLuLgLgHKLiLiLvLvLvLwHKIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdHNIjIjIjIjIjKqHNLkLkLxLkLkHNIjIjIjIjKqKqHNIeIeIeLyIfIfIfIfIeabIdIdIdIdIdIdIdIdHKLbInInLbLzInInLAHKLBInInLCLgLDLELFLgLGLiLiLiLiLiLHHKIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdHNIjIjIjIjIjIjKYLkLILJLKLkKYIjIjIjIjIjKqHNIeIdIeIeLLLMIfIeIeabIdIdIdIdIdIdIdIdHKLbInInLNLOInInLPHKLQInInHKLgLDLELFLgHKLiLiLvLvLvLRHKIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdIdHNKqIjHNKXKXKXHNLkLILSLKLkHNKXKXKXHNIjIjHNIeIdIdIeIeIeLTIfIeabIdIdIdIdIdIdIdIdHKLbInInInInInInLPHKInInInIKLgLgLULgLgHKLVLVLjLjLjHKHKIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdIdIdaaHNIjKqHNaaaaaaHNLWLkLXLkLkHNaaaaaaHNIjIjHNIeIdIdIdIdIeIeLYIeabIdIdIdIdIdIdIdIdHKHKHKLZMaMbMcHKHKHKHKInInHKIKLgLgLgIKHKHKHKIKIKIKHKIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdIdaaaaaaMdMeMeMfaaaaaaHNHNKXKXKXHNHNaaaaaaMdMeMeMfaaIdIdIdIdIdIdIdIdabIdIdIdIdIdIdIdIdIdIdHKHKHKHKHKHKaaaaMgMhMhMiIKIKIKIKIKaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdaaaaaaaaMdMjMkMfaaaaaaaaaaaaaaaaaaaaaaaaaaMdMjMkMfaaIdIdIdIdIdIdIdIdabIdIdIdIdIdIdIdIdIdIdaaaaaaaaaaaaaaaaMgMlMmMiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdIdaaaaaaaaMdMeMeMfaaaaaaaaaaaaaaaaaaaaaaaaaaMdMeMeMfaaaaIdIdIdIdIdIdIdabIdIdIdIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaMnMhMhMoaaaaaaaaaaaaMpMpMqMrMsMpMpMpMpMpMpMpaaaaaaIdIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdaaaaaaaaaaMtMuMvMtaaaaaaMtaaaaaaaaaaMtaaaaaaMtMwMxMtaaaaIdIdIdIdIdIdIdabIdIdIdIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaMpMzMzMpaaaaaaMpMpMpMpMAMBMBMBMBMBMCMpMDMEIcaaaaaaaaIdIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdaaaaaaaaaaMtMGMHMtaaaaaaMtMIMJMJMJMKMtaaaaaaMtMLMMMtaaaaaaaaIdIdIdIdIdabIdIdIdIdIdIdIdIdaaaaaaaaaaaaMpMpMpMpMNMOMPMQMRMSMpMpMTMUMpMVMBMBMBMBMBMWMpMDMEMFaaaaaaaaaaIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdaaaaaaaaaaMtMYMZMtaaaaMtMtNbNaNdNcNeMtMtaaaaMtNfNgMtaaaaaaaaaaIdIdIdIdabIdIdIdIdIdIdIdaaaaaaaaaaMpMpMpMBMBNhNiNjNkNlNmNnNnNoNpMBMpNqMBMBMBMpMpMpMpMDMEMFaaaaaaaaaaIdIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdaaaaaaaaaaMtNrMtMtaaaaMtMtNtNsNuNsNvNwMtaaaaMtMtNxMtaaaaaaaaaaIdIdIdIdabIdIdIdIdIdIdaaaaaaaaMpMpMpMpNyMBMBMpNzNANAMQNBMBMBMBMBNyMpNCMBMBNDMpNENFMpMDMEMXaaaaaaaaaaaaIdIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdIdaaaaaaaaaaMtNHNIMtMtMtMtNJNsNsNsNsNsNJMtMtMtMtNKNMMtaaaaaaaaaaIdIdIdIdabIdIdIdIdIdaaaaaaaaMpMpNNNOMpMBMBNPMpNQNRNSNTMpNUNVMBMBMpMpMpNWMBNXNYNZOaMpMpMpMpMpaaaaaaaaaaaaIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIdIdaaaaaaaaaaaaMtObOcOdOeOfMtOgNsNsNsNsNsOgMtOhOiOjOcObMtaaaaaaaaaaIdIdIdIdabIdIdIdIdaaaaaaaaaaOkOlMBOmMpMBMBOnMpOoOpOpOqMpMpMpMpOrMpOsMpMSOrMpMpNZOtMpOuOvOwMpMpaaaaaaaaaaIdIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaOxIdaaaaaaaaaaaaaaMtObOcOcOcOyMtOzOAOBOCOzOAOBMtNLOcOcOEObMtaaaaaaaaaaIdIdIdIdabIdIdIdIdaaaaaaaaaaOFOGOpOHMpMBMBNPMpOIOpOpOJMpMBOKOLOpMBMBMBOKOpMBMpMpMpMpNZNZNZOMMpMpaaaaaaaaaaIdIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaOOObOcOcOcOcOCNsNsNsNsNsNsNsOCOcOcOPOcObOOaaaaaaaaaaaaIdIdIdabIdIdIdIdaaaaaaaaaaOFOQOROpOSOpOpOpOSOpOpOpOpOSOpOpOpOpOpOTOpOpOpNZNZNZNZOUNZNZNZNZOVMpaaaaaaaaaaaaIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaOWOXOcOYOZOcMtPaPbNsNsNsPdPcMtOcPeOcPfObOWaaaaaaaaaaaaIdIdIdabIdIdIdaaaaaaaaaaaaOFPgOpPhMpMBMBNPMpOIOpOpOJMpMBNWMBOpMBMBMBNWOpMBMpMpMpMpPiNZNZPjMpMpaaaaaaaaaaaaIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaPkOXOcOcMtPlMtMtMtPmPoPnMtMtMtPpMtPqPrPsPkaaaaaaaaaaaaaaIdIdabIdIdIdaaaaaaaaaaaaPtPuMBPvMpMBMBOnMpOoOpOpOqMpMpMpMpOrMpPwMpMSOrMpMpPxPxMpPyPzPAMpMpaaaaaaaaaaaaaaIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaMtMtPBPCPCMtPDPEPDPFPGPIPHPFPJPKPLMtPMPNPOMtMtaaaaaaaaaaaaIdIdabIdIdaaaaaaaaaaaaaaMpMpPPPQMpMBMBNPMpPRMBMBPRMpPSPTMpMBMpMpMpPUOpPVOpPWPXMpMpMpMpMpaaaaaaaaaaaaaaaaIdIdIdabaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaMtMtPYPYMtMtPDPDPDPZPGQaPHPZPLPLQbMtMtPYPYMtMtaaaaaaaaaaaaIdIdabIdIdaaaaaaaaaaaaaaaaMpMpMpMpNyMBMBMpMpMpQcMpMpNZNZQdMBNPMpQeQfOpOpQgQhQiMpMDMEIcaaaaaaaaaaaaaaaaaaaaIdIdabaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaMtNGNGMtMtQkQlPDQmQnNsQnQmPLPLQoMtMtNGNGMtaaaaaaaaaaaaaaIdIdabIdaaaaaaaaaaaaaaaaaaaaaaMpMpMpMBMBMBMpNENZMpQpNZNZQqQrQsMpOpOpOpOpQtQuQvMpMDMEMFaaaaaaaaaaaaaaaaaaaaIdIdabaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaMtPDQwPDMtMtQxMtMtQyPLQzMtaaaaaaaaaaaaaaaaaaaaIdIdIdabIdaaaaaaaaaaaaaaaaaaaaaaaaaaMpMpMpMpMpQAQBMpMpMSMpMpQCQDMpQEOpOpOpQFOpQGMpMDMEMFaaaaaaaaaaaaaaaaaaaaIdIdabaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaMtPDPDQHMtQIQJQKMtPLPLQLMtaaaaaaaaaaaaaaaaaaaaIdIdIdabIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMpMpMpMpaaaaaaMpMpMpMpQMQNOpQOQPQQQRMpQSMEMXaaaaaaaaaaaaaaaaaaBrBrIdabaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaMtMtQTPDMtQUQJQVMtQWQXMtMtaaaaaaaaaaaaaaaaaaaaIdIdIdabIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMpMpQYQZRaMpMpMpMpMpMpMpaaaaaaaaaaaaaaaaBrBraaIdabaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaMtMtMtMtMtRbRcRdMtMtMtMtMtaaaaaaaaaaaaaaaaaaaaIdIdIdabIdBrBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBrBraaaaIdOxaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaaaaaMtMtPYPYPYPYPYMtMtaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdabIdaaBrBraaaaIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBrBraaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaIdIdIdaaaaaaaaaaaaaaaaaaMtNGNGNGNGNGMtaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdabIdaaaaBrBrIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdaaaaaaaaaaONaaaa +aaaaabababababababReabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdabIdaaaaaaIdIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdIdIdaaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdabIdaaaaaaIdIdIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdIdIdIdaaaaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdabIdaaaaaaIdIdIdIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdIdIdIdIdaaaaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdaaaaaaIdabIdaaaaaaaaIdIdIdIdIdIdIdBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrBrIdIdIdIdIdIdIdIdIdaaaaaaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdaaaaaaIdabIdaaaaaaaaaaIdIdIdIdIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdIdIdIdIdaaaaaaaaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdaaaaaaaaIdabIdaaaaaaaaaaaaaaaaIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdIdIdIdaaaaaaaaaaaaaaaaaaaaONaaaa +aaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIdabIdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaaaa +aaaaRfababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONRgRgOxONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONONaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd diff --git a/maps/southern_cross/southern_cross_defines.dm b/maps/southern_cross/southern_cross_defines.dm index 7a9f0a52a3..e44bad1a49 100644 --- a/maps/southern_cross/southern_cross_defines.dm +++ b/maps/southern_cross/southern_cross_defines.dm @@ -66,6 +66,7 @@ NETWORK_TELECOM ) + usable_email_tlds = list("freemail.nt") allowed_spawns = list("Arrivals Shuttle","Gateway", "Cryogenic Storage", "Cyborg Storage") unit_test_exempt_areas = list(/area/ninja_dojo, /area/ninja_dojo/firstdeck, /area/ninja_dojo/arrivals_dock) diff --git a/maps/submaps/surface_submaps/wilderness/Manor1.dmm b/maps/submaps/surface_submaps/wilderness/Manor1.dmm index ec837531c4..691311bc68 100644 --- a/maps/submaps/surface_submaps/wilderness/Manor1.dmm +++ b/maps/submaps/surface_submaps/wilderness/Manor1.dmm @@ -140,7 +140,7 @@ "cJ" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/obj/random/soap,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) "cK" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) "cL" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 1},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cM" = (/obj/structure/table/woodentable,/obj/item/device/laptop,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cM" = (/obj/structure/table/woodentable,/obj/item/modular_computer/laptop/preset/custom_loadout/cheap,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) "cN" = (/turf/template_noop,/area/template_noop) "cO" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Manor1) diff --git a/maps/submaps/surface_submaps/wilderness/Rockybase.dmm b/maps/submaps/surface_submaps/wilderness/Rockybase.dmm index 7e5889f458..112226d717 100644 --- a/maps/submaps/surface_submaps/wilderness/Rockybase.dmm +++ b/maps/submaps/surface_submaps/wilderness/Rockybase.dmm @@ -1,3 +1,4 @@ +<<<<<<< HEAD "aa" = (/turf/template_noop,/area/template_noop) "ab" = (/obj/effect/decal/remains,/turf/template_noop,/area/template_noop) "ac" = (/obj/item/weapon/grenade/chem_grenade/metalfoam,/turf/template_noop,/area/template_noop) @@ -224,4 +225,233 @@ aaaaaaadaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaabaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaadEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaadFaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaadFaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadGaaaaaaaaaaaaabaa -"} \ No newline at end of file +"} +======= +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/obj/effect/decal/remains,/turf/template_noop,/area/template_noop) +"ac" = (/obj/item/weapon/grenade/chem_grenade/metalfoam,/turf/template_noop,/area/template_noop) +"ad" = (/mob/living/simple_mob/mechanical/viscerator,/turf/template_noop,/area/template_noop) +"ae" = (/obj/effect/decal/remains,/turf/template_noop,/area/submap/Rockybase) +"af" = (/turf/template_noop,/area/submap/Rockybase) +"ag" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Rockybase) +"ah" = (/obj/effect/gibspawner/robot,/turf/template_noop,/area/submap/Rockybase) +"ai" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/Rockybase) +"aj" = (/obj/effect/decal/remains/robot,/turf/template_noop,/area/template_noop) +"ak" = (/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/template_noop,/area/submap/Rockybase) +"al" = (/turf/simulated/floor,/area/submap/Rockybase) +"am" = (/obj/effect/decal/remains/posi,/turf/simulated/floor,/area/submap/Rockybase) +"an" = (/obj/machinery/porta_turret/poi,/turf/simulated/floor,/area/submap/Rockybase) +"ao" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/submap/Rockybase) +"ap" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/template_noop) +"aq" = (/obj/effect/floor_decal/industrial/danger,/turf/simulated/floor,/area/submap/Rockybase) +"ar" = (/obj/machinery/light,/obj/effect/floor_decal/industrial/danger,/turf/simulated/floor,/area/submap/Rockybase) +"as" = (/obj/effect/decal/cleanable/blood,/obj/effect/floor_decal/industrial/danger,/turf/simulated/floor,/area/submap/Rockybase) +"at" = (/turf/simulated/wall/r_wall,/area/submap/Rockybase) +"au" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/submap/Rockybase) +"av" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aw" = (/obj/effect/decal/remains/deer,/turf/template_noop,/area/template_noop) +"ax" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"ay" = (/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"az" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/obj/item/weapon/soap,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"aA" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aB" = (/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aC" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aD" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/weapon/pickaxe/plasmacutter,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aE" = (/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aF" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aG" = (/obj/structure/table/woodentable,/obj/machinery/light{dir = 1},/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aH" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aI" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/toy/plushie/spider,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aJ" = (/obj/structure/closet/l3closet/janitor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aK" = (/mob/living/bot/cleanbot{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aL" = (/obj/item/weapon/stool,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aM" = (/obj/item/weapon/storage/belt/janitor,/obj/structure/table/standard,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aN" = (/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aO" = (/obj/structure/table/standard,/obj/item/modular_computer/laptop/preset/custom_loadout/cheap,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 9},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aP" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/pistol,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aR" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun/taser,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aS" = (/obj/machinery/light{dir = 1},/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aT" = (/obj/machinery/vending/coffee,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 5},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aU" = (/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"aV" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"aW" = (/obj/machinery/vending/hydronutrients,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 9},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aX" = (/obj/structure/closet/crate/hydroponics,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 5},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aY" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"aZ" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"ba" = (/obj/structure/janitorialcart,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bb" = (/obj/structure/table/standard,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bc" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bd" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "Carl's absolutly fucked in the head. He's trying to squeeze as much drone production out as he can since he's worried we're gonna get found out but he's getting sloppier with each batch. Now's he's telling us he can speed the time on the IFF encoding. I already have a hard enough time getting these damn things not to stare at walls and now he's gonna shortchange the only part of these tincans that tells em not to turn us into paste on a wall. I told Richter to get out while he can, We're counting days before either some Sif task force shows up at our door or these things decide we aren't there friends anymore."; name = "Note"},/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"be" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bf" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bg" = (/obj/machinery/vending/security,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bh" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/cell/device/weapon,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"bi" = (/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bj" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bk" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bl" = (/obj/item/mecha_parts/part/gygax_left_leg,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"bm" = (/obj/machinery/light,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"bn" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/weapon/gun/projectile/pistol,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"bo" = (/obj/structure/closet/crate/trashcart,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bp" = (/obj/structure/loot_pile/maint/trash,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bq" = (/obj/structure/table/standard,/obj/item/weapon/storage/bag/trash,/obj/item/weapon/storage/bag/trash,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"br" = (/obj/structure/table/standard,/obj/item/weapon/paper_bin,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 10},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bs" = (/obj/machinery/light,/obj/structure/table/standard,/obj/item/weapon/pen,/obj/effect/floor_decal/corner/red/border,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bt" = (/obj/effect/floor_decal/corner/red/border,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bu" = (/obj/effect/floor_decal/corner/red/border,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bv" = (/obj/machinery/door/airlock/security{icon_state = "door_locked"; locked = 1},/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"bw" = (/obj/machinery/light,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"bx" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle/pistol,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"by" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bz" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bA" = (/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 8},/mob/living/bot/farmbot{faction = "malf_drone"; name = "Mr. Weddleton"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bB" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bC" = (/obj/effect/decal/remains/posi,/turf/template_noop,/area/template_noop) +"bD" = (/obj/machinery/vending/cola,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bE" = (/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bF" = (/obj/machinery/light{dir = 1},/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bG" = (/obj/structure/door_assembly,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bH" = (/obj/effect/decal/cleanable/dirt,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bI" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb2,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bJ" = (/obj/effect/decal/mecha_wreckage/hoverpod,/turf/template_noop,/area/template_noop) +"bK" = (/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bL" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bM" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bN" = (/obj/effect/decal/remains,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bO" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bP" = (/obj/machinery/vending/snack,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bQ" = (/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bR" = (/obj/effect/decal/cleanable/dirt,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bS" = (/obj/item/stack/rods,/obj/structure/girder,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bT" = (/obj/effect/decal/remains,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bU" = (/obj/machinery/light,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bV" = (/obj/effect/decal/cleanable/blood,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bW" = (/obj/item/mecha_parts/part/gygax_right_arm,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bX" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bY" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bZ" = (/obj/machinery/door/airlock/engineering,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ca" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cb" = (/turf/simulated/wall,/area/submap/Rockybase) +"cc" = (/obj/structure/table/standard,/obj/item/device/kit/paint/gygax/darkgygax,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cd" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "I've decided to go forward and start some small scale tests of the Vicerator delivery grenades, Might as wall make sure they work like the real ones. There are a few Fauna areas nearbye and we're working to make sure the kinks in the code are worked out. Once we've made sure they stay flying we'll work on the IFF signals."; name = "V-Grenade Notice 2"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ce" = (/obj/structure/table/standard,/obj/random/toolbox,/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cf" = (/obj/structure/table/standard,/obj/random/toolbox,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cg" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "We've finally been able to get the Vicerator delivery grenades working, Took awhile to make sure the latching mechanism didn't fail but we're sure we've got it this time. Vel'Shem's worried about the miners having there own drone fab now but I say it's a small price to pay to keep the metal flowing, Especially since there telling us NT's starting to monopolize the metal rich parts."; name = "V-Grenade Notice 1"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ch" = (/obj/structure/table/standard,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ci" = (/obj/structure/table/standard,/obj/item/weapon/grenade/spawnergrenade/manhacks,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cj" = (/obj/structure/table/standard,/obj/item/stack/material/steel,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ck" = (/obj/structure/table/standard,/obj/machinery/light{dir = 1},/obj/item/weapon/circuitboard/mecha/gygax/main,/obj/item/weapon/circuitboard/mecha/gygax/peripherals,/obj/item/weapon/circuitboard/mecha/gygax/targeting,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cl" = (/obj/structure/door_assembly,/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cm" = (/obj/item/weapon/material/shard,/turf/simulated/floor,/area/submap/Rockybase) +"cn" = (/obj/structure/table/standard,/obj/fiftyspawner/rods,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"co" = (/obj/machinery/vending/engivend,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cp" = (/obj/machinery/vending/tool,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cq" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cr" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cs" = (/obj/item/mecha_parts/part/gygax_torso,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ct" = (/obj/machinery/light{dir = 1},/obj/structure/closet/crate/medical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cu" = (/obj/structure/table/standard,/obj/structure/table/standard,/obj/effect/decal/cleanable/dirt,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cv" = (/obj/structure/table/standard,/obj/item/clothing/mask/breath/medical,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cw" = (/obj/structure/closet/secure_closet/medical2,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cx" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"cy" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"cz" = (/obj/structure/table/standard,/obj/item/device/mmi/digital/robot,/obj/item/weapon/stock_parts/capacitor/adv,/obj/item/weapon/stock_parts/scanning_module/adv,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cA" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cC" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/port_gen/pacman,/turf/simulated/floor,/area/submap/Rockybase) +"cD" = (/obj/structure/door_assembly,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cE" = (/obj/item/stack/rods,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cF" = (/obj/effect/decal/cleanable/dirt,/obj/structure/girder,/turf/simulated/floor,/area/submap/Rockybase) +"cG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/Rockybase) +"cH" = (/obj/effect/decal/cleanable/dirt,/obj/structure/table,/turf/simulated/floor,/area/submap/Rockybase) +"cI" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/Rockybase) +"cJ" = (/obj/structure/closet/secure_closet/medical1,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cK" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"cL" = (/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cM" = (/obj/machinery/drone_fabricator{fabricator_tag = "Unknown"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cN" = (/obj/machinery/mecha_part_fabricator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cO" = (/obj/machinery/pros_fabricator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cP" = (/obj/structure/table/standard,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cQ" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cR" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cS" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cT" = (/obj/machinery/power/smes/buildable/point_of_interest,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/submap/Rockybase) +"cU" = (/obj/machinery/vending/medical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cV" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cW" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/Rockybase) +"cX" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/item/weapon/material/shard,/turf/simulated/floor,/area/submap/Rockybase) +"cY" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/Rockybase) +"cZ" = (/obj/item/mecha_parts/part/gygax_armour,/turf/simulated/floor,/area/submap/Rockybase) +"da" = (/obj/item/mecha_parts/chassis/gygax,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dc" = (/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dd" = (/obj/machinery/vending/robotics,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"de" = (/obj/machinery/power/apc{cell_type = /obj/item/weapon/cell/super; dir = 8; name = "Unknown APC"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"df" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dg" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dh" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"di" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/submap/Rockybase) +"dj" = (/obj/item/mecha_parts/part/gygax_right_leg,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dk" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/mecha_parts/part/gygax_left_arm,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"dl" = (/obj/machinery/vending,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dm" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dn" = (/obj/machinery/power/smes/buildable/point_of_interest,/obj/structure/cable/green,/turf/simulated/floor,/area/submap/Rockybase) +"do" = (/obj/machinery/light{dir = 8},/obj/structure/closet/secure_closet/medical3,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dp" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dq" = (/obj/structure/closet/secure_closet/hydroponics,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dr" = (/obj/effect/decal/cleanable/blood/oil,/turf/template_noop,/area/template_noop) +"ds" = (/obj/machinery/light,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dt" = (/obj/machinery/mech_recharger,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"du" = (/obj/structure/table/standard,/obj/item/stack/material/plasteel,/obj/item/stack/material/glass/reinforced,/obj/item/stack/material/phoron{amount = 25},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dv" = (/obj/structure/table/standard,/obj/item/stack/material/glass,/obj/item/stack/material/steel,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dw" = (/obj/structure/table/standard,/obj/item/mecha_parts/part/gygax_head,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dx" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dy" = (/obj/structure/closet/secure_closet/medical3,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dz" = (/obj/item/weapon/surgical/surgicaldrill,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dA" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dB" = (/obj/effect/decal/cleanable/dirt,/mob/living/bot/medbot{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dC" = (/obj/machinery/vending/hydroseeds,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 10},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dD" = (/obj/structure/closet/crate/secure/hydrosec,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 6},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dE" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/structure/gravemarker{dir = 1},/turf/template_noop,/area/template_noop) +"dF" = (/obj/effect/gibspawner/robot,/turf/template_noop,/area/template_noop) +"dG" = (/obj/effect/gibspawner/human,/turf/template_noop,/area/template_noop) + +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaabacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaa +aaaaaaaaaeafafafagafafafafagafafafafafaeafafafafafafafafafafafafafagafafafafafafafafafafafafaeafafafafafaaaaaaaa +aaaaaaaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahafafafafafafafafafafafafafaaaaaaaa +aaaaaaaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaaaaaaaa +aaaaaaaaafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafaaaaaaaa +abaaaaaaafafaiaiaiaiaiafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafaaaaajaa +aaaaaaaaafafaiaiaiaiaiaiakafafafaiaiaiaiaiafafafafafafafafalalamalalalafafafafafafafafafaiaiaiakafafafafaaaaaaaa +aaaaaaaaafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiafafafafafanalalaoalalalalalanafafafafafaiaiaiaiaiaiaiaiaiafaaaaaaaa +aaaaaaapafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaqaqaraqaqaqaqaqasaraqaqaiaiaiaiaiaiaiaiaiaiaiaiaiafaaaaaaaa +aaaaaaaaafaiaiatatatatatatatatatatatatatatatatatatatatatatatauavavauatatatatatatatatatatatatataiaiaiaiafaaawaaaa +aaaaaaaaafaiatataxayazataAaBaCaDaEaEaBaFaGaHaBaIatataJaKaLaMataNaNataOaPaQaRaSaTataUaVataWaXatataiaiaiafaaaaaaaa +aaaaaaaaaiaiatataYayaZataEaEaEaEaEaEaEaEaEaEaEaEatatbaaNaNbbatbcaNatbdbebfaNaNbgataUbhatbibjatataiaiaiafaaaaaaaa +aaaaaaaaaiaiatataYaybkataEblaEaEbmaEaBbnaBaHaBaFatatboaNbpbqataNaNatbrbsbtbtbubtbvbwbxatbibyatataiaiaiafaaaaaaaa +aaaaaaabaiaiatatayayayatatatbzatatatatatatatatatatatatbzatatatavavatatatatatbzatatatatatbAbBatataiaiaiafaaaaaabC +aaaaaaaaaiaiatatatbzatatbDbEbEbEbEbFbEbEbEbEbGbEbFbEbEbEbEbEbEbEbEbEbEbFbEbEbEbEbHbHbIatbibyatataiaiaiafaaaabJaa +aaaaaaaaaiaiatatbcaNaNaNaNaNaNbKbLbLaNbMbNaNaNaNaNaNaNaNaNaNaNbLaNaNaNaNaNaNaNaNbKbLbLbzbibyatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatatbOatatbPbQbQbRbRbRbQbQbQbSaNalbTbUbQbVbQbRbRbRbQbQbQbQbQbUbQbQbQbQbWatbibBatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatbXaybYatatatatatatatatatatatalalatatatatbZatatatatcaatatatatatatatatatatbibyatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatcbcbayatcccdcecfcgchcicjckclalcmcnatcocpaNcqcratcscaaNctcucvbLaNaNaNcwatbibyatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatcxbOcyataNaNaNaNaNaNaNaNaNcacaalczataNaNcAcBcCatcDaNbLbLcEcFcGcHcIaNcJatbibBatataiaiaiagaaaaaaaa +aaaaaaaaafaiatatcbcbcKataNcMaNaNcMaNaNcNaNcOcaalcPatcQbLcRcScTatcUaNbLcVcWcXcYcWcZalaNatbibyatataiaiafafaaaaaaaa +aaaaaaaaafaiatatcxbOayatcQaNaNdaaNcLaNdcbLdccacaddatdedfdgdfdhataNaNbLdicYcYcWcHalcmaNatbidjatataiaiafafaaaaaaaa +aaaaabaaafaiatatcbcbdkataNcMaNaNalalbLbLbLbLaNaNdlataNaNdmcSdnatdoaNaNdpcWcGcGcGcGalbLatbidqatataiakafafaaaadraa +aaaaaaaaafaiatatcxbOayataNaNaNaNaNaNdsdtaNdtaNaNcpatdudvdwaNdxatdyaNdzaNaNdAcIdAbLbLdBatdCdDatataiaiafafaaaabCaa +aaaaaaaaafaiaiatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataiaiafafafaaaaaaaa +aaaaaaaaafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiafafafaaaaaaaa +aaaaaaaaafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiafaiaiaiafafafaiaiaiaiaiaiaiafafafafaaaaaaaa +aaaaaaaaafafaiaiaiaiaiaiaiaiaiaiaiaiakafafafaiaiaiaiaiaiafafafafafafafafafafafafafafafafafafafafafafafafaaaadraa +aaaaaaaaafagafafafafafafaiaiaiaiaiafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaaaaaaaa +aaaaaaadaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaapaaaaaaaaaaaaabaaapaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaadEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaadFaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaadFaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadGaaaaaaaaaaaaabaa +"} +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd diff --git a/maps/~map_system/maps.dm b/maps/~map_system/maps.dm index 556f88edbc..a4a76e1c8d 100644 --- a/maps/~map_system/maps.dm +++ b/maps/~map_system/maps.dm @@ -36,6 +36,7 @@ var/list/all_maps = list() var/list/map_levels // Z-levels available to various consoles, such as the crew monitor (when that gets coded in). Defaults to station_levels if unset. var/list/base_turf_by_z = list() // Custom base turf by Z-level. Defaults to world.turf for unlisted Z-levels + var/list/usable_email_tlds = list("freemail.nt") //This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there. var/list/accessible_z_levels = list() diff --git a/nano/images/modular_computers/alarm_green.gif b/nano/images/modular_computers/alarm_green.gif new file mode 100644 index 0000000000..7c2570c8ce Binary files /dev/null and b/nano/images/modular_computers/alarm_green.gif differ diff --git a/nano/images/modular_computers/alarm_red.gif b/nano/images/modular_computers/alarm_red.gif new file mode 100644 index 0000000000..327d58e4db Binary files /dev/null and b/nano/images/modular_computers/alarm_red.gif differ diff --git a/nano/images/modular_computers/batt_100.gif b/nano/images/modular_computers/batt_100.gif new file mode 100644 index 0000000000..ccdbd4333e Binary files /dev/null and b/nano/images/modular_computers/batt_100.gif differ diff --git a/nano/images/modular_computers/batt_20.gif b/nano/images/modular_computers/batt_20.gif new file mode 100644 index 0000000000..1d5e38fc88 Binary files /dev/null and b/nano/images/modular_computers/batt_20.gif differ diff --git a/nano/images/modular_computers/batt_40.gif b/nano/images/modular_computers/batt_40.gif new file mode 100644 index 0000000000..d5cedb9967 Binary files /dev/null and b/nano/images/modular_computers/batt_40.gif differ diff --git a/nano/images/modular_computers/batt_5.gif b/nano/images/modular_computers/batt_5.gif new file mode 100644 index 0000000000..ceac8f3a94 Binary files /dev/null and b/nano/images/modular_computers/batt_5.gif differ diff --git a/nano/images/modular_computers/batt_60.gif b/nano/images/modular_computers/batt_60.gif new file mode 100644 index 0000000000..d39534c8cb Binary files /dev/null and b/nano/images/modular_computers/batt_60.gif differ diff --git a/nano/images/modular_computers/batt_80.gif b/nano/images/modular_computers/batt_80.gif new file mode 100644 index 0000000000..9c299773f0 Binary files /dev/null and b/nano/images/modular_computers/batt_80.gif differ diff --git a/nano/images/modular_computers/charging.gif b/nano/images/modular_computers/charging.gif new file mode 100644 index 0000000000..cf19ca7287 Binary files /dev/null and b/nano/images/modular_computers/charging.gif differ diff --git a/nano/images/modular_computers/downloader_finished.gif b/nano/images/modular_computers/downloader_finished.gif new file mode 100644 index 0000000000..f01b7c42af Binary files /dev/null and b/nano/images/modular_computers/downloader_finished.gif differ diff --git a/nano/images/modular_computers/downloader_running.gif b/nano/images/modular_computers/downloader_running.gif new file mode 100644 index 0000000000..68fb977c86 Binary files /dev/null and b/nano/images/modular_computers/downloader_running.gif differ diff --git a/nano/images/modular_computers/ntnrc_idle.gif b/nano/images/modular_computers/ntnrc_idle.gif new file mode 100644 index 0000000000..d47c01d580 Binary files /dev/null and b/nano/images/modular_computers/ntnrc_idle.gif differ diff --git a/nano/images/modular_computers/ntnrc_new.gif b/nano/images/modular_computers/ntnrc_new.gif new file mode 100644 index 0000000000..af72a8b332 Binary files /dev/null and b/nano/images/modular_computers/ntnrc_new.gif differ diff --git a/nano/images/modular_computers/power_norm.gif b/nano/images/modular_computers/power_norm.gif new file mode 100644 index 0000000000..2b8d60edfa Binary files /dev/null and b/nano/images/modular_computers/power_norm.gif differ diff --git a/nano/images/modular_computers/power_warn.gif b/nano/images/modular_computers/power_warn.gif new file mode 100644 index 0000000000..0c85b3a85a Binary files /dev/null and b/nano/images/modular_computers/power_warn.gif differ diff --git a/nano/images/modular_computers/sig_high.gif b/nano/images/modular_computers/sig_high.gif new file mode 100644 index 0000000000..efb20f6730 Binary files /dev/null and b/nano/images/modular_computers/sig_high.gif differ diff --git a/nano/images/modular_computers/sig_lan.gif b/nano/images/modular_computers/sig_lan.gif new file mode 100644 index 0000000000..07ba929f7f Binary files /dev/null and b/nano/images/modular_computers/sig_lan.gif differ diff --git a/nano/images/modular_computers/sig_low.gif b/nano/images/modular_computers/sig_low.gif new file mode 100644 index 0000000000..08f98baea8 Binary files /dev/null and b/nano/images/modular_computers/sig_low.gif differ diff --git a/nano/images/modular_computers/sig_none.gif b/nano/images/modular_computers/sig_none.gif new file mode 100644 index 0000000000..79840d8a2b Binary files /dev/null and b/nano/images/modular_computers/sig_none.gif differ diff --git a/nano/images/modular_computers/sig_warning.gif b/nano/images/modular_computers/sig_warning.gif new file mode 100644 index 0000000000..17f6f61981 Binary files /dev/null and b/nano/images/modular_computers/sig_warning.gif differ diff --git a/nano/images/modular_computers/smmon_0.gif b/nano/images/modular_computers/smmon_0.gif new file mode 100644 index 0000000000..7b716c4e1c Binary files /dev/null and b/nano/images/modular_computers/smmon_0.gif differ diff --git a/nano/images/modular_computers/smmon_1.gif b/nano/images/modular_computers/smmon_1.gif new file mode 100644 index 0000000000..bbe319b820 Binary files /dev/null and b/nano/images/modular_computers/smmon_1.gif differ diff --git a/nano/images/modular_computers/smmon_2.gif b/nano/images/modular_computers/smmon_2.gif new file mode 100644 index 0000000000..9c58edd340 Binary files /dev/null and b/nano/images/modular_computers/smmon_2.gif differ diff --git a/nano/images/modular_computers/smmon_3.gif b/nano/images/modular_computers/smmon_3.gif new file mode 100644 index 0000000000..dc7c8734ee Binary files /dev/null and b/nano/images/modular_computers/smmon_3.gif differ diff --git a/nano/images/modular_computers/smmon_4.gif b/nano/images/modular_computers/smmon_4.gif new file mode 100644 index 0000000000..8a75e6e118 Binary files /dev/null and b/nano/images/modular_computers/smmon_4.gif differ diff --git a/nano/images/modular_computers/smmon_5.gif b/nano/images/modular_computers/smmon_5.gif new file mode 100644 index 0000000000..59356beda0 Binary files /dev/null and b/nano/images/modular_computers/smmon_5.gif differ diff --git a/nano/images/modular_computers/smmon_6.gif b/nano/images/modular_computers/smmon_6.gif new file mode 100644 index 0000000000..aea2f87921 Binary files /dev/null and b/nano/images/modular_computers/smmon_6.gif differ diff --git a/nano/images/c_charging.gif b/nano/images/status_icons/c_charging.gif similarity index 100% rename from nano/images/c_charging.gif rename to nano/images/status_icons/c_charging.gif diff --git a/nano/images/c_discharging.gif b/nano/images/status_icons/c_discharging.gif similarity index 100% rename from nano/images/c_discharging.gif rename to nano/images/status_icons/c_discharging.gif diff --git a/nano/images/c_max.gif b/nano/images/status_icons/c_max.gif similarity index 100% rename from nano/images/c_max.gif rename to nano/images/status_icons/c_max.gif diff --git a/nano/templates/access_decrypter.tmpl b/nano/templates/access_decrypter.tmpl new file mode 100644 index 0000000000..f905815576 --- /dev/null +++ b/nano/templates/access_decrypter.tmpl @@ -0,0 +1,24 @@ +{{:helper.syndicateMode()}} +{{if data.message}} + ##INFO: {{:data.message}}

    {{:helper.link('RESET', null, { 'PRG_reset' : 1 })}} +{{else data.running}} + ##Attempting to decrypt network access codes. Please wait. Rate: {{:data.rate}} PHash/s
    + {{for data.dos_strings}} + {{:value}}
    + {{/for}} + {{:helper.link('ABORT', null, { 'PRG_reset' : 1 })}} +{{else}} + ##System ready. Select an access code to decrypt. +
    + {{for data.regions}} +
    +
    {{:value.name}}
    + {{for value.accesses :accessValue:accessKey}} +
    + {{:helper.link(accessValue.desc, '', {'PRG_execute' : accessValue.ref, 'allowed' : accessValue.allowed}, accessValue.blocked ? 'disabled' : null, accessValue.allowed ? 'selected' : null)}} +
    + {{/for}} +
    + {{/for}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/arcade_classic.tmpl b/nano/templates/arcade_classic.tmpl new file mode 100644 index 0000000000..996e8e4715 --- /dev/null +++ b/nano/templates/arcade_classic.tmpl @@ -0,0 +1,44 @@ +{{if data.gameover}} +

    Game Over!

    +

    {{:data.information}}

    + {{:helper.link('New Game', null, { "new_game" : 1 })}}
    +{{else}} + {{if data.information}} +
    {{:data.information}}
    + {{/if}} +

    Player

    +
    +
    + Health: +
    +
    + {{:data.player_health}} +
    +
    + Mana: +
    +
    + {{:data.player_mana}} +
    +
    +

    Enemy: {{:data.enemy_name}}

    +
    +
    + Health: +
    +
    + {{:data.enemy_health}} +
    +
    + Mana: +
    +
    + {{:data.enemy_mana}} +
    +
    +

    Actions

    + {{:helper.link('Attack', null, { "attack" : 1 })}} + {{:helper.link('Heal', null, { "heal" : 1 })}} + {{:helper.link('Regain Mana', null, { "regain_mana" : 1 })}} + {{:helper.link('New Game', null, { "new_game" : 1 })}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/computer_fabricator.tmpl b/nano/templates/computer_fabricator.tmpl new file mode 100644 index 0000000000..f3eceee431 --- /dev/null +++ b/nano/templates/computer_fabricator.tmpl @@ -0,0 +1,70 @@ +{{:helper.link('Clear Order', 'circle', { "clean_order" : 1 })}}

    +Your new computer device you always dreamed of is just four steps away...
    +{{if data.state == 0}} +
    +

    Step 1: Select your device type

    + {{:helper.link('Laptop', 'calc', { "pick_device" : 1 })}} + {{:helper.link('Tablet', 'calc', { "pick_device" : 2 })}} +
    +{{else data.state == 1}} +
    +

    Step 2: Personalise your device

    + + + + + + + + {{/if}} + + + +
    Current Price: + {{:data.totalprice}}T +
    Battery: + {{:helper.link('Standard', null, { "hw_battery" : 1 }, data.hw_battery == 1 ? 'selected' : null)}} + {{:helper.link('Upgraded', null, { "hw_battery" : 2 }, data.hw_battery == 2 ? 'selected' : null)}} + {{:helper.link('Advanced', null, { "hw_battery" : 3 }, data.hw_battery == 3 ? 'selected' : null)}} +
    Hard Drive: + {{:helper.link('Standard', null, { "hw_disk" : 1 }, data.hw_disk == 1 ? 'selected' : null)}} + {{:helper.link('Upgraded', null, { "hw_disk" : 2 }, data.hw_disk == 2 ? 'selected' : null)}} + {{:helper.link('Advanced', null, { "hw_disk" : 3 }, data.hw_disk == 3 ? 'selected' : null)}} +
    Network Card: + {{:helper.link('None', null, { "hw_netcard" : 0 }, data.hw_netcard == 0 ? 'selected' : null)}} + {{:helper.link('Standard', null, { "hw_netcard" : 1 }, data.hw_netcard == 1 ? 'selected' : null)}} + {{:helper.link('Advanced', null, { "hw_netcard" : 2 }, data.hw_netcard == 2 ? 'selected' : null)}} + {{if data.devtype != 2}} +
    Processor Unit: + {{:helper.link('Standard', null, { "hw_cpu" : 1 }, data.hw_cpu == 1 ? 'selected' : null)}} + {{:helper.link('Advanced', null, { "hw_cpu" : 2 }, data.hw_cpu == 2 ? 'selected' : null)}} +
    Tesla Relay: + {{:helper.link('None', null, { "hw_tesla" : 0 }, data.hw_tesla == 0 ? 'selected' : null)}} + {{:helper.link('Standard', null, { "hw_tesla" : 1 }, data.hw_tesla == 1 ? 'selected' : null)}} +
    Nano Printer: + {{:helper.link('None', null, { "hw_nanoprint" : 0 }, data.hw_nanoprint == 0 ? 'selected' : null)}} + {{:helper.link('Standard', null, { "hw_nanoprint" : 1 }, data.hw_nanoprint == 1 ? 'selected' : null)}} +
    Card Reader: + {{:helper.link('None', null, { "hw_card" : 0 }, data.hw_card == 0 ? 'selected' : null)}} + {{:helper.link('Standard', null, { "hw_card" : 1 }, data.hw_card == 1 ? 'selected' : null)}} +
    Confirm Order: + {{:helper.link('CONFIRM', null, { "confirm_order" : 1 })}} +
    +
    + Battery allows your device to operate without external utility power source. Advanced batteries increase battery life.
    + Hard Drive stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.
    + Network Card allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts. Advanced cards also tend to have better bandwidth.
    + Processor Unit is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.
    + Tesla Relay is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source.
    + Nano Printer is device that allows printing of various documents. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.
    + Card Reader adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards.
    +
    +{{else data.state == 2}} +

    Step 3: Payment

    + Your device is now ready for fabrication..
    + Please swipe your identification card to finish purchase.
    + Total price: {{:data.totalprice}}T +{{else data.state == 3}} +

    Step 4: Thank you for your purchase

    + Should you experience any issues with your new device, contact technical support at support@computerservice.nt +{{/if}} \ No newline at end of file diff --git a/nano/templates/digitalwarrant.tmpl b/nano/templates/digitalwarrant.tmpl new file mode 100644 index 0000000000..8693bca239 --- /dev/null +++ b/nano/templates/digitalwarrant.tmpl @@ -0,0 +1,89 @@ +{{if data.warrantauth}} + +
    + {{if data.type == "arrest"}} +
    + Name: +
    + {{/if}} + {{if data.type == "search"}} +
    + Location: +
    + {{/if}} +
    + {{:data.warrantname}} +
    +
    +
    + {{if data.type == "arrest"}} +
    + Charges: +
    + {{/if}} + {{if data.type == "search"}} +
    + Reason: +
    + {{/if}} +
    + {{:data.warrantcharges}} +
    +
    +
    +
    + Authorized by: +
    +
    + {{:data.warrantauth}} +
    +
    +
    +
    + Actions: +
    +
    + + {{if data.type == "arrest"}} +
    {{:helper.link('Edit Name', null, {'editwarrantname' : 1})}}{{:helper.link('Custom Name', null, {'editwarrantnamecustom' : 1})}} +
    {{:helper.link('Edit Charges', null, {'editwarrantcharges' : 1})}} + {{/if}} + {{if data.type == "search"}} +
    {{:helper.link('Edit Location', null, {'editwarrantnamecustom' : 1})}} +
    {{:helper.link('Edit Reason', null, {'editwarrantcharges' : 1})}} + {{/if}} +
    {{:helper.link('Authorize', null, {'editwarrantauth' : 1})}} +
    {{:helper.link('Save', null, {'savewarrant' : 1})}} + {{:helper.link('Delete', null, {'deletewarrant' : 1})}} +
    {{:helper.link('Back to Menu', null, {'back' : 1})}} +
    +
    +
    + +{{else}} + + {{:helper.link('Add a Warrant', null, {'addwarrant' : 1})}}

    +

    Arrest warrants

    + + + + + {{/if}} + {{/for}} +
    NameChargesAuthorized By + {{for data.allwarrants}} + {{if value.arrestsearch == "arrest"}} +
    {{:helper.link(value.warrantname, null, {'editwarrant' : value.id})}}{{:value.charges}}{{:value.auth}}
    +

    Search warrants

    + + + + + {{/if}} + {{/for}} +
    LocationReasonAuthorized By + {{for data.allwarrants}} + {{if value.arrestsearch == "search"}} +
    {{:helper.link(value.warrantname, null, {'editwarrant' : value.id})}}{{:value.charges}}{{:value.auth}}
    + +{{/if}} \ No newline at end of file diff --git a/nano/templates/email_administration.tmpl b/nano/templates/email_administration.tmpl new file mode 100644 index 0000000000..6f1e7ac364 --- /dev/null +++ b/nano/templates/email_administration.tmpl @@ -0,0 +1,91 @@ +{{if data.error}} + {{:data.error}}
    + {{:helper.link('Return', null, {'back' : 1})}} +{{else data.msg_title}} +
    +
    + Title: +
    +
    + {{:data.msg_title}}  +
    +
    + Source: +
    +
    + {{:data.msg_source}}  +
    +
    + Received at: +
    +
    + {{:data.msg_timestamp}}  +
    +
    + Message: +
    +
    + {{:data.msg_body}}  +
    +
    + Options: +
    +
    + {{:helper.link('Return', null, {'back' : 1})}} +
    +
    +{{else data.current_account}} + Viewing account {{:data.current_account}} in administrative mode. +
    +
    + Account status: +
    +
    + {{if data.cur_suspended}} + Suspended + {{else}} + Normal + {{/if}} +
    +
    + Options: +
    +
    + {{:helper.link(data.cur_suspended ? 'Unsuspend' : 'Suspend', null, {'ban' : data.cur_uid})}} + {{:helper.link('Set Password', null, {'changepass' : data.cur_uid})}} + {{:helper.link('Return', null, {'back' : 1})}} +
    +
    + {{if data.messagecount}} + + + + + + + + {{for data.messages}} + + + + + + + {{/for}} +
    SourceTitleReceived atActions
    {{:value.source}} {{:value.title}} {{:value.timestamp}}  + {{:helper.link('View', null, {'viewmail' : value.uid})}} +
    + {{else}} + No messages found in selected account. + {{/if}} +{{else}} +

    Welcome to NTNet Email Administration System

    + SECURE SYSTEM - Have your identification ready

    + {{:helper.link('Create New Account', null, {'newaccount' : 1})}}

    + Select account which you wish to administrate: + + {{for data.accounts}} +
    {{:helper.link(value.login, null, {'viewaccount' : value.uid})}} + {{/for}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/email_client.tmpl b/nano/templates/email_client.tmpl new file mode 100644 index 0000000000..2abaa3ee8f --- /dev/null +++ b/nano/templates/email_client.tmpl @@ -0,0 +1,183 @@ +{{if data.error}} + {{:data.error}}
    + {{:helper.link('Return', null, {'reset' : 1})}} +{{else data.downloading}} +

    Downloading attachment...

    +
    +
    + File name: +
    +
    + {{:data.down_filename}}  +
    +
    + Progress: +
    +
    + {{:helper.displayBar(data.down_progress, 0, data.down_size)}} {{:data.down_progress}} / {{:data.down_size}} GQ +
    +
    + Download rate: +
    +
    + {{:data.down_speed}} GQ/s  +
    +
    + {{:helper.link('Cancel Download', null, {'canceldownload' : 1})}} +{{else data.current_account}} + Welcome to your account, {{:data.current_account}}
    + {{:helper.link('New Message', null, {'new_message' : 1})}} + {{:helper.link('Change Password', null, {'changepassword' : 1})}} + {{:helper.link('Log Out', null, {'logout' : 1})}}

    + {{if data.addressbook}} + + {{for data.accounts}} +
    {{:helper.link(value.login, null, {'set_recipient' : value.login})}} + {{/for}} +
    + {{else data.new_message}} +
    +
    + Title: +
    +
    + {{:data.msg_title}}  +
    +
    + Recipient: +
    +
    + {{:data.msg_recipient}}  +
    +
    + Message: +
    +
    + {{:data.msg_body}}  +
    + {{if data.msg_hasattachment}} +
    + Attachment: +
    +
    + {{:data.msg_attachment_filename}} ({{:data.msg_attachment_size}}GQ) +
    + {{/if}} +
    + Options: +
    +
    + {{:helper.link('Edit Title', null, {'edit_title' : 1})}} + {{:helper.link('Find Recipient', null, {'addressbook' : 1})}} + {{:helper.link('Enter Recipient', null, {'edit_recipient' : 1})}} + {{:helper.link('Edit Message', null, {'edit_body' : 1})}} + {{:helper.link('Add attachment', null, {'addattachment' : 1})}} + {{if data.msg_hasattachment}} + {{:helper.link('Remove attachment', null, {'remove_attachment' : 1})}} + {{/if}} + {{:helper.link('Send', null, {'send' : 1})}} + {{:helper.link('Cancel', null, {'cancel' : 1})}} +
    +
    + {{else data.cur_title}} +
    +
    + Title: +
    +
    + {{:data.cur_title}}  +
    +
    + Origin: +
    +
    + {{:data.cur_source}}  +
    +
    + Received at: +
    +
    + {{:data.cur_timestamp}}  +
    +
    + Message: +
    +
    + {{:data.cur_body}}  +
    + {{if data.cur_hasattachment}} +
    + Attachment: +
    +
    + {{:data.cur_attachment_filename}} ({{:data.cur_attachment_size}}GQ) +
    + {{/if}} +
    + Options: +
    +
    + {{:helper.link('Reply', null, {'reply' : data.cur_uid})}} + {{:helper.link('Delete', null, {'delete' : data.cur_uid})}} + {{:helper.link('Close', null, {'cancel' : data.cur_uid})}} + {{:helper.link('Save to Disk', null, {'cancel' : data.cur_uid})}} + {{if data.cur_hasattachment}} + {{:helper.link('Save Attachment', null, {'downloadattachment' : 1})}} + {{/if}} +
    +
    + {{else}} + {{:helper.link('Inbox', null, {'set_folder' : 'Inbox'}, data.folder == 'Inbox' ? 'selected' : null)}} + {{:helper.link('Spam', null, {'set_folder' : 'Spam'}, data.folder == 'Spam' ? 'selected' : null)}} + {{:helper.link('Deleted', null, {'set_folder' : 'Deleted'}, data.folder == 'Deleted' ? 'selected' : null)}} +

    + {{if data.messagecount}} + + + + + + + + {{for data.messages}} + + + + + + + {{/for}} +
    SourceTitleReceived atActions
    {{:value.source}} {{:value.title}} {{:value.timestamp}}  + {{:helper.link('Delete', null, {'delete' : value.uid})}} + {{:helper.link('Reply', null, {'reply' : value.uid})}} + {{:helper.link('View', null, {'view' : value.uid})}} +
    + {{else}} + No messages found in selected folder + {{/if}} + {{/if}} +{{else}} + Welcome to NTNet Email System. Please log in. +
    +
    + Email address: +
    +
    + {{:data.stored_login}}  +
    +
    + Password: +
    +
    + {{:data.stored_password}}  +
    +
    + Options: +
    +
    + {{:helper.link('Enter Login', null, {'edit_login' : 1})}} + {{:helper.link('Enter Password', null, {'edit_password' : 1})}} + {{:helper.link('Log In', null, {'login' : 1})}} +
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/file_manager.tmpl b/nano/templates/file_manager.tmpl new file mode 100644 index 0000000000..71310397d2 --- /dev/null +++ b/nano/templates/file_manager.tmpl @@ -0,0 +1,58 @@ +{{if data.error}} +

    An error has occured and this program can not continue.

    + Additional information: {{:data.error}}
    + Please try again. If the problem persists contact your system administrator for assistance. + {{:helper.link('Restart program', null, { "PRG_closefile" : 1 })}} +{{else}} + {{if data.filename}} +

    Viewing file {{:data.filename}}

    +
    + {{:helper.link('CLOSE', null, { "PRG_closefile" : 1 })}} + {{:helper.link('EDIT', null, { "PRG_edit" : 1 })}} + {{:helper.link('PRINT', null, { "PRG_printfile" : 1 })}} +

    + {{:data.filedata}} + {{else}} +

    Available files (local):

    + +
    File name + File type + File size (GQ) + Operations + {{for data.files}} +
    {{:value.name}} + .{{:value.type}} + {{:value.size}}GQ + + {{:helper.link('VIEW', null, { "PRG_openfile" : value.name })}} + {{:helper.link('DELETE', null, { "PRG_deletefile" : value.name }, value.undeletable ? 'disabled' : null)}} + {{:helper.link('RENAME', null, { "PRG_rename" : value.name }, value.undeletable ? 'disabled' : null)}} + {{:helper.link('CLONE', null, { "PRG_clone" : value.name }, value.undeletable ? 'disabled' : null)}} + {{if data.usbconnected}} + {{:helper.link('EXPORT', null, { "PRG_copytousb" : value.name }, value.undeletable ? 'disabled' : null)}} + {{/if}} + {{/for}} +
    + {{if data.usbconnected}} +

    Available files (portable device):

    + +
    File name + File type + File size (GQ) + Operations + {{for data.usbfiles}} +
    {{:value.name}} + .{{:value.type}} + {{:value.size}}GQ + + {{:helper.link('DELETE', null, { "PRG_usbdeletefile" : value.name }, value.undeletable ? 'disabled' : null)}} + {{if data.usbconnected}} + {{:helper.link('IMPORT', null, { "PRG_copyfromusb" : value.name }, value.undeletable ? 'disabled' : null)}} + {{/if}} + {{/for}} +
    + {{/if}} + {{:helper.link('NEW DATA FILE', null, { "PRG_newtextfile" : 1 })}} + {{/if}} + +{{/if}} \ No newline at end of file diff --git a/nano/templates/laptop_configuration.tmpl b/nano/templates/laptop_configuration.tmpl new file mode 100644 index 0000000000..69af3bd6c0 --- /dev/null +++ b/nano/templates/laptop_configuration.tmpl @@ -0,0 +1,70 @@ +Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device.
    +

    Power Supply

    +
    + Battery Status: +
    +{{if data.battery_exists}} +
    + Active +
    +
    + Battery Rating: +
    +
    + {{:data.battery_rating}} +
    +
    + Battery Charge: +
    +
    + {{:helper.displayBar(data.battery_percent, 0, 100, (data.battery_percent <= 25) ? 'bad' : (data.battery_percent <= 50) ? 'average' : 'good')}} + {{:data.battery_percent}} % +
    +{{else}} +
    + Not Available +
    +{{/if}} +
    + Power Usage: +
    +
    + {{:data.power_usage}}W +
    +

    File System

    +
    + Used Capacity: +
    +
    + {{:helper.displayBar(data.disk_used, 0, data.disk_size, 'good')}} + {{:data.disk_used}}GQ / {{:data.disk_size}}GQ +
    +

    Computer Components

    +{{for data.hardware}} +

    {{:value.name}}

    + {{:value.desc}}
    +
    + State: +
    +
    + {{:value.enabled ? "Enabled" : "Disabled"}} +
    +
    + Power Usage: +
    +
    + {{:value.powerusage}}W +
    + {{if !value.critical}} +
    + Toggle Component: +
    +
    + {{:helper.link("ON", null, {'PC_enable_component' : value.name}, value.enabled ? 'disabled' : null)}} + {{:helper.link("OFF", null, {'PC_disable_component' : value.name}, value.enabled ? null : 'disabled')}} +
    + {{/if}} +

    +{{/for}} +

    +NTOS v2.0.4b Copyright NanoTrasen 2557 - 2559 \ No newline at end of file diff --git a/nano/templates/laptop_mainscreen.tmpl b/nano/templates/laptop_mainscreen.tmpl new file mode 100644 index 0000000000..9d7804ae72 --- /dev/null +++ b/nano/templates/laptop_mainscreen.tmpl @@ -0,0 +1,8 @@ +No program loaded. Please select program from list below. + +{{for data.programs}} +
    {{:helper.link(value.desc, value.icon, {'PC_runprogram' : value.name})}} + {{:helper.link('X', null, {'PC_killprogram' : value.name}, (value.running ? null : 'disabled'))}} + {{:helper.link('AR', null, {'PC_setautorun' : value.name}, null, (value.autorun ? 'yellowButton' : null))}} +{{/for}} +
    \ No newline at end of file diff --git a/nano/templates/layout_default.tmpl b/nano/templates/layout_default.tmpl index ec3e225bb6..53701e3030 100644 --- a/nano/templates/layout_default.tmpl +++ b/nano/templates/layout_default.tmpl @@ -1,3 +1,40 @@ +{{if data.PC_hasheader}} +
    +
    + + {{if data.PC_batteryicon && data.PC_showbatteryicon}} +
    + {{/if}} + {{if data.PC_batterypercent && data.PC_showbatteryicon}} + {{:data.PC_batterypercent}} + {{/if}} + {{if data.PC_ntneticon}} + + {{/if}} + {{if data.PC_apclinkicon}} + + {{/if}} + {{if data.PC_stationtime}} + {{:data.PC_stationtime}} + {{/if}} + {{for data.PC_programheaders}} + + {{/for}} +
    +
    +
    +
    + +
    {{:helper.link('Shutdown', null, {'PC_shutdown' : 1})}} + {{if data.PC_showexitprogram}} + {{:helper.link('Exit Program', null, {'PC_exit' : 1})}} + {{:helper.link('Minimize Program', null, {'PC_minimize' : 1})}} + {{/if}} +
    +
    +
    +{{/if}} +
    {{:config.title}}
    +{{else}} + {{:helper.link('Refresh', null, {'refresh' : 1})}}
    + {{for data.supermatters}} +
    +
    + Area: +
    +
    + {{:value.area_name}} - (#{{:value.uid}}) +
    +
    + Integrity: +
    +
    + {{:value.integrity}} % +
    +
    + Options: +
    +
    + {{:helper.link('View Details', null, {'set' : value.uid})}} +
    +
    + {{/for}} +{{/if}} diff --git a/nano/templates/word_processor.tmpl b/nano/templates/word_processor.tmpl new file mode 100644 index 0000000000..0a786f4973 --- /dev/null +++ b/nano/templates/word_processor.tmpl @@ -0,0 +1,49 @@ +{{if data.error}} +

    An error has occurred:

    +Additional information: {{:data.error}}
    +Please try again. If the problem persists, contact your system administrator for assistance. +{{:helper.link('Back to menu', null, { "PRG_backtomenu" : 1 })}} +{{else}} +{{if data.browsing}} + {{:helper.link('BACK TO EDITOR', null, { "PRG_closebrowser" : 1 })}} +

    Available documents (local):

    + +
    Name + Size (GQ) + {{for data.files}} +
    {{:value.name}} + {{:value.size}}GQ + {{:helper.link('OPEN', null, { "PRG_openfile" : value.name })}} + {{/for}} +
    + {{if data.usbconnected}} +

    Available documents (portable device):

    + +
    Name + Size (GQ) + {{for data.usbfiles}} +
    {{:value.name}} + {{:value.size}}GQ + {{:helper.link('OPEN', null, { "PRG_openfile" : value.name })}} + {{/for}} +
    + {{/if}} +{{else}} +

    Document: {{:data.filename}}

    +
    + {{:helper.link('NEW', null, { "PRG_newfile" : 1 })}} + {{:helper.link('LOAD', null, { "PRG_loadmenu" : 1 })}} + {{:helper.link('SAVE', null, { "PRG_savefile" : 1 })}} + {{:helper.link('SAVE AS', null, { "PRG_saveasfile" : 1 })}} +
    +
    + {{:helper.link('EDIT', null, { "PRG_editfile" : 1 })}} + {{:helper.link('PREVIEW', null, { "PRG_txtrpeview" : 1 }, data.filedata ? null : 'disabled')}} + {{:helper.link('FORMATTING HELP', null, { "PRG_taghelp" : 1 })}} + {{:helper.link('PRINT', null, { "PRG_printfile" : 1 })}} +

    +
    + {{:data.filedata}} +
    +{{/if}} +{{/if}} diff --git a/news_articles/space_magazine_1.html b/news_articles/space_magazine_1.html new file mode 100644 index 0000000000..dbdd3f43ed --- /dev/null +++ b/news_articles/space_magazine_1.html @@ -0,0 +1,135 @@ + +

    + + +

    Welcome to SPACE Magazine

    +
    +
    +

    + SPACE Magazine is a new force in Journalism in the 26th Century- bringing news and information to the multitudes of Star Systems settled by Sentient Life, + letting everyone know what’s happening across the Stars, millions of miles away. News if first and foremost our forte, but articles over important + individuals and new developments will also be here in the magazine, which we shall ship out every month with a new issue. This, is our very first issue, + and we hope to continue for many years to come. +

    +

    + In this first issue, we will address a few incidents that have come up as of recent days- a attempted, but disastrous attack by Pirates against the colony + of Onaios Prime, thwarted by the latest in weapons technology. A meteor shower that rained disaster on the colonial world of Brinkburn in the lucrative + system of Nyx, causing many citizens to leave the planet. An attack by terrorists on the colony of Asilliss VII, resulting in many deaths, and the Great + Carp Migrations that have been occurring in recent days in the Nyx System. +

    + + +

    +

    Pirates Underestimate Colonial Defenses

    +
    +

    + This week, a pirate group that has stolen a SolGov Battlecruiser has attempted to commit a raid with it upon a colony world Onaios Prime, in the Onaios + system. However, it was quickly eradicated along with its escort by a planetside battery of Mass Drivers produced recently by Dawnlight Celestial Defence. + After this incident Dawnlight has registered an influx of demand from other colonies, as their weapons are relatively affordable, registering slight growth + in stock ratings for the first time in 250 years, when the success of Dawnlight even competed with corporations like Hephaestus. We have found a written + account of one of the writers of local news agency, and with their permission are including it in this article. +

    +

    + “It was almost midnight when I was driving around the AURA 2, a new anti-orbital installation, on my way home from my office, after some overtime. I have + heard of its construction project and have never paid much attention to it, the world of Onaios Prime that I live on has always been only moderately + wealthy, and peaceful... until last night. A loud siren played from the complex's direction, breaking the silence of the night. I stopped my vehicle where + an overhang down to the valley let me look at the platform, from 50 meters above it, and about 300 meters away from it, and I saw it for my first time. +

    +

    + A great bunker in the middle was having its windows shut in blast doors, shying away from the reason this is an anti-orbital installation: The jeeps and + trucks that were scurrying to hide in the bunker were but the tiniest little dot, compared to the massive Mass Drivers, that slowly, but so steadily, with + a bass, gentle hum, began towering to the sky, reaching out to it with a barrel so long you would need two loaded semi-trucks to cover the length. The + barrels aligned, and I could still hear the humming, but it started growing stronger, stronger... before one of the barrels sparked inside a few times, and + I was blinded by a vast flash... Only then, the humming cut off, only then, I heard the lightning, and only then, a spiking, overwhelming pitch of + capacitor discharge plummeted to my eardrums, only to be followed by an encroaching thunder of a blastwave, shunting masses of air against me. +

    +

    + Only after a few seconds, I regained my hearing and sight to feel the echoes of the blast, and to see another Mass Driver was discharging, sparking. I + covered the sight of it in time, to see the entire valley was lit for a split second as well as the sun could do, and I heard the discharge again, and I + heard its calling. Every spike, a declaration of freedom. Every thunderblast, a declaration of sovereignty. The Mass Drivers would flash, marking dawn upon + the invaders to signal the humanity made its stand here, and it shall persevere. The warhead that it would expel was our fist that would smite them from + our sky. I did not know who have we fought against at that time, but at that moment, and ever since, I never looked at the night sky the same way again. I + believe that that sky is our home.” -Written by Liun Asitero, Onaios Daily +

    + Written by Lucas Shiito + + +

    +

    Brinkburn Refugees and Sapient’s Rights

    +
    +

    + One of Nyx's planets, Brinkburn, has had a catastrophe happen in form of a meteor storm three days ago. Nyx has lashed out with a solar corona that, while + having a miniscule effect on traffic and stations, has managed to deflect several asteroids from the belt natively present around Brinkburn. This caused + massive, unsustainable damage to the habitation complexes present on the planet that are occupied by several hundreds of settlers, and given their scarce + material stocks, they had no other choice but to escape, to find another place to survive in. +

    +

    + The situation was further complicated by the very asteroid rings that have started this misfortune; the refugees did not have sufficiently advanced + navigation computers on their pods to steer them safely through the rings. Approximately 20% of population is estimated to have not made it through. The + shuttles that have shipped the settlers on the world in the first place needed to be dismantled and used for scrap to expand the living area, and the more + advanced components were used to wrangle the escape pods together. +

    +

    + Most of the refugees have found their way to Emerald Habitation, a station in Nyx. The station already has issues with over-population and air + purification, and the sudden influx of human settlers has introduced even more problems. Firstly, it has made it much harder to process travelers passing + through, making travel in Nyx either very dangerous through Void Star, or very expensive through NAS Crescent. Secondly, Emerald Habitation has been + housing a large number of Unathi, which have been harassing the refugees, some of them are even a part of the station's security, making appeals to them + only worsen the situation. +

    +

    + We can only hope a new home will be found and built for the poor refugees, and that the Skrell present on station, that are keeping the situation + relatively free of casualties, continue to sustain a safe, if not non-hostile environment on the overpopulated station. +

    + Written by Laura Hunton + + +

    +

    Terror Attack on Asilliss VII

    +
    +

    + Planet Asilliss VI has been a civil uprising hotspot for a few weeks now, and things have recently yet again escalated. A research facility belonging to + NanoTrasen, one of several to be specific, that specializes on an undisclosed project, has been attacked by a group of masked raiders armed with automatic + weapons, using several buggies for transport. Two hours after the incident, Asilliss Liberation Force claimed responsibility. "Companies like NanoTrasen + are advancing us, but into slavery and containment! Their technology only brings control to the corrupt over the honest people of Asilliss! We cannot stand + idle! Join us and befall those who take our lives from our control!", claimed a man hiding in a shade on video that was sent to a local entertainment + station to be broadcasted under threat of attack. +

    +

    + Up until now, the government's militia has been relatively ineffective at quelling this terrorist cell, while their statistics register a number of arrests + and casualties, the group is still registering influx of recruits. However, NanoTrasen seems to have been highly impacted by this attack, judging from + press release of NanoTrasen, Nyx Division: "As a company, we must maintain our safety standard for our employees, as well as secure our installations. The + continued unrest on Asilliss that is resulting in loss of investments is forcing our hand to resort to particularly prejudicial measures and we are + arranging cooperation with the governmental forces." +

    +

    + We have information from a trusted source, who we shall allow to remain unnamed, that NanoTrasen is arranging a loan to Asiliss in form of acquisition of a + small number of vehicles from Terraphistus Military Armor and small arms shipped all the way from Mars Security Industries, as well as hiring services from + a newly instated PMC, SAARE, to protect other NanoTrasen's installations. We have very little information on SAARE due to its novelty, except that it has + accepted several decorated veterans from various security forces and armies, and specializes on top secret operations. Only time will tell if these + measures shall be taken and how shall they affect the unrest on Asilliss IV, but be sure that we shall provide our readers with full coverage! +

    +Written by Johnathan Townsend + + +

    +

    The Great Carp Migration

    +
    +

    + Carp and Pike have plagued space station windows and ship paint jobs for the past hundred years, and while local businesses make money off of eradicating + them by the hundreds, they only seem to increase in number and size. Xenobiologists at Brickburn have come to the conclusion that that these pests most + likely came from Erebus. "Was really hard to figure out at first," says researcher Gregory Hills, "They really like to, you know, bite things. But once we + got a few hundred tagged ones out there the answer became pretty obvious." He went further on to explain that through their research they've created a + basic carp life cycle, starting at the center of the gas giant and ending in the upper atmosphere, "They tend to die there.", he remarks, "Carp don't + really survive in space unless they are really, really big. Hence why we get so many." When asked why the carp come to space in the first place, he shrugs, + "We don't really know. We think maybe they can sense the stations up there somehow and are looking for food." +

    +

    + Sadly this does not help much in protecting the citizens of the stars from the dreadful beasts. In the last month, there have been a reported 37 deaths due + to Carp and Pike related incidents, making the Erebus Beasts a serious threat to people thinking of working on a station. Scientists believe that at some + point this year, stations and ships in the Nyx System will be subjected to the largest migration of Carp and Pike that has ever been seen, and it may cause + serious damage to interests in the system. +

    +Written by Peggy Re’saih \ No newline at end of file diff --git a/vorestation.dme b/vorestation.dme index df0bbee341..97d91bcfbb 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -346,6 +346,7 @@ #include "code\datums\repositories\decls.dm" #include "code\datums\repositories\radiation.dm" #include "code\datums\repositories\repository.dm" +#include "code\datums\repositories\unique.dm" #include "code\datums\supplypacks\atmospherics.dm" #include "code\datums\supplypacks\contraband.dm" #include "code\datums\supplypacks\contraband_vr.dm" @@ -794,6 +795,7 @@ #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\computer\supply.dm" #include "code\game\machinery\computer\syndicate_specops_shuttle.dm" +<<<<<<< HEAD:vorestation.dme #include "code\game\machinery\computer\timeclock_vr.dm" #include "code\game\machinery\computer\~computer_vr.dm" #include "code\game\machinery\computer3\bios.dm" @@ -826,6 +828,8 @@ #include "code\game\machinery\computer3\computers\robot.dm" #include "code\game\machinery\computer3\computers\security.dm" #include "code\game\machinery\computer3\computers\welcome.dm" +======= +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd:polaris.dme #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_control.dm" #include "code\game\machinery\doors\airlock_electronics.dm" @@ -2450,7 +2454,70 @@ #include "code\modules\mob\new_player\preferences_setup_vr.dm" #include "code\modules\mob\new_player\skill.dm" #include "code\modules\mob\new_player\sprite_accessories.dm" +<<<<<<< HEAD:vorestation.dme #include "code\modules\mob\new_player\sprite_accessories_vr.dm" +======= +#include "code\modules\modular_computers\laptop_vendor.dm" +#include "code\modules\modular_computers\computers\modular_computer\core.dm" +#include "code\modules\modular_computers\computers\modular_computer\damage.dm" +#include "code\modules\modular_computers\computers\modular_computer\hardware.dm" +#include "code\modules\modular_computers\computers\modular_computer\interaction.dm" +#include "code\modules\modular_computers\computers\modular_computer\power.dm" +#include "code\modules\modular_computers\computers\modular_computer\ui.dm" +#include "code\modules\modular_computers\computers\modular_computer\variables.dm" +#include "code\modules\modular_computers\computers\subtypes\dev_console.dm" +#include "code\modules\modular_computers\computers\subtypes\dev_laptop.dm" +#include "code\modules\modular_computers\computers\subtypes\dev_tablet.dm" +#include "code\modules\modular_computers\computers\subtypes\dev_telescreen.dm" +#include "code\modules\modular_computers\computers\subtypes\preset_console.dm" +#include "code\modules\modular_computers\computers\subtypes\preset_laptop.dm" +#include "code\modules\modular_computers\computers\subtypes\preset_tablet.dm" +#include "code\modules\modular_computers\computers\subtypes\preset_telescreen.dm" +#include "code\modules\modular_computers\file_system\computer_file.dm" +#include "code\modules\modular_computers\file_system\data.dm" +#include "code\modules\modular_computers\file_system\news_article.dm" +#include "code\modules\modular_computers\file_system\program.dm" +#include "code\modules\modular_computers\file_system\program_events.dm" +#include "code\modules\modular_computers\file_system\programs\antagonist\access_decrypter.dm" +#include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm" +#include "code\modules\modular_computers\file_system\programs\antagonist\hacked_camera.dm" +#include "code\modules\modular_computers\file_system\programs\antagonist\revelation.dm" +#include "code\modules\modular_computers\file_system\programs\command\card.dm" +#include "code\modules\modular_computers\file_system\programs\command\comm.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\alarm_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\atmos_control.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\power_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\rcon_console.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\supermatter_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\generic\camera.dm" +#include "code\modules\modular_computers\file_system\programs\generic\configurator.dm" +#include "code\modules\modular_computers\file_system\programs\generic\email_client.dm" +#include "code\modules\modular_computers\file_system\programs\generic\file_browser.dm" +#include "code\modules\modular_computers\file_system\programs\generic\game.dm" +#include "code\modules\modular_computers\file_system\programs\generic\news_browser.dm" +#include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm" +#include "code\modules\modular_computers\file_system\programs\generic\ntnrc_client.dm" +#include "code\modules\modular_computers\file_system\programs\generic\nttransfer.dm" +#include "code\modules\modular_computers\file_system\programs\generic\wordprocessor.dm" +#include "code\modules\modular_computers\file_system\programs\medical\suit_sensors.dm" +#include "code\modules\modular_computers\file_system\programs\research\email_administration.dm" +#include "code\modules\modular_computers\file_system\programs\research\ntmonitor.dm" +#include "code\modules\modular_computers\file_system\programs\security\digitalwarrant.dm" +#include "code\modules\modular_computers\hardware\_hardware.dm" +#include "code\modules\modular_computers\hardware\battery_module.dm" +#include "code\modules\modular_computers\hardware\card_slot.dm" +#include "code\modules\modular_computers\hardware\hard_drive.dm" +#include "code\modules\modular_computers\hardware\nano_printer.dm" +#include "code\modules\modular_computers\hardware\network_card.dm" +#include "code\modules\modular_computers\hardware\portable_hard_drive.dm" +#include "code\modules\modular_computers\hardware\processor_unit.dm" +#include "code\modules\modular_computers\hardware\tesla_link.dm" +#include "code\modules\modular_computers\NTNet\NTNet.dm" +#include "code\modules\modular_computers\NTNet\NTNet_relay.dm" +#include "code\modules\modular_computers\NTNet\emails\email_account.dm" +#include "code\modules\modular_computers\NTNet\emails\email_message.dm" +#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm" +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd:polaris.dme #include "code\modules\multiz\_stubs.dm" #include "code\modules\multiz\basic.dm" #include "code\modules\multiz\hoist.dm" @@ -2481,12 +2548,10 @@ #include "code\modules\nano\interaction\remote.dm" #include "code\modules\nano\interaction\self.dm" #include "code\modules\nano\interaction\zlevel.dm" -#include "code\modules\nano\modules\alarm_monitor.dm" -#include "code\modules\nano\modules\atmos_control.dm" -#include "code\modules\nano\modules\crew_monitor.dm" #include "code\modules\nano\modules\human_appearance.dm" #include "code\modules\nano\modules\law_manager.dm" #include "code\modules\nano\modules\nano_module.dm" +<<<<<<< HEAD:vorestation.dme #include "code\modules\nano\modules\power_monitor.dm" #include "code\modules\nano\modules\rcon.dm" #include "code\modules\nifsoft\nif.dm" @@ -2500,6 +2565,8 @@ #include "code\modules\nifsoft\software\13_soulcatcher.dm" #include "code\modules\nifsoft\software\14_commlink.dm" #include "code\modules\nifsoft\software\15_misc.dm" +======= +>>>>>>> 2baef09... Merge pull request #6031 from Novacat/spriteadd:polaris.dme #include "code\modules\organs\blood.dm" #include "code\modules\organs\misc.dm" #include "code\modules\organs\organ.dm"