diff --git a/.github/AUTODOC_GUIDE.md b/.github/AUTODOC_GUIDE.md new file mode 100644 index 00000000000..6a7d521a04d --- /dev/null +++ b/.github/AUTODOC_GUIDE.md @@ -0,0 +1,108 @@ +# dmdoc +[DOCUMENTATION]: https://codedocs.paradisestation.org/ + +[BYOND]: https://secure.byond.com/ + +[DMDOC]: https://github.com/AffectedArc07/ParaSpacemanDMM/tree/master/src/dmdoc + +[DMDOC] is a documentation generator for DreamMaker, the scripting language +of the [BYOND] game engine. It produces simple static HTML files based on +documented files, macros, types, procs, and vars. + +We use **dmdoc** to generate [DOCUMENTATION] for our code, and that documentation +is automatically generated and built on every new commit to the master branch + +This gives new developers a clickable reference [DOCUMENTATION] they can browse to better help +gain understanding of the Paradise codebase structure and api reference. + +## Documenting code on Paradise +We use block comments to document procs and classes, and we use `///` line comments +when documenting individual variables. + +Documentation is not required at Paradise, but it is highly recommended that all new code be covered with DMdoc code, according to the [Specifications](#Specification) + +We also recommend that when you touch older code, you document the functions that you +have touched in the process of updating that code + +### Specification +A class *should* always be autodocumented, and all public functions *should* be documented + +All class level defined variables *should* be documented + +Internal functions *can* be documented, but may not be + +A public function is any function that a developer might reasonably call while using +or interacting with your object. Internal functions are helper functions that your +public functions rely on to implement logic + + +### Documenting a proc +When documenting a proc, we give a short one line description (as this is shown +next to the proc definition in the list of all procs for a type or global +namespace), then a longer paragraph which will be shown when the user clicks on +the proc to jump to it's definition +``` +/** + * Short description of the proc + * + * Longer detailed paragraph about the proc + * including any relevant detail + * Arguments: + * * arg1 - Relevance of this argument + * * arg2 - Relevance of this argument + */ +``` + +### Documenting a class +We first give the name of the class as a header, this can be omitted if the name is +just going to be the typepath of the class, as dmdoc uses that by default + +Then we give a short oneline description of the class + +Finally we give a longer multi paragraph description of the class and it's details +``` +/** + * # Classname (Can be omitted if it's just going to be the typepath) + * + * The short overview + * + * A longer + * paragraph of functionality about the class + * including any assumptions/special cases + * + */ +``` + +### Documenting a variable/define +Give a short explanation of what the variable, in the context of the class, or define is. +``` +/// Type path of item to go in suit slot +var/suit = null +``` + +## Module level description of code +Modules are the best way to describe the structure/intent of a package of code +where you don't want to be tied to the formal layout of the class structure. + +On Paradise we do this by adding markdown files inside the `code` directory +that will also be rendered and added to the modules tree. The structure for +these is deliberately not defined, so you can be as freeform and as wheeling as +you would like. + +[Here is a representative example of what you might write](https://codedocs.paradisestation.org/code/modules/keybindings/readme.html) + +## Special variables +You can use certain special template variables in DM DOC comments and they will be expanded +``` + [DEFINE_NAME] - Expands to a link to the define definition if documented + [/mob] - Expands to a link to the docs for the /mob class + [/mob/proc/Dizzy] - Expands to a link that will take you to the /mob class and anchor you to the dizzy proc docs + [/mob/var/stat] - Expands to a link that will take you to the /mob class and anchor you to the stat var docs +``` + +You can customise the link name by using `[link name][link shorthand].` + +eg. `[see more about dizzy here] [/mob/proc/Dizzy]` + +This is very useful to quickly link to other parts of the autodoc code to expand +upon a comment made, or reasoning about code diff --git a/.github/workflows/generate_autodoc.yml b/.github/workflows/generate_autodoc.yml new file mode 100644 index 00000000000..44eb69eb570 --- /dev/null +++ b/.github/workflows/generate_autodoc.yml @@ -0,0 +1,32 @@ +name: Generate Documentation + +on: + schedule: + - cron: "0 0 * * *" # Every day at the very start of the day + +jobs: + generate_docs: + name: 'Generate Documentation' + runs-on: ubuntu-18.04 + steps: + - name: 'Update Branch' + uses: actions/checkout@v2 + with: + fetch-depth: 1 + ref: master + + - name: 'Generate Documentation' + run: | + ./tools/github-actions/doc-generator + touch dmdoc/.nojekyll + # Nojekyll is important to disable jeykll syntax, which can mess with files that start with underscores + + - name: 'Deploy Documentation' + uses: crazy-max/ghaction-github-pages@v2 + with: + keep_history: false + build_dir: dmdoc + jekyll: false + fqdn: codedocs.paradisestation.org + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/SpacemanDMM.toml b/SpacemanDMM.toml new file mode 100644 index 00000000000..9b658dce0fa --- /dev/null +++ b/SpacemanDMM.toml @@ -0,0 +1,6 @@ +[langserver] +dreamchecker = true + +[code_standards] +disallow_relative_type_definitions = true +disallow_relative_proc_definitions = true diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index b715346969b..f469b859f2b 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -40663,40 +40663,16 @@ /turf/simulated/wall/r_wall, /area/engine/break_room) "byz" = ( -/obj/structure/cable{ - icon_state = "0-4"; - d2 = 4 - }, -/obj/machinery/modular_computer/console/preset/engineering, /obj/machinery/status_display{ pixel_x = -32 }, +/obj/machinery/computer/security/engineering, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "caution" }, /area/atmos) -"byA" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - tag = "" - }, -/obj/structure/chair/office/dark{ - dir = 8 - }, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "neutralfull" - }, -/area/atmos) "byB" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, /obj/structure/cable{ d1 = 1; d2 = 4; @@ -41937,12 +41913,7 @@ icon_state = "1-2"; tag = "" }, -/obj/machinery/modular_computer/console/preset/command, -/obj/structure/cable{ - icon_state = "0-2"; - pixel_y = 1; - d2 = 2 - }, +/obj/machinery/computer/shuttle/mining, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "darkpurple" @@ -51367,18 +51338,6 @@ icon_state = "dark" }, /area/engine/break_room) -"bQf" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/turf/simulated/floor/plasteel{ - icon_state = "neutral"; - dir = 4 - }, -/area/crew_quarters/chief) "bQg" = ( /obj/structure/cable{ d1 = 1; @@ -51405,11 +51364,6 @@ }, /obj/structure/table/reinforced, /obj/item/clipboard, -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, /obj/item/toy/figure/ce, /turf/simulated/floor/plasteel{ dir = 8; @@ -54089,12 +54043,6 @@ /area/crew_quarters/chief) "bUq" = ( /obj/machinery/hologram/holopad, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, /obj/effect/decal/warning_stripes/yellow/hollow, /turf/simulated/floor/plasteel{ dir = 8; @@ -55398,11 +55346,6 @@ }, /area/crew_quarters/chief) "bWl" = ( -/obj/machinery/modular_computer/console/preset/engineering, -/obj/structure/cable{ - icon_state = "0-4"; - d2 = 4 - }, /obj/machinery/keycard_auth{ pixel_x = -24 }, @@ -55420,6 +55363,7 @@ pixel_y = -8; req_access_txt = "11" }, +/obj/machinery/computer/security/engineering, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -60477,6 +60421,9 @@ icon_state = "4-8"; tag = "" }, +/obj/machinery/computer/monitor{ + name = "Grid Power Monitoring Computer" + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark"; @@ -61203,10 +61150,6 @@ /obj/machinery/tcomms/core/station, /turf/simulated/floor/bluegrid, /area/tcommsat/chamber) -"cgA" = ( -/obj/machinery/ntnet_relay, -/turf/simulated/floor/bluegrid, -/area/tcommsat/chamber) "cgB" = ( /obj/machinery/camera{ c_tag = "Singularity NorthEast"; @@ -62511,7 +62454,6 @@ dir = 1; network = list("Engineering","SS13") }, -/obj/machinery/modular_computer/console/preset/engineering, /obj/machinery/firealarm{ dir = 8; pixel_x = -26; @@ -62521,6 +62463,9 @@ icon_state = "0-4"; d2 = 4 }, +/obj/machinery/computer/monitor{ + name = "Grid Power Monitoring Computer" + }, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "dark"; @@ -88629,7 +88574,7 @@ /area/maintenance/starboard) "dey" = ( /obj/structure/table/wood, -/obj/item/modular_computer/tablet/preset/cheap, +/obj/effect/spawner/lootdrop/maintenance, /turf/simulated/floor/plasteel{ icon_state = "wood" }, @@ -97237,7 +97182,6 @@ }, /area/crew_quarters/hor) "dtZ" = ( -/obj/structure/cable, /obj/structure/cable{ d1 = 1; d2 = 4; @@ -97247,7 +97191,6 @@ pixel_x = 0; pixel_y = -30 }, -/obj/machinery/modular_computer/console/preset/research, /turf/simulated/floor/plasteel{ dir = 2; icon_state = "whitepurplecorner" @@ -114776,6 +114719,9 @@ "qrT" = ( /turf/simulated/wall/r_wall, /area/tcommsat/chamber) +"rSI" = ( +/turf/simulated/floor/bluegrid, +/area/tcommsat/chamber) "udT" = ( /obj/structure/chair/comfy/shuttle{ dir = 8 @@ -123162,9 +123108,9 @@ bVO bPI bNM qrT -eaH +rSI ceL -cgu +eaH qrT qrT bkt @@ -123934,7 +123880,7 @@ bXJ bZh caX ccW -ccW +cgu ccW chW qrT @@ -124704,9 +124650,9 @@ bVT bXL bNM qrT -hng +rSI vzz -cgA +hng qrT qrT bkt @@ -138061,7 +138007,7 @@ bIr bKe bMh bOa -bQf +bOa bOa bUh bWk @@ -142420,7 +142366,7 @@ btt buD bvO ban -byA +bzY bzY bBK aOg diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 91339293420..28f2f2f5ebf 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -38185,7 +38185,7 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/modular_computer/console/preset/command, +/obj/machinery/computer/card, /turf/simulated/floor/plasteel{ icon_state = "dark" }, @@ -96408,10 +96408,7 @@ d2 = 2; icon_state = "1-2" }, -/turf/simulated/floor/plasteel/dark, -/area/tcommsat/server) -"gIG" = ( -/obj/machinery/ntnet_relay, +/obj/machinery/tcomms/core/station, /turf/simulated/floor/bluegrid, /area/tcommsat/server) "gRw" = ( @@ -96643,10 +96640,6 @@ }, /turf/space, /area/solar/starboard) -"rUQ" = ( -/obj/machinery/tcomms/core/station, -/turf/simulated/floor/bluegrid, -/area/tcommsat/server) "sjF" = ( /obj/structure/window/reinforced{ dir = 1 @@ -151146,7 +151139,7 @@ bDf bFi bIz bKl -gIG +bOa bOb odO bKl @@ -152174,7 +152167,7 @@ bDj bFm bRo bKl -rUQ +bOa dRN kwJ bKl diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm index 3d8d22218f6..671822abfeb 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm @@ -167,7 +167,7 @@ /turf/simulated/floor/wood, /area/ruin/powered/snow_cabin) "aL" = ( -/obj/structure/displaycase/captain, +/obj/mecha/working/ripley/mining, /turf/simulated/floor/wood, /area/ruin/powered/snow_cabin) "aM" = ( @@ -392,12 +392,6 @@ /obj/structure/filingcabinet, /turf/simulated/floor/pod/dark, /area/ruin/powered/snow_biodome) -"UM" = ( -/obj/machinery/computer/monitor/secret{ - dir = 1 - }, -/turf/simulated/floor/pod/dark, -/area/ruin/powered/snow_biodome) "Wg" = ( /turf/simulated/wall/r_wall, /area/ruin/powered/snow_biodome) @@ -484,7 +478,7 @@ HP tl PK gz -UM +HP Wg ak ak diff --git a/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm b/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm index 1dc60364d99..ceb8067f7ac 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm @@ -68,7 +68,6 @@ "an" = ( /obj/machinery/navbeacon/invisible{ codes_txt = "patrol;next_patrol=SDNW"; - invisibility = 100; location = "SDNE" }, /turf/simulated/floor/plating/asteroid/airless, @@ -292,15 +291,13 @@ "aU" = ( /obj/machinery/navbeacon/invisible{ codes_txt = "patrol;next_patrol=SDSW"; - invisibility = 100; location = "SDNW" }, /turf/simulated/floor/plating/asteroid/airless, /area/syndicate_depot/outer) "aV" = ( /obj/machinery/light{ - dir = 4; - icon_state = "tube1" + dir = 4 }, /turf/simulated/floor/plating/asteroid/airless, /area/syndicate_depot/outer) @@ -429,8 +426,7 @@ /area/syndicate_depot/core) "bo" = ( /obj/machinery/light{ - dir = 4; - icon_state = "tube1" + dir = 4 }, /obj/effect/spawner/random_spawners/syndicate/loot, /turf/simulated/floor/plasteel{ @@ -512,7 +508,6 @@ id = "syndi_depot_rear"; idle_power_usage = 0; name = "mysterious button"; - normaldoorcontrol = 0; pixel_x = 24; use_power = 0 }, @@ -663,8 +658,8 @@ /obj/machinery/turretid/syndicate{ name = "external turret controls"; pixel_x = -32; - pixel_y = 0; - req_access = list(150) + req_access = null; + req_access_txt = "150" }, /turf/simulated/floor/plasteel{ icon_state = "dark" @@ -745,9 +740,8 @@ /area/syndicate_depot/core) "ce" = ( /obj/machinery/light/small{ - tag = "icon-bulb1 (EAST)"; - icon_state = "bulb1"; - dir = 4 + dir = 4; + tag = "icon-bulb1 (EAST)" }, /turf/simulated/floor/mineral/silver, /area/syndicate_depot/core) @@ -757,7 +751,6 @@ id = "syndi_depot_rear"; idle_power_usage = 0; name = "mysterious button"; - normaldoorcontrol = 0; use_power = 0 }, /obj/structure/sign/poster/contraband/syndicate_recruitment, @@ -774,8 +767,8 @@ /area/syndicate_depot/core) "ci" = ( /obj/structure/cable{ - icon_state = "0-2"; - d2 = 2 + d2 = 2; + icon_state = "0-2" }, /obj/machinery/power/smes/upgraded{ charge = 5e+006; @@ -845,7 +838,6 @@ "cr" = ( /obj/structure/sink{ dir = 4; - icon_state = "sink"; pixel_x = 12 }, /turf/simulated/floor/mineral/silver, @@ -1154,7 +1146,6 @@ "dc" = ( /obj/machinery/navbeacon/invisible{ codes_txt = "patrol;next_patrol=SDSE"; - invisibility = 100; location = "SDSW" }, /turf/simulated/floor/plating/asteroid/airless, @@ -1179,7 +1170,6 @@ "df" = ( /obj/machinery/navbeacon/invisible{ codes_txt = "patrol;next_patrol=SDNE"; - invisibility = 100; location = "SDSE" }, /turf/simulated/floor/plating/asteroid/airless, diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index f8dc3f902c9..4b21edd5a54 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -26723,10 +26723,6 @@ dir = 4 }, /area/security/nuke_storage) -"aXS" = ( -/obj/machinery/vending/modularpc, -/turf/simulated/floor/plasteel, -/area/storage/primary) "aXU" = ( /obj/item/flag/mime, /obj/machinery/power/apc{ @@ -26847,23 +26843,13 @@ }, /area/crew_quarters/bar) "aYf" = ( -/obj/machinery/modular_computer/console/preset/command, -/obj/structure/cable{ - icon_state = "0-2"; - pixel_y = 1; - d2 = 2 - }, +/obj/machinery/computer/card, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "green" }, /area/bridge) "aYg" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "greencorner" @@ -38277,11 +38263,6 @@ /turf/simulated/floor/plasteel, /area/bridge) "bup" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/plasteel, /area/bridge) @@ -38894,11 +38875,6 @@ icon_state = "4-8"; tag = "" }, -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plasteel, /area/bridge) @@ -95344,6 +95320,11 @@ icon_state = "vault" }, /area/shuttle/escape) +"kIR" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/hidden/yellow, +/turf/space, +/area/space/nearstation) "kLF" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 @@ -95977,11 +95958,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/wall, /area/crew_quarters/dorms) -"rOX" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow, -/obj/machinery/ntnet_relay, -/turf/simulated/floor/plasteel/dark, -/area/tcommsat/chamber) "rSv" = ( /obj/structure/shuttle/engine/propulsion{ dir = 8; @@ -96028,10 +96004,6 @@ icon_state = "floor4" }, /area/shuttle/administration) -"sag" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/plasteel/dark, -/area/tcommsat/chamber) "sbp" = ( /turf/simulated/shuttle/wall{ icon_state = "wall3" @@ -115856,7 +115828,7 @@ aKb aNx aVi aWt -aXS +aXQ aZr bbp bdk @@ -131629,7 +131601,7 @@ dmW aaa aab aaa -iUc +aaa iUc iUc iUc @@ -131886,10 +131858,10 @@ ddC doE ddM ddO +kIR oOZ dQC fAw -rOX mkE dpe dpl @@ -132144,8 +132116,8 @@ dmB bfu dnT dpf +iUc rTy -sag wbr hyv dpd diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 4c916fe365c..66f2f61abee 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -4296,55 +4296,20 @@ dir = 2 }, /area/centcom/control) -"mE" = ( -/obj/structure/flora/ausbushes/lavendergrass, -/turf/unsimulated/floor{ - icon_state = "grass1"; - name = "grass" - }, -/area/centcom/specops) -"mF" = ( -/obj/structure/flora/ausbushes/stalkybush, -/turf/unsimulated/floor{ - icon_state = "grass1"; - name = "grass" - }, -/area/centcom/specops) -"mG" = ( -/obj/structure/flora/ausbushes/pointybush, -/turf/unsimulated/floor{ - icon_state = "grass1"; - name = "grass" - }, -/area/centcom/specops) -"mH" = ( -/obj/structure/flora/ausbushes/ywflowers, -/turf/unsimulated/floor{ - icon_state = "grass1"; - name = "grass" - }, -/area/centcom/specops) "mI" = ( /obj/structure/flora/ausbushes/brflowers, /turf/unsimulated/floor{ icon_state = "grass1"; name = "grass" }, -/area/centcom/specops) -"mJ" = ( -/obj/structure/flora/ausbushes/sparsegrass, -/turf/unsimulated/floor{ - icon_state = "grass1"; - name = "grass" - }, -/area/centcom/specops) +/area/centcom/control) "mK" = ( /obj/structure/flora/ausbushes/reedbush, /turf/unsimulated/floor{ icon_state = "grass1"; name = "grass" }, -/area/centcom/specops) +/area/centcom/control) "mL" = ( /turf/unsimulated/floor{ dir = 1; @@ -36255,7 +36220,7 @@ lH lH mu su -mF +mZ mY su nD @@ -36512,7 +36477,7 @@ mc lH lH su -mE +nd mX su nD @@ -36769,7 +36734,7 @@ mc lH lH su -mH +mY na su nD @@ -37026,7 +36991,7 @@ lH lH lH su -mG +WW mZ su nD @@ -37283,7 +37248,7 @@ lH mk mw su -mJ +na ne su nD diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 8dd95119aff..6f65661e2d4 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -173,6 +173,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new()) add_fingerprint(user) var/unsafe_wrenching = FALSE + var/safefromgusts = FALSE var/I = int_air ? int_air.return_pressure() : 0 var/E = env_air ? env_air.return_pressure() : 0 var/internal_pressure = I - E @@ -190,9 +191,16 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new()) "You hear ratchet.") investigate_log("was REMOVED by [key_name(usr)]", "atmos") + for(var/obj/item/clothing/shoes/magboots/usermagboots in user.get_equipped_items()) + if(usermagboots.gustprotection && usermagboots.magpulse) + safefromgusts = TRUE + //You unwrenched a pipe full of pressure? let's splat you into the wall silly. if(unsafe_wrenching) - unsafe_pressure_release(user,internal_pressure) + if(safefromgusts) + to_chat(user, "Your magboots cling to the floor as a great burst of wind bellows against you.") + else + unsafe_pressure_release(user,internal_pressure) deconstruct(TRUE) else return ..() diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 7e7a6e9eb49..ae099bf6d36 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -137,51 +137,56 @@ return add_fingerprint(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/binary/passive_gate/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state) + ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state) ui.open() -/obj/machinery/atmospherics/binary/passive_gate/ui_data(mob/user) - var/list/data = list() - data["on"] = on - data["pressure"] = round(target_pressure) - data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) +/obj/machinery/atmospherics/binary/passive_gate/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "rate" = round(target_pressure), + "max_rate" = MAX_OUTPUT_PRESSURE, + "gas_unit" = "kPa", + "step" = 10 // This is for the TGUI step. It's here since multiple pumps share the same UI, but need different values. + ) return data -/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list) +/obj/machinery/atmospherics/binary/passive_gate/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) + switch(action) + if("power") + toggle() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") + return TRUE + + if("max_rate") + target_pressure = MAX_OUTPUT_PRESSURE + . = TRUE + + if("min_rate") + target_pressure = 0 + . = TRUE + + if("custom_rate") + target_pressure = clamp(text2num(params["rate"]), 0 , MAX_OUTPUT_PRESSURE) + . = TRUE + if(.) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") + +/obj/machinery/atmospherics/binary/passive_gate/proc/toggle() + if(powered()) on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["pressure"]) - var/pressure = href_list["pressure"] - if(pressure == "max") - pressure = MAX_OUTPUT_PRESSURE - . = TRUE - else if(pressure == "input") - pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null - if(!isnull(pressure)) - . = TRUE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - . = TRUE - if(.) - target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") - - update_icon() - SSnanoui.update_uis(src) + update_icon() /obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params) if(!istype(W, /obj/item/wrench)) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 550fd140d1d..5178507bbc4 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -192,51 +192,51 @@ Thus, the two variables affect pump operation are set in New(): return add_fingerprint(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/atmospherics/binary/pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state) + ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state) ui.open() -/obj/machinery/atmospherics/binary/pump/ui_data(mob/user) - var/list/data = list() - data["on"] = on - data["pressure"] = round(target_pressure) - data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) +/obj/machinery/atmospherics/binary/pump/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "rate" = round(target_pressure), + "max_rate" = MAX_OUTPUT_PRESSURE, + "gas_unit" = "kPa", + "step" = 10 // This is for the TGUI step. It's here since multiple pumps share the same UI, but need different values. + ) return data -/obj/machinery/atmospherics/binary/pump/Topic(href,href_list) +/obj/machinery/atmospherics/binary/pump/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["pressure"]) - var/pressure = href_list["pressure"] - if(pressure == "max") - pressure = MAX_OUTPUT_PRESSURE - . = TRUE - else if(pressure == "input") - pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null - if(!isnull(pressure)) - . = TRUE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - . = TRUE - if(.) - target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") + switch(action) + if("power") + toggle() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") + return TRUE - update_icon() - SSnanoui.update_uis(src) + if("max_rate") + target_pressure = MAX_OUTPUT_PRESSURE + . = TRUE + + if("min_rate") + target_pressure = 0 + . = TRUE + + if("custom_rate") + target_pressure = clamp(text2num(params["rate"]), 0 , MAX_OUTPUT_PRESSURE) + . = TRUE + if(.) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") /obj/machinery/atmospherics/binary/pump/power_change() var/old_stat = stat diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 804d25cfa1b..12079341143 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -188,51 +188,51 @@ Thus, the two variables affect pump operation are set in New(): return add_fingerprint(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/binary/volume_pump/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/atmospherics/binary/volume_pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 310, 115, state = state) + ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state) ui.open() -/obj/machinery/atmospherics/binary/volume_pump/ui_data(mob/user) - var/list/data = list() - data["on"] = on - data["rate"] = round(transfer_rate) - data["max_rate"] = round(MAX_TRANSFER_RATE) +/obj/machinery/atmospherics/binary/volume_pump/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "rate" = round(transfer_rate), + "max_rate" = round(MAX_TRANSFER_RATE), + "gas_unit" = "L/s", + "step" = 1 // This is for the TGUI step. It's here since multiple pumps share the same UI, but need different values. + ) return data -/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list) +/obj/machinery/atmospherics/binary/volume_pump/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["rate"]) - var/rate = href_list["rate"] - if(rate == "max") - rate = MAX_TRANSFER_RATE - . = TRUE - else if(rate == "input") - rate = input("New transfer rate (0-[MAX_TRANSFER_RATE] L/s):", name, transfer_rate) as num|null - if(!isnull(rate)) - . = TRUE - else if(text2num(rate) != null) - rate = text2num(rate) - . = TRUE - if(.) - transfer_rate = clamp(rate, 0, MAX_TRANSFER_RATE) - investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos") + switch(action) + if("power") + toggle() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") + return TRUE - update_icon() - SSnanoui.update_uis(src) + if("max_rate") + transfer_rate = MAX_TRANSFER_RATE + . = TRUE + + if("min_rate") + transfer_rate = 0 + . = TRUE + + if("custom_rate") + transfer_rate = clamp(text2num(params["rate"]), 0 , MAX_TRANSFER_RATE) + . = TRUE + if(.) + investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos") /obj/machinery/atmospherics/binary/volume_pump/power_change() var/old_stat = stat diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm deleted file mode 100644 index d03329e24fc..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm +++ /dev/null @@ -1,94 +0,0 @@ -//-------------------------------------------- -// Omni device port types -//-------------------------------------------- -#define ATM_NONE 0 -#define ATM_INPUT 1 -#define ATM_OUTPUT 2 - -#define ATM_O2 3 -#define ATM_N2 4 -#define ATM_CO2 5 -#define ATM_P 6 //Plasma -#define ATM_N2O 7 - -//-------------------------------------------- -// Omni port datum -// -// Used by omni devices to manage connections -// to other atmospheric objects. -//-------------------------------------------- -/datum/omni_port - var/obj/machinery/atmospherics/omni/master - var/dir - var/update = 1 - var/mode = 0 - var/concentration = 0 - var/con_lock = 0 - var/transfer_moles = 0 - var/datum/gas_mixture/air - var/obj/machinery/atmospherics/node - var/datum/pipeline/parent - -/datum/omni_port/New(var/obj/machinery/atmospherics/omni/M, var/direction = NORTH) - ..() - dir = direction - if(istype(M)) - master = M - air = new - air.volume = 200 - -/datum/omni_port/proc/connect() - if(node) - return - master.atmos_init() - if(node) - node.atmos_init() - node.addMember(master) - master.build_network() - -/datum/omni_port/proc/disconnect() - if(node) - node.disconnect(master) - node = null - master.nullifyPipenet(parent) - -//-------------------------------------------- -// Need to find somewhere else for these -//-------------------------------------------- - -//returns a text string based on the direction flag input -// if capitalize is true, it will return the string capitalized -// otherwise it will return the direction string in lower case -/proc/dir_name(var/dir, var/capitalize = 0) - var/string = null - switch(dir) - if(NORTH) - string = "North" - if(SOUTH) - string = "South" - if(EAST) - string = "East" - if(WEST) - string = "West" - - if(!capitalize && string) - string = lowertext(string) - - return string - -//returns a direction flag based on the string passed to it -// case insensitive -/proc/dir_flag(var/dir) - dir = lowertext(dir) - switch(dir) - if("north") - return NORTH - if("south") - return SOUTH - if("east") - return EAST - if("west") - return WEST - else - return 0 - diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm deleted file mode 100644 index 0803d34e522..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ /dev/null @@ -1,273 +0,0 @@ -//-------------------------------------------- -// Gas filter - omni variant -//-------------------------------------------- -/obj/machinery/atmospherics/omni/filter - name = "omni gas filter" - icon_state = "map_filter" - - var/list/o_filters = new() - var/datum/omni_port/input - var/datum/omni_port/output - -/obj/machinery/atmospherics/omni/filter/Destroy() - input = null - output = null - o_filters.Cut() - return ..() - -/obj/machinery/atmospherics/omni/filter/sort_ports() - for(var/datum/omni_port/P in ports) - if(P.update) - if(output == P) - output = null - if(input == P) - input = null - if(o_filters.Find(P)) - o_filters -= P - - P.air.volume = 200 - switch(P.mode) - if(ATM_INPUT) - input = P - if(ATM_OUTPUT) - output = P - if(ATM_O2 to ATM_N2O) - o_filters += P - -/obj/machinery/atmospherics/omni/filter/error_check() - if(!input || !output || !o_filters) - return 1 - if(o_filters.len < 1 || o_filters.len > 2) //requires 1 or 2 o_filters ~otherwise why are you using a filter? - return 1 - - return 0 - -/obj/machinery/atmospherics/omni/filter/process_atmos() - ..() - if(!on) - return 0 - - if(!input || !output) - return 0 - - var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference - var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug* - - var/output_pressure = output_air.return_pressure() - - if(output_pressure >= target_pressure) - return 1 - for(var/datum/omni_port/P in o_filters) - if(P.air.return_pressure() >= target_pressure) - return 1 - - var/pressure_delta = target_pressure - output_pressure - - if(input_air.return_temperature() > 0) - input.transfer_moles = pressure_delta * output_air.volume / (input_air.return_temperature() * R_IDEAL_GAS_EQUATION) - - if(input.transfer_moles > 0) - var/datum/gas_mixture/removed = input_air.remove(input.transfer_moles) - - if(!removed) - return 1 - - for(var/datum/omni_port/P in o_filters) - var/datum/gas_mixture/filtered_out = new - filtered_out.temperature = removed.return_temperature() - - switch(P.mode) - if(ATM_O2) - filtered_out.oxygen = removed.oxygen - removed.oxygen = 0 - if(ATM_N2) - filtered_out.nitrogen = removed.nitrogen - removed.nitrogen = 0 - if(ATM_CO2) - filtered_out.carbon_dioxide = removed.carbon_dioxide - removed.carbon_dioxide = 0 - if(ATM_P) - filtered_out.toxins = removed.toxins - removed.toxins = 0 - - filtered_out.agent_b = removed.agent_b - removed.agent_b = 0 - if(ATM_N2O) - filtered_out.sleeping_agent = removed.sleeping_agent - removed.sleeping_agent = 0 - else - filtered_out = null - - P.air.merge(filtered_out) - P.parent.update = 1 - - output_air.merge(removed) - output.parent.update = 1 - - input.transfer_moles = 0 - input.parent.update = 1 - - return 1 - -/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) - usr.set_machine(src) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330) - ui.open() - -/obj/machinery/atmospherics/omni/filter/ui_data(mob/user, datum/topic_state/state) - var/data[0] - - data["power"] = on - data["config"] = configuring - - var/portData[0] - for(var/datum/omni_port/P in ports) - if(!configuring && P.mode == 0) - continue - - var/input = 0 - var/output = 0 - var/filter = 1 - var/f_type = null - switch(P.mode) - if(ATM_INPUT) - input = 1 - filter = 0 - if(ATM_OUTPUT) - output = 1 - filter = 0 - if(ATM_O2 to ATM_N2O) - f_type = mode_send_switch(P.mode) - - portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \ - "input" = input, \ - "output" = output, \ - "filter" = filter, \ - "f_type" = f_type) - - if(portData.len) - data["ports"] = portData - if(output) - data["pressure"] = target_pressure - - return data - -/obj/machinery/atmospherics/omni/filter/proc/mode_send_switch(var/mode = ATM_NONE) - switch(mode) - if(ATM_O2) - return "Oxygen" - if(ATM_N2) - return "Nitrogen" - if(ATM_CO2) - return "Carbon Dioxide" - if(ATM_P) - return "Plasma" //*cough* Plasma *cough* - if(ATM_N2O) - return "Nitrous Oxide" - else - return null - -/obj/machinery/atmospherics/omni/filter/Topic(href, href_list) - if(..()) - return 1 - switch(href_list["command"]) - if("power") - if(!configuring) - on = !on - else - on = 0 - if("configure") - configuring = !configuring - if(configuring) - on = 0 - - //only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on - if(configuring && !on) - switch(href_list["command"]) - if("set_pressure") - var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num - target_pressure = between(0, new_pressure, 4500) - if("switch_mode") - switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"])) - if("switch_filter") - var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Plasma", "Nitrous Oxide") - switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter)) - - update_icon() - SSnanoui.update_uis(src) - return - -/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode) - switch(mode) - if("Oxygen") - return ATM_O2 - if("Nitrogen") - return ATM_N2 - if("Carbon Dioxide") - return ATM_CO2 - if("Plasma") - return ATM_P - if("Nitrous Oxide") - return ATM_N2O - if("in") - return ATM_INPUT - if("out") - return ATM_OUTPUT - if("None") - return ATM_NONE - else - return null - -/obj/machinery/atmospherics/omni/filter/proc/switch_filter(var/dir, var/mode) - //check they aren't trying to disable the input or output ~this can only happen if they hack the cached tmpl file - for(var/datum/omni_port/P in ports) - if(P.dir == dir) - if(P.mode == ATM_INPUT || P.mode == ATM_OUTPUT) - return - - switch_mode(dir, mode) - -/obj/machinery/atmospherics/omni/filter/proc/switch_mode(var/port, var/mode) - if(mode == null || !port) - return - var/datum/omni_port/target_port = null - var/list/other_ports = new() - - for(var/datum/omni_port/P in ports) - if(P.dir == port) - target_port = P - else - other_ports += P - - var/previous_mode = null - if(target_port) - previous_mode = target_port.mode - target_port.mode = mode - if(target_port.mode != previous_mode) - handle_port_change(target_port) - else - return - else - return - - for(var/datum/omni_port/P in other_ports) - if(P.mode == mode) - var/old_mode = P.mode - P.mode = previous_mode - if(P.mode != old_mode) - handle_port_change(P) - - update_ports() - -/obj/machinery/atmospherics/omni/filter/proc/handle_port_change(var/datum/omni_port/P) - switch(P.mode) - if(ATM_NONE) - initialize_directions &= ~P.dir - P.disconnect() - else - initialize_directions |= P.dir - P.connect() - P.update = 1 diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm deleted file mode 100644 index 5586bdc3a98..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ /dev/null @@ -1,291 +0,0 @@ -//-------------------------------------------- -// Gas mixer - omni variant -//-------------------------------------------- -/obj/machinery/atmospherics/omni/mixer - name = "omni gas mixer" - icon_state = "map_mixer" - - var/list/inputs = new() - var/datum/omni_port/output - - //setup tags for initial concentration values (must be decimal) - var/tag_north_con - var/tag_south_con - var/tag_east_con - var/tag_west_con - -/obj/machinery/atmospherics/omni/mixer/New() - ..() - if(mapper_set()) - var/con = 0 - for(var/datum/omni_port/P in ports) - switch(P.dir) - if(NORTH) - if(tag_north_con && tag_north == 1) - P.concentration = tag_north_con - con += max(0, tag_north_con) - if(SOUTH) - if(tag_south_con && tag_south == 1) - P.concentration = tag_south_con - con += max(0, tag_south_con) - if(EAST) - if(tag_east_con && tag_east == 1) - P.concentration = tag_east_con - con += max(0, tag_east_con) - if(WEST) - if(tag_west_con && tag_west == 1) - P.concentration = tag_west_con - con += max(0, tag_west_con) - - //mappers who are bad at maths will be punished (total concentration must be 100%) - if(con != 1) - tag_north_con = null - tag_south_con = null - tag_east_con = null - tag_west_con = null - -/obj/machinery/atmospherics/omni/mixer/Destroy() - inputs.Cut() - output = null - return ..() - -/obj/machinery/atmospherics/omni/mixer/sort_ports() - for(var/datum/omni_port/P in ports) - if(P.update) - if(output == P) - output = null - if(inputs.Find(P)) - inputs -= P - - P.air.volume = 200 - switch(P.mode) - if(ATM_INPUT) - inputs += P - if(ATM_OUTPUT) - output = P - - if(!mapper_set()) - for(var/datum/omni_port/P in inputs) - P.concentration = 1 / max(1, inputs.len) - - if(output) - output.air.volume *= 0.75 * inputs.len - output.concentration = 1 - -/obj/machinery/atmospherics/omni/mixer/proc/mapper_set() - return (tag_north_con || tag_south_con || tag_east_con || tag_west_con) - -/obj/machinery/atmospherics/omni/mixer/error_check() - if(!output || !inputs) - return 1 - if(inputs.len < 2 || inputs.len > 3) //requires 2 or 3 inputs ~otherwise why are you using a mixer? - return 1 - - return 0 - -/obj/machinery/atmospherics/omni/mixer/process_atmos() - ..() - if(!on) - return 0 - - var/datum/gas_mixture/output_air = output.air - var/output_pressure = output_air.return_pressure() - - - if(output_pressure >= target_pressure * 0.999) - //No need to mix if target is already full! - 0.1% margin of error so we minimize processing minor gas volumes - return 1 - - //Calculate necessary moles to transfer using PV=nRT - - var/pressure_delta = target_pressure - output_pressure - - for(var/datum/omni_port/P in inputs) - if(P.air.return_temperature() > 0) - P.transfer_moles = (P.concentration * pressure_delta) * output_air.return_volume() / (P.air.return_temperature() * R_IDEAL_GAS_EQUATION) - - var/ratio_check = null - - for(var/datum/omni_port/P in inputs) - if(!P.transfer_moles) - return 1 - if(P.air.total_moles() < P.transfer_moles) - ratio_check = 1 - continue - - if(ratio_check) - var/list/ratio_list = new() - for(var/datum/omni_port/P in inputs) - ratio_list.Add(P.air.total_moles() / P.transfer_moles) - - var/ratio = min(ratio_list) - - for(var/datum/omni_port/P in inputs) - P.transfer_moles *= ratio - - for(var/datum/omni_port/P in inputs) - if(P.transfer_moles > 0) - output_air.merge(P.air.remove(P.transfer_moles)) - P.parent.update = 1 - P.transfer_moles = 0 - - output.parent.update = 1 - - return 1 - -/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) - usr.set_machine(src) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330) - ui.open() - -/obj/machinery/atmospherics/omni/mixer/ui_data(mob/user, datum/topic_state/state) - var/data[0] - - data["power"] = on - data["config"] = configuring - - var/portData[0] - for(var/datum/omni_port/P in ports) - if(!configuring && P.mode == 0) - continue - - var/input = 0 - var/output = 0 - switch(P.mode) - if(ATM_INPUT) - input = 1 - if(ATM_OUTPUT) - output = 1 - - portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \ - "concentration" = P.concentration, \ - "input" = input, \ - "output" = output, \ - "con_lock" = P.con_lock) - - if(portData.len) - data["ports"] = portData - if(output) - data["pressure"] = target_pressure - - return data - -/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list) - if(..()) - return 1 - - switch(href_list["command"]) - if("power") - if(!configuring) - on = !on - else - on = 0 - if("configure") - configuring = !configuring - if(configuring) - on = 0 - - //only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on - if(configuring && !on) - switch(href_list["command"]) - if("set_pressure") - var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num - target_pressure = between(0, new_pressure, 4500) - if("switch_mode") - switch_mode(dir_flag(href_list["dir"]), href_list["mode"]) - if("switch_con") - change_concentration(dir_flag(href_list["dir"])) - if("switch_conlock") - con_lock(dir_flag(href_list["dir"])) - - update_icon() - SSnanoui.update_uis(src) - return - -/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE) - if(mode != ATM_INPUT && mode != ATM_OUTPUT) - switch(mode) - if("in") - mode = ATM_INPUT - if("out") - mode = ATM_OUTPUT - else - mode = ATM_NONE - - for(var/datum/omni_port/P in ports) - var/old_mode = P.mode - if(P.dir == port) - switch(mode) - if(ATM_INPUT) - if(P.mode == ATM_OUTPUT) - return - P.mode = mode - if(ATM_OUTPUT) - P.mode = mode - if(ATM_NONE) - if(P.mode == ATM_OUTPUT) - return - if(P.mode == ATM_INPUT && inputs.len > 2) - P.mode = mode - else if(P.mode == ATM_OUTPUT && mode == ATM_OUTPUT) - P.mode = ATM_INPUT - if(P.mode != old_mode) - switch(P.mode) - if(ATM_NONE) - initialize_directions &= ~P.dir - P.disconnect() - else - initialize_directions |= P.dir - P.connect() - P.update = 1 - - update_ports() - -/obj/machinery/atmospherics/omni/mixer/proc/change_concentration(var/port = NORTH) - tag_north_con = null - tag_south_con = null - tag_east_con = null - tag_west_con = null - - var/old_con = 0 - var/non_locked = 0 - var/remain_con = 1 - - for(var/datum/omni_port/P in inputs) - if(P.dir == port) - old_con = P.concentration - else if(!P.con_lock) - non_locked++ - else - remain_con -= P.concentration - - //return if no adjustable ports - if(non_locked < 1) - return - - var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100 - - //cap it between 0 and the max remaining concentration - new_con = between(0, new_con, remain_con) - - //new_con = min(remain_con, new_con) - - //clamp remaining concentration so we don't go into negatives - remain_con = max(0, remain_con - new_con) - - //distribute remaining concentration between unlocked ports evenly - remain_con /= max(1, non_locked) - - for(var/datum/omni_port/P in inputs) - if(P.dir == port) - P.concentration = new_con - else if(!P.con_lock) - P.concentration = remain_con - -/obj/machinery/atmospherics/omni/mixer/proc/con_lock(var/port = NORTH) - for(var/datum/omni_port/P in inputs) - if(P.dir == port) - P.con_lock = !P.con_lock diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm deleted file mode 100644 index d75e2e683c1..00000000000 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ /dev/null @@ -1,302 +0,0 @@ -//-------------------------------------------- -// Base omni device -//-------------------------------------------- -/obj/machinery/atmospherics/omni - name = "omni device" - icon = 'icons/atmos/omni_devices.dmi' - icon_state = "base" - use_power = IDLE_POWER_USE - initialize_directions = 0 - - can_unwrench = 1 - - var/on = 0 - var/configuring = 0 - var/target_pressure = ONE_ATMOSPHERE - - var/tag_north = ATM_NONE - var/tag_south = ATM_NONE - var/tag_east = ATM_NONE - var/tag_west = ATM_NONE - - var/overlays_on[5] - var/overlays_off[5] - var/overlays_error[2] - var/underlays_current[4] - - var/list/ports = new() - -/obj/machinery/atmospherics/omni/New() - ..() - icon_state = "base" - - ports = new() - for(var/d in GLOB.cardinal) - var/datum/omni_port/new_port = new(src, d) - switch(d) - if(NORTH) - new_port.mode = tag_north - if(SOUTH) - new_port.mode = tag_south - if(EAST) - new_port.mode = tag_east - if(WEST) - new_port.mode = tag_west - if(new_port.mode > 0) - initialize_directions |= d - ports += new_port - - build_icons() - -/obj/machinery/atmospherics/omni/Destroy() - for(var/datum/omni_port/P in ports) - if(P.node) - P.node.disconnect(src) - P.node = null - nullifyPipenet(P.parent) - return ..() - -/obj/machinery/atmospherics/omni/atmos_init() - ..() - for(var/datum/omni_port/P in ports) - if(P.node || P.mode == 0) - continue - for(var/obj/machinery/atmospherics/target in get_step(src, P.dir)) - if(target.initialize_directions & get_dir(target,src)) - P.node = target - break - - for(var/datum/omni_port/P in ports) - P.update = 1 - - update_ports() - -/obj/machinery/atmospherics/omni/update_icon() - ..() - - if(stat & NOPOWER) - overlays = overlays_off - on = 0 - else if(error_check()) - overlays = overlays_error - on = 0 - else - overlays = on ? (overlays_on) : (overlays_off) - - underlays = underlays_current - -/obj/machinery/atmospherics/omni/proc/error_check() - return - -/obj/machinery/atmospherics/omni/power_change() - var/old_stat = stat - ..() - if(old_stat != stat) - update_icon() - -/obj/machinery/atmospherics/omni/attackby(var/obj/item/W as obj, var/mob/user as mob, params) - if(!istype(W, /obj/item/wrench)) - return ..() - - if(can_unwrench) - var/int_pressure = 0 - for(var/datum/omni_port/P in ports) - int_pressure += P.air.return_pressure() - var/datum/gas_mixture/env_air = loc.return_air() - if((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE) - to_chat(user, "You cannot unwrench [src], it is too exerted due to internal pressure.") - add_fingerprint(user) - return 1 - playsound(loc, W.usesound, 50, 1) - to_chat(user, "You begin to unfasten \the [src]...") - if(do_after(user, 40 * W.toolspeed, target = src)) - user.visible_message( \ - "[user] unfastens \the [src].", \ - "You have unfastened \the [src].", \ - "You hear a ratchet.") - new /obj/item/pipe(loc, make_from=src) - qdel(src) - else - return ..() - -/obj/machinery/atmospherics/omni/attack_hand(mob/user) - if(..()) - return - - add_fingerprint(usr) - ui_interact(user) - -/obj/machinery/atmospherics/omni/attack_ghost(mob/user) - ui_interact(user) - -/obj/machinery/atmospherics/omni/proc/build_icons() - if(!check_icon_cache()) - return - - var/core_icon = null - if(istype(src, /obj/machinery/atmospherics/omni/mixer)) - core_icon = "mixer" - else if(istype(src, /obj/machinery/atmospherics/omni/filter)) - core_icon = "filter" - else - return - - //directional icons are layers 1-4, with the core icon on layer 5 - if(core_icon) - overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon) - overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow") - - overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon) - overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error") - -/obj/machinery/atmospherics/omni/proc/update_port_icons() - if(!check_icon_cache()) - return - - for(var/datum/omni_port/P in ports) - if(P.update) - var/ref_layer = 0 - switch(P.dir) - if(NORTH) - ref_layer = 1 - if(SOUTH) - ref_layer = 2 - if(EAST) - ref_layer = 3 - if(WEST) - ref_layer = 4 - - if(!ref_layer) - continue - - var/list/port_icons = select_port_icons(P) - if(port_icons) - if(P.node) - underlays_current[ref_layer] = port_icons["pipe_icon"] - else - underlays_current[ref_layer] = null - overlays_off[ref_layer] = port_icons["off_icon"] - overlays_on[ref_layer] = port_icons["on_icon"] - else - underlays_current[ref_layer] = null - overlays_off[ref_layer] = null - overlays_on[ref_layer] = null - - update_icon() - -/obj/machinery/atmospherics/omni/proc/select_port_icons(var/datum/omni_port/P) - if(!istype(P)) - return - - if(P.mode > 0) - var/ic_dir = dir_name(P.dir) - var/ic_on = ic_dir - var/ic_off = ic_dir - switch(P.mode) - if(ATM_INPUT) - ic_on += "_in_glow" - ic_off += "_in" - if(ATM_OUTPUT) - ic_on += "_out_glow" - ic_off += "_out" - if(ATM_O2 to ATM_N2O) - ic_on += "_filter" - ic_off += "_out" - - ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on) - ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off) - - var/pipe_state - var/turf/T = get_turf(src) - if(!istype(T)) - return - if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 ) - //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node)) - pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down") - else - //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node)) - pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact") - - return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state) - -/obj/machinery/atmospherics/omni/update_underlays() - for(var/datum/omni_port/P in ports) - P.update = 1 - update_ports() - -/obj/machinery/atmospherics/omni/hide(var/i) - update_underlays() - -/obj/machinery/atmospherics/omni/proc/update_ports() - sort_ports() - update_port_icons() - for(var/datum/omni_port/P in ports) - P.update = 0 - -/obj/machinery/atmospherics/omni/proc/sort_ports() - return - -// Pipenet procs -/obj/machinery/atmospherics/omni/build_network(remove_deferral = FALSE) - for(var/datum/omni_port/P in ports) - if(!P.parent) - P.parent = new /datum/pipeline() - P.parent.build_pipeline(src) - ..() - -/obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference) - for(var/datum/omni_port/P in ports) - if(reference == P.node) - if(istype(P.node, /obj/machinery/atmospherics/pipe)) - qdel(P.parent) - P.node = null - update_ports() - -/obj/machinery/atmospherics/omni/nullifyPipenet(datum/pipeline/P) - ..() - if(!P) - return - for(var/datum/omni_port/PO in ports) - if(P == PO.parent) - PO.parent.other_airs -= PO.air - PO.parent = null - -/obj/machinery/atmospherics/omni/returnPipenetAir(datum/pipeline/P) - for(var/datum/omni_port/PO in ports) - if(P == PO.parent) - return PO.air - -/obj/machinery/atmospherics/omni/pipeline_expansion(datum/pipeline/P) - if(P) - for(var/datum/omni_port/PO in ports) - if(PO.parent == P) - return list(PO.node) - else - var/list/nodes = list() - for(var/datum/omni_port/PO in ports) - nodes += PO.node - - return nodes - -/obj/machinery/atmospherics/omni/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A) - for(var/datum/omni_port/PO in ports) - if(A == PO.node) - PO.parent = P - -/obj/machinery/atmospherics/omni/returnPipenet(obj/machinery/atmospherics/A) - for(var/datum/omni_port/P in ports) - if(A == P.node) - return P.parent - -/obj/machinery/atmospherics/omni/replacePipenet(datum/pipeline/Old, datum/pipeline/New) - for(var/datum/omni_port/P in ports) - if(Old == P.parent) - P.parent = New - - -/obj/machinery/atmospherics/omni/process_atmos() - ..() - for(var/datum/omni_port/port in ports) - if(!port.parent) - return 0 - return 1 diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 64fb308c2db..c06e863406d 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -1,26 +1,39 @@ + +/// Nothing will be filtered. +#define FILTER_NOTHING -1 +/// Plasma, and Oxygen Agent B. +#define FILTER_TOXINS 0 +/// Oxygen only. +#define FILTER_OXYGEN 1 +/// Nitrogen only. +#define FILTER_NITROGEN 2 +/// Carbon dioxide only. +#define FILTER_CO2 3 +/// Nitrous oxide only. +#define FILTER_N2O 4 + /obj/machinery/atmospherics/trinary/filter + name = "gas filter" icon = 'icons/atmos/filter.dmi' icon_state = "map" - - can_unwrench = 1 - - name = "gas filter" - + can_unwrench = TRUE + /// The amount of pressure the filter wants to operate at. var/target_pressure = ONE_ATMOSPHERE - - var/filter_type = 0 -/* -Filter types: --1: Nothing - 0: Toxins: Toxins, Oxygen Agent B - 1: Oxygen: Oxygen ONLY - 2: Nitrogen: Nitrogen ONLY - 3: Carbon Dioxide: Carbon Dioxide ONLY - 4: Sleeping Agent (N2O) -*/ - - var/frequency = 0 + /// The type of gas we want to filter. Valid values that go here are from the `FILTER` defines at the top of the file. + var/filter_type = FILTER_NOTHING + /// The frequency of the filter. Used with `radio_connection`. + var/frequency = NONE + /// A reference to the filter's `datum/radio_frequency`. var/datum/radio_frequency/radio_connection + /// A list of available filter options. Used with `tgui_data`. + var/list/filter_list = list( + "Nothing" = FILTER_NOTHING, + "Plasma" = FILTER_TOXINS, + "O2" = FILTER_OXYGEN, + "N2" = FILTER_NITROGEN, + "CO2" = FILTER_CO2, + "N2O" = FILTER_N2O + ) /obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user) if(!istype(user) || user.incapacitated()) @@ -146,26 +159,26 @@ Filter types: filtered_out.temperature = removed.temperature switch(filter_type) - if(0) //removing hydrocarbons + if(FILTER_TOXINS) filtered_out.toxins = removed.toxins removed.toxins = 0 filtered_out.agent_b = removed.agent_b removed.agent_b = 0 - if(1) //removing O2 + if(FILTER_OXYGEN) filtered_out.oxygen = removed.oxygen removed.oxygen = 0 - if(2) //removing N2 + if(FILTER_NITROGEN) filtered_out.nitrogen = removed.nitrogen removed.nitrogen = 0 - if(3) //removing CO2 + if(FILTER_CO2) filtered_out.carbon_dioxide = removed.carbon_dioxide removed.carbon_dioxide = 0 - if(4)//removing N2O + if(FILTER_N2O) filtered_out.sleeping_agent = removed.sleeping_agent removed.sleeping_agent = 0 else @@ -188,7 +201,7 @@ Filter types: ..() /obj/machinery/atmospherics/trinary/filter/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/trinary/filter/attack_hand(mob/user) if(..()) @@ -199,53 +212,56 @@ Filter types: return add_fingerprint(user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/atmospherics/trinary/filter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 475, 155, state = state) + ui = new(user, src, ui_key, "AtmosFilter", name, 380, 140, master_ui, state) ui.open() -/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user) - var/list/data = list() - data["on"] = on - data["pressure"] = round(target_pressure) - data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) - data["filter_type"] = filter_type +/obj/machinery/atmospherics/trinary/filter/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "pressure" = round(target_pressure), + "max_pressure" = round(MAX_OUTPUT_PRESSURE), + "filter_type" = filter_type + ) + data["filter_type_list"] = list() + for(var/label in filter_list) + data["filter_type_list"] += list(list("label" = label, "gas_type" = filter_list[label])) + return data -/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE +/obj/machinery/atmospherics/trinary/filter/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["pressure"]) - var/pressure = href_list["pressure"] - if(pressure == "max") - pressure = MAX_OUTPUT_PRESSURE - . = TRUE - else if(pressure == "input") - pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null - if(!isnull(pressure) && !..()) - . = TRUE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - . = TRUE - if(.) - target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") - if(href_list["filter"]) - filter_type = text2num(href_list["filter"]) - investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos") - . = TRUE + switch(action) + if("power") + toggle() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") + return TRUE - update_icon() - SSnanoui.update_uis(src) + if("set_filter") + filter_type = text2num(params["filter"]) + investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos") + return TRUE + + if("max_pressure") + target_pressure = MAX_OUTPUT_PRESSURE + . = TRUE + + if("min_pressure") + target_pressure = 0 + . = TRUE + + if("custom_pressure") + target_pressure = clamp(text2num(params["pressure"]), 0, MAX_OUTPUT_PRESSURE) + . = TRUE + if(.) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") /obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index be4bf969009..52845f1154d 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -152,7 +152,7 @@ return 1 /obj/machinery/atmospherics/trinary/mixer/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/trinary/mixer/attack_hand(mob/user) if(..()) @@ -163,62 +163,62 @@ return add_fingerprint(user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) +/obj/machinery/atmospherics/trinary/mixer/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 370, 165, state = state) + ui = new(user, src, ui_key, "AtmosMixer", name, 330, 165, master_ui, state) ui.open() -/obj/machinery/atmospherics/trinary/mixer/ui_data(mob/user) - var/list/data = list() - data["on"] = on - data["pressure"] = round(target_pressure) - data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) - data["node1_concentration"] = round(node1_concentration*100) - data["node2_concentration"] = round(node2_concentration*100) +/obj/machinery/atmospherics/trinary/mixer/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "pressure" = round(target_pressure, 0.01), + "max_pressure" = MAX_OUTPUT_PRESSURE, + "node1_concentration" = round(node1_concentration * 100), + "node2_concentration" = round(node2_concentration * 100) + ) return data -/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list) + + +/obj/machinery/atmospherics/trinary/mixer/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["pressure"]) - var/pressure = href_list["pressure"] - if(pressure == "max") - pressure = MAX_OUTPUT_PRESSURE - . = TRUE - else if(pressure == "input") - pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null - if(!isnull(pressure) && !..()) - . = TRUE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - . = TRUE - if(.) - target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") - if(href_list["node1"]) - var/value = text2num(href_list["node1"]) - node1_concentration = max(0, min(1, node1_concentration + value)) - node2_concentration = max(0, min(1, node2_concentration - value)) - investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos") - . = TRUE - if(href_list["node2"]) - var/value = text2num(href_list["node2"]) - node2_concentration = max(0, min(1, node2_concentration + value)) - node1_concentration = max(0, min(1, node1_concentration - value)) - investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos") - . = TRUE + switch(action) + if("power") + toggle() + investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos") + return TRUE - update_icon() - SSnanoui.update_uis(src) + if("set_node") + if(params["node_name"] == "Node 1") + node1_concentration = clamp(round(text2num(params["concentration"]), 0.01), 0, 1) + node2_concentration = round(1 - node1_concentration, 0.01) + investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos") + return TRUE + else + node2_concentration = clamp(round(text2num(params["concentration"]), 0.01), 0, 1) + node1_concentration = round(1 - node2_concentration, 0.01) + investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos") + return TRUE + + if("max_pressure") + target_pressure = MAX_OUTPUT_PRESSURE + . = TRUE + + if("min_pressure") + target_pressure = 0 + . = TRUE + + if("custom_pressure") + target_pressure = clamp(text2num(params["pressure"]), 0, MAX_OUTPUT_PRESSURE) + . = TRUE + if(.) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") /obj/machinery/atmospherics/trinary/mixer/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) diff --git a/code/ATMOSPHERICS/datum_icon_manager.dm b/code/ATMOSPHERICS/datum_icon_manager.dm index 2286b3523a0..014fafc5c18 100644 --- a/code/ATMOSPHERICS/datum_icon_manager.dm +++ b/code/ATMOSPHERICS/datum_icon_manager.dm @@ -33,7 +33,6 @@ //var/list/underlays_intact[] //var/list/pipe_underlays_exposed[] //var/list/pipe_underlays_intact[] - var/list/omni_icons[] /datum/pipe_icon_manager/New() check_icons() @@ -53,8 +52,6 @@ return manifold_icons[state + color] if("device") return device_icons[state] - if("omni") - return omni_icons[state] if("underlay") return underlays[state + dir + color] //if("underlay_intact") @@ -75,8 +72,6 @@ gen_manifold_icons() if(!device_icons) gen_device_icons() - if(!omni_icons) - gen_omni_icons() //if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact) if(!underlays) gen_underlay_icons() @@ -150,18 +145,6 @@ continue device_icons["scrubber" + state] = image('icons/atmos/vent_scrubber.dmi', icon_state = state) -/datum/pipe_icon_manager/proc/gen_omni_icons() - if(!omni_icons) - omni_icons = new() - - var/icon/omni = new('icons/atmos/omni_devices.dmi') - - for(var/state in omni.IconStates()) - if(!state || findtext(state, "map")) - continue - omni_icons[state] = image('icons/atmos/omni_devices.dmi', icon_state = state) - - /datum/pipe_icon_manager/proc/gen_underlay_icons() if(!underlays) diff --git a/code/LINDA/LINDA_system.dm b/code/LINDA/LINDA_system.dm index 3c8633c2b91..8d1ff95d3e9 100644 --- a/code/LINDA/LINDA_system.dm +++ b/code/LINDA/LINDA_system.dm @@ -32,13 +32,13 @@ if(!R) return 1 -atom/movable/proc/CanAtmosPass() +/atom/movable/proc/CanAtmosPass() return 1 -atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5) +/atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5) return (!density || !height) -turf/CanPass(atom/movable/mover, turf/target, height=1.5) +/turf/CanPass(atom/movable/mover, turf/target, height=1.5) if(!target) return 0 if(istype(mover)) // turf/Enter(...) will perform more advanced checks diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index acfa1983f72..8d71323cfb8 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -473,7 +473,7 @@ SSair.active_super_conductivity -= src return 0 -turf/simulated/proc/consider_superconductivity(starting) +/turf/simulated/proc/consider_superconductivity(starting) if(!thermal_conductivity) return 0 @@ -489,7 +489,7 @@ turf/simulated/proc/consider_superconductivity(starting) SSair.active_super_conductivity |= src return 1 -turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space +/turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space if(temperature > T0C) //Considering 0 degC as te break even point for radiation in and out var/delta_temperature = (temperature_archived - TCMB) //hardcoded space temperature if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)) diff --git a/code/__DEFINES/js.dm b/code/__DEFINES/js.dm index e1a86e664d4..eeca4da55dd 100644 --- a/code/__DEFINES/js.dm +++ b/code/__DEFINES/js.dm @@ -36,7 +36,7 @@ Be sure to include required js functions in your page, or it'll raise an excepti And yes I know this is a proc in a defines file, but its highly relevant so it can be here */ -proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null) +/proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null) if(receiver && target_element && control_id) // && winexists(receiver, control_id)) var/list/argums = list(target_element, new_content) if(callback) diff --git a/code/__DEFINES/martial_arts.dm b/code/__DEFINES/martial_arts.dm new file mode 100644 index 00000000000..4eb139cc44a --- /dev/null +++ b/code/__DEFINES/martial_arts.dm @@ -0,0 +1,16 @@ +#define MARTIAL_COMBO_FAIL 0 // If the combo failed +#define MARTIAL_COMBO_CONTINUE 1 // If the combo should continue +#define MARTIAL_COMBO_DONE 2 // If the combo is successful and done +#define MARTIAL_COMBO_DONE_NO_CLEAR 3 // If the combo is successful and done but the others should have a chance to finish +#define MARTIAL_COMBO_DONE_BASIC_HIT 4 // If the combo should do a basic hit after it's done +#define MARTIAL_COMBO_DONE_CLEAR_COMBOS 5 // If the combo should do a basic hit after it's done + +#define MARTIAL_ARTS_CANNOT_USE -1 + +#define MARTIAL_COMBO_STEP_HARM "Harm" +#define MARTIAL_COMBO_STEP_DISARM "Disarm" +#define MARTIAL_COMBO_STEP_GRAB "Grab" +#define MARTIAL_COMBO_STEP_HELP "Help" + +// A check used for all act types. Such as disarm_act +#define MARTIAL_ARTS_ACT_CHECK if((. = ..()) != FALSE) return . diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 719274857ec..7cd4cc7a918 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -208,6 +208,7 @@ #define isguardian(A) (istype((A), /mob/living/simple_animal/hostile/guardian)) #define isnymph(A) (istype((A), /mob/living/simple_animal/diona)) #define ishostile(A) (istype(A, /mob/living/simple_animal/hostile)) +#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider)) #define issilicon(A) (istype((A), /mob/living/silicon)) #define isAI(A) (istype((A), /mob/living/silicon/ai)) diff --git a/code/__DEFINES/pipes.dm b/code/__DEFINES/pipes.dm index c855a5e4260..d56d446ca1d 100644 --- a/code/__DEFINES/pipes.dm +++ b/code/__DEFINES/pipes.dm @@ -21,8 +21,6 @@ #define PIPE_TVALVE 18 #define PIPE_MANIFOLD4W 19 #define PIPE_CAP 20 -#define PIPE_OMNI_MIXER 21 -#define PIPE_OMNI_FILTER 22 #define PIPE_UNIVERSAL 23 #define PIPE_SUPPLY_STRAIGHT 24 #define PIPE_SUPPLY_BENT 25 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 6e3603f83a3..11732a22375 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -48,7 +48,7 @@ #define INIT_ORDER_GARBAGE 21 #define INIT_ORDER_DBCORE 20 #define INIT_ORDER_BLACKBOX 19 -#define INIT_ORDER_SERVER_MAINT 18 +#define INIT_ORDER_CLEANUP 18 #define INIT_ORDER_INPUT 17 #define INIT_ORDER_SOUNDS 16 #define INIT_ORDER_INSTRUMENTS 15 @@ -90,7 +90,7 @@ #define FIRE_PRIORITY_NANOMOB 10 #define FIRE_PRIORITY_NIGHTSHIFT 10 #define FIRE_PRIORITY_IDLE_NPC 10 -#define FIRE_PRIORITY_SERVER_MAINT 10 +#define FIRE_PRIORITY_CLEANUP 10 #define FIRE_PRIORITY_TICKETS 10 #define FIRE_PRIORITY_RESEARCH 10 #define FIRE_PRIORITY_GARBAGE 15 diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 0d3b26d0340..49c77ca0a4a 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -1,4 +1,4 @@ -proc/GetOppositeDir(var/dir) +/proc/GetOppositeDir(var/dir) switch(dir) if(NORTH) return SOUTH if(SOUTH) return NORTH @@ -10,7 +10,7 @@ proc/GetOppositeDir(var/dir) if(SOUTHEAST) return NORTHWEST return 0 -proc/random_underwear(gender, species = "Human") +/proc/random_underwear(gender, species = "Human") var/list/pick_list = list() switch(gender) if(MALE) pick_list = GLOB.underwear_m @@ -18,7 +18,7 @@ proc/random_underwear(gender, species = "Human") else pick_list = GLOB.underwear_list return pick_species_allowed_underwear(pick_list, species) -proc/random_undershirt(gender, species = "Human") +/proc/random_undershirt(gender, species = "Human") var/list/pick_list = list() switch(gender) if(MALE) pick_list = GLOB.undershirt_m @@ -26,7 +26,7 @@ proc/random_undershirt(gender, species = "Human") else pick_list = GLOB.undershirt_list return pick_species_allowed_underwear(pick_list, species) -proc/random_socks(gender, species = "Human") +/proc/random_socks(gender, species = "Human") var/list/pick_list = list() switch(gender) if(MALE) pick_list = GLOB.socks_m @@ -34,7 +34,7 @@ proc/random_socks(gender, species = "Human") else pick_list = GLOB.socks_list return pick_species_allowed_underwear(pick_list, species) -proc/pick_species_allowed_underwear(list/all_picks, species) +/proc/pick_species_allowed_underwear(list/all_picks, species) var/list/valid_picks = list() for(var/test in all_picks) var/datum/sprite_accessory/S = all_picks[test] @@ -46,7 +46,7 @@ proc/pick_species_allowed_underwear(list/all_picks, species) return pick(valid_picks) -proc/random_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead) +/proc/random_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead) var/h_style = "Bald" var/list/valid_hairstyles = list() for(var/hairstyle in GLOB.hair_styles_public_list) @@ -75,7 +75,7 @@ proc/random_hair_style(var/gender, species = "Human", var/datum/robolimb/robohea return h_style -proc/random_facial_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead) +/proc/random_facial_hair_style(var/gender, species = "Human", var/datum/robolimb/robohead) var/f_style = "Shaved" var/list/valid_facial_hairstyles = list() for(var/facialhairstyle in GLOB.facial_hair_styles_list) @@ -104,7 +104,7 @@ proc/random_facial_hair_style(var/gender, species = "Human", var/datum/robolimb/ return f_style -proc/random_head_accessory(species = "Human") +/proc/random_head_accessory(species = "Human") var/ha_style = "None" var/list/valid_head_accessories = list() for(var/head_accessory in GLOB.head_accessory_styles_list) @@ -119,7 +119,7 @@ proc/random_head_accessory(species = "Human") return ha_style -proc/random_marking_style(var/location = "body", species = "Human", var/datum/robolimb/robohead, var/body_accessory, var/alt_head) +/proc/random_marking_style(var/location = "body", species = "Human", var/datum/robolimb/robohead, var/body_accessory, var/alt_head) var/m_style = "None" var/list/valid_markings = list() for(var/marking in GLOB.marking_styles_list) @@ -158,7 +158,7 @@ proc/random_marking_style(var/location = "body", species = "Human", var/datum/ro return m_style -proc/random_body_accessory(species = "Vulpkanin") +/proc/random_body_accessory(species = "Vulpkanin") var/body_accessory = null var/list/valid_body_accessories = list() for(var/B in GLOB.body_accessory_by_name) @@ -174,7 +174,7 @@ proc/random_body_accessory(species = "Vulpkanin") return body_accessory -proc/random_name(gender, species = "Human") +/proc/random_name(gender, species = "Human") var/datum/species/current_species if(species) @@ -188,7 +188,7 @@ proc/random_name(gender, species = "Human") else return current_species.get_random_name(gender) -proc/random_skin_tone(species = "Human") +/proc/random_skin_tone(species = "Human") if(species == "Human" || species == "Drask") switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino")) if("caucasian") . = -10 @@ -202,7 +202,7 @@ proc/random_skin_tone(species = "Human") . = rand(1, 6) return . -proc/skintone2racedescription(tone, species = "Human") +/proc/skintone2racedescription(tone, species = "Human") if(species == "Human") switch(tone) if(30 to INFINITY) return "albino" @@ -225,7 +225,7 @@ proc/skintone2racedescription(tone, species = "Human") else return "unknown" -proc/age2agedescription(age) +/proc/age2agedescription(age) switch(age) if(0 to 1) return "infant" if(1 to 3) return "toddler" diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 034e8851c18..7019ee8b2c4 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -196,7 +196,7 @@ //checks text for html tags //if tag is not in whitelist (var/list/paper_tag_whitelist in global.dm) //relpaces < with < -proc/checkhtml(var/t) +/proc/checkhtml(var/t) t = sanitize_simple(t, list("&#"=".")) var/p = findtext(t,"<",1) while(p) //going through all the tags diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 83347c20d3b..a1da66b1373 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -60,7 +60,7 @@ return time2text(station_time(time, TRUE), format) /* Returns 1 if it is the selected month and day */ -proc/isDay(var/month, var/day) +/proc/isDay(var/month, var/day) if(isnum(month) && isnum(day)) var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day @@ -95,7 +95,7 @@ proc/isDay(var/month, var/day) /proc/seconds_to_time(var/seconds as num) var/numSeconds = seconds % 60 var/numMinutes = (seconds - numSeconds) / 60 - return "[numMinutes] [numMinutes > 1 ? "minutes" : "minute"] and [numSeconds] seconds." + return "[numMinutes] [numMinutes > 1 ? "minutes" : "minute"] and [numSeconds] seconds" //Take a value in seconds and makes it display like a clock /proc/seconds_to_clock(var/seconds as num) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index fc0f7520e0e..2a337c44563 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -20,31 +20,6 @@ return 0 -//Inverts the colour of an HTML string -/proc/invertHTML(HTMLstring) - - if(!( istext(HTMLstring) )) - CRASH("Given non-text argument!") - else - if(length(HTMLstring) != 7) - CRASH("Given non-HTML argument!") - var/textr = copytext(HTMLstring, 2, 4) - var/textg = copytext(HTMLstring, 4, 6) - var/textb = copytext(HTMLstring, 6, 8) - var/r = hex2num(textr) - var/g = hex2num(textg) - var/b = hex2num(textb) - textr = num2hex(255 - r) - textg = num2hex(255 - g) - textb = num2hex(255 - b) - if(length(textr) < 2) - textr = text("0[]", textr) - if(length(textg) < 2) - textr = text("0[]", textg) - if(length(textb) < 2) - textr = text("0[]", textb) - return text("#[][][]", textr, textg, textb) - //Returns the middle-most value /proc/dd_range(var/low, var/high, var/num) return max(low,min(high,num)) @@ -529,7 +504,7 @@ Returns 1 if the chain up to the area contains the given typepath return max(min(middle, high), low) //returns random gauss number -proc/GaussRand(var/sigma) +/proc/GaussRand(var/sigma) var/x,y,rsq do x=2*rand()-1 @@ -539,7 +514,7 @@ proc/GaussRand(var/sigma) return sigma*y*sqrt(-2*log(rsq)/rsq) //returns random gauss number, rounded to 'roundto' -proc/GaussRandRound(var/sigma,var/roundto) +/proc/GaussRandRound(var/sigma,var/roundto) return round(GaussRand(sigma),roundto) //Will return the contents of an atom recursivly to a depth of 'searchDepth' @@ -583,7 +558,7 @@ proc/GaussRandRound(var/sigma,var/roundto) return 1 -proc/is_blocked_turf(turf/T, exclude_mobs) +/proc/is_blocked_turf(turf/T, exclude_mobs) if(T.density) return 1 for(var/i in T) @@ -984,16 +959,16 @@ proc/is_blocked_turf(turf/T, exclude_mobs) -proc/get_cardinal_dir(atom/A, atom/B) +/proc/get_cardinal_dir(atom/A, atom/B) var/dx = abs(B.x - A.x) var/dy = abs(B.y - A.y) return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12) //chances are 1:value. anyprob(1) will always return true -proc/anyprob(value) +/proc/anyprob(value) return (rand(1,value)==value) -proc/view_or_range(distance = world.view , center = usr , type) +/proc/view_or_range(distance = world.view , center = usr , type) switch(type) if("view") . = view(distance,center) @@ -1001,7 +976,7 @@ proc/view_or_range(distance = world.view , center = usr , type) . = range(distance,center) return -proc/oview_or_orange(distance = world.view , center = usr , type) +/proc/oview_or_orange(distance = world.view , center = usr , type) switch(type) if("view") . = oview(distance,center) @@ -1009,7 +984,7 @@ proc/oview_or_orange(distance = world.view , center = usr , type) . = orange(distance,center) return -proc/get_mob_with_client_list() +/proc/get_mob_with_client_list() var/list/mobs = list() for(var/mob/M in GLOB.mob_list) if(M.client) @@ -1233,10 +1208,10 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(/obj/machinery/power/apc, /obj/mac return 0 -proc/get_angle(atom/a, atom/b) +/proc/get_angle(atom/a, atom/b) return atan2(b.y - a.y, b.x - a.x) -proc/atan2(x, y) +/proc/atan2(x, y) if(!x && !y) return 0 return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : -arccos(x / sqrt(x * x + y * y)) @@ -1329,7 +1304,7 @@ Standard way to write links -Sayu return FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR -atom/proc/GetTypeInAllContents(typepath) +/atom/proc/GetTypeInAllContents(typepath) var/list/processing_list = list(src) var/list/processed = list() diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index 283d92a954f..9c6fa81c1a2 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -10,12 +10,12 @@ GLOBAL_DATUM_INIT(command_announcer, /obj/item/radio/intercom/command, create_co // Load order issues means this can't be new'd until other code runs // This is probably not the way I should be doing this, but I don't know how to do it right! -proc/create_global_announcer() +/proc/create_global_announcer() spawn(0) GLOB.global_announcer = new(null) return -proc/create_command_announcer() +/proc/create_command_announcer() spawn(0) GLOB.command_announcer = new(null) return @@ -92,6 +92,7 @@ GLOBAL_VAR(map_name) // Self explanatory GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled +GLOBAL_VAR_INIT(pending_server_update, FALSE) //Database connections //A connection is established on world creation. Ideally, the connection dies when the server restarts (After feedback logging.). diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index b0676eabdc7..777a7625fe7 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -231,6 +231,13 @@ to_chat(user, "The door bolt lights have been enabled.") update_icon() +// FIRE ALARMS + +/obj/machinery/firealarm/AICtrlClick() + if(enabled) + reset() + else + alarm() // AI-CONTROLLED SLIP GENERATOR IN AI CORE diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index f9e5cbf3e5a..e61b9bdc8b6 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -170,6 +170,9 @@ /obj/machinery/ai_slipper/BorgAltClick() //Dispenses liquid if on Activate() +/obj/machinery/firealarm/BorgCtrlClick() + AICtrlClick() + /* As with AI, these are not used in click code, because the code for robots is specific, not generic. diff --git a/code/controllers/subsystem/cleanup.dm b/code/controllers/subsystem/cleanup.dm new file mode 100644 index 00000000000..f5962c45547 --- /dev/null +++ b/code/controllers/subsystem/cleanup.dm @@ -0,0 +1,44 @@ +/** + * # Cleanup Subsystem + * + * For now, all it does is periodically clean the supplied global lists of any null values they may contain. + * + * Why is this important? + * + * Sometimes, these lists can gain nulls due to errors. + * For example, when a dead player trasitions from the `dead_mob_list` to the `alive_mob_list`, a null value may get stuck in the dead mob list. + * This can cause issues when other code tries to do things with the values in the list, but are instead met with null values. + * These problems are incredibly hard to track down and fix, so this subsystem is a solution to that. + */ +SUBSYSTEM_DEF(cleanup) + name = "Null cleanup" + wait = 30 SECONDS + flags = SS_POST_FIRE_TIMING + priority = FIRE_PRIORITY_CLEANUP + init_order = INIT_ORDER_CLEANUP + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + offline_implications = "Certain global lists will no longer be cleared of nulls, which may result in runtimes. No immediate action is needed." + /// A list of global lists we want the subsystem to clean. + var/list/lists_to_clean + +/datum/controller/subsystem/cleanup/Initialize(start_timeofday) + // If you want this subsystem to clean out nulls from a specific list, add it here. + lists_to_clean = list( + GLOB.clients = "clients", + GLOB.player_list = "player_list", + GLOB.mob_list = "mob_list", + GLOB.alive_mob_list = "alive_mob_list", + GLOB.dead_mob_list = "dead_mob_list", + GLOB.human_list = "human_list", + GLOB.carbon_list = "carbon_list" + ) + return ..() + +/datum/controller/subsystem/cleanup/fire(resumed) + for(var/L in lists_to_clean) + var/list/_list = L + var/prev_length = length(_list) + listclearnulls(_list) + + if(length(_list) < prev_length) + stack_trace("Found a null value in GLOB.[lists_to_clean[_list]]!") diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index 3adfdf3972f..729c4dbe67b 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -620,20 +620,32 @@ SUBSYSTEM_DEF(jobs) var/mob/M = tgtcard.getPlayer() for(var/datum/job/job in occupations) if(tgtcard.assignment && tgtcard.assignment == job.title) - jobs_to_formats[job.title] = "disabled" // the job they already have is pre-selected + jobs_to_formats[job.title] = "green" // the job they already have is pre-selected + else if(tgtcard.assignment == "Demoted" || tgtcard.assignment == "Terminated") + jobs_to_formats[job.title] = "grey" else if(!job.would_accept_job_transfer_from_player(M)) - jobs_to_formats[job.title] = "linkDiscourage" // jobs which are karma-locked and not unlocked for this player are discouraged + jobs_to_formats[job.title] = "grey" // jobs which are karma-locked and not unlocked for this player are discouraged else if((job.title in GLOB.command_positions) && istype(M) && M.client && job.available_in_playtime(M.client)) - jobs_to_formats[job.title] = "linkDiscourage" // command jobs which are playtime-locked and not unlocked for this player are discouraged + jobs_to_formats[job.title] = "grey" // command jobs which are playtime-locked and not unlocked for this player are discouraged else if(job.total_positions && !job.current_positions && job.title != "Civilian") - jobs_to_formats[job.title] = "linkEncourage" // jobs with nobody doing them at all are encouraged + jobs_to_formats[job.title] = "teal" // jobs with nobody doing them at all are encouraged else if(job.total_positions >= 0 && job.current_positions >= job.total_positions) - jobs_to_formats[job.title] = "linkDiscourage" // jobs that are full (no free positions) are discouraged + jobs_to_formats[job.title] = "grey" // jobs that are full (no free positions) are discouraged + if(tgtcard.assignment == "Demoted" || tgtcard.assignment == "Terminated") + jobs_to_formats["Custom"] = "grey" return jobs_to_formats -/datum/controller/subsystem/jobs/proc/log_job_transfer(transferee, oldvalue, newvalue, whodidit) - id_change_records["[id_change_counter]"] = list("transferee" = transferee, "oldvalue" = oldvalue, "newvalue" = newvalue, "whodidit" = whodidit, "timestamp" = station_time_timestamp()) + +/datum/controller/subsystem/jobs/proc/log_job_transfer(transferee, oldvalue, newvalue, whodidit, reason) + id_change_records["[id_change_counter]"] = list( + "transferee" = transferee, + "oldvalue" = oldvalue, + "newvalue" = newvalue, + "whodidit" = whodidit, + "timestamp" = station_time_timestamp(), + "reason" = reason + ) id_change_counter++ /datum/controller/subsystem/jobs/proc/slot_job_transfer(oldtitle, newtitle) @@ -663,45 +675,35 @@ SUBSYSTEM_DEF(jobs) return var/datum/data/pda/app/messenger/PM = target_pda.find_program(/datum/data/pda/app/messenger) if(PM && PM.can_receive()) - PM.notify("Automated Notification: \"[antext]\" (Unable to Reply)") + PM.notify("Automated Notification: \"[antext]\" (Unable to Reply)", 0) // the 0 means don't make the PDA flash +/datum/controller/subsystem/jobs/proc/notify_by_name(target_name, antext) + // Used to notify a specific crew member based on their real_name + if(!target_name || !antext) + return + var/obj/item/pda/target_pda + for(var/obj/item/pda/check_pda in GLOB.PDAs) + if(check_pda.owner == target_name) + target_pda = check_pda + break + if(!target_pda) + return + var/datum/data/pda/app/messenger/PM = target_pda.find_program(/datum/data/pda/app/messenger) + if(PM && PM.can_receive()) + PM.notify("Automated Notification: \"[antext]\" (Unable to Reply)", 0) // the 0 means don't make the PDA flash -/datum/controller/subsystem/jobs/proc/fetch_transfer_record_html(var/centcom) - var/record_html = "" - - var/table_headers = list("Crewman", "Old Rank", "New Rank", "Authorized By", "Time") - var/hidden_fields = list("deletedby") - if(centcom) - table_headers += "Deleted By" - record_html += "" - for(var/thisheader in table_headers) - record_html += "" - record_html += "" - - var/visible_record_count = 0 +/datum/controller/subsystem/jobs/proc/format_job_change_records(centcom) + var/list/formatted = list() for(var/thisid in id_change_records) var/thisrecord = id_change_records[thisid] - if(thisrecord["deletedby"] && !centcom) continue - - record_html += "" + var/list/newlist = list() for(var/lkey in thisrecord) - if(lkey in hidden_fields) - if(centcom) - record_html += "" - else - continue - else - record_html += "" - record_html += "" - visible_record_count++ + newlist[lkey] = thisrecord[lkey] + formatted.Add(list(newlist)) + return formatted - record_html += "
[thisheader]
[thisrecord[lkey]][thisrecord[lkey]]
" - - if(!visible_record_count) - return "No records on file yet." - return record_html /datum/controller/subsystem/jobs/proc/delete_log_records(sourceuser, delete_all) . = 0 diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 9135f62b03f..1e3c8aca0d9 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -34,7 +34,7 @@ SUBSYSTEM_DEF(parallax) for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc); if(A != C.movingmob) - if(C.movingmob != null) + if(C.movingmob != null && C.movingmob.client_mobs_in_contents) C.movingmob.client_mobs_in_contents -= C.mob UNSETEMPTY(C.movingmob.client_mobs_in_contents) LAZYINITLIST(A.client_mobs_in_contents) diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index 08fa7709320..67b6a1b8dd7 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -93,6 +93,11 @@ SUBSYSTEM_DEF(shuttle) return S WARNING("couldn't find dock with id: [id]") +/datum/controller/subsystem/shuttle/proc/secondsToRefuel() + var/elapsed = world.time - SSticker.round_start_time + var/remaining = round((config.shuttle_refuel_delay - elapsed) / 10) + return remaining > 0 ? remaining : 0 + /datum/controller/subsystem/shuttle/proc/requestEvac(mob/user, call_reason) if(!emergency) WARNING("requestEvac(): There is no emergency shuttle, but the shuttle was called. Using the backup shuttle instead.") @@ -107,7 +112,7 @@ SUBSYSTEM_DEF(shuttle) return emergency = backup_shuttle - if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay) + if(secondsToRefuel()) to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again.") return @@ -131,7 +136,7 @@ SUBSYSTEM_DEF(shuttle) call_reason = trim(html_encode(call_reason)) if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH) - to_chat(user, "You must provide a reason.") + to_chat(user, "Reason is too short. [CALL_SHUTTLE_REASON_LENGTH] character minimum.") return var/area/signal_origin = get_area(user) @@ -192,7 +197,7 @@ SUBSYSTEM_DEF(shuttle) var/obj/machinery/computer/communications/C = thing if(C.stat & BROKEN) continue - else if(istype(thing, /datum/computer_file/program/comm) || istype(thing, /obj/item/circuitboard/communications)) + else if(istype(thing, /obj/item/circuitboard/communications)) continue var/turf/T = get_turf(thing) diff --git a/code/datums/action.dm b/code/datums/action.dm index 11ab496d386..1a146467b5a 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -450,6 +450,7 @@ /datum/action/spell_action check_flags = 0 background_icon_state = "bg_spell" + var/recharge_text_color = "#FFFFFF" /datum/action/spell_action/New(Target) ..() @@ -487,6 +488,18 @@ return spell.can_cast(owner) return 0 +/datum/action/spell_action/UpdateButtonIcon() + if(button && !(. = ..())) + var/obj/effect/proc_holder/spell/S = target + if(!istype(S)) + return + var/progress = S.get_availability_percentage() + var/col_val_high = 72 * progress + 128 + var/col_val_low = 200 * progress + button.maptext = "
[round_down(progress * 100)]%
" + button.color = rgb(col_val_high, col_val_low, col_val_low, col_val_high) + else + button.maptext = null /* /datum/action/spell_action/alien diff --git a/code/datums/cache/air_alarm.dm b/code/datums/cache/air_alarm.dm index 2edc0792a34..fd9e529d70a 100644 --- a/code/datums/cache/air_alarm.dm +++ b/code/datums/cache/air_alarm.dm @@ -1,3 +1,5 @@ +#define AIR_ALARM_DATA_CACHE_DURATION 10 SECONDS + GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new()) /datum/repository/air_alarm/proc/air_alarm_data(var/list/monitored_alarms, var/refresh = 0, var/obj/machinery/alarm/passed_alarm) @@ -8,7 +10,7 @@ GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new()) cache_entry = new/datum/cache_entry cache_data = cache_entry - if(!refresh) + if(!refresh && cache_entry.timestamp + AIR_ALARM_DATA_CACHE_DURATION > world.time) return cache_entry.data if(SSticker && SSticker.current_state < GAME_STATE_PLAYING && istype(passed_alarm)) // Generating the list for the first time as the game hasn't started - no need to run through the machines list everything every time @@ -29,3 +31,5 @@ GLOBAL_DATUM_INIT(air_alarm_repository, /datum/repository/air_alarm, new()) /datum/repository/air_alarm/proc/update_cache(var/obj/machinery/alarm/alarm) return air_alarm_data(refresh = 1, passed_alarm = alarm) + +#undef AIR_ALARM_DATA_CACHE_DURATION diff --git a/code/datums/cache/crew.dm b/code/datums/cache/crew.dm index f92bab9cf7a..84308dd4262 100644 --- a/code/datums/cache/crew.dm +++ b/code/datums/cache/crew.dm @@ -1,5 +1,8 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new()) +/datum/repository/crew + var/static/list/bold_jobs + /datum/repository/crew/New() cache_data = list() ..() @@ -18,6 +21,13 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new()) if(world.time < cache_entry.timestamp) return cache_entry.data + // Initialize the jobs here because in New(), GLOB.command_positions may not be inited yet + if(!bold_jobs) + bold_jobs = list() + bold_jobs += GLOB.command_positions + bold_jobs += get_all_centcom_jobs() + bold_jobs += list("Nanotrasen Representative", "Blueshield", "Magistrate") + for(var/thing in GLOB.human_list) var/mob/living/carbon/human/H = thing var/obj/item/clothing/under/C = H.w_uniform @@ -32,11 +42,13 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new()) crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown") crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job") crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") + crewmemberData["is_command"] = (crewmemberData["assignment"] in bold_jobs) if(C.sensor_mode >= SUIT_SENSOR_BINARY) - crewmemberData["dead"] = H.stat > UNCONSCIOUS + crewmemberData["dead"] = H.stat == DEAD if(C.sensor_mode >= SUIT_SENSOR_VITAL) + crewmemberData["stat"] = H.stat crewmemberData["oxy"] = round(H.getOxyLoss(), 1) crewmemberData["tox"] = round(H.getToxLoss(), 1) crewmemberData["fire"] = round(H.getFireLoss(), 1) diff --git a/code/datums/components/ducttape.dm b/code/datums/components/ducttape.dm index 49931db8edc..b41066d375d 100644 --- a/code/datums/components/ducttape.dm +++ b/code/datums/components/ducttape.dm @@ -47,23 +47,30 @@ return if(!isturf(target)) return - if(!user.unEquip(I)) - return var/turf/source_turf = get_turf(I) var/turf/target_turf = target - var/list/clickparams = params2list(params) - var/x_offset = text2num(clickparams["icon-x"]) - 16 - var/y_offset = text2num(clickparams["icon-y"]) - 16 + var/x_offset + var/y_offset if(target_turf != get_turf(I)) //Trying to stick it on a wall, don't move it to the actual wall or you can move the item through it. Instead set the pixels as appropriate var/target_direction = get_dir(source_turf, target_turf)//The direction we clicked + // Snowflake diagonal handling + if(target_direction in GLOB.diagonals) + to_chat(user, "You cant reach [target_turf].") + return if(target_direction & EAST) - x_offset += 32 + x_offset = 16 + y_offset = rand(-12, 12) else if(target_direction & WEST) - x_offset -= 32 - if(target_direction & NORTH) - y_offset += 32 + x_offset = -16 + y_offset = rand(-12, 12) + else if(target_direction & NORTH) + x_offset = rand(-12, 12) + y_offset = 16 else if(target_direction & SOUTH) - y_offset -= 32 + x_offset = rand(-12, 12) + y_offset = -16 + if(!user.unEquip(I)) + return to_chat(user, "You stick [I] to [target_turf].") I.pixel_x = x_offset I.pixel_y = y_offset diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index 3bf109eabd9..14705ae7375 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -191,6 +191,10 @@ ..() desc = "That's Definitely Not [M.real_name]." +/datum/dog_fashion/head/cone + name = "REAL_NAME" + desc = "Omnicone's Chosen Champion" + /datum/dog_fashion/back/hardsuit name = "Space Explorer REAL_NAME" desc = "That's one small step for a corgi. One giant yap for corgikind." @@ -200,3 +204,7 @@ D.mutations.Add(BREATHLESS) D.atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) D.minbodytemp = 0 + +/datum/dog_fashion/head/fried_vox_empty + name = "Colonel REAL_NAME" + desc = "Keep away from live vox." diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 4e20d2a675e..4609075ddd7 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -152,13 +152,11 @@ return doTeleport() return 0 -/datum/teleport/instant //teleports when datum is created - - start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) - if(..()) - if(teleport()) - return 1 - return 0 +/datum/teleport/instant/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null) + if(..()) + if(teleport()) + return 1 + return 0 /datum/teleport/instant/science diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0c992bbb32c..53230d1f83d 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -35,6 +35,7 @@ var/list/restricted_roles = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. + var/datum/martial_art/martial_art var/role_alt_title @@ -914,7 +915,7 @@ log_admin("[key_name(usr)] has equipped [key_name(current)] as a wizard") message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a wizard") if("name") - SSticker.mode.name_wizard(current) + INVOKE_ASYNC(SSticker.mode, /datum/game_mode/wizard.proc/name_wizard, current) log_admin("[key_name(usr)] has allowed wizard [key_name(current)] to name themselves") message_admins("[key_name_admin(usr)] has allowed wizard [key_name_admin(current)] to name themselves") if("autoobjectives") @@ -1102,8 +1103,8 @@ special_role = null to_chat(current,"Your infernal link has been severed! You are no longer a devil!") RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt) - RemoveSpell(/obj/effect/proc_holder/spell/fireball/hellish) - RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract) + RemoveSpell(/obj/effect/proc_holder/spell/targeted/click/fireball/hellish) + RemoveSpell(/obj/effect/proc_holder/spell/targeted/click/summon_contract) RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork) RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/greater) RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/ascended) @@ -1501,7 +1502,7 @@ SSticker.mode.equip_wizard(current) for(var/obj/item/spellbook/S in current.contents) S.op = 0 - SSticker.mode.name_wizard(current) + INVOKE_ASYNC(SSticker.mode, /datum/game_mode/wizard.proc/name_wizard, current) SSticker.mode.forge_wizard_objectives(src) SSticker.mode.greet_wizard(src) SSticker.mode.update_wiz_icons_added(src) diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index 2b48d5da5f7..d5be5f50f35 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -242,7 +242,7 @@ /obj/item/organ/internal/cyberimp/eyes/shield, /obj/item/organ/internal/cyberimp/eyes/hud/security, /obj/item/organ/internal/cyberimp/eyes/xray, - /obj/item/organ/internal/cyberimp/brain/anti_stun, + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/arm/combat/centcom ) diff --git a/code/datums/pipe_datums.dm b/code/datums/pipe_datums.dm index 83b77425447..8d3b0807f9c 100644 --- a/code/datums/pipe_datums.dm +++ b/code/datums/pipe_datums.dm @@ -351,16 +351,6 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable pipe_id = PIPE_CIRCULATOR pipe_icon = "circ" -/datum/pipes/atmospheric/omni_filter - pipe_name = "omni filter" - pipe_id = PIPE_OMNI_FILTER - pipe_icon = "omni_filter" - -/datum/pipes/atmospheric/omni_mixer - pipe_name = "omni mixer" - pipe_id = PIPE_OMNI_MIXER - pipe_icon = "omni_mixer" - /datum/pipes/atmospheric/insulated pipe_name = "insulated pipe" pipe_id = PIPE_INSULATED_STRAIGHT diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index f826b6ff0d2..2143fb5ad5c 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -16,7 +16,7 @@ name = "Biodome Winter" id = "biodome-winter" description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \ - Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)." + Includes the recently introduced I.C.E(tm)." suffix = "lavaland_biodome_winter.dmm" /datum/map_template/ruin/lavaland/biodome/clown @@ -42,7 +42,7 @@ cost = 10 allow_duplicates = FALSE -datum/map_template/ruin/lavaland/ash_walker +/datum/map_template/ruin/lavaland/ash_walker name = "Ash Walker Nest" id = "ash-walker" description = "A race of unbreathing lizards live here, that run faster than a human can, worship a broken dead city, and are capable of reproducing by something involving tentacles? \ diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm index a651edbc79c..a196a60fcc5 100644 --- a/code/datums/spawners_menu.dm +++ b/code/datums/spawners_menu.dm @@ -6,44 +6,47 @@ qdel(src) owner = new_owner -/datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = FALSE, datum/topic_state/state = GLOB.ghost_state, datum/nanoui/master_ui = null) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/datum/spawners_menu/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui_state/state = GLOB.tgui_observer_state, datum/tgui/master_ui = null) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "spawners_menu.tmpl", "Spawners Menu", 700, 600, master_ui, state = state) + ui = new(user, src, ui_key, "SpawnersMenu", "Spawners Menu", 700, 600, master_ui, state = state) ui.open() -/datum/spawners_menu/ui_data(mob/user) +/datum/spawners_menu/tgui_data(mob/user) var/list/data = list() data["spawners"] = list() for(var/spawner in GLOB.mob_spawners) var/list/this = list() this["name"] = spawner this["desc"] = "" + this["important_info"] = "" + this["fluff"] = "" this["uids"] = list() - for(var/spawner_obj in GLOB.mob_spawners[spawner]) + for(var/spawner_obj in GLOB.mob_spawners[spawner])//each spawner can contain multiple actual spawners, we use only one desc/info this["uids"] += "\ref[spawner_obj]" - if(!this["desc"]) + if(!this["desc"]) //haven't set descriptions yet if(istype(spawner_obj, /obj/effect/mob_spawn)) var/obj/effect/mob_spawn/MS = spawner_obj - this["desc"] = MS.flavour_text + this["desc"] = MS.description + this["important_info"] = MS.important_info + this["fluff"] = MS.flavour_text else var/obj/O = spawner_obj this["desc"] = O.desc this["amount_left"] = LAZYLEN(GLOB.mob_spawners[spawner]) data["spawners"] += list(this) - return data -/datum/spawners_menu/Topic(href, href_list) +/datum/spawners_menu/tgui_act(action, params) if(..()) - return 1 - var/spawners = replacetext(href_list["uid"], ",", ";") + return + var/spawners = replacetext(params["ID"], ",", ";") var/list/possible_spawners = params2list(spawners) var/obj/effect/mob_spawn/MS = locate(pick(possible_spawners)) if(!MS || !istype(MS)) log_runtime(EXCEPTION("A ghost tried to interact with an invalid spawner, or the spawner didn't exist.")) return - switch(href_list["action"]) + switch(action) if("jump") owner.forceMove(get_turf(MS)) . = TRUE diff --git a/code/datums/spell.dm b/code/datums/spell.dm index cb10700e5c6..abb9fdc37c9 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -24,6 +24,20 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) user.face_atom(A) return FALSE +/datum/click_intercept/proc_holder + var/obj/effect/proc_holder/spell + +/datum/click_intercept/proc_holder/New(client/C, obj/effect/proc_holder/spell_to_cast) + . = ..() + spell = spell_to_cast + +/datum/click_intercept/proc_holder/InterceptClickOn(user, params, atom/object) + spell.InterceptClickOn(user, params, object) + +/datum/click_intercept/proc_holder/quit() + spell.remove_ranged_ability(spell.ranged_ability_user) + return ..() + /obj/effect/proc_holder/proc/add_ranged_ability(mob/living/user, var/msg) if(!user || !user.client) return @@ -32,7 +46,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) user.ranged_ability.remove_ranged_ability(user) user.ranged_ability = src ranged_ability_user = user - user.client.click_intercept = user.ranged_ability + user.client.click_intercept = new /datum/click_intercept/proc_holder(user.client, user.ranged_ability) add_mousepointer(user.client) active = TRUE if(msg) @@ -48,15 +62,17 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) C.mouse_pointer_icon = initial(C.mouse_pointer_icon) /obj/effect/proc_holder/proc/remove_ranged_ability(mob/living/user, var/msg) - if(!user || !user.client || (user.ranged_ability && user.ranged_ability != src)) //To avoid removing the wrong ability + if(!user || (user.ranged_ability && user.ranged_ability != src)) //To avoid removing the wrong ability return user.ranged_ability = null ranged_ability_user = null - user.client.click_intercept = null - remove_mousepointer(user.client) active = FALSE - if(msg) - to_chat(user, msg) + if(user.client) + qdel(user.client.click_intercept) + user.client.click_intercept = null + remove_mousepointer(user.client) + if(msg) + to_chat(user, msg) update_icon() /obj/effect/proc_holder/spell @@ -114,10 +130,14 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) var/sound = null //The sound the spell makes when it is cast -/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0, mob/living/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell - if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list)) - to_chat(user, "You shouldn't have this spell! Something's wrong.") - return 0 +/* Checks if the user can cast the spell + * @param charge_check If the proc should do the cooldown check + * @param start_recharge If the proc should set the cooldown + * @param user The caster of the spell +*/ +/obj/effect/proc_holder/spell/proc/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/living/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell + if(!can_cast(user, charge_check, TRUE)) + return FALSE if(ishuman(user)) var/mob/living/carbon/human/caster = user @@ -126,49 +146,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) caster.reset_perspective(0) return 0 - if(is_admin_level(user.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel - return 0 - - if(!skipcharge) - switch(charge_type) - if("recharge") - if(charge_counter < charge_max) - to_chat(user, still_recharging_msg) - return 0 - if("charges") - if(!charge_counter) - to_chat(user, "[name] has no charges left.") - return 0 - - if(!ghost) - if(user.stat && !stat_allowed) - to_chat(user, "You can't cast this spell while incapacitated.") - return 0 - if(ishuman(user) && (invocation_type == "whisper" || invocation_type == "shout") && user.is_muzzled()) - to_chat(user, "Mmmf mrrfff!") - return 0 - - var/obj/effect/proc_holder/spell/noclothes/clothes_spell = locate() in (user.mob_spell_list | (user.mind ? user.mind.spell_list : list())) - if((ishuman(user) && clothes_req) && !istype(clothes_spell))//clothes check - var/mob/living/carbon/human/H = user - var/obj/item/clothing/robe = H.wear_suit - var/obj/item/clothing/hat = H.head - var/obj/item/clothing/shoes = H.shoes - if(!robe || !hat || !shoes) - to_chat(user, "Your outfit isn't complete, you should put on your robe and wizard hat, as well as sandals.") - return 0 - if(!robe.magical || !hat.magical || !shoes.magical) - to_chat(user, "Your outfit isn't magical enough, you should put on your robe and wizard hat, as well as your sandals.") - return 0 - else if(!ishuman(user)) - if(clothes_req || human_req) - to_chat(user, "This spell can only be cast by humans!") - return 0 - if(nonabstract_req && (isbrain(user) || ispAI(user))) - to_chat(user, "This spell can only be cast by physical beings!") - return 0 - - if(!skipcharge) + if(start_recharge) switch(charge_type) if("recharge") charge_counter = 0 //doesn't start recharging until the targets selecting ends @@ -230,12 +208,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) /obj/effect/proc_holder/spell/process() charge_counter += 2 + if(action) + action.UpdateButtonIcon() if(charge_counter < charge_max) return STOP_PROCESSING(SSfastprocess, src) charge_counter = charge_max - if(action) - action.UpdateButtonIcon() /obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr, make_attack_logs = TRUE) //if recharge is started is important for the trigger spells before_cast(targets) @@ -339,6 +317,19 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars return +/obj/effect/proc_holder/spell/proc/get_availability_percentage() + switch(charge_type) + if("recharge") + if(charge_counter == 0) + return 0 + return charge_counter / charge_max + if("charges") + if(charge_counter) + return 1 + return 0 + if("holdervar") + return 1 + /obj/effect/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast @@ -429,6 +420,100 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) return +/obj/effect/proc_holder/spell/targeted/click + var/click_radius = 1 // How big the radius around the clicked atom is to find a suitable target. -1 is only the selected atom is considered + var/selection_activated_message = "Click on a target to cast the spell." + var/selection_deactivated_message = "You choose to not cast this spell." + var/allowed_type = /mob/living // Which type the targets have to be + var/auto_target_single = TRUE // If the spell should auto select a target if only one is found + +/obj/effect/proc_holder/spell/targeted/click/Click() + var/mob/living/user = usr + if(!istype(user)) + return + + if(active) + remove_ranged_ability(user, selection_deactivated_message) + else + if(cast_check(TRUE, FALSE, user)) + if(auto_target_single && attempt_auto_target(user)) + return + + add_ranged_ability(user, selection_activated_message) + else + to_chat(user, "[src] is not ready to be used yet.") + +/obj/effect/proc_holder/spell/targeted/click/proc/attempt_auto_target(mob/user) + var/atom/target + for(var/atom/A in view_or_range(range, user, selection_type)) + if(valid_target(A, user)) + if(target) + return FALSE // Two targets found. ABORT + target = A + + if(target && cast_check(TRUE, TRUE, user)) // Singular target found. Cast it instantly + to_chat(user, "Only one target found. Casting [src] on [target]!") + perform(list(target), user = user) + return TRUE + return FALSE + +/obj/effect/proc_holder/spell/targeted/click/InterceptClickOn(mob/living/user, params, atom/A) + if(..() || !cast_check(TRUE, TRUE, user)) + remove_ranged_ability(user) + revert_cast(user) + return TRUE + + var/list/targets = list() + if(valid_target(A, user)) + targets.Add(A) + + if((!max_targets || max_targets > targets.len) && click_radius >= 0) + var/list/found_others = list() + for(var/atom/target in range(click_radius, A)) + if(valid_target(target, user)) + found_others |= target + if(!max_targets) + targets.Add(found_others) + else + if(max_targets <= found_others.len + targets.len) + targets.Add(found_others) + else + switch(random_target_priority) //Add in the rest + if(TARGET_RANDOM) + while(targets.len < max_targets && found_others.len) // Add the others + targets.Add(pick_n_take(found_others)) + if(TARGET_CLOSEST) + var/list/distances = list() + for(var/target in found_others) + distances[target] = get_dist(user, target) + sortTim(distances, /proc/cmp_numeric_asc, TRUE) // Sort on distance + for(var/target in distances) + targets.Add(target) + if(targets.len >= max_targets) + break + + + if(!targets.len) + to_chat(user, "No suitable target found.") + revert_cast(user) + return FALSE + + perform(targets, user = user) + remove_ranged_ability(user) + return TRUE + +/* Checks if a target is valid + * Should not include to_chats or other types of messages since this is used often on tons of targets. + * @param target The target to check + * @param user The user of the spell +*/ +/obj/effect/proc_holder/spell/targeted/click/proc/valid_target(target, user) + return istype(target, allowed_type) && (include_user || target != user) && \ + (target in view_or_range(range, user, selection_type)) + +/obj/effect/proc_holder/spell/targeted/click/choose_targets(mob/living/user, atom/A) // Not used + return + /obj/effect/proc_holder/spell/aoe_turf/choose_targets(mob/user = usr) var/list/targets = list() @@ -462,30 +547,39 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) qdel(dummy) return 1 -/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr) +/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list)) + if(show_message) + to_chat(user, "You shouldn't have this spell! Something's wrong.") return 0 if(is_admin_level(user.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel return 0 - switch(charge_type) - if("recharge") - if(charge_counter < charge_max) - return 0 - if("charges") - if(!charge_counter) - return 0 - - if(user.stat && !stat_allowed) - return 0 + if(charge_check) + switch(charge_type) + if("recharge") + if(charge_counter < charge_max) + if(show_message) + to_chat(user, still_recharging_msg) + return 0 + if("charges") + if(!charge_counter) + if(show_message) + to_chat(user, "[name] has no charges left.") + return 0 + if(!ghost) + if(user.stat && !stat_allowed) + if(show_message) + to_chat(user, "You can't cast this spell while incapacitated.") + return 0 + if(ishuman(user) && (invocation_type == "whisper" || invocation_type == "shout") && user.is_muzzled()) + if(show_message) + to_chat(user, "Mmmf mrrfff!") + return 0 if(ishuman(user)) var/mob/living/carbon/human/H = user - - if((invocation_type == "whisper" || invocation_type == "shout") && H.is_muzzled()) - return 0 - var/clothcheck = locate(/obj/effect/proc_holder/spell/noclothes) in user.mob_spell_list var/clothcheck2 = user.mind && (locate(/obj/effect/proc_holder/spell/noclothes) in user.mind.spell_list) if(clothes_req && !clothcheck && !clothcheck2) //clothes check @@ -493,12 +587,20 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) var/obj/item/clothing/hat = H.head var/obj/item/clothing/shoes = H.shoes if(!robe || !hat || !shoes) + if(show_message) + to_chat(user, "Your outfit isn't complete, you should put on your robe and wizard hat, as well as sandals.") return 0 if(!robe.magical || !hat.magical || !shoes.magical) + if(show_message) + to_chat(user, "Your outfit isn't magical enough, you should put on your robe and wizard hat, as well as your sandals.") return 0 else if(clothes_req || human_req) + if(show_message) + to_chat(user, "This spell can only be cast by humans!") return 0 if(nonabstract_req && (isbrain(user) || ispAI(user))) + if(show_message) + to_chat(user, "This spell can only be cast by physical beings!") return 0 return 1 diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 0d24a984014..5986da3a412 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -11,7 +11,7 @@ /obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1, mob/living/user = usr) var/thearea = before_cast(targets) - if(!thearea || !cast_check(1)) + if(!thearea || !cast_check(TRUE, FALSE, user)) revert_cast() return invocation(thearea) diff --git a/code/datums/spells/chaplain.dm b/code/datums/spells/chaplain.dm index bdb7bb3f551..f16a2a3fbac 100644 --- a/code/datums/spells/chaplain.dm +++ b/code/datums/spells/chaplain.dm @@ -1,25 +1,31 @@ -/obj/effect/proc_holder/spell/targeted/chaplain_bless +/obj/effect/proc_holder/spell/targeted/click/chaplain_bless name = "Bless" desc = "Blesses a single person." school = "transmutation" charge_max = 60 - clothes_req = 0 + clothes_req = FALSE invocation = "none" invocation_type = "none" max_targets = 1 - include_user = 0 - humans_only = 1 - + include_user = FALSE + allowed_type = /mob/living/carbon/human + selection_activated_message = "You prepare a blessing. Click on a target to start blessing." + selection_deactivated_message = "The crew will be blessed another time." range = 1 + click_radius = -1 // Only precision clicking cooldown_min = 20 action_icon_state = "shield" +/obj/effect/proc_holder/spell/targeted/click/chaplain_bless/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE -/obj/effect/proc_holder/spell/targeted/chaplain_bless/cast(list/targets, mob/living/user = usr, distanceoverride) + return target.mind && target.ckey && !target.stat +/obj/effect/proc_holder/spell/targeted/click/chaplain_bless/cast(list/targets, mob/living/user = usr) if(!istype(user)) to_chat(user, "Somehow, you are not a living mob. This should never happen. Report this bug.") revert_cast() @@ -35,32 +41,7 @@ revert_cast() return - var/mob/living/carbon/human/target = targets[range] - - if(!istype(target)) - to_chat(user, "No target.") - revert_cast() - return - - if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it. - to_chat(user, "[target] is too far away!") - revert_cast() - return - - if(!target.mind) - to_chat(user, "[target] appears to be catatonic. Your blessing would have no effect.") - revert_cast() - return - - if(!target.ckey) - to_chat(user, "[target] appears to be too out of it to benefit from this.") - revert_cast() - return - - if(target.stat == DEAD) - to_chat(user, "[target] is already dead. There is no point.") - revert_cast() - return + var/mob/living/carbon/human/target = targets[1] spawn(0) // allows cast to complete even if recipient ignores the prompt if(alert(target, "[user] wants to bless you, in the name of [user.p_their()] religion. Accept?", "Accept Blessing?", "Yes", "No") == "Yes") // prevents forced conversions diff --git a/code/datums/spells/devil.dm b/code/datums/spells/devil.dm index 27b2fcb8851..f9e075bdf81 100644 --- a/code/datums/spells/devil.dm +++ b/code/datums/spells/devil.dm @@ -21,13 +21,18 @@ action_background_icon_state = "bg_demon" -/obj/effect/proc_holder/spell/targeted/summon_contract +/obj/effect/proc_holder/spell/targeted/click/summon_contract name = "Summon infernal contract" desc = "Skip making a contract by hand, just do it by magic." invocation_type = "whisper" invocation = "Just sign on the dotted line." - include_user = 0 + selection_activated_message = "You prepare a detailed contract. Click on a target to summon the contract in his hands." + selection_deactivated_message = "You archive the contract for later use." + include_user = FALSE range = 5 + auto_target_single = FALSE // Prevent an accidental contract from summoning + click_radius = -1 // Precision clicking required + allowed_type = /mob/living/carbon clothes_req = FALSE school = "conjuration" charge_max = 150 @@ -35,8 +40,9 @@ action_icon_state = "spell_default" action_background_icon_state = "bg_demon" -/obj/effect/proc_holder/spell/targeted/summon_contract/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/C in targets) +/obj/effect/proc_holder/spell/targeted/click/summon_contract/cast(list/targets, mob/user = usr) + for(var/target in targets) + var/mob/living/carbon/C = target if(C.mind && user.mind) if(C.stat == DEAD) if(user.drop_item()) @@ -63,7 +69,7 @@ to_chat(user,"[C] seems to not be sentient. You are unable to summon a contract for them.") -/obj/effect/proc_holder/spell/fireball/hellish +/obj/effect/proc_holder/spell/targeted/click/fireball/hellish name = "Hellfire" desc = "This spell launches hellfire at the target." school = "evocation" @@ -74,8 +80,8 @@ fireball_type = /obj/item/projectile/magic/fireball/infernal action_background_icon_state = "bg_demon" -/obj/effect/proc_holder/spell/fireball/hellish/cast(list/targets, mob/living/user = usr) - msg_admin_attack("[key_name_admin(usr)] has fired a fireball.", ATKLOG_FEW) +/obj/effect/proc_holder/spell/targeted/click/fireball/hellish/cast(list/targets, mob/living/user = usr) + add_attack_logs(user, targets, "has fired a Hellfire ball", ATKLOG_FEW) .=..() diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 0140fbdf951..d5f686fb763 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -1,39 +1,31 @@ -/obj/effect/proc_holder/spell/targeted/horsemask +/obj/effect/proc_holder/spell/targeted/click/horsemask name = "Curse of the Horseman" desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes." school = "transmutation" charge_type = "recharge" charge_max = 150 charge_counter = 0 - clothes_req = 0 - stat_allowed = 0 + clothes_req = FALSE + stat_allowed = FALSE invocation = "KN'A FTAGHU, PUCK 'BTHNK!" invocation_type = "shout" range = 7 cooldown_min = 30 //30 deciseconds reduction per rank selection_type = "range" + selection_activated_message = "You start to quietly neigh an incantation. Click on or near a target to cast the spell." + selection_deactivated_message = "You stop neighing to yourself." + allowed_type = /mob/living/carbon/human + action_icon_state = "barn" sound = 'sound/magic/HorseHead_curse.ogg' -/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) +/obj/effect/proc_holder/spell/targeted/click/horsemask/cast(list/targets, mob/user = usr) if(!targets.len) to_chat(user, "No target found in range.") return - var/mob/living/carbon/target = targets[1] - - if(!target) - return - - - if(!ishuman(target)) - to_chat(user, "It'd be stupid to curse [target] with a horse's head!") - return - - if(!(target in oview(range)))//If they are not in overview after selection. - to_chat(user, "They are too far away!") - return + var/mob/living/carbon/human/target = targets[1] var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead magichead.flags |= NODROP | DROPDEL //curses! diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm index e7821aed6c2..20cd8dccdf5 100644 --- a/code/datums/spells/lightning.dm +++ b/code/datums/spells/lightning.dm @@ -25,10 +25,10 @@ /obj/effect/proc_holder/spell/targeted/lightning/Click() if(!ready && start_time == 0) - if(cast_check()) + if(cast_check(TRUE, FALSE, usr)) StartChargeup() else - if(ready && cast_check(skipcharge=1)) + if(ready && cast_check(TRUE, TRUE, usr)) choose_targets() return 1 @@ -44,7 +44,7 @@ if(ready) Discharge() -obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) +/obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) ready = 0 start_time = 0 if(halo) diff --git a/code/datums/spells/magnet.dm b/code/datums/spells/magnet.dm index fea6780085c..155a3cb0b45 100644 --- a/code/datums/spells/magnet.dm +++ b/code/datums/spells/magnet.dm @@ -20,10 +20,10 @@ /obj/effect/proc_holder/spell/targeted/magnet/Click() if(!ready && start_time == 0) - if(cast_check()) + if(cast_check(TRUE, FALSE, usr)) StartChargeup() else - if(ready && cast_check(skipcharge=1)) + if(ready && cast_check(TRUE, TRUE, usr)) choose_targets() return 1 @@ -39,7 +39,7 @@ if(ready) Discharge() -obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr) +/obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr) ready = 0 energy = 0 start_time = 0 diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm index 3d9031a8e03..e4924ee1c2f 100644 --- a/code/datums/spells/mind_transfer.dm +++ b/code/datums/spells/mind_transfer.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/targeted/mind_transfer +/obj/effect/proc_holder/spell/targeted/click/mind_transfer name = "Mind Transfer" desc = "This spell allows the user to switch bodies with a target." @@ -8,33 +8,29 @@ invocation = "GIN'YU CAPAN" invocation_type = "whisper" range = 1 + click_radius = 0 // Still gotta be pretty accurate + selection_activated_message = "You prepare to transfer your mind. Click on a target to cast the spell." + selection_deactivated_message = "You decide that your current form is good enough." cooldown_min = 200 //100 deciseconds reduction per rank var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell var/paralysis_amount_caster = 20 //how much the caster is paralysed for after the spell var/paralysis_amount_victim = 20 //how much the victim is paralysed for after the spell action_icon_state = "mindswap" +/obj/effect/proc_holder/spell/targeted/click/mind_transfer/valid_target(mob/living/target, user) + if(!..()) + return FALSE + return target.stat != DEAD && target.key && target.mind + /* Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do. Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering. Also, you never added distance checking after target is selected. I've went ahead and did that. */ -/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/user = usr, distanceoverride) +/obj/effect/proc_holder/spell/targeted/click/mind_transfer/cast(list/targets, mob/user = usr) var/mob/living/target = targets[range] - if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it. - to_chat(user, "They are too far away!") - return - - if(target.stat == DEAD) - to_chat(user, "You don't particularly want to be dead.") - return - - if(!target.key || !target.mind) - to_chat(user, "[target.p_they(TRUE)] appear[target.p_s()] to be catatonic. Not even magic can affect [target.p_their()] vacant mind.") - return - if(user.suiciding) to_chat(user, "You're killing yourself! You can't concentrate enough to do this!") return diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 94383f1b1e2..a99655222a4 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -308,76 +308,50 @@ duration = 300 sound = 'sound/magic/blind.ogg' -/obj/effect/proc_holder/spell/fireball +/obj/effect/proc_holder/spell/targeted/click/fireball name = "Fireball" desc = "This spell fires a fireball at a target and does not require wizard garb." school = "evocation" charge_max = 60 - clothes_req = 0 + clothes_req = FALSE invocation = "ONI SOMA" invocation_type = "shout" + auto_target_single = FALSE // Having this true won't ever find a single target and is just lost processing power range = 20 cooldown_min = 20 //10 deciseconds reduction per rank + + click_radius = -1 + selection_activated_message = "Your prepare to cast your fireball spell! Left-click to cast at a target!" + selection_deactivated_message = "You extinguish your fireball...for now." + allowed_type = /atom // FIRE AT EVERYTHING + var/fireball_type = /obj/item/projectile/magic/fireball action_icon_state = "fireball0" sound = 'sound/magic/fireball.ogg' active = FALSE -/obj/effect/proc_holder/spell/fireball/Click() - var/mob/living/user = usr - if(!istype(user)) - return - - var/msg - - if(!can_cast(user)) - msg = "You can no longer cast Fireball." - remove_ranged_ability(user, msg) - return - - if(active) - msg = "You extinguish your fireball...for now." - remove_ranged_ability(user, msg) - else - msg = "Your prepare to cast your fireball spell! Left-click to cast at a target!" - add_ranged_ability(user, msg) - -/obj/effect/proc_holder/spell/fireball/update_icon() +/obj/effect/proc_holder/spell/targeted/click/fireball/update_icon() if(!action) return action.button_icon_state = "fireball[active]" action.UpdateButtonIcon() -/obj/effect/proc_holder/spell/fireball/InterceptClickOn(mob/living/user, params, atom/target) - if(..()) - return FALSE - - if(!cast_check(0, user)) - remove_ranged_ability(user) - return FALSE - - var/list/targets = list(target) - perform(targets, user = user) - - return TRUE - -/obj/effect/proc_holder/spell/fireball/cast(list/targets, mob/living/user = usr) +/obj/effect/proc_holder/spell/targeted/click/fireball/cast(list/targets, mob/living/user = usr) var/target = targets[1] //There is only ever one target for fireball var/turf/T = user.loc var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction if(!isturf(U) || !isturf(T)) - return 0 + return FALSE var/obj/item/projectile/magic/fireball/FB = new fireball_type(user.loc) FB.current = get_turf(user) FB.preparePixelProjectile(target, get_turf(target), user) FB.fire() user.newtonian_move(get_dir(U, T)) - remove_ranged_ability(user) - return 1 + return TRUE /obj/effect/proc_holder/spell/aoe_turf/repulse name = "Repulse" diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index c8f2b6bb99b..0eae7ecc765 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -344,6 +344,14 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY cost = 15 containername = "tactical armor crate" +/datum/supply_packs/security/armory/webbing + name = "Webbing Crate" + contains = list(/obj/item/storage/belt/security/webbing, + /obj/item/storage/belt/security/webbing, + /obj/item/storage/belt/security/webbing) + cost = 15 + containername = "tactical webbing crate" + /datum/supply_packs/security/armory/swat name = "SWAT gear crate" contains = list(/obj/item/clothing/head/helmet/swat, @@ -980,12 +988,6 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY containername = "shield generators crate" access = ACCESS_TELEPORTER -/datum/supply_packs/science/modularpc - name = "Deluxe Silicate Selections restocking unit" - cost = 15 - contains = list(/obj/item/vending_refill/modularpc) - containername = "computer supply crate" - /datum/supply_packs/science/transfer_valves name = "Tank Transfer Valves Crate" contains = list(/obj/item/transfer_valve, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 3562cfd9d80..42f74e234a0 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -412,9 +412,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/jobspecific/energizedfireaxe name = "Energized Fire Axe" - desc = "A fire axe with a massive electrical charge built into it. It can release this charge on its first victim and will be rather plain after that." + desc = "A fire axe with a massive energy charge built into it. Upon striking someone while charged it will throw them backwards while stunning them briefly, but will take some time to charge up again. It is also much sharper than a regular axe and can pierce light armor." reference = "EFA" - item = /obj/item/twohanded/energizedfireaxe + item = /obj/item/twohanded/fireaxe/energized cost = 10 job = list("Life Support Specialist") @@ -1563,11 +1563,11 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 10 /datum/uplink_item/cyber_implants/antistun - name = "CNS Rebooter Implant" - desc = "This implant will help you get back up on your feet faster after being stunned. \ + name = "Hardened CNS Rebooter Implant" + desc = "This implant will help you get back up on your feet faster after being stunned. It is invulnerable to EMPs. \ Comes with an automated implanting tool." reference = "CIAS" - item = /obj/item/organ/internal/cyberimp/brain/anti_stun + item = /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened cost = 12 /datum/uplink_item/cyber_implants/reviver diff --git a/code/datums/wires/suitstorage.dm b/code/datums/wires/suitstorage.dm index 828e56884bf..ec651002747 100644 --- a/code/datums/wires/suitstorage.dm +++ b/code/datums/wires/suitstorage.dm @@ -17,7 +17,7 @@ . += "The green light is [A.shocked ? "on" : "off"]." . += "The UV display shows [A.uv_super ? "15 nm" : "185 nm"]." -datum/wires/suitstorage/interactable(mob/user) +/datum/wires/suitstorage/interactable(mob/user) var/obj/machinery/suit_storage_unit/A = holder if(iscarbon(user) && A.Adjacent(user) && A.shocked) return A.shock(user, 100) @@ -42,7 +42,7 @@ datum/wires/suitstorage/interactable(mob/user) A.uv_super = !mend ..() -datum/wires/suitstorage/on_pulse(wire) +/datum/wires/suitstorage/on_pulse(wire) var/obj/machinery/suit_storage_unit/A = holder if(is_cut(wire)) return diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 27d1448ac77..d2c092211ec 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -62,7 +62,7 @@ * In the `colors` list, the name of the color is the key, and the wire is the value. * For example: `colors["red"] = WIRE_ELECTRIFY`. This will look like `list("red" = WIRE_ELECTRIFY)` internally. */ -datum/wires/proc/randomize() +/datum/wires/proc/randomize() var/static/list/possible_colors = list("red", "blue", "green", "silver", "orange", "brown", "gold", "white", "cyan", "magenta", "purple", "pink") var/list/my_possible_colors = possible_colors.Copy() diff --git a/code/defines/procs/dbcore.dm b/code/defines/procs/dbcore.dm index 90a5b0db40c..945ab8af23a 100644 --- a/code/defines/procs/dbcore.dm +++ b/code/defines/procs/dbcore.dm @@ -29,7 +29,7 @@ #define BLOB 14 // TODO: Investigate more recent type additions and see if I can handle them. - Nadrew -DBConnection +/DBConnection var/_db_con // This variable contains a reference to the actual database connection. var/dbi // This variable is a string containing the DBI MySQL requires. var/user // This variable contains the username data. @@ -39,14 +39,14 @@ DBConnection var/server = "" var/port = 3306 -DBConnection/New(dbi_handler,username,password_handler,cursor_handler) +/DBConnection/New(dbi_handler,username,password_handler,cursor_handler) src.dbi = dbi_handler src.user = username src.password = password_handler src.default_cursor = cursor_handler _db_con = _dm_db_new_con() -DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler) +/DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler) if(!config.sql_enabled) return 0 if(!src) return 0 @@ -54,24 +54,24 @@ DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_han if(!cursor_handler) cursor_handler = Default_Cursor return _dm_db_connect(_db_con,dbi_handler,user_handler,password_handler,cursor_handler,null) -DBConnection/proc/Disconnect() return _dm_db_close(_db_con) +/DBConnection/proc/Disconnect() return _dm_db_close(_db_con) -DBConnection/proc/IsConnected() +/DBConnection/proc/IsConnected() if(!config.sql_enabled) return 0 var/success = _dm_db_is_connected(_db_con) return success -DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str) +/DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str) -DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con) -DBConnection/proc/SelectDB(database_name,dbi) +/DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con) +/DBConnection/proc/SelectDB(database_name,dbi) if(IsConnected()) Disconnect() //return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password) return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]",user,password) -DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler) +/DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler) -DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler) +/DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler) if(IsAdminAdvancedProcCall()) to_chat(usr, "DB query blocked: Advanced ProcCall detected.") message_admins("[key_name(usr)] attempted to create a DB query via advanced proc-call") @@ -83,12 +83,12 @@ DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler) _db_query = _dm_db_new_query() return ..() -DBQuery/CanProcCall() +/DBQuery/CanProcCall() // dont even try it return FALSE -DBQuery +/DBQuery var/sql // The sql query being executed. var/default_cursor var/list/columns //list of DB Columns populated by Columns() @@ -98,26 +98,26 @@ DBQuery var/DBConnection/db_connection var/_db_query -DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler +/DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler -DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor) +/DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor) Close() return _dm_db_execute(_db_query,sql_query,db_connection._db_con,cursor_handler,null) -DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions) +/DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions) -DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query) +/DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query) -DBQuery/proc/RowCount() return _dm_db_row_count(_db_query) +/DBQuery/proc/RowCount() return _dm_db_row_count(_db_query) -DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query) +/DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query) -DBQuery/proc/Columns() +/DBQuery/proc/Columns() if(!columns) columns = _dm_db_columns(_db_query,/DBColumn) return columns -DBQuery/proc/GetRowData() +/DBQuery/proc/GetRowData() var/list/columns = Columns() var/list/results if(columns.len) @@ -128,23 +128,23 @@ DBQuery/proc/GetRowData() results[C] = src.item[(cur_col.position+1)] return results -DBQuery/proc/Close() +/DBQuery/proc/Close() item.len = 0 columns = null conversions = null return _dm_db_close(_db_query) -DBQuery/proc/Quote(str) +/DBQuery/proc/Quote(str) return db_connection.Quote(str) -DBQuery/proc/SetConversion(column,conversion) +/DBQuery/proc/SetConversion(column,conversion) if(istext(column)) column = columns.Find(column) if(!conversions) conversions = new/list(column) else if(conversions.len < column) conversions.len = column conversions[column] = conversion -DBColumn +/DBColumn var/name var/table var/position //1-based index into item data @@ -153,7 +153,7 @@ DBColumn var/length var/max_length -DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler) +/DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler) src.name = name_handler src.table = table_handler src.position = position_handler @@ -164,7 +164,7 @@ DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handl return ..() -DBColumn/proc/SqlTypeName(type_handler=src.sql_type) +/DBColumn/proc/SqlTypeName(type_handler=src.sql_type) switch(type_handler) if(TINYINT) return "TINYINT" if(SMALLINT) return "SMALLINT" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index de913ac9f91..990e2f1694d 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -570,7 +570,7 @@ /area/proc/prison_break() for(var/obj/machinery/power/apc/temp_apc in src) - temp_apc.overload_lighting(70) + INVOKE_ASYNC(temp_apc, /obj/machinery/power/apc.proc/overload_lighting, 70) for(var/obj/machinery/door/airlock/temp_airlock in src) temp_airlock.prison_open() for(var/obj/machinery/door/window/temp_windoor in src) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 776a2bccd12..73dcd14c7c8 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -231,7 +231,7 @@ /atom/proc/on_reagent_change() return -/atom/proc/Bumped(AM as mob|obj) +/atom/proc/Bumped(atom/movable/AM) return /// Convenience proc to see if a container is open for chemistry handling @@ -257,7 +257,7 @@ /atom/proc/CheckExit() return TRUE -/atom/proc/HasProximity(atom/movable/AM as mob|obj) +/atom/proc/HasProximity(atom/movable/AM) return /atom/proc/emp_act(severity) diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index 87bbdf97c5c..77eb58e84b7 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -123,13 +123,13 @@ instability = GENE_INSTABILITY_MODERATE mutation = CRYO - spelltype = /obj/effect/proc_holder/spell/targeted/cryokinesis + spelltype = /obj/effect/proc_holder/spell/targeted/click/cryokinesis /datum/dna/gene/basic/grant_spell/cryo/New() ..() block = GLOB.cryoblock -/obj/effect/proc_holder/spell/targeted/cryokinesis +/obj/effect/proc_holder/spell/targeted/click/cryokinesis name = "Cryokinesis" desc = "Drops the bodytemperature of another person." panel = "Abilities" @@ -137,45 +137,44 @@ charge_type = "recharge" charge_max = 1200 - clothes_req = 0 - stat_allowed = 0 + clothes_req = FALSE + stat_allowed = FALSE + + click_radius = 0 + auto_target_single = FALSE // Give the clueless geneticists a way out and to have them not target themselves + selection_activated_message = "Your mind grow cold. Click on a target to cast the spell." + selection_deactivated_message = "Your mind returns to normal." + allowed_type = /mob/living/carbon invocation_type = "none" range = 7 selection_type = "range" - include_user = 1 + include_user = TRUE var/list/compatible_mobs = list(/mob/living/carbon/human) action_icon_state = "genetic_cryo" -/obj/effect/proc_holder/spell/targeted/cryokinesis/cast(list/targets, mob/user = usr) - if(!targets.len) - to_chat(user, "No target found in range.") - return +/obj/effect/proc_holder/spell/targeted/click/cryokinesis/cast(list/targets, mob/user = usr) var/mob/living/carbon/C = targets[1] - if(!iscarbon(C)) - to_chat(user, "This will only work on normal organic beings.") - return - if(COLDRES in C.mutations) C.visible_message("A cloud of fine ice crystals engulfs [C.name], but disappears almost instantly!") return - var/handle_suit = 0 + var/handle_suit = FALSE if(ishuman(C)) var/mob/living/carbon/human/H = C if(istype(H.head, /obj/item/clothing/head/helmet/space)) if(istype(H.wear_suit, /obj/item/clothing/suit/space)) - handle_suit = 1 + handle_suit = TRUE if(H.internal) H.visible_message("[user] sprays a cloud of fine ice crystals, engulfing [H]!", "[user] sprays a cloud of fine ice crystals over your [H.head]'s visor.") - add_attack_logs(user, C, "Cryokinesis") else H.visible_message("[user] sprays a cloud of fine ice crystals engulfing, [H]!", "[user] sprays a cloud of fine ice crystals cover your [H.head]'s visor and make it into your air vents!.") - add_attack_logs(user, C, "Cryokinesis") + H.bodytemperature = max(0, H.bodytemperature - 100) + add_attack_logs(user, C, "Cryokinesis") if(!handle_suit) C.bodytemperature = max(0, C.bodytemperature - 200) C.ExtinguishMob() @@ -454,7 +453,7 @@ name = "Polymorphism" desc = "Enables the subject to reconfigure their appearance to mimic that of others." - spelltype =/obj/effect/proc_holder/spell/targeted/polymorph + spelltype =/obj/effect/proc_holder/spell/targeted/click/polymorph //cooldown = 1800 activation_messages = list("You don't feel entirely like yourself somehow.") deactivation_messages = list("You feel secure in your identity.") @@ -465,34 +464,36 @@ ..() block = GLOB.polymorphblock -/obj/effect/proc_holder/spell/targeted/polymorph +/obj/effect/proc_holder/spell/targeted/click/polymorph name = "Polymorph" desc = "Mimic the appearance of others!" panel = "Abilities" charge_max = 1800 - clothes_req = 0 - human_req = 1 - stat_allowed = 0 + clothes_req = FALSE + stat_allowed = FALSE + + click_radius = -1 // Precision required + auto_target_single = FALSE // Safety to not turn into monkey (420) + selection_activated_message = "You body becomes unstable. Click on a target to cast transform into them." + selection_deactivated_message = "Your body calms down again." + allowed_type = /mob/living/carbon/human + invocation_type = "none" range = 1 selection_type = "range" action_icon_state = "genetic_poly" -/obj/effect/proc_holder/spell/targeted/polymorph/cast(list/targets, mob/user = usr) - var/mob/living/M = targets[1] - if(!ishuman(M)) - to_chat(usr, "You can only change your appearance to that of another human.") - return +/obj/effect/proc_holder/spell/targeted/click/polymorph/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/target = targets[1] user.visible_message("[user]'s body shifts and contorts.") spawn(10) - if(M && user) + if(target && user) playsound(user.loc, 'sound/goonstation/effects/gib.ogg', 50, 1) var/mob/living/carbon/human/H = user - var/mob/living/carbon/human/target = M H.UpdateAppearance(target.dna.UI) H.real_name = target.real_name H.name = target.name diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 9092448e398..e08d35b681d 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -214,25 +214,21 @@ /obj/effect/proc_holder/spell/targeted/remotetalk/choose_targets(mob/user = usr) var/list/targets = new /list() - var/list/validtargets = new /list() - var/turf/T = get_turf(user) - for(var/mob/living/M in range(14, T)) - if(M && M.mind) - if(M == user) - continue - validtargets += M + var/list/validtargets = user.get_telepathic_targets() - if(!validtargets.len) + if(!length(validtargets)) to_chat(user, "There are no valid targets!") start_recharge() return - targets += input("Choose the target to talk to.", "Targeting") as null|mob in validtargets + var/target_name = input("Choose the target to talk to.", "Targeting") as null|anything in validtargets - if(!targets.len || !targets[1]) //doesn't waste the spell + var/mob/living/target + if(!target_name || !(target = validtargets[target_name])) revert_cast(user) return + targets += target perform(targets, user = user) /obj/effect/proc_holder/spell/targeted/remotetalk/cast(list/targets, mob/user = usr) @@ -249,7 +245,7 @@ target.show_message("You hear [user.real_name]'s voice: [say]") else target.show_message("You hear a voice that seems to echo around the room: [say]") - user.show_message("You project your mind into [target.name]: [say]") + user.show_message("You project your mind into [(target in user.get_visible_mobs()) ? target.name : "the unknown entity"]: [say]") for(var/mob/dead/observer/G in GLOB.player_list) G.show_message("Telepathic message from [user] ([ghost_follow_link(user, ghost=G)]) to [target] ([ghost_follow_link(target, ghost=G)]): [say]") @@ -266,26 +262,22 @@ var/list/available_targets = list() /obj/effect/proc_holder/spell/targeted/mindscan/choose_targets(mob/user = usr) - var/list/targets = new /list() - var/list/validtargets = new /list() - var/turf/T = get_turf(user) - for(var/mob/living/M in range(14, T)) - if(M && M.mind) - if(M == user) - continue - validtargets += M + var/list/targets = list() + var/list/validtargets = user.get_telepathic_targets() - if(!validtargets.len) + if(!length(validtargets)) to_chat(user, "There are no valid targets!") start_recharge() return - targets += input("Choose the target to listen to.", "Targeting") as null|mob in validtargets + var/target_name = input("Choose the target to listen to.", "Targeting") as null|anything in validtargets - if(!targets.len || !targets[1]) //doesn't waste the spell + var/mob/living/target + if(!target_name || !(target = validtargets[target_name])) revert_cast(user) return + targets += target perform(targets, user = user) /obj/effect/proc_holder/spell/targeted/mindscan/cast(list/targets, mob/user = usr) @@ -295,7 +287,7 @@ var/message = "You feel your mind expand briefly... (Click to send a message.)" if(REMOTE_TALK in target.mutations) message = "You feel [user.real_name] request a response from you... (Click here to project mind.)" - user.show_message("You offer your mind to [target.name].") + user.show_message("You offer your mind to [(target in user.get_visible_mobs()) ? target.name : "the unknown entity"].") target.show_message("[message]") available_targets += target addtimer(CALLBACK(src, .proc/removeAvailability, target), 100) diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 8f6ba965222..93b84dbb54d 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -18,7 +18,7 @@ intercepttext += "
Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.
" intercepttext += "Message ends." if(2) - var/nukecode = "[rand(10000, 99999)]" + var/nukecode = rand(10000, 99999) for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines) if(bomb && bomb.r_code) if(is_station_level(bomb.z)) @@ -40,7 +40,7 @@ aiPlayer.set_zeroth_law(law) to_chat(aiPlayer, "Laws Updated: [law]") - print_command_report(intercepttext, interceptname) + print_command_report(intercepttext, interceptname, FALSE) GLOB.event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg', from = "[command_name()] Update") /datum/station_state diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index fbfb75b8b6a..9bc9fc7b511 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -112,7 +112,7 @@ feedback_add_details("changeling_powers","TS") return TRUE -datum/action/changeling/sting/extract_dna +/datum/action/changeling/sting/extract_dna name = "Extract DNA Sting" desc = "We stealthily sting a target and extract their DNA. Costs 25 chemicals." helptext = "Will give you the DNA of your target, allowing you to transform into them." @@ -132,7 +132,7 @@ datum/action/changeling/sting/extract_dna feedback_add_details("changeling_powers","ED") return 1 -datum/action/changeling/sting/mute +/datum/action/changeling/sting/mute name = "Mute Sting" desc = "We silently sting a human, completely silencing them for a short time. Costs 20 chemicals." helptext = "Does not provide a warning to the victim that they have been stung, until they try to speak and cannot." @@ -147,7 +147,7 @@ datum/action/changeling/sting/mute feedback_add_details("changeling_powers","MS") return 1 -datum/action/changeling/sting/blind +/datum/action/changeling/sting/blind name = "Blind Sting" desc = "We temporarily blind our victim. Costs 25 chemicals." helptext = "This sting completely blinds a target for a short time, and leaves them with blurred vision for a long time." @@ -165,7 +165,7 @@ datum/action/changeling/sting/blind feedback_add_details("changeling_powers","BS") return 1 -datum/action/changeling/sting/LSD +/datum/action/changeling/sting/LSD name = "Hallucination Sting" desc = "We cause mass terror to our victim. Costs 10 chemicals." helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung, and the effect occurs after 30 to 60 seconds." @@ -182,7 +182,7 @@ datum/action/changeling/sting/LSD feedback_add_details("changeling_powers","HS") return 1 -datum/action/changeling/sting/cryo //Enable when mob cooling is fixed so that frostoil actually makes you cold, instead of mostly just hungry. +/datum/action/changeling/sting/cryo //Enable when mob cooling is fixed so that frostoil actually makes you cold, instead of mostly just hungry. name = "Cryogenic Sting" desc = "We silently sting our victim with a cocktail of chemicals that freezes them from the inside. Costs 15 chemicals." helptext = "Does not provide a warning to the victim, though they will likely realize they are suddenly freezing." diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index c06913c1abe..17ae54591aa 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -270,14 +270,10 @@ GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list( /obj/effect/gateway/singularity_pull() return -/obj/effect/gateway/Bumped(mob/M as mob|obj) - spawn(0) - return +/obj/effect/gateway/Bumped(atom/movable/AM) return -/obj/effect/gateway/Crossed(AM as mob|obj, oldloc) - spawn(0) - return +/obj/effect/gateway/Crossed(atom/movable/AM, oldloc) return diff --git a/code/game/gamemodes/devil/contracts/friend.dm b/code/game/gamemodes/devil/contracts/friend.dm index 7760ee10ee7..8838dc8a371 100644 --- a/code/game/gamemodes/devil/contracts/friend.dm +++ b/code/game/gamemodes/devil/contracts/friend.dm @@ -17,7 +17,8 @@ /obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell) . = ..() owner = owner_mind - flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, [owner.p_they()] can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." + description = "Be someone's loyal friend/slave. If they die, you die as well." //best I could think of in the moment, not sure how this role plays in practise, have never seen it. + flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, [owner.p_they()] can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." var/area/A = get_area(src) if(!mapload && A) notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = TRUE) diff --git a/code/game/gamemodes/devil/devilinfo.dm b/code/game/gamemodes/devil/devilinfo.dm index ecbeb54f7f7..22a5f4a6cde 100644 --- a/code/game/gamemodes/devil/devilinfo.dm +++ b/code/game/gamemodes/devil/devilinfo.dm @@ -92,7 +92,7 @@ GLOBAL_LIST_INIT(lawlorify, list ( var/form = BASIC_DEVIL var/exists = 0 var/static/list/dont_remove_spells = list( - /obj/effect/proc_holder/spell/targeted/summon_contract, + /obj/effect/proc_holder/spell/targeted/click/summon_contract, /obj/effect/proc_holder/spell/targeted/conjure_item/violin, /obj/effect/proc_holder/spell/targeted/summon_dancefloor) var/ascendable = FALSE @@ -326,12 +326,12 @@ GLOBAL_LIST_INIT(lawlorify, list ( owner.RemoveSpell(S) /datum/devilinfo/proc/give_summon_contract() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/summon_contract(null)) /datum/devilinfo/proc/give_base_spells(give_summon_contract = 0) remove_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork(null)) if(give_summon_contract) give_summon_contract() @@ -343,13 +343,13 @@ GLOBAL_LIST_INIT(lawlorify, list ( /datum/devilinfo/proc/give_lizard_spells() remove_spells() owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) /datum/devilinfo/proc/give_true_spells() remove_spells() owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/pitchfork/greater(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null)) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 1e2dd3d554b..8757fa00d4f 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -337,7 +337,7 @@ ////////////////////////// //Reports player logouts// ////////////////////////// -proc/display_roundstart_logout_report() +/proc/display_roundstart_logout_report() var/msg = "Roundstart logout report\n\n" for(var/mob/living/L in GLOB.mob_list) @@ -507,7 +507,7 @@ proc/display_roundstart_logout_report() message_text += G.get_report() message_text += "
" - print_command_report(message_text, "[command_name()] Orders") + print_command_report(message_text, "[command_name()] Orders", FALSE) /datum/game_mode/proc/declare_station_goal_completion() for(var/V in station_goals) diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 142ae33c078..f95702e7f28 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -250,7 +250,7 @@ GLOBAL_LIST_EMPTY(cortical_stacks) //Stacks for 'leave nobody behind' objective. ..() -datum/game_mode/proc/auto_declare_completion_heist() +/datum/game_mode/proc/auto_declare_completion_heist() if(raiders.len) var/check_return = 0 if(GAMEMODE_IS_HEIST) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 9f5db8d5dae..9ed2adf3332 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -679,7 +679,7 @@ for(var/thing in GLOB.apcs) var/obj/machinery/power/apc/apc if(prob(30 * apc.overload)) - apc.overload_lighting() + INVOKE_ASYNC(apc, /obj/machinery/power/apc.proc/overload_lighting) else apc.overload++ to_chat(owner, "Overcurrent applied to the powernet.") diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 8da5b4468d7..7fe146d3e47 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -19,15 +19,13 @@ mob_name = "a swarmer" death = FALSE roundstart = FALSE - flavour_text = {" - You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate. - Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful. - Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage. - Objectives: + important_info = "Follow your objectives, do not make the station inhospitable or try and kill crew." + flavour_text = "You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate." + description = {" Your goal is to create more of yourself by consuming the station. Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful. Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage. + Objectives: 1. Consume resources and replicate until there are no more resources left. 2. Ensure that this location is fit for invasion at a later date; do not perform actions that would render it dangerous or inhospitable. - 3. Biological resources will be harvested at a later date; do not harm them. - "} + 3. Biological resources will be harvested at a later date; do not harm them."} /obj/effect/mob_spawn/swarmer/Initialize(mapload) . = ..() diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm index fbceda6bd94..5c4b83e965c 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm @@ -7,7 +7,7 @@ var/swarmer_report = "[command_name()] High-Priority Update" swarmer_report += "

Our long-range sensors have detected an odd signal emanating from your station's gateway. We recommend immediate investigation of your gateway, as something may have come \ through." - print_command_report(swarmer_report, "Classified [command_name()] Update") + print_command_report(swarmer_report, "Classified [command_name()] Update", FALSE) GLOB.event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg') /datum/event/spawn_swarmer/start() diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index fdf17f6ddda..d063b742047 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -363,7 +363,7 @@ if("Protector") pickedtype = /mob/living/simple_animal/hostile/guardian/protector - var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user) + var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user, user) G.summoner = user G.summoned = TRUE G.key = key diff --git a/code/game/gamemodes/miniantags/guardian/types/lightning.dm b/code/game/gamemodes/miniantags/guardian/types/lightning.dm index bf84e199bab..2c716d5d4a4 100644 --- a/code/game/gamemodes/miniantags/guardian/types/lightning.dm +++ b/code/game/gamemodes/miniantags/guardian/types/lightning.dm @@ -3,12 +3,12 @@ layer = LYING_MOB_LAYER /mob/living/simple_animal/hostile/guardian/beam - melee_damage_lower = 7 - melee_damage_upper = 7 + melee_damage_lower = 12 + melee_damage_upper = 12 attacktext = "shocks" melee_damage_type = BURN attack_sound = 'sound/machines/defib_zap.ogg' - damage_transfer = 0.7 + damage_transfer = 0.6 range = 7 playstyle_string = "As a Lightning type, you will apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them." magic_fluff_string = "..And draw the Tesla, a shocking, lethal source of power." @@ -18,6 +18,17 @@ var/list/enemychains = list() var/successfulshocks = 0 +/mob/living/simple_animal/hostile/guardian/beam/New(loc, mob/living/user) + . = ..() + if(!user) + return + summoner = user + if(!(NO_SHOCK in summoner.mutations)) + summoner.mutations.Add(NO_SHOCK) + +/mob/living/simple_animal/hostile/guardian/beam/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + return FALSE //You are lightning, you should not be hurt by such things. + /mob/living/simple_animal/hostile/guardian/beam/AttackingTarget() . = ..() if(. && isliving(target) && target != src && target != summoner) @@ -106,3 +117,8 @@ ) L.adjustFireLoss(1.2) //adds up very rapidly . = 1 + +/mob/living/simple_animal/hostile/guardian/beam/death(gibbed) + if(summoner && (NO_SHOCK in summoner.mutations)) + summoner.mutations.Remove(NO_SHOCK) + return ..() diff --git a/code/game/gamemodes/miniantags/guardian/types/protector.dm b/code/game/gamemodes/miniantags/guardian/types/protector.dm index 534b7e16934..fda005a58ed 100644 --- a/code/game/gamemodes/miniantags/guardian/types/protector.dm +++ b/code/game/gamemodes/miniantags/guardian/types/protector.dm @@ -25,6 +25,7 @@ overlays.Cut() melee_damage_lower = initial(melee_damage_lower) melee_damage_upper = initial(melee_damage_upper) + obj_damage = initial(obj_damage) speed = initial(speed) damage_transfer = 0.4 to_chat(src, "You switch to combat mode.") @@ -35,6 +36,7 @@ overlays.Add(shield_overlay) melee_damage_lower = 2 melee_damage_upper = 2 + obj_damage = 6 //40/7.5 rounded up, we don't want a protector guardian 2 shotting blob tiles while taking 5% damage, thats just silly. speed = 1 damage_transfer = 0.05 //damage? what's damage? to_chat(src, "You switch to protection mode.") diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index 91ed583efc7..47e5e759c77 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -153,7 +153,7 @@ else name = "[initial(name)] ([cast_amount]E)" -/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr) +/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, charge_check = TRUE, show_message = FALSE) if(user.inhibited) return 0 if(charge_counter < charge_max) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 8316364781b..7c87083dfe5 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -3,7 +3,7 @@ /datum/game_mode var/list/datum/mind/syndicates = list() -proc/issyndicate(mob/living/M as mob) +/proc/issyndicate(mob/living/M as mob) return istype(M) && M.mind && SSticker && SSticker.mode && (M.mind in SSticker.mode.syndicates) /datum/game_mode/nuclear @@ -103,7 +103,7 @@ proc/issyndicate(mob/living/M as mob) var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb") - var/nuke_code = "[rand(10000, 99999)]" + var/nuke_code = rand(10000, 99999) var/leader_selected = 0 var/agent_number = 1 var/spawnpos = 1 diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index c73293da519..209f9689de1 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -14,29 +14,29 @@ GLOBAL_VAR(bomb_set) icon_state = "nuclearbomb0" density = 1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/deployable = 0 - var/extended = 0 - var/lighthack = 0 + var/extended = FALSE + var/lighthack = FALSE var/timeleft = 120 - var/timing = 0 + var/timing = FALSE + var/exploded = FALSE var/r_code = "ADMIN" - var/code = "" - var/yes_code = 0 - var/safety = 1 + var/code + var/yes_code = FALSE + var/safety = TRUE var/obj/item/disk/nuclear/auth = null var/removal_stage = NUKE_INTACT var/lastentered - var/is_syndicate = 0 + var/is_syndicate = FALSE use_power = NO_POWER_USE var/previous_level = "" var/datum/wires/nuclearbomb/wires = null /obj/machinery/nuclearbomb/syndicate - is_syndicate = 1 + is_syndicate = TRUE /obj/machinery/nuclearbomb/New() ..() - r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn. + r_code = rand(10000, 99999.0) // Creates a random code upon object spawn. wires = new/datum/wires/nuclearbomb(src) previous_level = get_security_level() GLOB.poi_list |= src @@ -49,25 +49,24 @@ GLOBAL_VAR(bomb_set) /obj/machinery/nuclearbomb/process() if(timing) - GLOB.bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed. + GLOB.bomb_set = TRUE // So long as there is one nuke timing, it means one nuke is armed. timeleft = max(timeleft - 2, 0) // 2 seconds per process() if(timeleft <= 0) INVOKE_ASYNC(src, .proc/explode) - SSnanoui.update_uis(src) return /obj/machinery/nuclearbomb/attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/disk/nuclear)) if(extended) if(!user.drop_item()) - to_chat(user, "\The [O] is stuck to your hand!") + to_chat(user, "[O] is stuck to your hand!") return O.forceMove(src) auth = O add_fingerprint(user) return attack_hand(user) else - to_chat(user, "You need to deploy \the [src] first. Right click on the sprite, select 'Make Deployable' then click on \the [src] with an empty hand.") + to_chat(user, "You need to deploy [src] first.") return return ..() @@ -171,181 +170,157 @@ GLOBAL_VAR(bomb_set) removal_stage = NUKE_SEALANT_OPEN /obj/machinery/nuclearbomb/attack_ghost(mob/user as mob) - if(extended) - attack_hand(user) + attack_hand(user) /obj/machinery/nuclearbomb/attack_hand(mob/user as mob) - if(extended) - if(panel_open) - wires.Interact(user) - else - ui_interact(user) - else if(deployable) - if(removal_stage != NUKE_MOBILE) - anchored = 1 - visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring!") - else - visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") - if(!lighthack) - flick("nuclearbombc", src) - icon_state = "nuclearbomb1" - extended = 1 - return - -/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "nuclear_bomb.tmpl", "Nuke Control Panel", 450, 550, state = GLOB.physical_state) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/nuclearbomb/ui_data(mob/user, datum/topic_state/state) - var/data[0] - data["is_syndicate"] = is_syndicate - data["hacking"] = 0 - data["auth"] = is_auth(user) - if(is_auth(user)) - if(yes_code) - data["authstatus"] = timing ? "Functional/Set" : "Functional" - else - data["authstatus"] = "Auth. S2" + if(panel_open) + wires.Interact(user) else - if(timing) - data["authstatus"] = "Set" - else - data["authstatus"] = "Auth. S1" + tgui_interact(user) + +/obj/machinery/nuclearbomb/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_physical_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "NuclearBomb", name, 450, 300, master_ui, state) + ui.open() + +/obj/machinery/nuclearbomb/tgui_data(mob/user) + var/list/data = list() + data["extended"] = extended + data["authdisk"] = is_auth(user) + data["diskname"] = auth ? auth.name : FALSE + data["authcode"] = yes_code + data["authfull"] = data["authdisk"] && data["authcode"] data["safe"] = safety ? "Safe" : "Engaged" data["time"] = timeleft data["timer"] = timing data["safety"] = safety data["anchored"] = anchored - data["yescode"] = yes_code - data["message"] = "AUTH" if(is_auth(user)) - data["message"] = code if(yes_code) - data["message"] = "*****" - - return data - -/obj/machinery/nuclearbomb/verb/make_deployable() - set category = "Object" - set name = "Make Deployable" - set src in oview(1) - - if(usr.stat || !usr.canmove || usr.restrained()) - return - - if(deployable) - to_chat(usr, "You close several panels to make [src] undeployable.") - deployable = 0 + data["codemsg"] = "CLEAR CODE" + else if(code) + data["codemsg"] = "RE-ENTER CODE" + else + data["codemsg"] = "ENTER CODE" else - to_chat(usr, "You adjust some panels to make [src] deployable.") - deployable = 1 - return + data["codemsg"] = "-----" + return data /obj/machinery/nuclearbomb/proc/is_auth(var/mob/user) if(auth) - return 1 + return TRUE else if(user.can_admin_interact()) - return 1 + return TRUE else - return 0 + return FALSE -/obj/machinery/nuclearbomb/Topic(href, href_list) +/obj/machinery/nuclearbomb/tgui_act(action, params) if(..()) - return 1 - - if(href_list["auth"]) - if(auth) - auth.loc = loc - yes_code = 0 - auth = null - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/disk/nuclear)) - usr.drop_item() - I.loc = src - auth = I - if(is_auth(usr)) - if(href_list["type"]) - if(href_list["type"] == "E") + return + . = TRUE + if(exploded) + return + switch(action) + if("deploy") + if(removal_stage != NUKE_MOBILE) + anchored = TRUE + visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring!") + else + visible_message("[src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") + if(!lighthack) + flick("nuclearbombc", src) + icon_state = "nuclearbomb1" + extended = TRUE + return + if("auth") + if(auth) + if(!usr.get_active_hand() && Adjacent(usr)) + usr.put_in_hands(auth) + else + auth.forceMove(get_turf(src)) + yes_code = FALSE + auth = null + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/disk/nuclear)) + usr.drop_item() + I.forceMove(src) + auth = I + return + if(!is_auth(usr)) // All requests below here require NAD inserted. + return FALSE + switch(action) + if("code") + if(yes_code) // Clear code + code = null + yes_code = FALSE + return + // If no code set, enter new one + var/tempcode = input(usr, "Code", "Input Code", null) as num|null + if(tempcode) + code = min(max(round(tempcode), 0), 999999) if(code == r_code) - yes_code = 1 + yes_code = TRUE code = null else code = "ERROR" + return + + if(!yes_code) // All requests below here require both NAD inserted AND code correct + return + + switch(action) + if("toggle_anchor") + if(removal_stage == NUKE_MOBILE) + anchored = FALSE + visible_message("[src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") + else if(isinspace()) + to_chat(usr, "There is nothing to anchor to!") + return FALSE else - if(href_list["type"] == "R") - yes_code = 0 - code = null - else - lastentered = text("[]", href_list["type"]) - if(text2num(lastentered) == null) - var/turf/LOC = get_turf(usr) - message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]! ([LOC ? "JMP" : "null"])", 0) - log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!") - else - code += lastentered - if(length(code) > 5) - code = "ERROR" - if(yes_code) - if(href_list["time"]) - var/time = text2num(href_list["time"]) - timeleft += time - timeleft = min(max(round(src.timeleft), 120), 600) - if(href_list["timer"]) - if(timing == -1.0) - SSnanoui.update_uis(src) - return - if(safety) - to_chat(usr, "The safety is still on.") - SSnanoui.update_uis(src) - return - timing = !(timing) - if(timing) - if(!lighthack) - icon_state = "nuclearbomb2" - if(!safety) - message_admins("[key_name_admin(usr)] engaged a nuclear bomb (JMP)") - if(!is_syndicate) - set_security_level("delta") - GLOB.bomb_set = 1 //There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N - else - GLOB.bomb_set = 0 + anchored = !(anchored) + if(anchored) + visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring.") else + visible_message("The anchoring bolts slide back into the depths of [src].") + return + if("set_time") + var/time = input(usr, "Detonation time (seconds, min 120, max 600)", "Input Time", 120) as num|null + if(time) + timeleft = min(max(round(time), 120), 600) + if("toggle_safety") + safety = !(safety) + if(safety) + if(!is_syndicate) + set_security_level(previous_level) + timing = FALSE + GLOB.bomb_set = FALSE + if("toggle_armed") + if(safety) + to_chat(usr, "The safety is still on.") + return + timing = !(timing) + if(timing) + if(!lighthack) + icon_state = "nuclearbomb2" + if(!safety) + message_admins("[key_name_admin(usr)] engaged a nuclear bomb [ADMIN_JMP(src)]") if(!is_syndicate) - set_security_level(previous_level) - GLOB.bomb_set = 0 - if(!lighthack) - icon_state = "nuclearbomb1" - if(href_list["safety"]) - safety = !(safety) - if(safety) - if(!is_syndicate) - set_security_level(previous_level) - timing = 0 - GLOB.bomb_set = 0 - if(href_list["anchor"]) - if(removal_stage == NUKE_MOBILE) - anchored = 0 - visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") - SSnanoui.update_uis(src) - return - - if(!isinspace()) - anchored = !(anchored) - if(anchored) - visible_message("With a steely snap, bolts slide out of [src] and anchor it to the flooring.") - else - visible_message("The anchoring bolts slide back into the depths of [src].") + set_security_level("delta") + GLOB.bomb_set = TRUE // There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke else - to_chat(usr, "There is nothing to anchor to!") + GLOB.bomb_set = TRUE + else + if(!is_syndicate) + set_security_level(previous_level) + GLOB.bomb_set = FALSE + if(!lighthack) + icon_state = "nuclearbomb1" - SSnanoui.update_uis(src) /obj/machinery/nuclearbomb/blob_act(obj/structure/blob/B) - if(timing == -1.0) + if(exploded) return if(timing) //boom INVOKE_ASYNC(src, .proc/explode) @@ -360,11 +335,11 @@ GLOBAL_VAR(bomb_set) #define NUKERANGE 80 /obj/machinery/nuclearbomb/proc/explode() if(safety) - timing = 0 + timing = FALSE return - timing = -1.0 - yes_code = 0 - safety = 1 + exploded = TRUE + yes_code = FALSE + safety = TRUE if(!lighthack) icon_state = "nuclearbomb3" playsound(src,'sound/machines/alarm.ogg',100,0,5) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 27267d2ec02..4be50a6cd59 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -18,80 +18,56 @@ return 0 -/obj/effect/proc_holder/spell/targeted/glare //Stuns and mutes a human target, depending on the distance relative to the shadowling +/obj/effect/proc_holder/spell/targeted/click/glare //Stuns and mutes a human target, depending on the distance relative to the shadowling name = "Glare" desc = "Stuns and mutes a target for a decent duration. Duration depends on the proximity to the target." panel = "Shadowling Abilities" charge_max = 300 - clothes_req = 0 + clothes_req = FALSE range = 10 //has no effect beyond this range, so setting this makes invalid/useless targets not show up in popup action_icon_state = "glare" - humans_only = 1 //useless since we override chose_targets, but might be used for other code later??? Might remove, idk -/obj/effect/proc_holder/spell/targeted/glare/choose_targets(mob/user) - var/list/possible_targets = list() - for(var/mob/living/carbon/human/target in view_or_range(range, user, "view")) - if(target.stat) - continue - if(is_shadow_or_thrall(target)) - continue - possible_targets += target - var/mob/living/carbon/human/M - var/list/targets = list() - if(possible_targets.len == 1)//no choice involved - targets = possible_targets - else - M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets - if(M in view_or_range(range, user, "view")) - targets += M + selection_activated_message = "Your prepare to your eyes for a stunning glare! Left-click to cast at a target!" + selection_deactivated_message = "Your eyes relax... for now." + allowed_type = /mob/living/carbon/human +/obj/effect/proc_holder/spell/targeted/click/glare/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/living/user = usr) + if(!shadowling_check(user)) + return FALSE + return ..() - if(!targets.len) //doesn't waste the spell - revert_cast(user) +/obj/effect/proc_holder/spell/targeted/click/glare/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE + return !target.stat && !is_shadow_or_thrall(target) + +/obj/effect/proc_holder/spell/targeted/click/glare/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/H = targets[1] + + user.visible_message("[user]'s eyes flash a blinding red!") + var/distance = get_dist(H, user) + if (distance <= 1) //Melee glare + H.visible_message("[H] freezes in place, [H.p_their()] eyes glazing over...", \ + "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by [user.p_their()] heavenly beauty...") + H.Stun(10) + H.AdjustSilence(10) + else //Distant glare + var/loss = 10 - distance + var/duration = 10 - loss + if(loss <= 0) + to_chat(user, "Your glare had no effect over a such long distance!") + return + H.slowed = duration + H.AdjustSilence(10) + to_chat(H, "A red light flashes across your vision, and your mind tries to resist them.. you are exhausted.. you are not able to speak..") + addtimer(CALLBACK(src, .proc/do_stun, H, user, loss), duration SECONDS) + +/obj/effect/proc_holder/spell/targeted/click/glare/proc/do_stun(mob/living/carbon/human/target, user, stun_time) + if(!istype(target) || target.stat) return - - perform(targets, user = user) - return - - -/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets, mob/user = usr) - for(var/mob/living/carbon/human/target in targets) - if(!ishuman(target)) - to_chat(user, "You may only glare at humans!") - charge_counter = charge_max - return - if(!shadowling_check(user)) - charge_counter = charge_max - return - if(target.stat) - to_chat(user, "[target] must be conscious!") - charge_counter = charge_max - return - if(is_shadow_or_thrall(target)) - to_chat(user, "You don't see why you would want to paralyze an ally.") - charge_counter = charge_max - return - var/mob/living/carbon/human/M = target - user.visible_message("[user]'s eyes flash a blinding red!") - var/distance = get_dist(target, user) - if (distance <= 1) //Melee glare - target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...") - to_chat(target, "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by [user.p_their()] heavenly beauty...") - target.Stun(10) - M.AdjustSilence(10) - else //Distant glare - var/loss = 10 - distance - var/duration = 10 - loss - if(loss <= 0) - to_chat(user, "Your glare had no effect over a such long distance!") - return - target.slowed = duration - M.AdjustSilence(10) - to_chat(target, "A red light flashes across your vision, and your mind tries to resist them.. you are exhausted.. you are not able to speak..") - sleep(duration*10) - target.Stun(loss) - target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...") - to_chat(target, "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights...") + target.Stun(stun_time) + target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...",\ + "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights...") /obj/effect/proc_holder/spell/aoe_turf/veil name = "Veil" @@ -109,9 +85,10 @@ return to_chat(user, "You silently disable all nearby lights.") for(var/obj/structure/glowshroom/G in orange(2, user)) //Why the fuck was this in the loop below? - G.visible_message("\The [G] withers away!") + G.visible_message("[G] withers away!") qdel(G) for(var/turf/T in targets) + T.extinguish_light() for(var/atom/A in T.contents) A.extinguish_light() @@ -227,96 +204,80 @@ M.reagents.add_reagent("frostoil", 15) //Half of a cryosting -/obj/effect/proc_holder/spell/targeted/enthrall //Turns a target into the shadowling's slave. This overrides all previous loyalties +/obj/effect/proc_holder/spell/targeted/click/enthrall //Turns a target into the shadowling's slave. This overrides all previous loyalties name = "Enthrall" desc = "Allows you to enslave a conscious, non-braindead, non-catatonic human to your will. This takes some time to cast." panel = "Shadowling Abilities" charge_max = 0 - clothes_req = 0 + clothes_req = FALSE range = 1 //Adjacent to user - var/enthralling = 0 + var/enthralling = FALSE action_icon_state = "enthrall" - humans_only = 1 -/obj/effect/proc_holder/spell/targeted/enthrall/cast(list/targets, mob/user = usr) + click_radius = -1 // Precision baby + selection_activated_message = "Your prepare your mind to entrall a mortal. Left-click to cast at a target!" + selection_deactivated_message = "Your mind relaxes." + allowed_type = /mob/living/carbon/human + +/obj/effect/proc_holder/spell/targeted/click/enthrall/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) + if(enthralling || !shadowling_check(user)) + return FALSE + return ..() + +/obj/effect/proc_holder/spell/targeted/click/enthrall/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE + return target.key && target.mind && !target.stat && !is_shadow_or_thrall(target) && target.client + +/obj/effect/proc_holder/spell/targeted/click/enthrall/cast(list/targets, mob/user = usr) var/mob/living/carbon/human/ling = user listclearnulls(SSticker.mode.shadowling_thralls) if(!(ling.mind in SSticker.mode.shadows)) return - if(!isshadowling(ling)) - if(SSticker.mode.shadowling_thralls.len >= 5) - charge_counter = charge_max - return - for(var/mob/living/carbon/human/target in targets) - if(!in_range(user, target)) - to_chat(user, "You need to be closer to enthrall [target].") - charge_counter = charge_max - return - if(!target.key || !target.mind) - to_chat(user, "The target has no mind.") - charge_counter = charge_max - return - if(target.stat) - to_chat(user, "The target must be conscious.") - charge_counter = charge_max - return - if(is_shadow_or_thrall(target)) - to_chat(user, "You can not enthrall allies.") - charge_counter = charge_max - return - if(!ishuman(target)) - to_chat(user, "You can only enthrall humans.") - charge_counter = charge_max - return - if(enthralling) - to_chat(user, "You are already enthralling!") - charge_counter = charge_max - return - if(!target.client) - to_chat(user, "[target]'s mind is vacant of activity.") - enthralling = 1 - to_chat(user, "This target is valid. You begin the enthralling.") - to_chat(target, "[user] stares at you. You feel your head begin to pulse.") + var/mob/living/carbon/human/target = targets[1] + enthralling = TRUE + to_chat(user, "This target is valid. You begin the enthralling.") + to_chat(target, "[user] stares at you. You feel your head begin to pulse.") - for(var/progress = 0, progress <= 3, progress++) - switch(progress) - if(1) - to_chat(user, "You place your hands to [target]'s head...") - user.visible_message("[user] places [user.p_their()] hands onto the sides of [target]'s head!") - if(2) - to_chat(user, "You begin preparing [target]'s mind as a blank slate...") - user.visible_message("[user]'s palms flare a bright red against [target]'s temples!") - to_chat(target, "A terrible red light floods your mind. You collapse as conscious thought is wiped away.") - target.Weaken(12) - sleep(20) - if(ismindshielded(target)) - to_chat(user, "They have a mindshield implant. You begin to deactivate it - this will take some time.") - user.visible_message("[user] pauses, then dips [user.p_their()] head in concentration!") - to_chat(target, "Your mindshield implant becomes hot as it comes under attack!") - sleep(100) //10 seconds - not spawn() so the enthralling takes longer - to_chat(user, "The nanobots composing the mindshield implant have been rendered inert. Now to continue.") - user.visible_message("[user] relaxes again.") - for(var/obj/item/implant/mindshield/L in target) - if(L && L.implanted) - qdel(L) - to_chat(target, "Your mental protection implant unexpectedly falters, dims, dies.") - if(3) - to_chat(user, "You begin planting the tumor that will control the new thrall...") - user.visible_message("A strange energy passes from [user]'s hands into [target]'s head!") - to_chat(target, "You feel your memories twisting, morphing. A sense of horror dominates your mind.") - if(!do_mob(user, target, 70)) //around 21 seconds total for enthralling, 31 for someone with a mindshield implant - to_chat(user, "The enthralling has been interrupted - your target's mind returns to its previous state.") - to_chat(target, "You wrest yourself away from [user]'s hands and compose yourself") - enthralling = 0 - return + for(var/progress = 0, progress <= 3, progress++) + switch(progress) + if(1) + to_chat(user, "You place your hands to [target]'s head...") + user.visible_message("[user] places [user.p_their()] hands onto the sides of [target]'s head!") + if(2) + to_chat(user, "You begin preparing [target]'s mind as a blank slate...") + user.visible_message("[user]'s palms flare a bright red against [target]'s temples!") + to_chat(target, "A terrible red light floods your mind. You collapse as conscious thought is wiped away.") + target.Weaken(12) + sleep(20) + if(ismindshielded(target)) + to_chat(user, "They have a mindshield implant. You begin to deactivate it - this will take some time.") + user.visible_message("[user] pauses, then dips [user.p_their()] head in concentration!") + to_chat(target, "Your mindshield implant becomes hot as it comes under attack!") + sleep(100) //10 seconds - not spawn() so the enthralling takes longer + to_chat(user, "The nanobots composing the mindshield implant have been rendered inert. Now to continue.") + user.visible_message("[user] relaxes again.") + for(var/obj/item/implant/mindshield/L in target) + if(L && L.implanted) + qdel(L) + to_chat(target, "Your mental protection implant unexpectedly falters, dims, dies.") + if(3) + to_chat(user, "You begin planting the tumor that will control the new thrall...") + user.visible_message("A strange energy passes from [user]'s hands into [target]'s head!") + to_chat(target, "You feel your memories twisting, morphing. A sense of horror dominates your mind.") + if(!do_mob(user, target, 70)) //around 21 seconds total for enthralling, 31 for someone with a mindshield implant + to_chat(user, "The enthralling has been interrupted - your target's mind returns to its previous state.") + to_chat(target, "You wrest yourself away from [user]'s hands and compose yourself") + enthralling = FALSE + return - enthralling = 0 - to_chat(user, "You have enthralled [target]!") - target.visible_message("[target] looks to have experienced a revelation!", \ - "False faces all dark not real not real not--") - target.setOxyLoss(0) //In case the shadowling was choking them out - SSticker.mode.add_thrall(target.mind) - target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL + enthralling = FALSE + to_chat(user, "You have enthralled [target]!") + target.visible_message("[target] looks to have experienced a revelation!", \ + "False faces all dark not real not real not--") + target.setOxyLoss(0) //In case the shadowling was choking them out + SSticker.mode.add_thrall(target.mind) + target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL /obj/effect/proc_holder/spell/targeted/shadowling_regenarmor //Resets a shadowling's species to normal, removes genetic defects, and re-equips their armor name = "Rapid Re-Hatch" @@ -404,7 +365,7 @@ reviveThrallAcquired = 1 to_chat(target, "The power of your thralls has granted you the Black Recuperation ability. \ This will, after a short time, bring a dead thrall completely back to life with no bodily defects.") - target.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/reviveThrall(null)) + target.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/reviveThrall(null)) if(thralls < victory_threshold) to_chat(target, "You do not have the power to ascend. You require [victory_threshold] thralls, but only [thralls] living thralls are present.") @@ -570,169 +531,170 @@ -/obj/effect/proc_holder/spell/targeted/reviveThrall +/obj/effect/proc_holder/spell/targeted/click/reviveThrall name = "Black Recuperation" desc = "Revives or empowers a thrall." panel = "Shadowling Abilities" range = 1 charge_max = 600 - clothes_req = 0 - include_user = 0 + clothes_req = FALSE + include_user = FALSE action_icon_state = "revive_thrall" - humans_only = 1 + click_radius = -1 // Precision baby + selection_activated_message = "You start focusing your powers on mending wounds of allies. Left-click to cast at a target!" + selection_deactivated_message = "Your mind relaxes." + allowed_type = /mob/living/carbon/human -/obj/effect/proc_holder/spell/targeted/reviveThrall/cast(list/targets, mob/user = usr) +/obj/effect/proc_holder/spell/targeted/click/reviveThrall/can_cast(mob/user = usr) if(!shadowling_check(user)) - charge_counter = charge_max - return - for(var/mob/living/carbon/human/thrallToRevive in targets) - var/choice = alert(user,"Empower a living thrall or revive a dead one?",,"Empower","Revive","Cancel") - switch(choice) - if("Empower") - if(!is_thrall(thrallToRevive)) - to_chat(user, "[thrallToRevive] is not a thrall.") - charge_counter = charge_max - return - if(thrallToRevive.stat != CONSCIOUS) - to_chat(user, "[thrallToRevive] must be conscious to become empowered.") - charge_counter = charge_max - return - if(isshadowlinglesser(thrallToRevive)) - to_chat(user, "[thrallToRevive] is already empowered.") - charge_counter = charge_max - return - var/empowered_thralls = 0 - for(var/datum/mind/M in SSticker.mode.shadowling_thralls) - if(!ishuman(M.current)) - return - var/mob/living/carbon/human/H = M.current - if(isshadowlinglesser(H)) - empowered_thralls++ - if(empowered_thralls >= EMPOWERED_THRALL_LIMIT) - to_chat(user, "You cannot spare this much energy. There are too many empowered thralls.") - charge_counter = charge_max - return - user.visible_message("[user] places [user.p_their()] hands over [thrallToRevive]'s face, red light shining from beneath.", \ - "You place your hands on [thrallToRevive]'s face and begin gathering energy...") - to_chat(thrallToRevive, "[user] places [user.p_their()] hands over your face. You feel energy gathering. Stand still...") - if(!do_mob(user, thrallToRevive, 80)) - to_chat(user, "Your concentration snaps. The flow of energy ebbs.") - charge_counter = charge_max - return - to_chat(user, "You release a massive surge of power into [thrallToRevive]!") - user.visible_message("Red lightning surges into [thrallToRevive]'s face!") - playsound(thrallToRevive, 'sound/weapons/egloves.ogg', 50, 1) - playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1) - user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) - thrallToRevive.Weaken(5) - thrallToRevive.visible_message("[thrallToRevive] collapses, [thrallToRevive.p_their()] skin and face distorting!", \ - "AAAAAAAAAAAAAAAAAAAGH-") - sleep(20) - thrallToRevive.visible_message("[thrallToRevive] slowly rises, no longer recognizable as human.", \ - "You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \ - darkness but wither slowly in light. In addition, you now have glare and true shadow walk.") - thrallToRevive.set_species(/datum/species/shadow/ling/lesser) - thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) - thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null)) - thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk(null)) - if("Revive") - if(!is_thrall(thrallToRevive)) - to_chat(user, "[thrallToRevive] is not a thrall.") - charge_counter = charge_max - return - if(thrallToRevive.stat != DEAD) - to_chat(user, "[thrallToRevive] is not dead.") - charge_counter = charge_max - return - user.visible_message("[user] kneels over [thrallToRevive], placing [user.p_their()] hands on [thrallToRevive.p_their()] chest.", \ - "You crouch over the body of your thrall and begin gathering energy...") - thrallToRevive.notify_ghost_cloning("Your masters are resuscitating you! Re-enter your corpse if you wish to be brought to life.", source = thrallToRevive) - if(!do_mob(user, thrallToRevive, 30)) - to_chat(user, "Your concentration snaps. The flow of energy ebbs.") - charge_counter = charge_max - return - to_chat(user, "You release a massive surge of power into [thrallToRevive]!") - user.visible_message("Red lightning surges from [user]'s hands into [thrallToRevive]'s chest!") - playsound(thrallToRevive, 'sound/weapons/egloves.ogg', 50, 1) - playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1) - user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) - sleep(10) - if(thrallToRevive.revive()) - thrallToRevive.visible_message("[thrallToRevive] heaves in breath, dim red light shining in [thrallToRevive.p_their()] eyes.", \ - "You have returned. One of your masters has brought you from the darkness beyond.") - thrallToRevive.Weaken(4) - thrallToRevive.emote("gasp") - playsound(thrallToRevive, "bodyfall", 50, 1) - else - charge_counter = charge_max - return + return FALSE + return ..() -/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle +/obj/effect/proc_holder/spell/targeted/click/reviveThrall/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE + + return is_thrall(target) + +/obj/effect/proc_holder/spell/targeted/click/reviveThrall/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/thrallToRevive = targets[1] + if(thrallToRevive.stat == CONSCIOUS) + if(isshadowlinglesser(thrallToRevive)) + to_chat(user, "[thrallToRevive] is already empowered.") + revert_cast(user) + return + var/empowered_thralls = 0 + for(var/datum/mind/M in SSticker.mode.shadowling_thralls) + if(!ishuman(M.current)) + return + var/mob/living/carbon/human/H = M.current + if(isshadowlinglesser(H)) + empowered_thralls++ + if(empowered_thralls >= EMPOWERED_THRALL_LIMIT) + to_chat(user, "You cannot spare this much energy. There are too many empowered thralls.") + revert_cast(user) + return + user.visible_message("[user] places [user.p_their()] hands over [thrallToRevive]'s face, red light shining from beneath.", \ + "You place your hands on [thrallToRevive]'s face and begin gathering energy...") + to_chat(thrallToRevive, "[user] places [user.p_their()] hands over your face. You feel energy gathering. Stand still...") + if(!do_mob(user, thrallToRevive, 80)) + to_chat(user, "Your concentration snaps. The flow of energy ebbs.") + revert_cast(user) + return + to_chat(user, "You release a massive surge of power into [thrallToRevive]!") + user.visible_message("Red lightning surges into [thrallToRevive]'s face!") + playsound(thrallToRevive, 'sound/weapons/egloves.ogg', 50, 1) + playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1) + user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) + thrallToRevive.Weaken(5) + thrallToRevive.visible_message("[thrallToRevive] collapses, [thrallToRevive.p_their()] skin and face distorting!", \ + "AAAAAAAAAAAAAAAAAAAGH-") + sleep(20) + thrallToRevive.visible_message("[thrallToRevive] slowly rises, no longer recognizable as human.", \ + "You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \ + darkness but wither slowly in light. In addition, you now have glare and true shadow walk.") + thrallToRevive.set_species(/datum/species/shadow/ling/lesser) + thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) + thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/glare(null)) + thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk(null)) + else if(thrallToRevive.stat == DEAD) + user.visible_message("[user] kneels over [thrallToRevive], placing [user.p_their()] hands on [thrallToRevive.p_their()] chest.", \ + "You crouch over the body of your thrall and begin gathering energy...") + thrallToRevive.notify_ghost_cloning("Your masters are resuscitating you! Re-enter your corpse if you wish to be brought to life.", source = thrallToRevive) + if(!do_mob(user, thrallToRevive, 30)) + to_chat(user, "Your concentration snaps. The flow of energy ebbs.") + revert_cast(user) + return + to_chat(user, "You release a massive surge of power into [thrallToRevive]!") + user.visible_message("Red lightning surges from [user]'s hands into [thrallToRevive]'s chest!") + playsound(thrallToRevive, 'sound/weapons/egloves.ogg', 50, 1) + playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1) + user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) + sleep(10) + if(thrallToRevive.revive()) + thrallToRevive.visible_message("[thrallToRevive] heaves in breath, dim red light shining in [thrallToRevive.p_their()] eyes.", \ + "You have returned. One of your masters has brought you from the darkness beyond.") + thrallToRevive.Weaken(4) + thrallToRevive.emote("gasp") + playsound(thrallToRevive, "bodyfall", 50, 1) + else + to_chat(user, "The target must be awake to empower or dead to revive.") + revert_cast(user) + +/obj/effect/proc_holder/spell/targeted/click/shadowling_extend_shuttle name = "Destroy Engines" desc = "Extends the time of the emergency shuttle's arrival by ten minutes using a life force of our enemy. Shuttle will be unable to be recalled. This can only be used once." panel = "Shadowling Abilities" range = 1 - clothes_req = 0 + clothes_req = FALSE charge_max = 600 + click_radius = -1 // Precision baby + selection_activated_message = "You start gathering destructive powers to delay the shuttle. Left-click to cast at a target!" + selection_deactivated_message = "Your mind relaxes." + allowed_type = /mob/living/carbon/human action_icon_state = "extend_shuttle" var/global/extendlimit = 0 -/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets, mob/user = usr) +/obj/effect/proc_holder/spell/targeted/click/shadowling_extend_shuttle/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) if(!shadowling_check(user)) - charge_counter = charge_max - return + return FALSE if(extendlimit == 1) - to_chat(user, "Shuttle was already delayed.") - charge_counter = charge_max - return - for(var/mob/living/carbon/human/target in targets) - if(target.stat) - charge_counter = charge_max - return - if(is_shadow_or_thrall(target)) - to_chat(user, "[target] must not be an ally.") - charge_counter = charge_max - return - if(SSshuttle.emergency.mode != SHUTTLE_CALL) + if(show_message) + to_chat(user, "Shuttle was already delayed.") + return FALSE + if(SSshuttle.emergency.mode != SHUTTLE_CALL) + if(show_message) to_chat(user, "The shuttle must be inbound only to the station.") - charge_counter = charge_max - return - var/mob/living/carbon/human/M = target - user.visible_message("[user]'s eyes flash a bright red!", \ - "You begin to draw [M]'s life force.") - M.visible_message("[M]'s face falls slack, [M.p_their()] jaw slightly distending.", \ - "You are suddenly transported... far, far away...") - extendlimit = 1 - if(!do_after(user, 150, target = M)) - extendlimit = 0 - to_chat(M, "You are snapped back to reality, your haze dissipating!") - to_chat(user, "You have been interrupted. The draw has failed.") - return - to_chat(user, "You project [M]'s life force toward the approaching shuttle, extending its arrival duration!") - M.visible_message("[M]'s eyes suddenly flare red. They proceed to collapse on the floor, not breathing.", \ - "...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...") - M.death() - if(SSshuttle.emergency.mode == SHUTTLE_CALL) - var/more_minutes = 6000 - var/timer = SSshuttle.emergency.timeLeft(1) + more_minutes - GLOB.event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 10 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg') - SSshuttle.emergency.setTimer(timer) - SSshuttle.emergency.canRecall = FALSE - user.mind.spell_list.Remove(src) //Can only be used once! - qdel(src) + return FALSE + return ..() + +/obj/effect/proc_holder/spell/targeted/click/shadowling_extend_shuttle/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE + return !target.stat && !is_shadow_or_thrall(target) + + +/obj/effect/proc_holder/spell/targeted/click/shadowling_extend_shuttle/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/target = targets[1] + + user.visible_message("[user]'s eyes flash a bright red!", \ + "You begin to draw [target]'s life force.") + target.visible_message("[target]'s face falls slack, [target.p_their()] jaw slightly distending.", \ + "You are suddenly transported... far, far away...") + extendlimit = 1 + if(!do_after(user, 150, target = target)) + extendlimit = 0 + to_chat(target, "You are snapped back to reality, your haze dissipating!") + to_chat(user, "You have been interrupted. The draw has failed.") + return + to_chat(user, "You project [target]'s life force toward the approaching shuttle, extending its arrival duration!") + target.visible_message("[target]'s eyes suddenly flare red. They proceed to collapse on the floor, not breathing.", \ + "...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...") + target.death() + if(SSshuttle.emergency.mode == SHUTTLE_CALL) + var/more_minutes = 6000 + var/timer = SSshuttle.emergency.timeLeft(1) + more_minutes + GLOB.event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 10 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg') + SSshuttle.emergency.setTimer(timer) + SSshuttle.emergency.canRecall = FALSE + user.mind.spell_list.Remove(src) //Can only be used once! + qdel(src) // ASCENDANT ABILITIES BEYOND THIS POINT // -/obj/effect/proc_holder/spell/targeted/annihilate +/obj/effect/proc_holder/spell/targeted/click/annihilate name = "Annihilate" desc = "Gibs someone instantly." panel = "Ascendant" range = 7 - charge_max = 0 - clothes_req = 0 + charge_max = FALSE + clothes_req = FALSE action_icon_state = "annihilate" + selection_activated_message = "You start thinking about gibs. Left-click to cast at a target!" + selection_deactivated_message = "Your mind relaxes." + allowed_type = /mob/living/carbon/human -/obj/effect/proc_holder/spell/targeted/annihilate/cast(list/targets, mob/user = usr) +/obj/effect/proc_holder/spell/targeted/click/annihilate/cast(list/targets, mob/user = usr) var/mob/living/simple_animal/ascendant_shadowling/SHA = user if(SHA.phasing) to_chat(user, "You are not in the same plane of existence. Unphase first.") @@ -755,45 +717,42 @@ -/obj/effect/proc_holder/spell/targeted/hypnosis +/obj/effect/proc_holder/spell/targeted/click/hypnosis name = "Hypnosis" desc = "Instantly enthralls a human." panel = "Ascendant" range = 7 - charge_max = 0 - clothes_req = 0 + charge_max = FALSE + clothes_req = FALSE action_icon_state = "enthrall" -/obj/effect/proc_holder/spell/targeted/hypnosis/cast(list/targets, mob/user = usr) - var/mob/living/simple_animal/ascendant_shadowling/SHA = user - if(SHA.phasing) - charge_counter = charge_max - to_chat(user, "You are not in the same plane of existence. Unphase first.") - return + click_radius = -1 + selection_activated_message = "You start preparing to mindwash over a mortal mind. Left-click to cast at a target!" + selection_deactivated_message = "Your mind relaxes." + allowed_type = /mob/living/carbon/human - for(var/mob/living/carbon/human/target in targets) - if(is_shadow_or_thrall(target)) - to_chat(user, "You cannot enthrall an ally.") - charge_counter = charge_max - return - if(!target.ckey || !target.mind) - to_chat(user, "The target has no mind.") - charge_counter = charge_max - return - if(target.stat) - to_chat(user, "The target must be conscious.") - charge_counter = charge_max - return - if(!ishuman(target)) - to_chat(user, "You can only enthrall humans.") - charge_counter = charge_max - return +/obj/effect/proc_holder/spell/targeted/click/hypnosis/can_cast(mob/living/simple_animal/ascendant_shadowling/user = usr, charge_check = TRUE, show_message = FALSE) + if(!istype(user)) + return FALSE + if(user.phasing) + if(show_message) + to_chat(user, "You are not in the same plane of existence. Unphase first.") + return FALSE + return ..() - to_chat(user, "You instantly rearrange [target]'s memories, hyptonitizing [target.p_them()] into a thrall.") - to_chat(target, "An agonizing spike of pain drives into your mind, and--") - SSticker.mode.add_thrall(target.mind) - target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL - target.add_language("Shadowling Hivemind") +/obj/effect/proc_holder/spell/targeted/click/hypnosis/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE + return !is_shadow_or_thrall(target) && target.ckey && target.mind && !target.stat + +/obj/effect/proc_holder/spell/targeted/click/hypnosis/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/target = targets[1] + + to_chat(user, "You instantly rearrange [target]'s memories, hyptonitizing [target.p_them()] into a thrall.") + to_chat(target, "An agonizing spike of pain drives into your mind, and--") + SSticker.mode.add_thrall(target.mind) + target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL + target.add_language("Shadowling Hivemind") diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 5fc5e1e78cc..28c934f7d38 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -99,14 +99,14 @@ GLOBAL_LIST_INIT(possibleShadowlingNames, list("U'ruan", "Y`shej", "Nex", "Hel-u to_chat(H, "Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies.") H.ExtinguishMob() H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_vision(null)) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/enthrall(null)) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null)) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/enthrall(null)) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/glare(null)) H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/veil(null)) H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk(null)) H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze(null)) H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/collective_mind(null)) H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_regenarmor(null)) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle(null)) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/shadowling_extend_shuttle(null)) QDEL_NULL(H.hud_used) H.hud_used = new /datum/hud/human(H, ui_style2icon(H.client.prefs.UI_style), H.client.prefs.UI_style_color, H.client.prefs.UI_style_alpha) @@ -163,7 +163,7 @@ GLOBAL_LIST_INIT(possibleShadowlingNames, list("U'ruan", "Y`shej", "Nex", "Hel-u to_chat(M, "An immense pressure slams you onto the ground!") for(var/thing in GLOB.apcs) var/obj/machinery/power/apc/A = thing - A.overload_lighting() + INVOKE_ASYNC(A, /obj/machinery/power/apc.proc/overload_lighting) var/mob/living/simple_animal/ascendant_shadowling/A = new /mob/living/simple_animal/ascendant_shadowling(H.loc) A.announce("VYSHA NERADA YEKHEZET U'RUU!!", 5, 'sound/hallucinations/veryfar_noise.ogg') for(var/obj/effect/proc_holder/spell/S in H.mind.spell_list) @@ -172,8 +172,8 @@ GLOBAL_LIST_INIT(possibleShadowlingNames, list("U'ruan", "Y`shej", "Nex", "Hel-u H.mind.transfer_to(A) A.name = H.real_name A.languages = H.languages - A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/annihilate(null)) - A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/hypnosis(null)) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/annihilate(null)) + A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/hypnosis(null)) A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_phase_shift(null)) A.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/ascendant_storm(null)) A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit(null)) diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm index 4175883fc1a..a20b0e1654b 100644 --- a/code/game/gamemodes/steal_items.dm +++ b/code/game/gamemodes/steal_items.dm @@ -57,7 +57,7 @@ typepath = /obj/item/aicard location_override = "AI Satellite. An intellicard for transportation can be found in Tech Storage, Science Department or manufactured" -datum/theft_objective/ai/check_special_completion(var/obj/item/aicard/C) +/datum/theft_objective/ai/check_special_completion(var/obj/item/aicard/C) if(..()) for(var/mob/living/silicon/ai/A in C) if(istype(A, /mob/living/silicon/ai) && A.stat != 2) //See if any AI's are alive inside that card. diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index c7ab4490f48..e7c5b4541a8 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -82,22 +82,10 @@ /datum/game_mode/proc/auto_declare_completion_traitor() if(traitors.len) - var/text = "The traitors were:" + var/text = "The traitors were:
" for(var/datum/mind/traitor in traitors) var/traitorwin = 1 - - text += "
[traitor.key] was [traitor.name] (" - if(traitor.current) - if(traitor.current.stat == DEAD) - text += "died" - else - text += "survived" - if(traitor.current.real_name != traitor.name) - text += " as [traitor.current.real_name]" - else - text += "body destroyed" - text += ")" - + text += printplayer(traitor) var/TC_uses = 0 var/uplink_true = 0 @@ -131,12 +119,20 @@ if(traitorwin) - text += "
The [special_role_text] was successful!" + text += "
The [special_role_text] was successful!
" feedback_add_details("traitor_success","SUCCESS") else - text += "
The [special_role_text] has failed!" + text += "
The [special_role_text] has failed!
" feedback_add_details("traitor_success","FAIL") + if(length(SSticker.mode.implanted)) + text += "

The mindslaves were:
" + for(var/datum/mind/mindslave in SSticker.mode.implanted) + text += printplayer(mindslave) + var/datum/mind/master_mind = SSticker.mode.implanted[mindslave] + var/mob/living/carbon/human/master = master_mind.current + text += " (slaved by: [master])
" + var/phrases = jointext(GLOB.syndicate_code_phrase, ", ") var/responses = jointext(GLOB.syndicate_code_response, ", ") diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 3caf860383d..75748448527 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -279,6 +279,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha var/blood = 0 var/old_bloodtotal = 0 //used to see if we increased our blood total var/old_bloodusable = 0 //used to see if we increased our blood usable + var/blood_volume_warning = 9999 //Blood volume threshold for warnings if(owner.is_muzzled()) to_chat(owner, "[owner.wear_mask] prevents you from biting [H]!") draining = null @@ -291,13 +292,10 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha H.LAssailant = owner while(do_mob(owner, H, 50)) if(!(owner.mind in SSticker.mode.vampires)) - to_chat(owner, "Your fangs have disappeared!") + to_chat(owner, "Your fangs have disappeared!") return old_bloodtotal = bloodtotal old_bloodusable = bloodusable - if(!H.blood_volume) - to_chat(owner, "They've got no blood left to give.") - break if(H.stat < DEAD) if(H.ckey || H.player_ghosted) //Requires ckey regardless if monkey or humanoid, or the body has been ghosted before it died blood = min(20, H.blood_volume) // if they have less than 20 blood, give them the remnant else they get 20 blood @@ -312,6 +310,17 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha to_chat(owner, "You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""].") check_vampire_upgrade() H.blood_volume = max(H.blood_volume - 25, 0) + //Blood level warnings (Code 'borrowed' from Fulp) + if(H.blood_volume) + if(H.blood_volume <= BLOOD_VOLUME_BAD && blood_volume_warning > BLOOD_VOLUME_BAD) + to_chat(owner, "Your victim's blood volume is dangerously low.") + else if(H.blood_volume <= BLOOD_VOLUME_OKAY && blood_volume_warning > BLOOD_VOLUME_OKAY) + to_chat(owner, "Your victim's blood is at an unsafe level.") + blood_volume_warning = H.blood_volume //Set to blood volume, so that you only get the message once + else + to_chat(owner, "You have bled your victim dry!") + break + if(ishuman(owner)) var/mob/living/carbon/human/V = owner if(!H.ckey && !H.player_ghosted)//Only runs if there is no ckey and the body has not being ghosted while alive diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 7906deeb718..406ab50b70d 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -15,7 +15,7 @@ if(!gain_desc) gain_desc = "You have gained \the [src] ability." -/obj/effect/proc_holder/spell/vampire/cast_check(skipcharge = 0, mob/living/user = usr) +/obj/effect/proc_holder/spell/vampire/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/living/user = usr) if(!user.mind) return 0 if(!ishuman(user)) @@ -45,7 +45,7 @@ return 0 return ..() -/obj/effect/proc_holder/spell/vampire/can_cast(mob/user = usr) +/obj/effect/proc_holder/spell/vampire/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) if(!user.mind) return 0 if(!ishuman(user)) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 44dec855f82..cb0c277b1e6 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -61,7 +61,7 @@ switch(href_list["school"]) if("destruction") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/fireball(null)) to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.") if("bluespace") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) @@ -74,7 +74,7 @@ to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") if("robeless") M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/mind_transfer(null)) to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.") M.equip_to_slot_or_del(new /obj/item/radio/headset(M), slot_l_ear) @@ -836,6 +836,10 @@ GLOBAL_LIST_EMPTY(multiverse) var/wgw = sanitize(input(user, "What would you like the victim to say", "Voodoo", null) as text) target.say(wgw) log_game("[user][user.key] made [target][target.key] say [wgw] with a voodoo doll.") + log_say("Wicker doll say to [target][target.key]: [wgw]", user) + log_admin("[user][user.key] made [target][target.key] say [wgw] with a voodoo doll.") + user.create_log(SAY_LOG, "forced [target] to say [wgw] through [src].", target) + target.create_log(SAY_LOG, "was forced to say [wgw] through [src] by [user].", user) if("eyes") user.set_machine(src) user.reset_perspective(target) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index d0773947c21..efa3303c26b 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -132,7 +132,7 @@ /datum/spellbook_entry/horseman name = "Curse of the Horseman" - spell_type = /obj/effect/proc_holder/spell/targeted/horsemask + spell_type = /obj/effect/proc_holder/spell/targeted/click/horsemask log_name = "HH" category = "Offensive" @@ -144,7 +144,7 @@ /datum/spellbook_entry/fireball name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/fireball + spell_type = /obj/effect/proc_holder/spell/targeted/click/fireball log_name = "FB" category = "Offensive" @@ -257,7 +257,7 @@ /datum/spellbook_entry/mindswap name = "Mindswap" - spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer + spell_type = /obj/effect/proc_holder/spell/targeted/click/mind_transfer log_name = "MT" category = "Mobility" @@ -877,7 +877,7 @@ return /obj/item/spellbook/oneuse/fireball - spell = /obj/effect/proc_holder/spell/fireball + spell = /obj/effect/proc_holder/spell/targeted/click/fireball spellname = "fireball" icon_state = "bookfireball" desc = "This book feels warm to the touch." @@ -910,7 +910,7 @@ user.EyeBlind(10) /obj/item/spellbook/oneuse/mindswap - spell = /obj/effect/proc_holder/spell/targeted/mind_transfer + spell = /obj/effect/proc_holder/spell/targeted/click/mind_transfer spellname = "mindswap" icon_state = "bookmindswap" desc = "This book's cover is pristine, though its pages look ragged and torn." @@ -934,8 +934,8 @@ to_chat(user, "You stare at the book some more, but there doesn't seem to be anything else to learn...") return - var/obj/effect/proc_holder/spell/targeted/mind_transfer/swapper = new - swapper.cast(user, stored_swap, 1) + var/obj/effect/proc_holder/spell/targeted/click/mind_transfer/swapper = new + swapper.cast(user, stored_swap) to_chat(stored_swap, "You're suddenly somewhere else... and someone else?!") to_chat(user, "Suddenly you're staring at [src] again... where are you, who are you?!") @@ -966,7 +966,7 @@ user.Weaken(20) /obj/item/spellbook/oneuse/horsemask - spell = /obj/effect/proc_holder/spell/targeted/horsemask + spell = /obj/effect/proc_holder/spell/targeted/click/horsemask spellname = "horses" icon_state = "bookhorses" desc = "This book is more horse than your mind has room for." diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index a0bb4c349af..77972b00880 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -45,9 +45,8 @@ for(var/datum/mind/wizard in wizards) log_game("[key_name(wizard)] has been selected as a Wizard") forge_wizard_objectives(wizard) - //learn_basic_spells(wizard.current) equip_wizard(wizard.current) - name_wizard(wizard.current) + INVOKE_ASYNC(src, .proc/name_wizard, wizard.current) greet_wizard(wizard) if(use_huds) update_wiz_icons_added(wizard) @@ -89,17 +88,15 @@ var/wizard_name_first = pick(GLOB.wizard_first) var/wizard_name_second = pick(GLOB.wizard_second) var/randomname = "[wizard_name_first] [wizard_name_second]" - spawn(0) - var/newname = sanitize(copytext(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text,1,MAX_NAME_LEN)) + var/newname = sanitize(copytext(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text,1,MAX_NAME_LEN)) - if(!newname) - newname = randomname + if(!newname) + newname = randomname - wizard_mob.real_name = newname - wizard_mob.name = newname - if(wizard_mob.mind) - wizard_mob.mind.name = newname - return + wizard_mob.real_name = newname + wizard_mob.name = newname + if(wizard_mob.mind) + wizard_mob.mind.name = newname /datum/game_mode/proc/greet_wizard(var/datum/mind/wizard, var/you_are=1) addtimer(CALLBACK(wizard.current, /mob/.proc/playsound_local, null, 'sound/ambience/antag/ragesmages.ogg', 100, 0), 30) diff --git a/code/game/gamemodes/wizard/wizloadouts.dm b/code/game/gamemodes/wizard/wizloadouts.dm index c050b27f273..518b9a68ca8 100644 --- a/code/game/gamemodes/wizard/wizloadouts.dm +++ b/code/game/gamemodes/wizard/wizloadouts.dm @@ -18,7 +18,7 @@ Care should be taken in hiding the item you choose as your phylactery after using Bind Soul, as you cannot revive if it destroyed or too far from your body!

\ Provides Bind Soul, Ethereal Jaunt, Fireball, Rod Form, Disable Tech, and Greater Forcewall." log_name = "DL" - spells_path = list(/obj/effect/proc_holder/spell/targeted/lichdom, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/fireball, \ + spells_path = list(/obj/effect/proc_holder/spell/targeted/lichdom, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt, /obj/effect/proc_holder/spell/targeted/click/fireball, \ /obj/effect/proc_holder/spell/targeted/rod_form, /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech, /obj/effect/proc_holder/spell/targeted/forcewall/greater) is_ragin_restricted = TRUE diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 48ac91c72fa..ac533f0b7ef 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -426,6 +426,7 @@ //gets the alt title, failing that the actual job rank //this is unused +// THEN WHY IS IT STILL HERE?? -AA07, 2020-07-31 /obj/proc/sdsdsd() //GetJobDisplayName if(!istype(src, /obj/item/pda) && !istype(src,/obj/item/card/id)) return @@ -442,7 +443,7 @@ return "Unknown" -proc/GetIdCard(var/mob/living/carbon/human/H) +/proc/GetIdCard(var/mob/living/carbon/human/H) if(H.wear_id) var/id = H.wear_id.GetID() if(id) @@ -451,7 +452,7 @@ proc/GetIdCard(var/mob/living/carbon/human/H) var/obj/item/I = H.get_active_hand() return I.GetID() -proc/FindNameFromID(var/mob/living/carbon/human/H) +/proc/FindNameFromID(var/mob/living/carbon/human/H) ASSERT(istype(H)) var/obj/item/card/id/C = H.get_active_hand() if( istype(C) || istype(C, /obj/item/pda) ) @@ -480,7 +481,7 @@ proc/FindNameFromID(var/mob/living/carbon/human/H) if(ID) return ID.registered_name -proc/get_all_job_icons() //For all existing HUD icons +/proc/get_all_job_icons() //For all existing HUD icons return GLOB.joblist + list("Prisoner") /obj/proc/GetJobName() //Used in secHUD icon generation @@ -511,7 +512,7 @@ proc/get_all_job_icons() //For all existing HUD icons return "Unknown" //Return unknown if none of the above apply -proc/get_accesslist_static_data(num_min_region = REGION_GENERAL, num_max_region = REGION_COMMAND) +/proc/get_accesslist_static_data(num_min_region = REGION_GENERAL, num_max_region = REGION_COMMAND) var/list/retval for(var/i in num_min_region to num_max_region) var/list/accesses = list() diff --git a/code/game/jobs/job/central.dm b/code/game/jobs/job/central.dm index f91460ba234..8684ca7d1b0 100644 --- a/code/game/jobs/job/central.dm +++ b/code/game/jobs/job/central.dm @@ -94,7 +94,7 @@ ) cybernetic_implants = list( /obj/item/organ/internal/cyberimp/eyes/xray, - /obj/item/organ/internal/cyberimp/brain/anti_stun, + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/arm/combat/centcom ) diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 84f903dd2b1..a3333e1dc82 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -18,7 +18,7 @@ ACCESS_HEADS, ACCESS_CONSTRUCTION, ACCESS_SEC_DOORS, ACCESS_CE, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_MINISAT, ACCESS_MECHANIC, ACCESS_MINERAL_STOREROOM) minimal_player_age = 21 - exp_requirements = 300 + exp_requirements = 1200 exp_type = EXP_TYPE_ENGINEERING outfit = /datum/outfit/job/chief_engineer diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 2d1b091a10d..b1b81e0b849 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -16,7 +16,7 @@ ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_PSYCHIATRIST, ACCESS_MAINT_TUNNELS, ACCESS_PARAMEDIC, ACCESS_MINERAL_STOREROOM) minimal_player_age = 21 - exp_requirements = 300 + exp_requirements = 1200 exp_type = EXP_TYPE_MEDICAL outfit = /datum/outfit/job/cmo diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 684de933832..f6fdb02477b 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -18,7 +18,7 @@ ACCESS_RESEARCH, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_AI_UPLOAD, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_GATEWAY, ACCESS_XENOARCH, ACCESS_MINISAT, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM, ACCESS_NETWORK) minimal_player_age = 21 - exp_requirements = 300 + exp_requirements = 1200 exp_type = EXP_TYPE_SCIENCE // All science-y guys get bonuses for maxing out their tech. required_objectives = list( diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index a32656598df..6f4eb3759de 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -18,7 +18,7 @@ ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING, ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_PILOT, ACCESS_WEAPONS) minimal_player_age = 21 - exp_requirements = 300 + exp_requirements = 1200 exp_type = EXP_TYPE_SECURITY disabilities_allowed = 0 outfit = /datum/outfit/job/hos @@ -64,7 +64,7 @@ minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS) minimal_player_age = 21 exp_requirements = 600 - exp_type = EXP_TYPE_CREW + exp_type = EXP_TYPE_SECURITY outfit = /datum/outfit/job/warden /datum/outfit/job/warden diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 0858554ecf3..87ab2774384 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -13,7 +13,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca access = list() //See get_access() minimal_access = list() //See get_access() minimal_player_age = 30 - exp_requirements = 300 + exp_requirements = 1200 exp_type = EXP_TYPE_COMMAND disabilities_allowed = 0 outfit = /datum/outfit/job/captain @@ -67,7 +67,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca req_admin_notify = 1 is_command = 1 minimal_player_age = 21 - exp_requirements = 300 + exp_requirements = 1200 exp_type = EXP_TYPE_COMMAND access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_FORENSICS_LOCKERS, ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS, diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 09328865b59..fda831242f9 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -458,6 +458,7 @@ total_positions = 0 spawn_positions = 0 supervisors = "the head of personnel" + department_head = list("Head of Personnel") selection_color = "#dddddd" access = list(ACCESS_MAINT_TUNNELS, ACCESS_GATEWAY, ACCESS_EVA, ACCESS_EXTERNAL_AIRLOCKS) minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_GATEWAY, ACCESS_EVA, ACCESS_EXTERNAL_AIRLOCKS) diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm index b39eed344ae..bfd9c4520f5 100644 --- a/code/game/jobs/job/support_chaplain.dm +++ b/code/game/jobs/job/support_chaplain.dm @@ -26,7 +26,7 @@ /obj/item/camera/spooky = 1, /obj/item/nullrod = 1 ) - + /datum/outfit/job/chaplain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) . = ..() @@ -77,7 +77,7 @@ new_deity = deity_name B.deity_name = new_deity - H.AddSpell(new /obj/effect/proc_holder/spell/targeted/chaplain_bless(null)) + H.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/chaplain_bless(null)) var/accepted = 0 var/outoftime = 0 diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 81cc54aa3c3..2f8e426e030 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -69,7 +69,7 @@ GLOBAL_LIST_INIT(supply_positions, list( "Shaft Miner" )) -GLOBAL_LIST_INIT(service_positions, (support_positions - supply_positions + list("Head of Personnel"))) +GLOBAL_LIST_INIT(service_positions, (list("Head of Personnel") + (support_positions - supply_positions))) GLOBAL_LIST_INIT(security_positions, list( diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm index d9243005ead..a2a69fad357 100644 --- a/code/game/machinery/Freezer.dm +++ b/code/game/machinery/Freezer.dm @@ -104,59 +104,46 @@ to_chat(user, "Close the maintenance panel first.") return - src.ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/unary/cold_sink/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/atmospherics/unary/cold_sink/freezer/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 540, 300) - // open the new ui window + ui = new(user, src, ui_key, "GasFreezer", "Gas Cooling System", 540, 200) ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) -/obj/machinery/atmospherics/unary/cold_sink/freezer/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] - data["on"] = on ? 1 : 0 - data["gasPressure"] = round(air_contents.return_pressure()) - data["gasTemperature"] = round(air_contents.temperature) - data["gasTemperatureCelsius"] = round(air_contents.temperature - T0C,1) +/obj/machinery/atmospherics/unary/cold_sink/freezer/tgui_data(mob/user) + var/list/data = list() + data["on"] = on + data["pressure"] = round(air_contents.return_pressure()) + data["temperature"] = round(air_contents.temperature) + data["temperatureCelsius"] = round(air_contents.temperature - T0C, 1) if(air_contents.total_moles() == 0 && air_contents.temperature == 0) - data["gasTemperatureCelsius"] = 0 - data["minGasTemperature"] = round(min_temperature) - data["maxGasTemperature"] = round(T20C) - data["targetGasTemperature"] = round(current_temperature) - data["targetGasTemperatureCelsius"] = round(current_temperature - T0C,1) - - var/temp_class = "good" - if(air_contents.temperature > (T0C - 20)) - temp_class = "bad" - else if(air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100)) - temp_class = "average" - data["gasTemperatureClass"] = temp_class + data["temperatureCelsius"] = 0 + data["min"] = round(min_temperature) + data["max"] = round(T20C) + data["target"] = round(current_temperature) + data["targetCelsius"] = round(current_temperature - T0C, 1) return data -/obj/machinery/atmospherics/unary/cold_sink/freezer/Topic(href, href_list) +/obj/machinery/atmospherics/unary/cold_sink/freezer/tgui_act(action, params) if(..()) - return 1 - if(href_list["toggleStatus"]) - src.on = !src.on - update_icon() - else if(href_list["minimum"]) - current_temperature = min_temperature - else if(href_list["maximum"]) - current_temperature = T20C - else if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - src.current_temperature = min(T20C, src.current_temperature+amount) - else - src.current_temperature = max(min_temperature, src.current_temperature+amount) - src.add_fingerprint(usr) - return 1 + return + add_fingerprint(usr) + . = TRUE + + switch(action) + if("power") + on = !on + update_icon() + if("minimum") + current_temperature = min_temperature + if("maximum") + current_temperature = T20C + if("temp") + var/amount = params["temp"] + amount = text2num(amount) + current_temperature = clamp(amount, T20C, min_temperature) /obj/machinery/atmospherics/unary/cold_sink/freezer/power_change() ..() @@ -273,57 +260,46 @@ if(panel_open) to_chat(user, "Close the maintenance panel first.") return - src.ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/unary/heat_reservoir/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/atmospherics/unary/heat_reservoir/heater/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 540, 300) - // open the new ui window + ui = new(user, src, ui_key, "GasFreezer", "Gas Heating System", 540, 200) ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) -/obj/machinery/atmospherics/unary/heat_reservoir/heater/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] - data["on"] = on ? 1 : 0 - data["gasPressure"] = round(air_contents.return_pressure()) - data["gasTemperature"] = round(air_contents.temperature) - data["gasTemperatureCelsius"] = round(air_contents.temperature - T0C,1) +/obj/machinery/atmospherics/unary/heat_reservoir/heater/tgui_data(mob/user) + var/list/data = list() + data["on"] = on + data["pressure"] = round(air_contents.return_pressure()) + data["temperature"] = round(air_contents.temperature) + data["temperatureCelsius"] = round(air_contents.temperature - T0C, 1) if(air_contents.total_moles() == 0 && air_contents.temperature == 0) - data["gasTemperatureCelsius"] = 0 - data["minGasTemperature"] = round(T20C) - data["maxGasTemperature"] = round(T20C+max_temperature) - data["targetGasTemperature"] = round(current_temperature) - data["targetGasTemperatureCelsius"] = round(current_temperature - T0C,1) - - var/temp_class = "normal" - if(air_contents.temperature > (T20C+40)) - temp_class = "bad" - data["gasTemperatureClass"] = temp_class + data["temperatureCelsius"] = 0 + data["min"] = round(T20C) + data["max"] = round(T20C + max_temperature) + data["target"] = round(current_temperature) + data["targetCelsius"] = round(current_temperature - T0C, 1) return data -/obj/machinery/atmospherics/unary/heat_reservoir/heater/Topic(href, href_list) +/obj/machinery/atmospherics/unary/heat_reservoir/heater/tgui_act(action, params) if(..()) - return 1 - if(href_list["toggleStatus"]) - src.on = !src.on - update_icon() - else if(href_list["minimum"]) - current_temperature = T20C - else if(href_list["maximum"]) - current_temperature = max_temperature + T20C - else if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - src.current_temperature = min((T20C+max_temperature), src.current_temperature+amount) - else - src.current_temperature = max(T20C, src.current_temperature+amount) - src.add_fingerprint(usr) - return 1 + return + add_fingerprint(usr) + . = TRUE + + switch(action) + if("power") + on = !on + update_icon() + if("minimum") + current_temperature = T20C + if("maximum") + current_temperature = max_temperature + T20C + if("temp") + var/amount = params["temp"] + amount = text2num(amount) + current_temperature = clamp(amount, T20C, T20C + max_temperature) /obj/machinery/atmospherics/unary/heat_reservoir/heater/power_change() ..() diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 3c09da548f5..ea273850d90 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -353,7 +353,7 @@ update_flag if(valve_open) logmsg = "Valve was opened by [key_name(usr)], starting a transfer into the [holding || "air"].
" if(!holding) - logmsg = "Valve was opened by [key_name(usr)], starting a transfer into the [holding || "air"].
" + logmsg = "Valve was opened by [key_name(usr)], starting a transfer into the air.
" if(air_contents.toxins > 0) message_admins("[key_name_admin(usr)] opened a canister that contains plasma in [get_area(src)]! (JMP)") log_admin("[key_name(usr)] opened a canister that contains plasma at [get_area(src)]: [x], [y], [z]") @@ -367,8 +367,9 @@ update_flag if("eject") if(holding) if(valve_open) + if(air_contents && (air_contents.toxins > 0 || air_contents.sleeping_agent > 0)) + message_admins("[ADMIN_LOOKUPFLW(usr)] removed [holding] from [src] with valve still open at [ADMIN_VERBOSEJMP(src)] releasing contents into the air.") release_log += "[key_name(usr)] removed the [holding], leaving the valve open and transferring into the air
" - message_admins("[ADMIN_LOOKUPFLW(usr)] removed [holding] from [src] with valve still open at [ADMIN_VERBOSEJMP(src)] releasing contents into the air.") investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transferring into the air.", "atmos") replace_tank(usr, FALSE) if("recolor") diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index 4d54b162466..8d974f97a70 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -1,21 +1,26 @@ + +/// The maximum `target_pressure` you can set on the pump. Equates to about 1013.25 kPa. +#define MAX_TARGET_PRESSURE 10 * ONE_ATMOSPHERE +/// The pump will be siphoning gas. +#define DIRECTION_IN 0 +/// The pump will be pumping gas out. +#define DIRECTION_OUT 1 + /obj/machinery/portable_atmospherics/pump name = "Portable Air Pump" - icon = 'icons/obj/atmos.dmi' icon_state = "psiphon:0" - density = 1 - - var/on = 0 - var/direction_out = 0 //0 = siphoning, 1 = releasing - var/target_pressure = 100 - - var/pressuremin = 0 - var/pressuremax = 10 * ONE_ATMOSPHERE - + density = TRUE volume = 1000 + /// If the pump is turned on or off. + var/on = FALSE + /// The direction the pump is operating in. This should be either `DIRECTION_IN` or `DIRECTION_OUT`. + var/direction = DIRECTION_IN + /// The desired pressure the pump should be outputting, either into the atmosphere, or into a holding tank. + var/target_pressure = 101.325 /obj/machinery/portable_atmospherics/pump/update_icon() - src.overlays = 0 + overlays = 0 if(on) icon_state = "psiphon:1" @@ -39,7 +44,7 @@ on = !on if(prob(100/severity)) - direction_out = !direction_out + direction = !direction target_pressure = rand(0,1300) update_icon() @@ -54,7 +59,7 @@ environment = holding.air_contents else environment = loc.return_air() - if(direction_out) + if(direction == DIRECTION_OUT) var/pressure_delta = target_pressure - environment.return_pressure() //Can not have a pressure delta that would cause environment pressure > tank pressure @@ -87,9 +92,7 @@ air_update_turf() air_contents.merge(removed) - //src.update_icon() - src.updateDialog() return /obj/machinery/portable_atmospherics/pump/return_air() @@ -102,72 +105,74 @@ if(on) on = FALSE update_icon() - else if(on && holding && direction_out) + else if(on && holding && direction == DIRECTION_OUT) investigate_log("[key_name(user)] started a transfer into [holding].
", "atmos") -/obj/machinery/portable_atmospherics/pump/attack_ai(var/mob/user as mob) - src.add_hiddenprint(user) - return src.attack_hand(user) +/obj/machinery/portable_atmospherics/pump/attack_ai(mob/user) + add_hiddenprint(user) + return attack_hand(user) -/obj/machinery/portable_atmospherics/pump/attack_ghost(var/mob/user as mob) - return src.attack_hand(user) +/obj/machinery/portable_atmospherics/pump/attack_ghost(mob/user) + return attack_hand(user) -/obj/machinery/portable_atmospherics/pump/attack_hand(var/mob/user as mob) - ui_interact(user) +/obj/machinery/portable_atmospherics/pump/attack_hand(mob/user) + tgui_interact(user) -/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.physical_state) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/portable_atmospherics/pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "portpump.tmpl", "Portable Pump", 480, 400, state = state) - // open the new ui window + ui = new(user, src, ui_key, "PortablePump", "Portable Pump", 434, 377, master_ui, state) ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + ui.set_autoupdate(TRUE) -/obj/machinery/portable_atmospherics/pump/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.physical_state) - var/data[0] - data["portConnected"] = connected_port ? 1 : 0 - data["tankPressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0) - data["targetpressure"] = round(target_pressure) - data["pump_dir"] = direction_out - data["minpressure"] = round(pressuremin) - data["maxpressure"] = round(pressuremax) - data["on"] = on ? 1 : 0 - - data["hasHoldingTank"] = holding ? 1 : 0 +/obj/machinery/portable_atmospherics/pump/tgui_data(mob/user) + var/list/data = list( + "on" = on, + "direction" = direction, + "port_connected" = connected_port ? TRUE : FALSE, + "max_target_pressure" = MAX_TARGET_PRESSURE, + "target_pressure" = round(target_pressure, 0.001), + "tank_pressure" = air_contents.return_pressure() > 0 ? round(air_contents.return_pressure(), 0.001) : 0 + ) if(holding) - data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)) + data["has_holding_tank"] = TRUE + data["holding_tank"] = list("name" = holding.name, "tank_pressure" = holding.air_contents.return_pressure() > 0 ? round(holding.air_contents.return_pressure(), 0.001) : 0) + else + data["has_holding_tank"] = FALSE return data -/obj/machinery/portable_atmospherics/pump/Topic(href, href_list) +/obj/machinery/portable_atmospherics/pump/tgui_act(action, list/params) if(..()) - return 1 + return - if(href_list["power"]) - on = !on - if(on && direction_out) - investigate_log("[key_name(usr)] started a transfer into [holding].
", "atmos") - update_icon() + switch(action) + if("power") + on = !on + if(on && direction == DIRECTION_OUT) + investigate_log("[key_name(usr)] started a transfer into [holding].
", "atmos") + update_icon() + return TRUE - if(href_list["direction"]) - direction_out = !direction_out - if(on && holding) - investigate_log("[key_name(usr)] started a transfer into [holding].
", "atmos") + if("set_direction") + if(text2num(params["direction"]) == DIRECTION_IN) + direction = DIRECTION_IN + else + direction = DIRECTION_OUT + if(on && holding) + investigate_log("[key_name(usr)] started a transfer into [holding].
", "atmos") + return TRUE - if(href_list["remove_tank"]) - if(holding) - on = FALSE - holding.loc = loc - holding = null - update_icon() + if("remove_tank") + if(holding) + on = FALSE + holding.forceMove(get_turf(src)) + holding = null + update_icon() + return TRUE - if(href_list["pressure_adj"]) - var/diff = text2num(href_list["pressure_adj"]) - target_pressure = clamp(target_pressure+diff, pressuremin, pressuremax) - update_icon() + if("set_pressure") + target_pressure = clamp(text2num(params["pressure"]), 0, MAX_TARGET_PRESSURE) + return TRUE - src.add_fingerprint(usr) + add_fingerprint(usr) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 5c1b84d8cba..3fffc598334 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -24,7 +24,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 - var/busy = 0 + var/busy = FALSE var/prod_coeff var/datum/wires/autolathe/wires = null @@ -33,7 +33,7 @@ var/list/datum/design/matching_designs var/temp_search var/selected_category - var/screen = 1 + var/list/recipiecache = list() var/list/categories = list("Tools", "Electronics", "Construction", "Communication", "Security", "Machinery", "Medical", "Miscellaneous", "Dinnerware", "Imported") @@ -79,63 +79,121 @@ if(panel_open) wires.Interact(user) else - ui_interact(user) + tgui_interact(user) -/obj/machinery/autolathe/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/autolathe/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "autolathe.tmpl", name, 800, 550) + ui = new(user, src, ui_key, "Autolathe", name, 750, 700, master_ui, state) ui.open() -/obj/machinery/autolathe/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) + +/obj/machinery/autolathe/tgui_static_data(mob/user) + var/list/data = list() + data["categories"] = categories + if(!recipiecache.len) + var/list/recipes = list() + for(var/v in files.known_designs) + var/datum/design/D = files.known_designs[v] + var/list/cost_list = design_cost_data(D) + var/list/matreq = list() + for(var/list/x in cost_list) + if(!x["amount"]) + continue + if(x["name"] == "metal") // Do not use MAT_METAL or MAT_GLASS here. + matreq["metal"] = x["amount"] + if(x["name"] == "glass") + matreq["glass"] = x["amount"] + var/obj/item/I = D.build_path + var/maxmult = 1 + if(ispath(D.build_path, /obj/item/stack)) + maxmult = D.maxstack + recipes.Add(list(list( + "name" = D.name, + "category" = D.category, + "uid" = D.UID(), + "requirements" = matreq, + "hacked" = ("hacked" in D.category) ? TRUE : FALSE, + "max_multiplier" = maxmult, + "image" = "[icon2base64(icon(initial(I.icon), initial(I.icon_state), SOUTH, 1))]" + ))) + recipiecache = recipes + data["recipes"] = recipiecache + return data + +/obj/machinery/autolathe/tgui_data(mob/user) + var/list/data = list() //..() var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/data[0] - data["screen"] = screen data["total_amount"] = materials.total_amount data["max_amount"] = materials.max_amount + data["fill_percent"] = round((materials.total_amount / materials.max_amount) * 100) data["metal_amount"] = materials.amount(MAT_METAL) data["glass_amount"] = materials.amount(MAT_GLASS) - switch(screen) - if(AUTOLATHE_MAIN_MENU) - data["uid"] = UID() - data["categories"] = categories - if(AUTOLATHE_CATEGORY_MENU) - data["selected_category"] = selected_category - var/list/designs = list() - data["designs"] = designs - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(selected_category in D.category)) - continue - var/list/design = list() - designs[++designs.len] = design - design["name"] = D.name - design["id"] = D.id - design["disabled"] = disabled || !can_build(D) ? "disabled" : null - if(ispath(D.build_path, /obj/item/stack)) - design["max_multiplier"] = min(D.maxstack, D.materials[MAT_METAL] ? round(materials.amount(MAT_METAL) / D.materials[MAT_METAL]) : INFINITY, D.materials[MAT_GLASS] ? round(materials.amount(MAT_GLASS) / D.materials[MAT_GLASS]) : INFINITY) - else - design["max_multiplier"] = null - design["materials"] = design_cost_data(D) - if(AUTOLATHE_SEARCH_MENU) - data["search"] = temp_search - var/list/designs = list() - data["designs"] = designs - for(var/datum/design/D in matching_designs) - var/list/design = list() - designs[++designs.len] = design - design["name"] = D.name - design["id"] = D.id - design["disabled"] = disabled || !can_build(D) ? "disabled" : null - if(ispath(D.build_path, /obj/item/stack)) - design["max_multiplier"] = min(D.maxstack, D.materials[MAT_METAL] ? round(materials.amount(MAT_METAL) / D.materials[MAT_METAL]) : INFINITY, D.materials[MAT_GLASS] ? round(materials.amount(MAT_GLASS) / D.materials[MAT_GLASS]) : INFINITY) - else - design["max_multiplier"] = null - design["materials"] = design_cost_data(D) - - data = queue_data(data) + data["busyname"] = FALSE + data["busyamt"] = 1 + if(length(being_built) > 0) + var/datum/design/D = being_built[1] + data["busyname"] = istype(D) && D.name ? D.name : FALSE + data["busyamt"] = length(being_built) > 1 ? being_built[2] : 1 + data["showhacked"] = hacked ? TRUE : FALSE + data["buildQueue"] = queue + data["buildQueueLen"] = queue.len return data +/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return FALSE + + add_fingerprint(usr) + + . = TRUE + switch(action) + if("clear_queue") + queue = list() + if("remove_from_queue") + var/index = text2num(params["remove_from_queue"]) + if(isnum(index) && ISINRANGE(index, 1, queue.len)) + remove_from_queue(index) + to_chat(usr, "Removed item from queue.") + if("make") + BuildTurf = loc + var/datum/design/design_last_ordered + design_last_ordered = locateUID(params["make"]) + if(!istype(design_last_ordered)) + to_chat(usr, "Invalid design") + return + if(!(design_last_ordered.build_type & AUTOLATHE)) + to_chat(usr, "Invalid design (not buildable in autolathe, report this error.)") + return + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + if(design_last_ordered.materials["$metal"] > materials.amount(MAT_METAL)) + to_chat(usr, "Invalid design (not enough metal)") + return + if(design_last_ordered.materials["$glass"] > materials.amount(MAT_GLASS)) + to_chat(usr, "Invalid design (not enough glass)") + return + if(!hacked && ("hacked" in design_last_ordered.category)) + to_chat(usr, "Invalid design (lathe requires hacking)") + return + //multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier + var/multiplier = text2num(params["multiplier"]) + var/max_multiplier = min(design_last_ordered.maxstack, design_last_ordered.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/design_last_ordered.materials[MAT_METAL]):INFINITY,design_last_ordered.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/design_last_ordered.materials[MAT_GLASS]):INFINITY) + var/is_stack = ispath(design_last_ordered.build_path, /obj/item/stack) + + if(!is_stack && (multiplier > 1)) + return + if(!(multiplier in list(1, 10, 25, max_multiplier))) //"enough materials ?" is checked in the build proc + message_admins("Player [key_name_admin(usr)] attempted to pass invalid multiplier [multiplier] to an autolathe in tgui_act. Possible href exploit.") + return + if((queue.len + 1) < queue_max_len) + add_to_queue(design_last_ordered, multiplier) + else + to_chat(usr, "The autolathe queue is full!") + if(!busy) + busy = TRUE + process_queue() + busy = FALSE + /obj/machinery/autolathe/proc/design_cost_data(datum/design/D) var/list/data = list() var/coeff = get_coeff(D) @@ -185,14 +243,21 @@ if(istype(O, /obj/item/disk/design_disk)) var/obj/item/disk/design_disk/D = O if(D.blueprint) + if(!(D.blueprint.build_type & AUTOLATHE)) // otherwise, would silently fail in AddDesign2Known + to_chat(user, "This design is not compatible with the autolathe.") + return 1 user.visible_message("[user] begins to load \the [O] in \the [src]...", "You begin to load a design from \the [O]...", "You hear the chatter of a floppy drive.") playsound(get_turf(src), 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - busy = 1 + busy = TRUE if(do_after(user, 14.4, target = src)) + if(!("Imported" in D.blueprint.category)) // R&D should always ensure this is set on design disks, but it doesn't. + D.blueprint.category += "Imported" // now it will actually show up in the list. files.AddDesign2Known(D.blueprint) - busy = 0 + recipiecache = list() + SStgui.close_uis(src) // forces all connected users to re-open the TGUI. Imported entries won't show otherwise due to static_data + busy = FALSE else to_chat(user, "That disk does not have a design on it!") return 1 @@ -222,7 +287,6 @@ to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.") return if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", I)) - SSnanoui.update_uis(src) I.play_tool_sound(user, I.tool_volume) /obj/machinery/autolathe/wirecutter_act(mob/user, obj/item/I) @@ -254,7 +318,7 @@ if(MAT_GLASS) flick("autolathe_r", src)//plays glass insertion animation use_power(min(1000, amount_inserted / 100)) - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/autolathe/attack_ghost(mob/user) interact(user) @@ -264,79 +328,6 @@ return interact(user) -/obj/machinery/autolathe/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["menu"]) - screen = text2num(href_list["menu"]) - - if(href_list["category"]) - selected_category = href_list["category"] - screen = AUTOLATHE_CATEGORY_MENU - - if(href_list["make"]) - BuildTurf = loc - - ///////////////// - //href protection - var/datum/design/design_last_ordered - design_last_ordered = files.FindDesignByID(href_list["make"]) //check if it's a valid design - if(!design_last_ordered) - return - if(!(design_last_ordered.build_type & AUTOLATHE)) - return - - //multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier - var/multiplier = text2num(href_list["multiplier"]) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/max_multiplier = min(design_last_ordered.maxstack, design_last_ordered.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/design_last_ordered.materials[MAT_METAL]):INFINITY,design_last_ordered.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/design_last_ordered.materials[MAT_GLASS]):INFINITY) - var/is_stack = ispath(design_last_ordered.build_path, /obj/item/stack) - - if(!is_stack && (multiplier > 1)) - return - if(!(multiplier in list(1, 10, 25, max_multiplier))) //"enough materials ?" is checked in the build proc - return - ///////////////// - - if((queue.len + 1) < queue_max_len) - add_to_queue(design_last_ordered,multiplier) - else - to_chat(usr, "The autolathe queue is full!") - if(!busy) - busy = 1 - process_queue() - busy = 0 - - if(href_list["remove_from_queue"]) - var/index = text2num(href_list["remove_from_queue"]) - if(isnum(index) && ISINRANGE(index, 1, queue.len)) - remove_from_queue(index) - if(href_list["queue_move"] && href_list["index"]) - var/index = text2num(href_list["index"]) - var/new_index = index + text2num(href_list["queue_move"]) - if(isnum(index) && isnum(new_index)) - if(ISINRANGE(new_index, 1, queue.len)) - queue.Swap(index,new_index) - if(href_list["clear_queue"]) - queue = list() - if(href_list["search"]) - if(href_list["to_search"]) - temp_search = href_list["to_search"] - if(!temp_search) - return - matching_designs.Cut() - - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(findtext(D.name, temp_search)) - matching_designs.Add(D) - - screen = AUTOLATHE_SEARCH_MENU - - SSnanoui.update_uis(src) - return 1 - /obj/machinery/autolathe/RefreshParts() var/tot_rating = 0 prod_coeff = 0 @@ -371,7 +362,7 @@ else var/list/materials_used = list(MAT_METAL=metal_cost/coeff, MAT_GLASS=glass_cost/coeff) materials.use_amount(materials_used) - SSnanoui.update_uis(src) + SStgui.update_uis(src) sleep(32/coeff) if(is_stack) var/obj/item/stack/S = new D.build_path(BuildTurf) @@ -380,7 +371,7 @@ var/obj/item/new_item = new D.build_path(BuildTurf) new_item.materials[MAT_METAL] /= coeff new_item.materials[MAT_GLASS] /= coeff - SSnanoui.update_uis(src) + SStgui.update_uis(src) desc = initial(desc) /obj/machinery/autolathe/proc/can_build(datum/design/D, multiplier = 1, custom_metal, custom_glass) @@ -455,7 +446,6 @@ D = listgetindex(listgetindex(queue, 1),1) multiplier = listgetindex(listgetindex(queue,1),2) being_built = new /list() - //visible_message("[bicon(src)] \The [src] beeps, \"Queue processing finished successfully.\"") /obj/machinery/autolathe/proc/adjust_hacked(hack) hacked = hack @@ -468,6 +458,8 @@ for(var/datum/design/D in files.known_designs) if("hacked" in D.category) files.known_designs -= D.id + SStgui.close_uis(src) // forces all connected users to re-open the TGUI, thus adding/removing hacked entries from lists + recipiecache = list() /obj/machinery/autolathe/proc/check_hacked_callback() if(!wires.is_cut(WIRE_AUTOLATHE_HACK)) diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 44b55ed1d2c..57554d92867 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -288,7 +288,7 @@ That prevents a few funky behaviors. //The type of interaction, the player performing the operation, the AI itself, and the card object, if any. -atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) +/atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) if(istype(card)) if(card.flush) to_chat(user, "ERROR: AI flush is in progress, cannot execute transfer protocol.") diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 0d715fe5759..38ec50abc6e 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -22,23 +22,22 @@ return ..() /obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob) - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/computer/aifixer/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ai_fixer.tmpl", "AI System Integrity Restorer", 550, 500) + ui = new(user, src, ui_key, "AIFixer", name, 550, 500, master_ui, state) ui.open() - ui.set_auto_update(1) -/obj/machinery/computer/aifixer/ui_data(mob/user, datum/topic_state/state) +/obj/machinery/computer/aifixer/tgui_data(mob/user, datum/topic_state/state) var/data[0] + data["occupant"] = (occupant ? occupant.name : null) // a null occupant isn't passed on if this is below the if. if(occupant) - data["occupant"] = occupant.name data["reference"] = "\ref[occupant]" data["integrity"] = (occupant.health+100)/2 data["stat"] = occupant.stat @@ -48,45 +47,49 @@ var/laws[0] for(var/datum/ai_law/law in occupant.laws.all_laws()) - laws.Add(list(list("law" = law.law, "number" = law.get_index()))) - + if(law in occupant.laws.ion_laws) // If we're an ion law, give it an ion index code + laws.Add(ionnum() + ". " + law.law) + else + laws.Add(num2text(law.get_index()) + ". " + law.law) data["laws"] = laws + data["has_laws"] = length(laws) return data -/obj/machinery/computer/aifixer/Topic(href, href_list) +/obj/machinery/computer/aifixer/tgui_act(action, params) if(..()) - return 1 + return + switch(action) + if("fix") + if(active) // Prevent from starting a fix while fixing. + to_chat(usr, "You are already fixing this AI!") + return + active = TRUE + INVOKE_ASYNC(src, .proc/fix_ai) + add_fingerprint(usr) - if(href_list["fix"]) - active = 1 - while(occupant.health < 100) - occupant.adjustOxyLoss(-1, FALSE) - occupant.adjustFireLoss(-1, FALSE) - occupant.adjustToxLoss(-1, FALSE) - occupant.adjustBruteLoss(-1, FALSE) - occupant.updatehealth() - if(occupant.health >= 0 && occupant.stat == DEAD) - occupant.update_revive() - occupant.lying = 0 - update_icon() - sleep(10) - active = 0 - add_fingerprint(usr) + if("wireless") + occupant.control_disabled = !occupant.control_disabled - if(href_list["wireless"]) - var/wireless = text2num(href_list["wireless"]) - if(wireless == 0 || wireless == 1) - occupant.control_disabled = wireless + if("radio") + occupant.aiRadio.disabledAi = !occupant.aiRadio.disabledAi - if(href_list["radio"]) - var/radio = text2num(href_list["radio"]) - if(radio == 0 || radio == 1) - occupant.aiRadio.disabledAi = radio - - SSnanoui.update_uis(src) update_icon() - return + return TRUE + +/obj/machinery/computer/aifixer/proc/fix_ai() // Can we fix it? Probrably. + while(occupant.health < 100) + occupant.adjustOxyLoss(-1, FALSE) + occupant.adjustFireLoss(-1, FALSE) + occupant.adjustToxLoss(-1, FALSE) + occupant.adjustBruteLoss(-1, FALSE) + occupant.updatehealth() + if(occupant.health >= 0 && occupant.stat == DEAD) + occupant.update_revive() + occupant.lying = FALSE + update_icon() + sleep(10) + active = FALSE /obj/machinery/computer/aifixer/update_icon() ..() diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 3f8fc080bf8..cfe82db29e8 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -130,6 +130,10 @@ // adding a template with the key "mapHeader" replaces the map header content ui.add_template("mapHeader", "sec_camera_map_header.tmpl") + // Send nanomaps + var/datum/asset/nanomaps = get_asset_datum(/datum/asset/simple/nanomaps) + nanomaps.send(user) + ui.open() /obj/machinery/computer/security/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 98f56feeb6a..7211970fd14 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -2,6 +2,12 @@ //increase the slots of many jobs. GLOBAL_VAR_INIT(time_last_changed_position, 0) +#define IDCOMPUTER_SCREEN_TRANSFER 0 +#define IDCOMPUTER_SCREEN_SLOTS 1 +#define IDCOMPUTER_SCREEN_ACCESS 2 +#define IDCOMPUTER_SCREEN_RECORDS 3 +#define IDCOMPUTER_SCREEN_DEPT 4 + /obj/machinery/computer/card name = "identification computer" desc = "Terminal for programming Nanotrasen employee ID cards to access parts of the station." @@ -12,9 +18,9 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) light_color = LIGHT_COLOR_LIGHTBLUE var/obj/item/card/id/scan = null var/obj/item/card/id/modify = null - var/mode = 0.0 - var/printing = null + var/mode = 0 var/target_dept = 0 //Which department this computer has access to. 0=all departments + var/obj/item/radio/Radio //Cooldown for closing positions in seconds //if set to -1: No cooldown... probably a bad idea @@ -54,15 +60,27 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) //Assoc array: "JobName" = (int) var/list/opened_positions = list() + +/obj/machinery/computer/card/Initialize() + ..() + Radio = new /obj/item/radio(src) + Radio.listening = 0 + Radio.config(list("Command" = 0)) + Radio.follow_target = src + +/obj/machinery/computer/card/Destroy() + QDEL_NULL(Radio) + return ..() + /obj/machinery/computer/card/proc/is_centcom() - return istype(src, /obj/machinery/computer/card/centcom) + return FALSE /obj/machinery/computer/card/proc/is_authenticated(var/mob/user) if(user.can_admin_interact()) - return 1 + return TRUE if(scan) return check_access(scan) - return 0 + return FALSE /obj/machinery/computer/card/proc/get_target_rank() return modify && modify.assignment ? modify.assignment : "Unassigned" @@ -134,18 +152,18 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) if(!istype(id_card)) return ..() - if(!scan && (ACCESS_CHANGE_IDS in id_card.access)) + if(!scan && check_access(id_card)) user.drop_item() - id_card.loc = src + id_card.forceMove(src) scan = id_card playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) else if(!modify) user.drop_item() - id_card.loc = src + id_card.forceMove(src) modify = id_card playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - SSnanoui.update_uis(src) + SStgui.update_uis(src) attack_hand(user) //Check if you can't touch a job in any way whatsoever @@ -156,68 +174,123 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) /obj/machinery/computer/card/proc/job_blacklisted_partial(datum/job/job) return (job.type in blacklisted_partial) -//Logic check for Topic() if you can open the job +// Logic check for if you can open the job /obj/machinery/computer/card/proc/can_open_job(datum/job/job) if(job) - if(!job_blacklisted_full(job) && !job_blacklisted_partial(job) && job_in_department(job, FALSE)) - if((job.total_positions <= GLOB.player_list.len * (max_relative_positions / 100))) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] < 0)) - return 1 - return -2 - return -1 - return 0 + if(job_blacklisted_full(job)) + return FALSE + if(job_blacklisted_partial(job)) + return FALSE + if(!job_in_department(job, FALSE)) + return FALSE + if((job.total_positions > GLOB.player_list.len * (max_relative_positions / 100))) + return FALSE + if(opened_positions[job.title] < 0) + return TRUE + var/delta = (world.time / 10) - GLOB.time_last_changed_position + if(change_position_cooldown < delta) + return TRUE + return FALSE -//Logic check for Topic() if you can close the job +// Logic check for if you can close the job /obj/machinery/computer/card/proc/can_close_job(datum/job/job) if(job) - if(!job_blacklisted_full(job) && !job_blacklisted_partial(job) && job_in_department(job, FALSE)) - if(job.total_positions > job.current_positions && !(job in SSjobs.prioritized_jobs)) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) - return 1 - return -2 - return -1 - return 0 + if(job_blacklisted_full(job)) + return FALSE + if(job_blacklisted_partial(job)) + return FALSE + if(!job_in_department(job, FALSE)) + return FALSE + if(job in SSjobs.prioritized_jobs) // different to above + return FALSE + if(job.total_positions <= job.current_positions) // different to above + return FALSE + if(opened_positions[job.title] > 0) // different to above + return TRUE + var/delta = (world.time / 10) - GLOB.time_last_changed_position + if(change_position_cooldown < delta) + return TRUE + return FALSE /obj/machinery/computer/card/proc/can_prioritize_job(datum/job/job) if(job) - if(!job_blacklisted_full(job) && job_in_department(job, FALSE)) - if(job in SSjobs.prioritized_jobs) - return 2 - else - if(SSjobs.prioritized_jobs.len >= 3) - return 0 - if(job.total_positions <= job.current_positions) - return 0 - return 1 - return -1 + if(job_blacklisted_full(job)) + return FALSE + if(!job_in_department(job, FALSE)) + return FALSE + if(job in SSjobs.prioritized_jobs) + return TRUE // because this also lets us un-prioritize the job + if(SSjobs.prioritized_jobs.len >= 3) + return FALSE + if(job.total_positions <= job.current_positions) + return FALSE + return TRUE + return FALSE +/obj/machinery/computer/card/proc/has_idchange_access() + return scan && scan.access && (ACCESS_CHANGE_IDS in scan.access) ? TRUE : FALSE -/obj/machinery/computer/card/proc/job_in_department(datum/job/targetjob, includecivs = 1) +/obj/machinery/computer/card/proc/job_in_department(datum/job/targetjob, includecivs = TRUE) if(!scan || !scan.access) - return 0 + return FALSE if(!target_dept) - return 1 + return TRUE if(!scan.assignment) - return 0 - if(ACCESS_CAPTAIN in scan.access) - return 1 + return FALSE + if(has_idchange_access()) + return TRUE if(!targetjob || !targetjob.title) - return 0 + return FALSE if(targetjob.title in get_subordinates(scan.assignment, includecivs)) - return 1 - return 0 + return TRUE + return FALSE /obj/machinery/computer/card/proc/get_subordinates(rank, addcivs) var/list/jobs_returned = list() for(var/datum/job/thisjob in SSjobs.occupations) + if(thisjob.title in GLOB.nonhuman_positions) // hides AI from list when Captain ID is inserted into dept console + continue if(rank in thisjob.department_head) jobs_returned += thisjob.title if(addcivs) jobs_returned += "Civilian" return jobs_returned +/obj/machinery/computer/card/proc/get_employees(list/selectedranks) + var/list/names_returned = list() + if(isnull(GLOB.data_core.general) || isnull(GLOB.data_core.security)) + return names_returned + for(var/datum/data/record/R in GLOB.data_core.general) + if(!R.fields || !R.fields["name"] || !R.fields["real_rank"]) + continue + if(!(R.fields["real_rank"] in selectedranks)) + continue + for(var/datum/data/record/E in GLOB.data_core.security) + if(E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]) + var/buttontext + var/isdemotable = FALSE + if(status_valid_for_demotion(E.fields["criminal"])) + buttontext = "Demote" + isdemotable = TRUE + else if(E.fields["criminal"] == SEC_RECORD_STATUS_DEMOTE) + buttontext = "Pending Demotion" + else + buttontext = "Ineligible" + names_returned.Add(list(list( + "name" = E.fields["name"], + "crimstat" = E.fields["criminal"], + "title" = R.fields["real_rank"], + "buttontext" = buttontext, + "demotable" = isdemotable + ))) + break + return names_returned + +/obj/machinery/computer/card/proc/status_valid_for_demotion(crimstat) + if(crimstat in list(SEC_RECORD_STATUS_NONE, SEC_RECORD_STATUS_MONITOR, SEC_RECORD_STATUS_RELEASED, SEC_RECORD_STATUS_SEARCH)) + return TRUE + return FALSE + /obj/machinery/computer/card/attack_ai(var/mob/user as mob) return attack_hand(user) @@ -227,103 +300,119 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) if(stat & (NOPOWER|BROKEN)) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/card/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/computer/card/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "identification_computer.tmpl", src.name, 775, 700) + ui = new(user, src, ui_key, "CardComputer", name, 800, 800, master_ui, state) ui.open() -/obj/machinery/computer/card/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] - data["src"] = UID() - data["station_name"] = station_name() +/obj/machinery/computer/card/tgui_data(mob/user) + var/list/data = list() data["mode"] = mode - data["printing"] = printing - data["manifest"] = GLOB.data_core ? GLOB.data_core.get_manifest(0) : null - data["target_name"] = modify ? modify.name : "-----" - data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----" - data["target_rank"] = get_target_rank() - data["scan_name"] = scan ? scan.name : "-----" - data["scan_owner"] = scan && scan.registered_name ? scan.registered_name : null - data["authenticated"] = is_authenticated(user) - data["has_modify"] = !!modify - data["account_number"] = modify ? modify.associated_account_number : null - data["centcom_access"] = is_centcom() - data["all_centcom_access"] = null - data["regions"] = null + data["modify_name"] = modify ? modify.name : FALSE + data["modify_owner"] = modify && modify.registered_name ? modify.registered_name : "-----" + data["modify_rank"] = get_target_rank() + data["modify_lastlog"] = modify && modify.lastlog ? modify.lastlog : FALSE + data["scan_name"] = scan ? scan.name : FALSE + data["scan_rank"] = scan ? scan.rank : FALSE + + data["authenticated"] = is_authenticated(user) ? TRUE : FALSE data["target_dept"] = target_dept - data["card_is_owned"] = modify && modify.owner_ckey + data["iscentcom"] = is_centcom() ? TRUE : FALSE - var/list/job_formats = SSjobs.format_jobs_for_id_computer(modify) - - data["top_jobs"] = format_jobs(list("Captain", "Custom"), data["target_rank"], job_formats) - data["engineering_jobs"] = format_jobs(GLOB.engineering_positions, data["target_rank"], job_formats) - data["medical_jobs"] = format_jobs(GLOB.medical_positions, data["target_rank"], job_formats) - data["science_jobs"] = format_jobs(GLOB.science_positions, data["target_rank"], job_formats) - data["security_jobs"] = format_jobs(GLOB.security_positions, data["target_rank"], job_formats) - data["support_jobs"] = format_jobs(GLOB.support_positions, data["target_rank"], job_formats) - data["civilian_jobs"] = format_jobs(GLOB.civilian_positions, data["target_rank"], job_formats) - data["special_jobs"] = format_jobs(GLOB.whitelisted_positions, data["target_rank"], job_formats) - data["centcom_jobs"] = format_jobs(get_all_centcom_jobs(), data["target_rank"], job_formats) - data["card_skins"] = format_card_skins(get_station_card_skins()) - - data["job_slots"] = format_job_slots() - - var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) - var/mins = round(time_to_wait / 60) - var/seconds = time_to_wait - (60*mins) - data["cooldown_mins"] = mins - data["cooldown_secs"] = (seconds < 10) ? "0[seconds]" : seconds - - if(mode == 3 && is_authenticated(user)) - data["id_change_html"] = SSjobs.fetch_transfer_record_html(is_centcom()) - - if(modify) - data["current_skin"] = modify.icon_state - - if(modify && 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 modify.access) ? 1 : 0))) - - data["all_centcom_access"] = all_centcom_access - data["all_centcom_skins"] = format_card_skins(get_centcom_card_skins()) - - else if(modify) - 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 modify.access) ? 1 : 0))) - - regions.Add(list(list( - "name" = get_region_accesses_name(i), - "accesses" = accesses))) - - data["regions"] = regions + switch(mode) + if(IDCOMPUTER_SCREEN_TRANSFER) // JOB TRANSFER + if(modify) + if(!scan) + return data + else if(target_dept) + data["jobs_dept"] = get_subordinates(scan.assignment, FALSE) + data["canterminate"] = has_idchange_access() + else + data["account_number"] = modify ? modify.associated_account_number : null + data["jobs_top"] = list("Captain", "Custom") + data["jobs_engineering"] = GLOB.engineering_positions + data["jobs_medical"] = GLOB.medical_positions + data["jobs_science"] = GLOB.science_positions + data["jobs_security"] = GLOB.security_positions + data["jobs_service"] = GLOB.service_positions + data["jobs_supply"] = GLOB.supply_positions - "Head of Personnel" + data["jobs_civilian"] = GLOB.civilian_positions + data["jobs_karma"] = GLOB.whitelisted_positions + data["jobs_centcom"] = get_all_centcom_jobs() + data["jobFormats"] = SSjobs.format_jobs_for_id_computer(modify) + data["current_skin"] = modify.icon_state + data["card_skins"] = format_card_skins(get_station_card_skins()) + data["all_centcom_skins"] = is_centcom() ? format_card_skins(get_centcom_card_skins()) : FALSE + if(IDCOMPUTER_SCREEN_SLOTS) // JOB SLOTS + data["job_slots"] = format_job_slots() + data["priority_jobs"] = list() + for(var/datum/job/a in SSjobs.prioritized_jobs) + data["priority_jobs"] += a.title + var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) + if(time_to_wait > 0) + var/mins = round(time_to_wait / 60) + var/seconds = time_to_wait - (60*mins) + seconds = (seconds < 10) ? "0[seconds]" : seconds + data["cooldown_time"] = "[mins]:[seconds]" + else + data["cooldown_time"] = FALSE + if(IDCOMPUTER_SCREEN_ACCESS) // ACCESS CHANGES + if(modify) + data["selectedAccess"] = modify.access + data["regions"] = get_accesslist_static_data(REGION_GENERAL, is_centcom() ? REGION_CENTCOMM : REGION_COMMAND) + if(IDCOMPUTER_SCREEN_RECORDS) // RECORDS + if(is_authenticated(user)) + data["records"] = SSjobs.format_job_change_records(data["iscentcom"]) + if(IDCOMPUTER_SCREEN_DEPT) // DEPARTMENT EMPLOYEE LIST + if(is_authenticated(user) && scan) // .requires both (aghosts don't count) + data["jobs_dept"] = get_subordinates(scan.assignment, FALSE) + data["people_dept"] = get_employees(data["jobs_dept"]) return data -/obj/machinery/computer/card/Topic(href, href_list) - if(..()) - return 1 +/obj/machinery/computer/card/proc/regenerate_id_name() + if(modify) + modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") - switch(href_list["choice"]) - if("modify") +/obj/machinery/computer/card/tgui_act(action, params) + if(..()) + return + . = TRUE + + // 1st, handle the functions that require no authorization at all + + switch(action) + if("scan") // inserting or removing your authorizing ID + if(scan) + if(ishuman(usr)) + scan.forceMove(get_turf(src)) + if(!usr.get_active_hand() && Adjacent(usr)) + usr.put_in_hands(scan) + scan = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + else + scan.forceMove(get_turf(src)) + scan = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + else if(Adjacent(usr)) + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/card/id)) + if(!check_access(I)) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + to_chat(usr, "This card does not have access.") + return FALSE + usr.drop_item() + I.forceMove(src) + scan = I + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + return + if("modify") // inserting or removing the ID you plan to modify if(modify) GLOB.data_core.manifest_modify(modify.registered_name, modify.assignment) - modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") + regenerate_id_name() if(ishuman(usr)) modify.forceMove(get_turf(src)) if(!usr.get_active_hand() && Adjacent(usr)) @@ -341,274 +430,299 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) I.forceMove(src) modify = I playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + return + if("mode") // changing mode in the menu + mode = text2num(params["mode"]) + return - if("scan") - if(scan) - if(ishuman(usr)) - scan.forceMove(get_turf(src)) - if(!usr.get_active_hand() && Adjacent(usr)) - usr.put_in_hands(scan) - scan = null - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - else - scan.forceMove(get_turf(src)) - scan = null - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - else if(Adjacent(usr)) - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/card/id)) - usr.drop_item() - I.forceMove(src) - scan = I - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + // Everything below HERE requires auth + if(!is_authenticated(usr)) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + to_chat(usr, "This function is not available unless you are logged in.") + return FALSE - if("access") - if(href_list["allowed"] && !target_dept) - if(is_authenticated(usr)) - var/access_type = text2num(href_list["access_target"]) - var/access_allowed = text2num(href_list["allowed"]) - if(access_type in (is_centcom() ? get_all_centcom_access() : get_all_accesses())) - modify.access -= access_type - if(!access_allowed) - modify.access += access_type - - if("skin") - if(!target_dept) - var/skin = href_list["skin_target"] - if(is_authenticated(usr) && modify && ((skin in get_station_card_skins()) || ((skin in get_centcom_card_skins()) && is_centcom()))) - modify.icon_state = href_list["skin_target"] - - if("assign") - if(is_authenticated(usr) && modify) - var/t1 = href_list["assign_target"] - if(target_dept && modify.assignment == "Demoted") - visible_message("[src]: Demoted individuals must see the HoP for a new job.") - return 0 + // 2nd, handle the functions that are available to head-level consoles (department consoles) + switch(action) + if("assign") // transfer to a new job + if(!modify) + return + var/t1 = params["assign_target"] + if(target_dept) + if(modify.assignment == "Demoted") + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src]: Reassigning a demoted individual requires a full ID computer.") + return FALSE if(!job_in_department(SSjobs.GetJob(modify.rank), FALSE)) - visible_message("[src]: Cross-department job transfers must be done by the HoP.") - return 0 + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src]: Reassigning someone outside your department requires a full ID computer.") + return FALSE if(!job_in_department(SSjobs.GetJob(t1))) - return 0 - if(t1 == "Custom") - var/temp_t = sanitize(reject_bad_name(copytext(input("Enter a custom job assignment.", "Assignment"), 1, MAX_MESSAGE_LEN), TRUE)) - //let custom jobs function as an impromptu alt title, mainly for sechuds - if(temp_t && modify) - SSjobs.log_job_transfer(modify.registered_name, modify.getRankAndAssignment(), temp_t, scan.registered_name) - modify.assignment = temp_t - log_game("[key_name(usr)] has given \"[modify.registered_name]\" the custom job title \"[temp_t]\".") + return FALSE + if(t1 == "Custom") + var/temp_t = sanitize(reject_bad_name(copytext(input("Enter a custom job assignment.", "Assignment"), 1, MAX_MESSAGE_LEN), TRUE)) + //let custom jobs function as an impromptu alt title, mainly for sechuds + if(temp_t && scan && modify) + var/oldrank = modify.getRankAndAssignment() + SSjobs.log_job_transfer(modify.registered_name, oldrank, temp_t, scan.registered_name, null) + modify.lastlog = "[station_time_timestamp()]: Reassigned by \"[scan.registered_name]\" from \"[oldrank]\" to \"[temp_t]\"." + modify.assignment = temp_t + log_game("[key_name(usr)] ([scan.assignment]) has reassigned \"[modify.registered_name]\" from \"[oldrank]\" to \"[temp_t]\".") + SSjobs.notify_dept_head(modify.rank, "[scan.registered_name] has transferred \"[modify.registered_name]\" the \"[oldrank]\" to \"[temp_t]\".") + else + var/list/access = list() + if(is_centcom() && islist(get_centcom_access(t1))) + access = get_centcom_access(t1) else - var/list/access = list() - if(is_centcom() && islist(get_centcom_access(t1))) - 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]") + 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() + + var/jobnamedata = modify.getRankAndAssignment() + log_game("[key_name(usr)] ([scan.assignment]) has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".") + if(t1 == "Civilian") + message_admins("[key_name_admin(usr)] has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".") + + SSjobs.log_job_transfer(modify.registered_name, jobnamedata, t1, scan.registered_name, null) + modify.lastlog = "[station_time_timestamp()]: Reassigned by \"[scan.registered_name]\" from \"[jobnamedata]\" to \"[t1]\"." + SSjobs.notify_dept_head(t1, "[scan.registered_name] has transferred \"[modify.registered_name]\" the \"[jobnamedata]\" to \"[t1]\".") + if(modify.owner_uid) + SSjobs.slot_job_transfer(modify.rank, t1) + + var/mob/living/carbon/human/H = modify.getPlayer() + if(istype(H)) + if(jobban_isbanned(H, t1)) + message_admins("[ADMIN_FULLMONTY(H)] has been assigned the job [t1], in possible violation of their job ban.") + if(H.mind) + H.mind.playtime_role = t1 + + modify.access = access + modify.rank = t1 + modify.assignment = t1 + regenerate_id_name() + return + if("demote") + if(modify.assignment == "Demoted") + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src]: Demoted crew cannot be demoted any further. If further action is warranted, ask the Captain about Termination.") + return FALSE + if(!job_in_department(SSjobs.GetJob(modify.rank), FALSE)) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src]: Heads may only demote members of their own department.") + return FALSE + var/reason = sanitize(copytext(input("Enter legal reason for demotion. Enter nothing to cancel.","Legal Demotion"), 1, MAX_MESSAGE_LEN)) + if(!reason || !is_authenticated(usr) || !modify) + return FALSE + var/list/access = list() + var/datum/job/jobdatum = new /datum/job/civilian + access = jobdatum.get_access() + var/jobnamedata = modify.getRankAndAssignment() + var/m_ckey = modify.getPlayerCkey() + var/m_ckey_text = m_ckey ? "([m_ckey])" : "(no ckey)" + log_game("[key_name(usr)] ([scan.assignment]) has demoted \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\" for: \"[reason]\".") + message_admins("[key_name_admin(usr)] has demoted \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\" for: \"[reason]\".") + usr.create_log(MISC_LOG, "demoted \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\"") + SSjobs.log_job_transfer(modify.registered_name, jobnamedata, "Demoted", scan.registered_name, reason) + modify.lastlog = "[station_time_timestamp()]: DEMOTED by \"[scan.registered_name]\" ([scan.assignment]) from \"[jobnamedata]\" for: \"[reason]\"." + SSjobs.notify_dept_head(modify.rank, "[scan.registered_name] ([scan.assignment]) has demoted \"[modify.registered_name]\" ([jobnamedata]) for \"[reason]\".") + modify.access = access + modify.rank = "Civilian" + modify.assignment = "Demoted" + modify.icon_state = "id" + regenerate_id_name() + return + if("terminate") + if(!has_idchange_access()) // because captain/HOP can use this even on dept consoles + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src]: Only the Captain or HOP may completely terminate the employment of a crew member.") + return FALSE + var/jobnamedata = modify.getRankAndAssignment() + var/reason = sanitize(copytext(input("Enter legal reason for termination. Enter nothing to cancel.", "Employment Termination"), 1, MAX_MESSAGE_LEN)) + if(!reason || !has_idchange_access() || !modify) + return FALSE + var/m_ckey = modify.getPlayerCkey() + var/m_ckey_text = m_ckey ? "([m_ckey])" : "(no ckey)" + log_game("[key_name(usr)] ([scan.assignment]) has terminated \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\" for: \"[reason]\".") + message_admins("[key_name_admin(usr)] has terminated \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\" for: \"[reason]\".") + usr.create_log(MISC_LOG, "terminated the employment of \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\"") + SSjobs.log_job_transfer(modify.registered_name, jobnamedata, "Terminated", scan.registered_name, reason) + modify.lastlog = "[station_time_timestamp()]: TERMINATED by \"[scan.registered_name]\" ([scan.assignment]) from \"[jobnamedata]\" for: \"[reason]\"." + SSjobs.notify_dept_head(modify.rank, "[scan.registered_name] ([scan.assignment]) has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\" for \"[reason]\".") + modify.assignment = "Terminated" + modify.access = list() + regenerate_id_name() + return + if("make_job_available") // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS + var/edit_job_target = params["job"] + var/datum/job/j = SSjobs.GetJob(edit_job_target) + if(!job_in_department(j, FALSE)) + return FALSE + if(!j) + return FALSE + if(!can_open_job(j)) + return FALSE + if(opened_positions[edit_job_target] >= 0) + GLOB.time_last_changed_position = world.time / 10 + j.total_positions++ + opened_positions[edit_job_target]++ + log_game("[key_name(usr)] ([scan.assignment]) has opened a job slot for job \"[j.title]\".") + message_admins("[key_name_admin(usr)] has opened a job slot for job \"[j.title]\".") + return + if("make_job_unavailable") // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS + var/edit_job_target = params["job"] + var/datum/job/j = SSjobs.GetJob(edit_job_target) + if(!job_in_department(j, FALSE)) + return FALSE + if(!j) + return FALSE + if(!can_close_job(j)) + return FALSE + //Allow instant closing without cooldown if a position has been opened before + if(opened_positions[edit_job_target] <= 0) + GLOB.time_last_changed_position = world.time / 10 + j.total_positions-- + opened_positions[edit_job_target]-- + log_game("[key_name(usr)] ([scan.assignment]) has closed a job slot for job \"[j.title]\".") + message_admins("[key_name_admin(usr)] has closed a job slot for job \"[j.title]\".") + return + if("remote_demote") + var/reason = sanitize(copytext(input("Enter legal reason for demotion. Enter nothing to cancel.","Legal Demotion"), 1, MAX_MESSAGE_LEN)) + if(!reason || !is_authenticated(usr) || !scan) + return FALSE + for(var/datum/data/record/E in GLOB.data_core.general) + if(E.fields["name"] == params["remote_demote"]) + var/datum/job/j = SSjobs.GetJob(E.fields["real_rank"]) + var/tempname = params["remote_demote"] + var/temprank = E.fields["real_rank"] + if(!j) + visible_message("[src]: This employee has either no job, or a customized job ([temprank]).") + return FALSE + if(!job_in_department(j, FALSE)) + visible_message("[src]: Only the head of this employee may demote them.") + return FALSE + for(var/datum/data/record/R in GLOB.data_core.security) + if(R.fields["id"] == E.fields["id"]) + if(status_valid_for_demotion(R.fields["criminal"])) + set_criminal_status(usr, R, SEC_RECORD_STATUS_DEMOTE, reason, scan.assignment) + Radio.autosay("[scan.registered_name] ([scan.assignment]) has set [tempname] ([temprank]) to demote for: [reason]", name, "Command", list(z)) + message_admins("[key_name_admin(usr)] ([scan.assignment]) has set [tempname] ([temprank]) to demote for: \"[reason]\"") + log_game("[key_name(usr)] ([scan.assignment]) has set \"[tempname]\" ([temprank]) to demote for: \"[reason]\".") + SSjobs.notify_by_name(tempname, "[scan.registered_name] ([scan.assignment]) has ordered your demotion. Report to their office, or the HOP. Reason given: \"[reason]\"") + else + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + to_chat(usr, "[src]: Cannot demote, due to their current security status.") + return FALSE return + return - access = jobdatum.get_access() + // Everything below here requires a full ID computer (dept consoles do not qualify) + if(target_dept) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + to_chat(usr, "This function is not available on department-level consoles.") + return - var/jobnamedata = modify.getRankAndAssignment() - log_game("[key_name(usr)] has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".") - if(t1 == "Civilian") - message_admins("[key_name_admin(usr)] has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".") + // 3rd, handle the functions that require a full ID computer + switch(action) + // Changing basic card info + if("reg") // registered name on card + var/temp_name = reject_bad_name(input(usr, "Who is this ID for?", "ID Card Renaming", modify.registered_name), TRUE) + if(!modify || !temp_name) + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 0) + visible_message("[src] buzzes rudely.") + return FALSE + modify.registered_name = temp_name + regenerate_id_name() + return + if("account") // card account number + var/account_num = input(usr, "Account Number", "Input Number", null) as num|null + if(!scan || !modify) + return FALSE + modify.associated_account_number = clamp(round(account_num), 0, 999999) + return + if("skin") + if(!modify) + return FALSE + var/skin = params["skin_target"] + var/skin_list = is_centcom() ? get_centcom_card_skins() : get_station_card_skins() + if(skin in skin_list) + modify.icon_state = skin + return + // Changing card access + if("set") // add/remove a single access number + var/access = text2num(params["access"]) + var/list/changable = is_centcom() ? get_all_centcom_access() + get_all_accesses() : get_all_accesses() + if(access in changable) + if(access in modify.access) + modify.access -= access + else + modify.access += access + return + if("grant_region") + var/region = text2num(params["region"]) + if(isnull(region) || region < REGION_GENERAL || region > (is_centcom() ? REGION_CENTCOMM : REGION_COMMAND)) + return + modify.access |= get_region_accesses(region) + return + if("deny_region") + var/region = text2num(params["region"]) + if(isnull(region) || region < REGION_GENERAL || region > (is_centcom() ? REGION_CENTCOMM : REGION_COMMAND)) + return + modify.access -= get_region_accesses(region) + return + if("clear_all") + modify.access = list() + return + if("grant_all") + modify.access = get_all_accesses() + return - SSjobs.log_job_transfer(modify.registered_name, jobnamedata, t1, scan.registered_name) - if(modify.owner_uid) - SSjobs.slot_job_transfer(modify.rank, t1) + // JOB SLOT MANAGEMENT functions - var/mob/living/carbon/human/H = modify.getPlayer() - if(istype(H)) - if(jobban_isbanned(H, t1)) - message_admins("[ADMIN_FULLMONTY(H)] has been assigned the job [t1], in possible violation of their job ban.") - if(H.mind) - H.mind.playtime_role = t1 + if("prioritize_job") // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY + var/priority_target = params["job"] + var/datum/job/j = SSjobs.GetJob(priority_target) + if(!j) + return FALSE + if(!job_in_department(j)) + return FALSE + var/priority = TRUE + if(j in SSjobs.prioritized_jobs) + SSjobs.prioritized_jobs -= j + priority = FALSE + else if(SSjobs.prioritized_jobs.len < 3) + SSjobs.prioritized_jobs += j + else + return FALSE + log_game("[key_name(usr)] ([scan.assignment]) [priority ? "prioritized" : "unprioritized"] the job \"[j.title]\".") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + return - modify.access = access - modify.rank = t1 - modify.assignment = t1 - - if("reg") - if(is_authenticated(usr) && !target_dept) - var/t2 = modify - if((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf))) - var/temp_name = reject_bad_name(href_list["reg"], TRUE) - if(temp_name) - modify.registered_name = temp_name - else - visible_message("[src] buzzes rudely.") - SSnanoui.update_uis(src) - - if("account") - if(is_authenticated(usr) && !target_dept) - var/t2 = modify - if((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf))) - var/account_num = text2num(href_list["account"]) - modify.associated_account_number = account_num - SSnanoui.update_uis(src) - - if("mode") - mode = text2num(href_list["mode_target"]) - - if("wipe_my_logs") - if(is_authenticated(usr) && is_centcom()) - var/delcount = SSjobs.delete_log_records(scan.registered_name, FALSE) - if(delcount) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - SSnanoui.update_uis(src) - - if("wipe_all_logs") + if("wipe_all_logs") // Delete all records from 'records' section if(is_authenticated(usr) && !target_dept) var/delcount = SSjobs.delete_log_records(scan.registered_name, TRUE) if(delcount) message_admins("[key_name_admin(usr)] has wiped all ID computer logs.") usr.create_log(MISC_LOG, "wiped all ID computer logs.") playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - SSnanoui.update_uis(src) + return - if("print") - if(!printing && !target_dept) - printing = 1 - playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - spawn(50) - printing = null - SSnanoui.update_uis(src) + // Everything below here is exclusive to the CC card computer. + if(!is_centcom()) + return - var/obj/item/paper/P = new(loc) - if(mode == 2) - P.name = "crew manifest ([station_time_timestamp()])" - P.info = {"

Crew Manifest

-
- [GLOB.data_core ? GLOB.data_core.get_manifest(0) : ""] - "} - else if(modify && !mode) - P.name = "access report" - P.info = {"

Access Report

- Prepared By: [scan && scan.registered_name ? scan.registered_name : "Unknown"]
- For: [modify.registered_name ? modify.registered_name : "Unregistered"]
-
- Assignment: [modify.assignment]
- Account Number: #[modify.associated_account_number]
- Blood Type: [modify.blood_type]

- Access:
- "} - - var/first = 1 - for(var/A in modify.access) - P.info += "[first ? "" : ", "][get_access_desc(A)]" - first = 0 - P.info += "
" - - if("terminate") - if(is_authenticated(usr) && !target_dept) - var/jobnamedata = modify.getRankAndAssignment() - var/reason = sanitize(copytext(input("Enter legal reason for termination. Enter nothing to cancel.", "Employment Termination"), 1, MAX_MESSAGE_LEN)) - if(!reason || !is_authenticated(usr) || !modify) - return FALSE - var/m_ckey = modify.getPlayerCkey() - var/m_ckey_text = m_ckey ? "([m_ckey])" : "(no ckey)" - log_game("[key_name(usr)] has terminated the employment of \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\" for: \"[reason]\".") - message_admins("[key_name_admin(usr)] has terminated the employment of \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\" for: \"[reason]\".") - usr.create_log(MISC_LOG, "terminated the employment of \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\"") - SSjobs.log_job_transfer(modify.registered_name, jobnamedata, "Terminated", scan.registered_name) - SSjobs.notify_dept_head(modify.rank, "[scan.registered_name] has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\" for \"[reason]\".") - modify.assignment = "Terminated" - modify.access = list() - - if("demote") - if(is_authenticated(usr)) - if(modify.assignment == "Demoted") - visible_message("[src]: Demoted crew cannot be demoted any further. If further action is warranted, ask the Captain about Termination.") - return 0 - if(!job_in_department(SSjobs.GetJob(modify.rank), FALSE)) - visible_message("[src]: Heads may only demote members of their own department.") - return 0 - var/reason = sanitize(copytext(input("Enter legal reason for demotion. Enter nothing to cancel.","Legal Demotion"),1,MAX_MESSAGE_LEN)) - if(!reason || !is_authenticated(usr) || !modify) - return 0 - var/list/access = list() - var/datum/job/jobdatum = new /datum/job/civilian - access = jobdatum.get_access() - var/jobnamedata = modify.getRankAndAssignment() - var/m_ckey = modify.getPlayerCkey() - var/m_ckey_text = m_ckey ? "([m_ckey])" : "(no ckey)" - log_game("[key_name(usr)] has demoted \"[modify.registered_name]\" the \"[jobnamedata]\" [m_ckey_text] to \"Civilian (Demoted)\" for: \"[reason]\".") - message_admins("[key_name_admin(usr)] has demoted \"[modify.registered_name]\" the \"[jobnamedata]\" [m_ckey_text] to \"Civilian (Demoted)\" for: \"[reason]\".") - usr.create_log(MISC_LOG, "demoted \"[modify.registered_name]\" [m_ckey_text] the \"[jobnamedata]\"") - SSjobs.log_job_transfer(modify.registered_name, jobnamedata, "Demoted", scan.registered_name) - SSjobs.notify_dept_head(modify.rank, "[scan.registered_name] has demoted \"[modify.registered_name]\" the \"[jobnamedata]\" for \"[reason]\".") - modify.access = access - modify.rank = "Civilian" - modify.assignment = "Demoted" - modify.icon_state = "id" - - if("make_job_available") - // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS - if(is_authenticated(usr)) - var/edit_job_target = href_list["job"] - var/datum/job/j = SSjobs.GetJob(edit_job_target) - if(!job_in_department(j, FALSE)) - return 0 - if(!j) - return 0 - if(can_open_job(j) != 1) - return 0 - if(opened_positions[edit_job_target] >= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions++ - opened_positions[edit_job_target]++ - log_game("[key_name(usr)] has opened a job slot for job \"[j]\".") - message_admins("[key_name_admin(usr)] has opened a job slot for job \"[j.title]\".") - SSnanoui.update_uis(src) - - if("make_job_unavailable") - // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS - if(is_authenticated(usr)) - var/edit_job_target = href_list["job"] - var/datum/job/j = SSjobs.GetJob(edit_job_target) - if(!job_in_department(j, FALSE)) - return 0 - if(!j) - return 0 - if(can_close_job(j) != 1) - return 0 - //Allow instant closing without cooldown if a position has been opened before - if(opened_positions[edit_job_target] <= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions-- - opened_positions[edit_job_target]-- - log_game("[key_name(usr)] has closed a job slot for job \"[j]\".") - message_admins("[key_name_admin(usr)] has closed a job slot for job \"[j.title]\".") - SSnanoui.update_uis(src) - - if("prioritize_job") - // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY - if(is_authenticated(usr) && !target_dept) - var/priority_target = href_list["job"] - var/datum/job/j = SSjobs.GetJob(priority_target) - if(!j) - return 0 - if(!job_in_department(j)) - return 0 - var/priority = TRUE - if(j in SSjobs.prioritized_jobs) - SSjobs.prioritized_jobs -= j - priority = FALSE - else if(SSjobs.prioritized_jobs.len < 3) - SSjobs.prioritized_jobs += j - else - return 0 - log_game("[key_name(usr)] [priority ? "prioritized" : "unprioritized"] the job \"[j.title]\".") + switch(action) + if("wipe_my_logs") + var/delcount = SSjobs.delete_log_records(scan.registered_name, FALSE) + if(delcount) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - if(modify) - modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") - return 1 /obj/machinery/computer/card/centcom name = "\improper CentComm identification computer" @@ -618,6 +732,9 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) blacklisted_full = list() blacklisted_partial = list() +/obj/machinery/computer/card/centcom/is_centcom() + return TRUE + /obj/machinery/computer/card/minor name = "department management console" target_dept = TARGET_DEPT_GENERIC diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 366946254ea..60563e692b3 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -1,35 +1,39 @@ #define COMM_SCREEN_MAIN 1 #define COMM_SCREEN_STAT 2 #define COMM_SCREEN_MESSAGES 3 -#define COMM_SCREEN_SECLEVEL 4 #define COMM_AUTHENTICATION_NONE 0 #define COMM_AUTHENTICATION_MIN 1 #define COMM_AUTHENTICATION_MAX 2 +#define COMM_MSGLEN_MINIMUM 6 +#define COMM_CCMSGLEN_MINIMUM 20 + // The communications computer /obj/machinery/computer/communications name = "communications console" - desc = "This can be used for various important functions. Still under developement." + desc = "This allows the Captain to contact Central Command, or change the alert level. It also allows the command staff to call the Escape Shuttle." icon_keyboard = "tech_key" icon_screen = "comm" req_access = list(ACCESS_HEADS) circuit = /obj/item/circuitboard/communications - var/prints_intercept = 1 - var/authenticated = COMM_AUTHENTICATION_NONE var/list/messagetitle = list() var/list/messagetext = list() - var/currmsg = 0 - var/aicurrmsg = 0 + var/currmsg + + var/authenticated = COMM_AUTHENTICATION_NONE var/menu_state = COMM_SCREEN_MAIN var/ai_menu_state = COMM_SCREEN_MAIN - var/message_cooldown = 0 - var/centcomm_message_cooldown = 0 + var/aicurrmsg + + var/message_cooldown + var/centcomm_message_cooldown var/tmp_alertlevel = 0 var/stat_msg1 var/stat_msg2 - var/display_type="blank" + var/display_type = "blank" + var/display_icon var/datum/announcement/priority/crew_announcement = new @@ -70,123 +74,113 @@ feedback_inc("alert_comms_blue",1) tmp_alertlevel = 0 -/obj/machinery/computer/communications/Topic(href, href_list) - if(..(href, href_list)) - return 1 - - if(!is_secure_level(src.z)) +/obj/machinery/computer/communications/tgui_act(action, params) + if(..()) + return + if(!is_secure_level(z)) to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return 1 + return - if(href_list["login"]) + . = TRUE + + if(action == "auth") if(!ishuman(usr)) to_chat(usr, "Access denied.") + return FALSE + // Logout function. + if(authenticated != COMM_AUTHENTICATION_NONE) + authenticated = COMM_AUTHENTICATION_NONE + crew_announcement.announcer = null + setMenuState(usr, COMM_SCREEN_MAIN) return - + // Login function. var/list/access = usr.get_access() if(allowed(usr)) authenticated = COMM_AUTHENTICATION_MIN - if(ACCESS_CAPTAIN in access) authenticated = COMM_AUTHENTICATION_MAX var/mob/living/carbon/human/H = usr var/obj/item/card/id = H.get_idcard(TRUE) if(istype(id)) crew_announcement.announcer = GetNameAndAssignmentFromId(id) - - SSnanoui.update_uis(src) - return - - if(href_list["logout"]) - authenticated = COMM_AUTHENTICATION_NONE - crew_announcement.announcer = "" - setMenuState(usr,COMM_SCREEN_MAIN) - SSnanoui.update_uis(src) + if(authenticated == COMM_AUTHENTICATION_NONE) + to_chat(usr, "You need to wear your ID.") return + // All functions below this point require authentication. if(!is_authenticated(usr)) - return 1 + return FALSE - switch(href_list["operation"]) + switch(action) if("main") - setMenuState(usr,COMM_SCREEN_MAIN) - - if("changeseclevel") - setMenuState(usr,COMM_SCREEN_SECLEVEL) + setMenuState(usr, COMM_SCREEN_MAIN) if("newalertlevel") if(isAI(usr) || isrobot(usr)) to_chat(usr, "Firewalls prevent you from changing the alert level.") - return 1 + return else if(usr.can_admin_interact()) - change_security_level(text2num(href_list["level"])) - return 1 + change_security_level(text2num(params["level"])) + return else if(!ishuman(usr)) to_chat(usr, "Security measures prevent you from changing the alert level.") - return 1 + return - var/mob/living/carbon/human/L = usr - var/obj/item/card = L.get_active_hand() - var/obj/item/card/id/I = (card && card.GetID()) || L.wear_id || L.wear_pda - if(istype(I, /obj/item/pda)) - var/obj/item/pda/pda = I - I = pda.id - if(I && istype(I)) + var/mob/living/carbon/human/H = usr + var/obj/item/card/id/I = H.get_idcard(TRUE) + if(istype(I)) if(ACCESS_CAPTAIN in I.access) - change_security_level(text2num(href_list["level"])) + change_security_level(text2num(params["level"])) else to_chat(usr, "You are not authorized to do this.") - setMenuState(usr,COMM_SCREEN_MAIN) + setMenuState(usr, COMM_SCREEN_MAIN) else - to_chat(usr, "You need to swipe your ID.") + to_chat(usr, "You need to wear your ID.") if("announce") if(is_authenticated(usr) == COMM_AUTHENTICATION_MAX) - if(message_cooldown) + if(message_cooldown > world.time) to_chat(usr, "Please allow at least one minute to pass between announcements.") - SSnanoui.update_uis(src) return var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") - if(!input || message_cooldown || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) + if(!input || message_cooldown > world.time || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) + return + if(length(input) < COMM_MSGLEN_MINIMUM) + to_chat(usr, "Message '[input]' is too short. [COMM_MSGLEN_MINIMUM] character minimum.") return crew_announcement.Announce(input) - message_cooldown = 1 - spawn(600)//One minute cooldown - message_cooldown = 0 + message_cooldown = world.time + 600 //One minute if("callshuttle") var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") if(!input || ..() || !is_authenticated(usr)) - SSnanoui.update_uis(src) return - call_shuttle_proc(usr, input) if(SSshuttle.emergency.timer) post_status("shuttle") - setMenuState(usr,COMM_SCREEN_MAIN) + setMenuState(usr, COMM_SCREEN_MAIN) if("cancelshuttle") if(isAI(usr) || isrobot(usr)) to_chat(usr, "Firewalls prevent you from recalling the shuttle.") - SSnanoui.update_uis(src) - return 1 + return var/response = alert("Are you sure you wish to recall the shuttle?", "Confirm", "Yes", "No") if(response == "Yes") cancel_call_proc(usr) if(SSshuttle.emergency.timer) post_status("shuttle") - setMenuState(usr,COMM_SCREEN_MAIN) + setMenuState(usr, COMM_SCREEN_MAIN) if("messagelist") - currmsg = 0 - if(href_list["msgid"]) - setCurrentMessage(usr, text2num(href_list["msgid"])) - setMenuState(usr,COMM_SCREEN_MESSAGES) + currmsg = null + aicurrmsg = null + if(params["msgid"]) + setCurrentMessage(usr, text2num(params["msgid"])) + setMenuState(usr, COMM_SCREEN_MESSAGES) if("delmessage") - if(href_list["msgid"]) - currmsg = text2num(href_list["msgid"]) + if(params["msgid"]) + currmsg = text2num(params["msgid"]) var/response = alert("Are you sure you wish to delete this message?", "Confirm", "Yes", "No") if(response == "Yes") if(currmsg) @@ -196,95 +190,95 @@ messagetitle.Remove(title) messagetext.Remove(text) if(currmsg == id) - currmsg = 0 + currmsg = null if(aicurrmsg == id) - aicurrmsg = 0 - setMenuState(usr,COMM_SCREEN_MESSAGES) + aicurrmsg = null + setMenuState(usr, COMM_SCREEN_MESSAGES) if("status") - setMenuState(usr,COMM_SCREEN_STAT) + setMenuState(usr, COMM_SCREEN_STAT) // Status display stuff if("setstat") - display_type=href_list["statdisp"] + display_type = params["statdisp"] switch(display_type) if("message") + display_icon = null post_status("message", stat_msg1, stat_msg2, usr) if("alert") - post_status("alert", href_list["alert"], user = usr) + display_icon = params["alert"] + post_status("alert", params["alert"], user = usr) else - post_status(href_list["statdisp"], user = usr) - setMenuState(usr,COMM_SCREEN_STAT) + display_icon = null + post_status(params["statdisp"], user = usr) + setMenuState(usr, COMM_SCREEN_STAT) if("setmsg1") stat_msg1 = clean_input("Line 1", "Enter Message Text", stat_msg1) - setMenuState(usr,COMM_SCREEN_STAT) + setMenuState(usr, COMM_SCREEN_STAT) if("setmsg2") stat_msg2 = clean_input("Line 2", "Enter Message Text", stat_msg2) - setMenuState(usr,COMM_SCREEN_STAT) + setMenuState(usr, COMM_SCREEN_STAT) if("nukerequest") if(is_authenticated(usr) == COMM_AUTHENTICATION_MAX) - if(centcomm_message_cooldown) + if(centcomm_message_cooldown > world.time) to_chat(usr, "Arrays recycling. Please stand by.") - SSnanoui.update_uis(src) return var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) + return + if(length(input) < COMM_CCMSGLEN_MINIMUM) + to_chat(usr, "Message '[input]' is too short. [COMM_CCMSGLEN_MINIMUM] character minimum.") return Nuke_request(input, usr) to_chat(usr, "Request sent.") log_game("[key_name(usr)] has requested the nuclear codes from Centcomm") GLOB.priority_announcement.Announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/AI/commandreport.ogg') - centcomm_message_cooldown = 1 - spawn(6000)//10 minute cooldown - centcomm_message_cooldown = 0 - setMenuState(usr,COMM_SCREEN_MAIN) + centcomm_message_cooldown = world.time + 6000 // 10 minutes + setMenuState(usr, COMM_SCREEN_MAIN) if("MessageCentcomm") if(is_authenticated(usr) == COMM_AUTHENTICATION_MAX) - if(centcomm_message_cooldown) + if(centcomm_message_cooldown > world.time) to_chat(usr, "Arrays recycling. Please stand by.") - SSnanoui.update_uis(src) return var/input = stripped_input(usr, "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.", "To abort, send an empty message.", "") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) + return + if(length(input) < COMM_CCMSGLEN_MINIMUM) + to_chat(usr, "Message '[input]' is too short. [COMM_CCMSGLEN_MINIMUM] character minimum.") return Centcomm_announce(input, usr) print_centcom_report(input, station_time_timestamp() + " Captain's Message") to_chat(usr, "Message transmitted.") log_game("[key_name(usr)] has made a Centcomm announcement: [input]") - centcomm_message_cooldown = 1 - spawn(6000)//10 minute cooldown - centcomm_message_cooldown = 0 - setMenuState(usr,COMM_SCREEN_MAIN) + centcomm_message_cooldown = world.time + 6000 // 10 minutes + setMenuState(usr, COMM_SCREEN_MAIN) // OMG SYNDICATE ...LETTERHEAD if("MessageSyndicate") if((is_authenticated(usr) == COMM_AUTHENTICATION_MAX) && (src.emagged)) - if(centcomm_message_cooldown) + if(centcomm_message_cooldown > world.time) to_chat(usr, "Arrays recycling. Please stand by.") - SSnanoui.update_uis(src) return var/input = stripped_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 || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) + return + if(length(input) < COMM_CCMSGLEN_MINIMUM) + to_chat(usr, "Message '[input]' is too short. [COMM_CCMSGLEN_MINIMUM] character minimum.") return Syndicate_announce(input, usr) to_chat(usr, "Message transmitted.") log_game("[key_name(usr)] has made a Syndicate announcement: [input]") - centcomm_message_cooldown = 1 - spawn(6000)//10 minute cooldown - centcomm_message_cooldown = 0 - setMenuState(usr,COMM_SCREEN_MAIN) + centcomm_message_cooldown = world.time + 6000 // 10 minutes + setMenuState(usr, COMM_SCREEN_MAIN) if("RestoreBackup") to_chat(usr, "Backup routing data restored!") src.emagged = 0 - setMenuState(usr,COMM_SCREEN_MAIN) + setMenuState(usr, COMM_SCREEN_MAIN) if("RestartNanoMob") if(SSmob_hunt) @@ -298,14 +292,13 @@ else to_chat(usr, "Nano-Mob Hunter GO! game server is offline for extended maintenance. Contact your Central Command administrators for more info if desired.") - SSnanoui.update_uis(src) - return 1 + /obj/machinery/computer/communications/emag_act(user as mob) if(!emagged) src.emagged = 1 to_chat(user, "You scramble the communication routing circuits!") - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/computer/communications/attack_ai(var/mob/user as mob) return src.attack_hand(user) @@ -321,28 +314,25 @@ to_chat(user, "Unable to establish a connection: You're too far away from the station!") return - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/communications/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui) +/obj/machinery/computer/communications/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "comm_console.tmpl", "Communications Console", 400, 500) - // open the new ui window + ui = new(user, src, ui_key, "CommunicationsComputer", name, 500, 600, master_ui, state) ui.open() -/obj/machinery/computer/communications/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] +/obj/machinery/computer/communications/tgui_data(mob/user) + var/list/data = list() data["is_ai"] = isAI(user) || isrobot(user) data["menu_state"] = data["is_ai"] ? ai_menu_state : menu_state data["emagged"] = emagged data["authenticated"] = is_authenticated(user, 0) - data["screen"] = getMenuState(usr) + data["authmax"] = data["authenticated"] == COMM_AUTHENTICATION_MAX ? TRUE : FALSE data["stat_display"] = list( "type" = display_type, + "icon" = display_icon, "line_1" = (stat_msg1 ? stat_msg1 : "-----"), "line_2" = (stat_msg2 ? stat_msg2 : "-----"), @@ -360,12 +350,20 @@ ) ) - data["security_level"] = GLOB.security_level + data["security_level"] = GLOB.security_level + switch(GLOB.security_level) + if(SEC_LEVEL_GREEN) + data["security_level_color"] = "green"; + if(SEC_LEVEL_BLUE) + data["security_level_color"] = "blue"; + if(SEC_LEVEL_RED) + data["security_level_color"] = "red"; + else + data["security_level_color"] = "purple"; data["str_security_level"] = capitalize(get_security_level()) data["levels"] = list( - list("id" = SEC_LEVEL_GREEN, "name" = "Green"), - list("id" = SEC_LEVEL_BLUE, "name" = "Blue"), - //SEC_LEVEL_RED = list("name"="Red"), + list("id" = SEC_LEVEL_GREEN, "name" = "Green", "icon" = "dove"), + list("id" = SEC_LEVEL_BLUE, "name" = "Blue", "icon" = "eye"), ) var/list/msg_data = list() @@ -373,27 +371,30 @@ msg_data.Add(list(list("title" = messagetitle[i], "body" = messagetext[i], "id" = i))) data["messages"] = msg_data + + data["current_message"] = null + data["current_message_title"] = null if((data["is_ai"] && aicurrmsg) || (!data["is_ai"] && currmsg)) data["current_message"] = data["is_ai"] ? messagetext[aicurrmsg] : messagetext[currmsg] data["current_message_title"] = data["is_ai"] ? messagetitle[aicurrmsg] : messagetitle[currmsg] data["lastCallLoc"] = SSshuttle.emergencyLastCallLoc ? format_text(SSshuttle.emergencyLastCallLoc.name) : null + data["msg_cooldown"] = message_cooldown ? (round((message_cooldown - world.time) / 10)) : 0 + data["cc_cooldown"] = centcomm_message_cooldown ? (round((centcomm_message_cooldown - world.time) / 10)) : 0 - var/shuttle[0] - switch(SSshuttle.emergency.mode) - if(SHUTTLE_IDLE, SHUTTLE_RECALL) - shuttle["callStatus"] = 2 //#define - else - shuttle["callStatus"] = 1 - if(SSshuttle.emergency.mode == SHUTTLE_CALL) + var/secondsToRefuel = SSshuttle.secondsToRefuel() + data["esc_callable"] = SSshuttle.emergency.mode == SHUTTLE_IDLE && !secondsToRefuel ? TRUE : FALSE + data["esc_recallable"] = SSshuttle.emergency.mode == SHUTTLE_CALL ? TRUE : FALSE + data["esc_status"] = FALSE + if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) var/timeleft = SSshuttle.emergency.timeLeft() - shuttle["eta"] = "[timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" - - data["shuttle"] = shuttle - + data["esc_status"] = SSshuttle.emergency.mode == SHUTTLE_CALL ? "ETA:" : "RECALLING:" + data["esc_status"] += " [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" + else if(secondsToRefuel) + data["esc_status"] = "Refueling: [secondsToRefuel / 60 % 60]:[add_zero(num2text(secondsToRefuel % 60), 2)]" + data["esc_section"] = data["esc_status"] || data["esc_callable"] || data["esc_recallable"] || data["lastCallLoc"] return data - /obj/machinery/computer/communications/proc/setCurrentMessage(var/mob/user,var/value) if(isAI(user) || isrobot(user)) aicurrmsg = value @@ -412,12 +413,6 @@ else menu_state=value -/obj/machinery/computer/communications/proc/getMenuState(var/mob/user) - if(isAI(user) || isrobot(user)) - return ai_menu_state - else - return menu_state - /proc/call_shuttle_proc(var/mob/user, var/reason) if(GLOB.sent_strike_team == 1) to_chat(user, "Central Command will not allow the shuttle to be called. Consider all contracts terminated.") @@ -521,24 +516,16 @@ SSshuttle.autoEvac() return ..() -/proc/print_command_report(text = "", title = "Central Command Update") +/proc/print_command_report(text = "", title = "Central Command Update", add_to_records = TRUE) for(var/obj/machinery/computer/communications/C in GLOB.shuttle_caller_list) if(!(C.stat & (BROKEN|NOPOWER)) && is_station_contact(C.z)) var/obj/item/paper/P = new /obj/item/paper(C.loc) P.name = "paper- '[title]'" P.info = text P.update_icon() - C.messagetitle.Add("[title]") - C.messagetext.Add(text) - for(var/datum/computer_file/program/comm/P in GLOB.shuttle_caller_list) - var/turf/T = get_turf(P.computer) - if(T && P.program_state != PROGRAM_STATE_KILLED && is_station_contact(T.z)) - if(P.computer) - var/obj/item/computer_hardware/printer/printer = P.computer.all_components[MC_PRINT] - if(printer) - printer.print_text(text, "paper- '[title]'") - P.messagetitle.Add("[title]") - P.messagetext.Add(text) + if(add_to_records) + C.messagetitle.Add("[title]") + C.messagetext.Add(text) /proc/print_centcom_report(text = "", title = "Incoming Message") for(var/obj/machinery/computer/communications/C in GLOB.shuttle_caller_list) @@ -549,12 +536,5 @@ P.update_icon() C.messagetitle.Add("[title]") C.messagetext.Add(text) - for(var/datum/computer_file/program/comm/P in GLOB.shuttle_caller_list) - var/turf/T = get_turf(P.computer) - if(T && P.program_state != PROGRAM_STATE_KILLED && is_admin_level(T.z)) - if(P.computer) - var/obj/item/computer_hardware/printer/printer = P.computer.all_components[MC_PRINT] - if(printer) - printer.print_text(text, "paper- '[title]'") - P.messagetitle.Add("[title]") - P.messagetext.Add(text) + + diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 74cc417e7ce..d7987477a65 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -11,55 +11,57 @@ light_range_on = 2 - verb/AccessInternals() - set category = "Object" - set name = "Access Computer's Internals" - set src in oview(1) - if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon)) - return - - opened = !opened - if(opened) - to_chat(usr, "The access panel is now open.") - else - to_chat(usr, "The access panel is now closed.") +// What the fuck even is this +/obj/machinery/computer/aiupload/verb/AccessInternals() + set category = "Object" + set name = "Access Computer's Internals" + set src in oview(1) + if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon)) 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 - attackby(obj/item/O as obj, mob/user as mob, params) - if(istype(O, /obj/item/aiModule)) - if(!current)//no AI selected - to_chat(user, "No AI selected. Please chose a target before proceeding with upload.") - return - var/turf/T = get_turf(current) - if(!atoms_share_level(T, src)) - to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!") - return - var/obj/item/aiModule/M = O - M.install(src) + +/obj/machinery/computer/aiupload/attackby(obj/item/O as obj, mob/user as mob, params) + if(istype(O, /obj/item/aiModule)) + if(!current)//no AI selected + to_chat(user, "No AI selected. Please chose a target before proceeding with upload.") return - return ..() - - - attack_hand(var/mob/user as mob) - if(src.stat & NOPOWER) - to_chat(usr, "The upload computer has no power!") - return - if(src.stat & BROKEN) - to_chat(usr, "The upload computer is broken!") + var/turf/T = get_turf(current) + if(!atoms_share_level(T, src)) + to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!") return + var/obj/item/aiModule/M = O + M.install(src) + return + return ..() - src.current = select_active_ai(user) - if(!src.current) - to_chat(usr, "No active AIs detected.") - else - to_chat(usr, "[src.current.name] selected for law changes.") +/obj/machinery/computer/aiupload/attack_hand(var/mob/user as mob) + if(src.stat & NOPOWER) + to_chat(usr, "The upload computer has no power!") + return + if(src.stat & BROKEN) + to_chat(usr, "The upload computer is broken!") return - attack_ghost(user as mob) - return 1 + src.current = select_active_ai(user) + if(!src.current) + to_chat(usr, "No active AIs detected.") + else + to_chat(usr, "[src.current.name] selected for law changes.") + return + +/obj/machinery/computer/aiupload/attack_ghost(user as mob) + return 1 + +// Why is this not a subtype /obj/machinery/computer/borgupload name = "cyborg upload console" desc = "Used to upload laws to Cyborgs." @@ -69,35 +71,35 @@ var/mob/living/silicon/robot/current = null - attackby(obj/item/aiModule/module as obj, mob/user as mob, params) - if(istype(module, /obj/item/aiModule)) - if(!current)//no borg selected - to_chat(user, "No borg selected. Please chose a target before proceeding with upload.") - return - var/turf/T = get_turf(current) - if(!atoms_share_level(T, src)) - to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!") - return - module.install(src) +/obj/machinery/computer/borgupload/attackby(obj/item/aiModule/module as obj, mob/user as mob, params) + if(istype(module, /obj/item/aiModule)) + if(!current)//no borg selected + to_chat(user, "No borg selected. Please chose a target before proceeding with upload.") return - return ..() - - - attack_hand(var/mob/user as mob) - if(src.stat & NOPOWER) - to_chat(usr, "The upload computer has no power!") - return - if(src.stat & BROKEN) - to_chat(usr, "The upload computer is broken!") + var/turf/T = get_turf(current) + if(!atoms_share_level(T, src)) + to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!") return + module.install(src) + return + return ..() - src.current = freeborg() - if(!src.current) - to_chat(usr, "No free cyborgs detected.") - else - to_chat(usr, "[src.current.name] selected for law changes.") +/obj/machinery/computer/borgupload/attack_hand(var/mob/user as mob) + if(src.stat & NOPOWER) + to_chat(usr, "The upload computer has no power!") + return + if(src.stat & BROKEN) + to_chat(usr, "The upload computer is broken!") return - attack_ghost(user as mob) + src.current = freeborg() + + if(!src.current) + to_chat(usr, "No free cyborgs detected.") + else + to_chat(usr, "[src.current.name] selected for law changes.") + return + +/obj/machinery/computer/borgupload/attack_ghost(user as mob) return 1 diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index ed3b3d95099..f676d861f96 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -46,7 +46,7 @@ return FALSE if(R.scrambledcodes) return FALSE - if(!atoms_share_level(src, R)) + if(!atoms_share_level(get_turf(src), get_turf(R))) return FALSE return TRUE diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index ee29504fe99..8ee774d1ae0 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -253,7 +253,6 @@ to destroy them and players will be able to make replacements. /obj/machinery/vending/engineering = "Robco Tool Maker", /obj/machinery/vending/sovietsoda = "BODA", /obj/machinery/vending/security = "SecTech", - /obj/machinery/vending/modularpc = "Deluxe Silicate Selections", /obj/machinery/vending/crittercare = "CritterCare") /obj/item/circuitboard/vendor/screwdriver_act(mob/user, obj/item/I) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index ba8f430937c..70798c0b92e 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -27,12 +27,13 @@ var/running_bob_animation = 0 // This is used to prevent threads from building up if update_icons is called multiple times light_color = LIGHT_COLOR_WHITE - power_change() - ..() - if(!(stat & (BROKEN|NOPOWER))) - set_light(2) - else - set_light(0) + +/obj/machinery/atmospherics/unary/cryo_cell/power_change() + ..() + if(!(stat & (BROKEN|NOPOWER))) + set_light(2) + else + set_light(0) /obj/machinery/atmospherics/unary/cryo_cell/New() ..() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index fecd006886e..a13f87845ff 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -784,6 +784,9 @@ if(free_cryopods.len) target_cryopod = safepick(free_cryopods) if(target_cryopod.check_occupant_allowed(person_to_cryo)) + var/turf/T = get_turf(person_to_cryo) + var/obj/effect/portal/SP = new /obj/effect/portal(T, null, null, 40) + SP.name = "NT SSD Teleportation Portal" target_cryopod.take_occupant(person_to_cryo, 1) return 1 return 0 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 3f074c9051d..27c37f19c1a 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1261,8 +1261,10 @@ About the new airlock wires panel: return 1 /obj/machinery/door/airlock/emp_act(severity) - ..() - if(prob(40/severity)) + . = ..() + if(prob(20 / severity)) + open() + if(prob(40 / severity)) var/duration = world.time + (30 / severity) SECONDS if(duration > electrified_until) electrify(duration) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 36eba1a6ee5..a4cacc19abd 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -36,9 +36,10 @@ var/crimes = CELL_NONE var/time = 0 var/officer = CELL_NONE - var/prisoner_name = "" - var/prisoner_charge = "" - var/prisoner_time = "" + var/prisoner_name + var/prisoner_charge + var/prisoner_time + var/prisoner_hasrecord = FALSE /obj/machinery/door_timer/New() GLOB.celltimers_list += src @@ -82,10 +83,15 @@ var/datum/data/record/R = find_security_record("name", occupant) - var/announcetext = "Detainee [occupant] ([prisoner_drank]) has been incarcerated for [seconds_to_time(timetoset / 10)] for the charges of: '[crimes]'. \ + var/timetext = seconds_to_time(timetoset / 10) + var/announcetext = "Detainee [occupant] ([prisoner_drank]) has been incarcerated for [timetext] for the crime of: '[crimes]'. \ Arresting Officer: [usr.name].[R ? "" : " Detainee record not found, manual record update required."]" Radio.autosay(announcetext, name, "Security", list(z)) + // Notify the actual criminal being brigged. This is a QOL thing to ensure they always know the charges against them. + // Announcing it on radio isn't enough, as they're unlikely to have sec radio. + notify_prisoner("You have been incarcerated for [timetext] for the crime of: '[crimes]'.") + if(prisoner_trank != "unknown" && prisoner_trank != "Civilian") SSjobs.notify_dept_head(prisoner_trank, announcetext) @@ -104,6 +110,13 @@ update_all_mob_security_hud() return 1 +/obj/machinery/door_timer/proc/notify_prisoner(notifytext) + for(var/mob/living/carbon/human/H in range(4, get_turf(src))) + if(occupant == H.name) + to_chat(H, "[src] beeps, \"[notifytext]\"") + return + atom_say("[src] beeps, \"[occupant]: [notifytext]\"") + /obj/machinery/door_timer/Initialize() ..() @@ -224,8 +237,7 @@ for(var/obj/machinery/door/window/brigdoor/door in targets) if(!door.density) continue - spawn(0) - door.open() + INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/open) for(var/obj/structure/closet/secure_closet/brig/C in targets) if(C.broken) @@ -261,13 +273,11 @@ return -//Allows AIs to use door_timer, see human attack_hand function below /obj/machinery/door_timer/attack_ai(mob/user) - attack_hand(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/door_timer/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) //Allows humans to use door_timer //Opens dialog window when someone clicks on door timer @@ -276,71 +286,109 @@ /obj/machinery/door_timer/attack_hand(mob/user) if(..()) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/door_timer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/door_timer/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "brig_timer.tmpl", "Brig Timer", 500, 400) + ui = new(user, src, ui_key, "BrigTimer", name, 500, 450, master_ui, state) ui.open() - ui.set_auto_update(TRUE) -/obj/machinery/door_timer/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] +/obj/machinery/door_timer/tgui_static_data(mob/user) + var/list/data = list() + data["spns"] = list() + for(var/mob/living/carbon/human/H in range(4, get_turf(src))) + if(H.handcuffed) + data["spns"] += H.name + return data + +/obj/machinery/door_timer/tgui_data(mob/user) + var/list/data = list() data["cell_id"] = name data["occupant"] = occupant data["crimes"] = crimes data["brigged_by"] = officer - data["time_set"] = seconds_to_clock(time / 10) + data["time_set"] = seconds_to_clock(timetoset / 10) data["time_left"] = seconds_to_clock(timeleft()) data["timing"] = timing data["isAllowed"] = allowed(user) data["prisoner_name"] = prisoner_name data["prisoner_charge"] = prisoner_charge data["prisoner_time"] = prisoner_time - + data["prisoner_hasrec"] = prisoner_hasrecord return data -/obj/machinery/door_timer/Topic(href, href_list) - if(!allowed(usr) && !usr.can_admin_interact()) - return 1 +/obj/machinery/door_timer/allowed(mob/user) + if(user.can_admin_interact()) + return TRUE + return ..() - if(href_list["flash"]) - for(var/obj/machinery/flasher/F in targets) - if(F.last_flash && (F.last_flash + 150) > world.time) - to_chat(usr, "Flash still charging.") +/obj/machinery/door_timer/tgui_act(action, params) + if(..()) + return + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return + . = TRUE + switch(action) + if("prisoner_name") + if(params["prisoner_name"]) + prisoner_name = params["prisoner_name"] else - F.flash() - - if(href_list["release"]) - if(timing) - timer_end() - Radio.autosay("Timer stopped manually from cell control.", name, "Security", list(z)) - ui_interact(usr) - - if(href_list["prisoner_name"]) - prisoner_name = input("Prisoner Name:", name, prisoner_name) as text|null - - if(href_list["prisoner_charge"]) - prisoner_charge = input("Prisoner Charge:", name, prisoner_charge) as text|null - - if(href_list["prisoner_time"]) - prisoner_time = input("Prisoner Time (in minutes):", name, prisoner_time) as num|null - prisoner_time = min(max(round(prisoner_time), 0), 60) - - if(href_list["set_timer"]) - if(!prisoner_name || !prisoner_charge || !prisoner_time) - return - timeset(prisoner_time * 60) - occupant = prisoner_name - crimes = prisoner_charge - prisoner_name = "" - prisoner_charge = "" - prisoner_time = "" - timing = TRUE - timer_start() - ui_interact(usr) - update_icon() + prisoner_name = input("Prisoner Name:", name, prisoner_name) as text|null + if(prisoner_name) + var/datum/data/record/R = find_security_record("name", prisoner_name) + if(istype(R)) + prisoner_hasrecord = TRUE + else + prisoner_hasrecord = FALSE + if("prisoner_charge") + prisoner_charge = input("Prisoner Charge:", name, prisoner_charge) as text|null + if("prisoner_time") + prisoner_time = input("Prisoner Time (in minutes):", name, prisoner_time) as num|null + prisoner_time = min(max(round(prisoner_time), 0), 60) + if("start") + if(!prisoner_name || !prisoner_charge || !prisoner_time) + return FALSE + timeset(prisoner_time * 60) + occupant = prisoner_name + crimes = prisoner_charge + prisoner_name = null + prisoner_charge = null + prisoner_time = null + timing = TRUE + timer_start() + update_icon() + if("restart_timer") + if(timing) + var/reset_reason = sanitize(copytext(input(usr, "Reason for resetting timer:", name, "") as text|null, 1, MAX_MESSAGE_LEN)) + if(!reset_reason) + to_chat(usr, "Cancelled reset: reason field is required.") + return FALSE + releasetime = world.timeofday + timetoset + var/resettext = isobserver(usr) ? "for: [reset_reason]." : "by [usr.name] for: [reset_reason]." + Radio.autosay("Prisoner [occupant] had their timer reset [resettext]", name, "Security", list(z)) + notify_prisoner("Your brig timer has been reset for: '[reset_reason]'.") + var/datum/data/record/R = find_security_record("name", occupant) + if(istype(R)) + R.fields["comments"] += "Autogenerated by [name] on [GLOB.current_date_string] [station_time_timestamp()]
Timer reset [resettext]" + else + . = FALSE + if("stop") + if(timing) + timer_end() + var/stoptext = isobserver(usr) ? "from cell control." : "by [usr.name]." + Radio.autosay("Timer stopped manually [stoptext]", name, "Security", list(z)) + else + . = FALSE + if("flash") + for(var/obj/machinery/flasher/F in targets) + if(F.last_flash && (F.last_flash + 150) > world.time) + to_chat(usr, "Flash still charging.") + else + F.flash() + else + . = FALSE //icon update function diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 2d6fac3bb81..4ed92910c5a 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -234,12 +234,6 @@ emagged = 1 return 1 -/obj/machinery/door/emp_act(severity) - if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) ) - spawn(0) - open() - ..() - /obj/machinery/door/update_icon() if(density) icon_state = "door1" diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index e423f92683c..f27d4bf34a8 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -57,6 +57,11 @@ if(emagged) . += "Its access panel is smoking slightly." +/obj/machinery/door/window/emp_act(severity) + . = ..() + if(prob(20 / severity)) + open() + /obj/machinery/door/window/proc/open_and_close() open() if(check_access(null)) diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index 8ad85a608f0..d9500e30808 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -305,7 +305,7 @@ signalDoor(tag_exterior_door, command) signalDoor(tag_interior_door, command) -datum/computer/file/embedded_program/airlock/proc/signal_mech_sensor(var/command, var/sensor) +/datum/computer/file/embedded_program/airlock/proc/signal_mech_sensor(var/command, var/sensor) var/datum/signal/signal = new signal.data["tag"] = sensor signal.data["command"] = command diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index b387f404d8c..6144d1c3883 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -30,9 +30,9 @@ FIRE ALARM light_range = 7 light_color = "#ff3232" - var/last_process = 0 var/wiresexposed = 0 var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone + var/enabled = FALSE var/report_fire_alarms = TRUE // Should triggered fire alarms also trigger an actual alarm? var/show_alert_level = TRUE // Should fire alarms display the current alert level? @@ -84,7 +84,8 @@ FIRE ALARM return attack_hand(user) /obj/machinery/firealarm/attack_ghost(mob/user) - ui_interact(user) + if(user.can_admin_interact()) + toggle_alarm(user) /obj/machinery/firealarm/emp_act(severity) if(prob(50/severity)) @@ -217,21 +218,6 @@ FIRE ALARM else set_light(l_power = 0) -/obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed - if(stat & (NOPOWER|BROKEN)) - return - - if(timing) - if(time > 0) - time = time - ((world.timeofday - last_process)/10) - else - alarm() - time = 0 - timing = 0 - STOP_PROCESSING(SSobj, src) - updateDialog() - last_process = world.timeofday - /obj/machinery/firealarm/power_change() if(powered(ENVIRON)) stat &= ~NOPOWER @@ -248,56 +234,21 @@ FIRE ALARM if(user.incapacitated()) return 1 - ui_interact(user) + toggle_alarm(user) -/obj/machinery/firealarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "firealarm.tmpl", name, 400, 400, state = state) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/firealarm/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] +/obj/machinery/firealarm/proc/toggle_alarm(mob/user) var/area/A = get_area(src) - data["fire"] = A.fire - data["timing"] = timing + if(istype(A)) + add_fingerprint(user) + if(A.fire) + reset() + else + alarm() - data["sec_level"] = get_security_level() - - var/second = round(time % 60) - var/minute = round(time / 60) - - data["time_left"] = "[minute ? "[minute]:" : ""][add_zero(num2text(second), 2)]" - return data - -/obj/machinery/firealarm/Topic(href, href_list) - if(..()) - return 1 - - if(buildstage != 2) - return 1 - - add_fingerprint(usr) - - if(href_list["reset"]) - reset() - else if(href_list["alarm"]) - alarm() - else if(href_list["time"]) - var/oldTiming = timing - timing = text2num(href_list["time"]) - last_process = world.timeofday - if(oldTiming != timing) - if(timing) - START_PROCESSING(SSobj, src) - else - STOP_PROCESSING(SSobj, src) - else if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 120) +/obj/machinery/firealarm/examine(mob/user) + . = ..() + . += "It shows the alert level as: [capitalize(get_security_level())]." /obj/machinery/firealarm/proc/reset() if(!working || !report_fire_alarms) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index 0cc6dda7098..b4babfbabfd 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -146,3 +146,4 @@ /obj/machinery/floodlight/extinguish_light() on = 0 set_light(0) + update_icon() diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 7165cceb1ff..7d8910d6ef5 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -342,13 +342,13 @@ return -proc/getr(col) +/proc/getr(col) return hex2num( copytext(col, 2,4)) -proc/getg(col) +/proc/getg(col) return hex2num( copytext(col, 4,6)) -proc/getb(col) +/proc/getb(col) return hex2num( copytext(col, 6)) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 42452a9f8e2..a8c9710ff6c 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -106,10 +106,6 @@ else if(istype(make_from, /obj/machinery/atmospherics/unary/passive_vent)) src.pipe_type = PIPE_PASV_VENT - else if(istype(make_from, /obj/machinery/atmospherics/omni/mixer)) - src.pipe_type = PIPE_OMNI_MIXER - else if(istype(make_from, /obj/machinery/atmospherics/omni/filter)) - src.pipe_type = PIPE_OMNI_FILTER else if(istype(make_from, /obj/machinery/atmospherics/binary/circulator)) src.pipe_type = PIPE_CIRCULATOR @@ -259,7 +255,7 @@ return dir //dir|acw if(PIPE_CONNECTOR, PIPE_UVENT, PIPE_PASV_VENT, PIPE_SCRUBBER, PIPE_HEAT_EXCHANGE, PIPE_INJECTOR) return dir|flip - if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER) + if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W) return dir|flip|cw|acw if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD) return flip|cw|acw @@ -317,7 +313,7 @@ dir = 1 else if(dir==8) dir = 4 - else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER)) + else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W)) dir = 2 /obj/item/pipe/attack_self(mob/user as mob) @@ -499,14 +495,6 @@ P.name = pipename P.on_construction(dir, pipe_dir, color) - if(PIPE_OMNI_MIXER) - var/obj/machinery/atmospherics/omni/mixer/P = new(loc) - P.on_construction(dir, pipe_dir, color) - - if(PIPE_OMNI_FILTER) - var/obj/machinery/atmospherics/omni/filter/P = new(loc) - P.on_construction(dir, pipe_dir, color) - user.visible_message( \ "[user] fastens the [src].", \ "You have fastened the [src].", \ diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 6fb34254f3a..85fe8fcf843 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -12,7 +12,7 @@ active_power_usage = 200 pass_flags = PASSTABLE - var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs, /obj/item/bodyanalyzer) + var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/rcs, /obj/item/bodyanalyzer) var/icon_state_off = "rechargeroff" var/icon_state_charged = "recharger2" var/icon_state_charging = "recharger1" @@ -155,12 +155,6 @@ var/obj/item/melee/baton/B = I return B.cell - if(istype(I, /obj/item/modular_computer)) - var/obj/item/modular_computer/C = I - var/obj/item/computer_hardware/battery/B = C.all_components[MC_CELL] - if(B) - return B.battery - if(istype(I, /obj/item/rcs)) var/obj/item/rcs/R = I return R.rcell diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 822c4af3e1a..59865dee52a 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -96,7 +96,7 @@ name = "atmospherics suit storage unit" suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos mask_type = /obj/item/clothing/mask/gas - magboots_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots/atmos req_access = list(ACCESS_ATMOSPHERICS) /obj/machinery/suit_storage_unit/atmos/secure diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 2a476c215ef..37dd2c6d439 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -260,9 +260,9 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) if(payload && !istype(payload, /obj/item/bombcore/training)) - msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at [A.name] (JMP).", ATKLOG_FEW) log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]") investigate_log("[key_name(user)] has has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed a [name] ([payload]) for detonation", ATKLOG_FEW) payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!" ///Bomb Subtypes/// @@ -652,8 +652,8 @@ var/turf/T = get_turf(src) var/area/A = get_area(T) detonated-- - message_admins("[key_name_admin(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP).") investigate_log("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using", ATKLOG_FEW) log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])") detonated = 0 existant = 0 diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 59bae3174c4..005e6720b8b 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -1,16 +1,24 @@ +#define REGIME_TELEPORT 0 +#define REGIME_GATE 1 +#define REGIME_GPS 2 + /obj/machinery/computer/teleporter name = "teleporter control console" desc = "Used to control a linked teleportation Hub and Station." icon_screen = "teleport" icon_keyboard = "teleport_key" circuit = /obj/item/circuitboard/teleporter - var/obj/item/gps/locked = null - var/regime_set = "Teleporter" + var/obj/item/gps/locked = null /// A GPS with a locked destination + var/regime = REGIME_TELEPORT /// Switches mode between teleporter, gate and gps var/id = null - var/obj/machinery/teleport/station/power_station - var/calibrating - var/turf/target //Used for one-time-use teleport cards (such as clown planet coordinates.) - //Setting this to 1 will set src.locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. + var/obj/machinery/teleport/station/power_station /// The power station that's connected to the console + var/calibrating = FALSE /// Whether calibration is in progress or not. Calibration prevents changes. + var/turf/target ///The target turf of the teleporter + var/target_list ///lists of suitable teleport targets, dependent on regime. Used in the UI + + /* var/area_bypass is for one-time-use teleport cards (such as clown planet coordinates.) + Setting this to TRUE will set var/obj/item/gps/locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. + */ var/area_bypass = FALSE var/cc_beacon = FALSE @@ -24,6 +32,7 @@ ..() link_power_station() update_icon() + target_list = targets_teleport() /obj/machinery/computer/teleporter/Destroy() if(power_station) @@ -55,202 +64,238 @@ /obj/machinery/computer/teleporter/emag_act(mob/user) if(!emagged) - emagged = 1 + emagged = TRUE to_chat(user, "The teleporter can now lock on to Syndicate beacons!") else - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/teleporter/attack_ai(mob/user) - src.attack_hand(user) + attack_hand(user) /obj/machinery/computer/teleporter/attack_hand(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + +/obj/machinery/computer/teleporter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) if(stat & (NOPOWER|BROKEN)) return - - // Set up the Nano UI - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "teleporter_console.tmpl", "Teleporter Console UI", 400, 400) + ui = new(user, src, ui_key, "Teleporter", "Teleporter Console", 380, 260) ui.open() -/obj/machinery/computer/teleporter/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] +/obj/machinery/computer/teleporter/tgui_data(mob/user) + var/list/data = list() data["powerstation"] = power_station if(power_station?.teleporter_hub) data["teleporterhub"] = power_station.teleporter_hub data["calibrated"] = power_station.teleporter_hub.calibrated - data["accurate"] = power_station.teleporter_hub.accurate else data["teleporterhub"] = null data["calibrated"] = null - data["accurate"] = null - data["regime"] = regime_set + data["regime"] = regime var/area/targetarea = get_area(target) data["target"] = (!target || !targetarea) ? "None" : sanitize(targetarea.name) data["calibrating"] = calibrating - data["locked"] = locked + data["locked"] = locked ? TRUE : FALSE + data["targetsTeleport"] = target_list return data -/obj/machinery/computer/teleporter/Topic(href, href_list) +/obj/machinery/computer/teleporter/tgui_act(action, params) if(..()) - return 1 - - if(href_list["eject"]) - eject() - SSnanoui.update_uis(src) return if(!check_hub_connection()) - to_chat(usr, "Error: Unable to detect hub.") - SSnanoui.update_uis(src) + atom_say("Error: Unable to detect hub.") return if(calibrating) - to_chat(usr, "Error: Calibration in progress. Stand by.") - SSnanoui.update_uis(src) + atom_say("Error: Calibration in progress. Stand by.") return - if(href_list["regimeset"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - reset_regime() - SSnanoui.update_uis(src) - if(href_list["settarget"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - set_target(usr) - SSnanoui.update_uis(src) - if(href_list["lock"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - target = get_turf(locked.locked_location) - SSnanoui.update_uis(src) - if(href_list["calibrate"]) - if(!target) - to_chat(usr, "Error: No target set to calibrate to.") - SSnanoui.update_uis(src) - return - if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3) - to_chat(usr, "Hub is already calibrated.") - SSnanoui.update_uis(src) - return - src.visible_message("Processing hub calibration to target...") + . = TRUE - calibrating = 1 - SSnanoui.update_uis(src) - spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration - calibrating = 0 - if(check_hub_connection()) - power_station.teleporter_hub.calibrated = 1 - src.visible_message("Calibration complete.") - else - src.visible_message("Error: Unable to detect hub.") - SSnanoui.update_uis(src) + switch(action) + if("eject") //eject gps device + eject() + if("load") //load gps coordinates + target = locate(locked.locked_location.x,locked.locked_location.y,locked.locked_location.z) + if("setregime") + regime = text2num(params["regime"]) + if(regime == REGIME_TELEPORT) + target_list = targets_teleport() + if(regime == REGIME_GATE) + target_list = targets_gate() + if(regime == REGIME_GPS) + target_list = null //clears existing entries, target is added by load action + resetPowerstation() + target = null + if("settarget") + resetPowerstation() + var/turf/tmpTarget = locate(text2num(params["x"]),text2num(params["y"]),text2num(params["z"])) + if(!istype(tmpTarget, /turf)) + atom_say("No valid targets available.") + return + target = tmpTarget + if(regime == REGIME_TELEPORT) + teleport_helper() + if(regime == REGIME_GATE) + gate_helper() + if("calibrate") + if(!target) + atom_say("Error: No target set to calibrate to.") + return + if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3) + atom_say("Hub is already calibrated.") + return - SSnanoui.update_uis(src) + atom_say("Processing hub calibration to target...") + calibrating = TRUE + addtimer(CALLBACK(src, .proc/calibrateCallback), 50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration + +/** +* Resets the connected powerstation to initial values. Helper function of tgui_act +*/ +/obj/machinery/computer/teleporter/proc/resetPowerstation() + power_station.engaged = FALSE + power_station.teleporter_hub.calibrated = FALSE + power_station.teleporter_hub.update_icon() + +/** +* Calibrates the hub. Helper function of tgui_act +*/ +/obj/machinery/computer/teleporter/proc/calibrateCallback() + calibrating = FALSE + if(check_hub_connection()) + power_station.teleporter_hub.calibrated = TRUE + atom_say("Calibration complete.") + else + atom_say("Error: Unable to detect hub.") /obj/machinery/computer/teleporter/proc/check_hub_connection() if(!power_station) return if(!power_station.teleporter_hub) return - return 1 - -/obj/machinery/computer/teleporter/proc/reset_regime() - target = null - if(regime_set == "Teleporter") - regime_set = "Gate" - else - regime_set = "Teleporter" + return TRUE +/** +* Helper function of tgui_act +* +* Triggered when ejecting a gps device. Sets the gps to the ground and resets the console +*/ /obj/machinery/computer/teleporter/proc/eject() if(locked) locked.loc = loc locked = null + regime = REGIME_TELEPORT + target_list = targets_teleport() -/obj/machinery/computer/teleporter/proc/set_target(mob/user) - area_bypass = FALSE - if(regime_set == "Teleporter") - var/list/L = list() - var/list/areaindex = list() +/** +* Creates a list of viable targets for the teleport. Helper function of tgui_data +*/ +/obj/machinery/computer/teleporter/proc/targets_teleport() + var/list/L = list() + var/list/areaindex = list() - for(var/obj/item/radio/beacon/R in GLOB.beacons) - var/turf/T = get_turf(R) - if(!T) - continue - if(!is_teleport_allowed(T.z) && !R.cc_beacon) - continue - if(R.syndicate == 1 && emagged == 0) - continue - var/tmpname = T.loc.name + for(var/obj/item/radio/beacon/R in GLOB.beacons) + var/turf/T = get_turf(R) + if(!T) + continue + if(!is_teleport_allowed(T.z) && !R.cc_beacon) + continue + if(R.syndicate && !emagged) + continue + var/tmpname = T.loc.name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" + else + areaindex[tmpname] = 1 + L[tmpname] = list( + "name" = tmpname, + "x" = T.x, + "y" = T.y, + "z" = T.z) + + for(var/obj/item/implant/tracking/I in GLOB.tracked_implants) + if(!I.implanted || !ismob(I.loc)) + continue + else + var/mob/M = I.loc + if(M.stat == DEAD) + if(M.timeofdeath + 6000 < world.time) + continue + var/turf/T = get_turf(M) + if(!T) continue + if(!is_teleport_allowed(T.z)) continue + var/tmpname = M.real_name if(areaindex[tmpname]) tmpname = "[tmpname] ([++areaindex[tmpname]])" else areaindex[tmpname] = 1 - L[tmpname] = R + L[tmpname] = list( + "name" = tmpname, + "x" = T.x, + "y" = T.y, + "z" = T.z) + return L - for(var/obj/item/implant/tracking/I in GLOB.tracked_implants) - if(!I.implanted || !ismob(I.loc)) - continue - else - var/mob/M = I.loc - if(M.stat == DEAD) - if(M.timeofdeath + 6000 < world.time) - continue - var/turf/T = get_turf(M) - if(!T) continue - if(!is_teleport_allowed(T.z)) continue - var/tmpname = M.real_name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = I +/** +* Creates a list of viable targets for the gate. Helper function of tgui_data +*/ +/obj/machinery/computer/teleporter/proc/targets_gate(mob/users) + var/list/L = list() + var/list/areaindex = list() + var/list/S = power_station.linked_stations + if(!S.len) + return L + for(var/obj/machinery/teleport/station/R in S) + var/turf/T = get_turf(R) + if(!T || !R.teleporter_hub || !R.teleporter_console) + continue + if(!is_teleport_allowed(T.z)) + continue + var/tmpname = T.loc.name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" + else + areaindex[tmpname] = 1 + L[tmpname] = list( + "name" = tmpname, + "x" = T.x, + "y" = T.y, + "z" = T.z) + return L - var/desc = input("Please select a location to lock in.", "Locking Computer") in L - target = L[desc] - if(istype(target, /obj/item/radio/beacon)) - var/obj/item/radio/beacon/B = target +/** +* Helper function of tgui_act. +* +* Called after selecting a target for the gate in the UI. Sets area_bypass and cc_beacon. +*/ +/obj/machinery/computer/teleporter/proc/teleport_helper() + area_bypass = FALSE + for(var/item in target.contents) + if(istype(item, /obj/item/radio/beacon)) + var/obj/item/radio/beacon/B = item if(B.area_bypass) area_bypass = TRUE cc_beacon = B.cc_beacon - else - var/list/L = list() - var/list/areaindex = list() - var/list/S = power_station.linked_stations - if(!S.len) - to_chat(user, "No connected stations located.") - return - for(var/obj/machinery/teleport/station/R in S) - var/turf/T = get_turf(R) - if(!T || !R.teleporter_hub || !R.teleporter_console) - continue - if(!is_teleport_allowed(T.z)) - continue - var/tmpname = T.loc.name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = R - var/desc = input("Please select a station to lock in.", "Locking Computer") in L - target = L[desc] - if(target) - var/obj/machinery/teleport/station/trg = target - trg.linked_stations |= power_station - trg.stat &= ~NOPOWER - if(trg.teleporter_hub) - trg.teleporter_hub.stat &= ~NOPOWER - trg.teleporter_hub.update_icon() - if(trg.teleporter_console) - trg.teleporter_console.stat &= ~NOPOWER - trg.teleporter_console.update_icon() - return + +/** +* Helper function of tgui_act. +* +* Called after selecting a target for the teleporter in the UI. +*/ +/obj/machinery/computer/teleporter/proc/gate_helper() + area_bypass = FALSE + var/obj/machinery/teleport/station/trg = target + trg.linked_stations |= power_station + trg.stat &= ~NOPOWER + if(trg.teleporter_hub) + trg.teleporter_hub.stat &= ~NOPOWER + trg.teleporter_hub.update_icon() + if(trg.teleporter_console) + trg.teleporter_console.stat &= ~NOPOWER + trg.teleporter_console.update_icon() /proc/find_loc(obj/R as obj) if(!R) return null @@ -263,20 +308,20 @@ /obj/machinery/teleport name = "teleport" icon = 'icons/obj/stationobjs.dmi' - density = 1 - anchored = 1.0 + density = TRUE + anchored = TRUE /obj/machinery/teleport/hub name = "teleporter hub" desc = "It's the hub of a teleporting machine." icon_state = "tele0" - var/accurate = 0 + var/accurate = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 2000 var/obj/machinery/teleport/station/power_station var/calibrated //Calibration prevents mutation - var/admin_usage = 0 // if 1, works on z2. If 0, doesn't. Used for admin room teleport. + var/admin_usage = FALSE // if 1, works on z2. If 0, doesn't. Used for admin room teleport. /obj/machinery/teleport/hub/New() ..() @@ -317,6 +362,7 @@ for(dir in list(NORTH,EAST,SOUTH,WEST)) power_station = locate(/obj/machinery/teleport/station, get_step(src, dir)) if(power_station) + power_station.link_console_and_hub() break return power_station @@ -324,27 +370,12 @@ if(!is_teleport_allowed(z) && !admin_usage) to_chat(M, "You can't use this here.") return - if(power_station && power_station.engaged && !panel_open) - //--FalseIncarnate - //Prevents AI cores from using the teleporter, prints out failure messages for clarity - if(istype(M, /mob/living/silicon/ai) || istype(M, /obj/structure/AIcore)) - visible_message("The teleporter rejects the AI unit.") - if(istype(M, /mob/living/silicon/ai)) - var/mob/living/silicon/ai/T = M - var/list/TPError = list("Firmware instructions dictate you must remain on your assigned station!", - "You cannot interface with this technology and get rejected!", - "External firewalls prevent you from utilizing this machine!", - "Your AI core's anti-bluespace failsafes trigger and prevent teleportation!") - to_chat(T, "[pick(TPError)]") - return - else - if(!teleport(M) && isliving(M)) // the isliving(M) is needed to avoid triggering errors if a spark bumps the telehub - visible_message("[src] emits a loud buzz, as its teleport portal flickers and fails!") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - power_station.toggle() // turn off the portal. - - use_power(5000) - //--FalseIncarnate + if(power_station && power_station.engaged && !panel_open && !blockAI(M) && !istype(M, /obj/spacepod)) + if(!teleport(M) && isliving(M)) // the isliving(M) is needed to avoid triggering errors if a spark bumps the telehub + visible_message("[src] emits a loud buzz, as its teleport portal flickers and fails!") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + power_station.toggle() // turn off the portal. + use_power(5000) return /obj/machinery/teleport/hub/attackby(obj/item/I, mob/user, params) @@ -375,7 +406,7 @@ . = do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), 3), 2, bypass_area_flag = com.area_bypass) else . = do_teleport(M, com.target, bypass_area_flag = com.area_bypass) - calibrated = 0 + calibrated = FALSE /obj/machinery/teleport/hub/update_icon() if(panel_open) @@ -389,7 +420,7 @@ name = "permanent teleporter" desc = "A teleporter with the target pre-set on the circuit board." icon_state = "tele0" - var/recalibrating = 0 + var/recalibrating = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 2000 @@ -406,37 +437,42 @@ tele_delay = max(A, 0) update_icon() -/obj/machinery/teleport/perma/Bumped(M as mob|obj) +/** + Internal helper function + + Prevents AI from using the teleporter, prints out failure messages for clarity +*/ +/obj/machinery/teleport/proc/blockAI(atom/A) + if(istype(A, /mob/living/silicon/ai) || istype(A, /obj/structure/AIcore)) + visible_message("The teleporter rejects the AI unit.") + if(istype(A, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/T = A + var/list/TPError = list("Firmware instructions dictate you must remain on your assigned station!", + "You cannot interface with this technology and get rejected!", + "External firewalls prevent you from utilizing this machine!", + "Your AI core's anti-bluespace failsafes trigger and prevent teleportation!") + to_chat(T, "[pick(TPError)]") + return TRUE + return FALSE + +/obj/machinery/teleport/perma/Bumped(atom/A) if(stat & (BROKEN|NOPOWER)) return if(!is_teleport_allowed(z)) - to_chat(M, "You can't use this here.") + to_chat(A, "You can't use this here.") return - if(target && !recalibrating && !panel_open) - //--FalseIncarnate - //Prevents AI cores from using the teleporter, prints out failure messages for clarity - if(istype(M, /mob/living/silicon/ai) || istype(M, /obj/structure/AIcore)) - visible_message("The teleporter rejects the AI unit.") - if(istype(M, /mob/living/silicon/ai)) - var/mob/living/silicon/ai/T = M - var/list/TPError = list("Firmware instructions dictate you must remain on your assigned station!", - "You cannot interface with this technology and get rejected!", - "External firewalls prevent you from utilizing this machine!", - "Your AI core's anti-bluespace failsafes trigger and prevent teleportation!") - to_chat(T, "[pick(TPError)]") - return - else - do_teleport(M, target) - use_power(5000) - if(tele_delay) - recalibrating = 1 - update_icon() - spawn(tele_delay) - recalibrating = 0 - update_icon() - //--FalseIncarnate - return + if(target && !recalibrating && !panel_open && !blockAI(A)) + do_teleport(A, target) + use_power(5000) + if(tele_delay) + recalibrating = TRUE + update_icon() + addtimer(CALLBACK(src, .proc/BumpedCallback), tele_delay) + +/obj/machinery/teleport/perma/proc/BumpedCallback() + recalibrating = FALSE + update_icon() /obj/machinery/teleport/perma/power_change() ..() @@ -467,7 +503,7 @@ name = "station" desc = "The power control station for a bluespace teleporter." icon_state = "controller" - var/engaged = 0 + var/engaged = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 2000 @@ -568,7 +604,7 @@ /obj/machinery/teleport/station/attack_ai() - src.attack_hand() + attack_hand() /obj/machinery/teleport/station/attack_hand(mob/user) if(!panel_open) @@ -583,12 +619,12 @@ to_chat(user, "Close the hub's maintenance panel first.") return if(teleporter_console.target) - src.engaged = !src.engaged + engaged = !engaged use_power(5000) visible_message("Teleporter [engaged ? "" : "dis"]engaged!") else visible_message("No target detected.") - src.engaged = 0 + engaged = FALSE teleporter_hub.update_icon() if(istype(user)) add_fingerprint(user) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 48b022a65f3..20fd93547eb 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -447,7 +447,7 @@ /obj/machinery/vending/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - var/estimated_height = 100 + (length(product_records) * 34) + var/estimated_height = 100 + min(length(product_records) * 34, 500) if(length(prices) > 0) estimated_height += 100 // to account for the "current user" interface ui = new(user, src, ui_key, "Vending", name, 470, estimated_height, master_ui, state) @@ -1272,7 +1272,7 @@ ads_list = list("We like plants!","Don't you want some?","The greenest thumbs ever.","We like big plants.","Soft soil...") icon_state = "nutri" icon_deny = "nutri-deny" - products = list(/obj/item/reagent_containers/glass/bottle/nutrient/ez = 30,/obj/item/reagent_containers/glass/bottle/nutrient/l4z = 20,/obj/item/reagent_containers/glass/bottle/nutrient/rh = 10,/obj/item/reagent_containers/spray/pestspray = 20, + products = list(/obj/item/reagent_containers/glass/bottle/nutrient/ez = 20,/obj/item/reagent_containers/glass/bottle/nutrient/l4z = 13,/obj/item/reagent_containers/glass/bottle/nutrient/rh = 6,/obj/item/reagent_containers/spray/pestspray = 20, /obj/item/reagent_containers/syringe = 5,/obj/item/storage/bag/plants = 5,/obj/item/cultivator = 3,/obj/item/shovel/spade = 3,/obj/item/plant_analyzer = 4) contraband = list(/obj/item/reagent_containers/glass/bottle/ammonia = 10,/obj/item/reagent_containers/glass/bottle/diethylamine = 5) refill_canister = /obj/item/vending_refill/hydronutrients @@ -1907,46 +1907,3 @@ component_parts += new /obj/item/vending_refill/crittercare(null) RefreshParts() return ..() - -/obj/machinery/vending/modularpc - name = "\improper Deluxe Silicate Selections" - desc = "All the parts you need to build your own custom pc." - icon_state = "modularpc" - icon_deny = "modularpc-deny" - ads_list = list("Get your gamer gear!","The best GPUs for all of your space-crypto needs!","The most robust cooling!","The finest RGB in space!") - vend_reply = "Game on!" - products = list(/obj/item/modular_computer/laptop = 4, - /obj/item/modular_computer/tablet = 4, - /obj/item/computer_hardware/hard_drive = 4, - /obj/item/computer_hardware/hard_drive/small = 4, - /obj/item/computer_hardware/network_card = 8, - /obj/item/computer_hardware/hard_drive/portable = 8, - /obj/item/computer_hardware/battery = 8, - /obj/item/stock_parts/cell/computer = 8, - /obj/item/computer_hardware/processor_unit = 4, - /obj/item/computer_hardware/processor_unit/small = 4) - premium = list(/obj/item/computer_hardware/card_slot = 2, - /obj/item/computer_hardware/ai_slot = 2, - /obj/item/computer_hardware/printer/mini = 2, - /obj/item/computer_hardware/recharger/APC = 2, - /obj/item/paicard = 2) - prices = list(/obj/item/modular_computer/laptop = 300, - /obj/item/modular_computer/tablet = 300, - /obj/item/computer_hardware/hard_drive = 100, - /obj/item/computer_hardware/hard_drive/small = 50, - /obj/item/computer_hardware/network_card = 100, - /obj/item/computer_hardware/hard_drive/portable = 100, - /obj/item/computer_hardware/battery = 100, - /obj/item/stock_parts/cell/computer = 100, - /obj/item/computer_hardware/processor_unit = 100, - /obj/item/computer_hardware/processor_unit/small = 100) - refill_canister = /obj/item/vending_refill/modularpc - -/obj/machinery/vending/modularpc/Initialize(mapload) - component_parts = list() - var/obj/item/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/vending_refill/modularpc(null) - RefreshParts() - return ..() diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm index 1bb73856f1b..eb7bfad8942 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/game/mecha/combat/honker.dm @@ -137,7 +137,7 @@ squeak = 0 return result -obj/mecha/combat/honker/Topic(href, href_list) +/obj/mecha/combat/honker/Topic(href, href_list) ..() if(href_list["play_sound"]) switch(href_list["play_sound"]) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index e05fef18e5a..d1e63deaf0c 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -60,7 +60,7 @@ set_ready_state(0) log_message("Fired from [name], targeting [target].") var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])") + add_attack_logs(chassis.occupant, target, "fired a [src]", ATKLOG_FEW) log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") do_after_cooldown() return @@ -238,7 +238,7 @@ chassis.use_power(energy_drain) log_message("Honked from [name]. HONK!") var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] used a Mecha Honker in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])") + add_attack_logs(chassis.occupant, target, "used a Mecha Honker", ATKLOG_MOST) log_game("[key_name(chassis.occupant)] used a Mecha Honker in [T.x], [T.y], [T.z]") do_after_cooldown() return @@ -357,7 +357,7 @@ projectiles-- log_message("Fired from [name], targeting [target].") var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])") + add_attack_logs(chassis.occupant, target, "fired a [src]", ATKLOG_FEW) log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") do_after_cooldown() return diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 2cc543b9dc9..54a431c92db 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -424,12 +424,7 @@ return if(isobj(obstacle)) var/obj/O = obstacle - if(istype(O, /obj/effect/portal)) //derpfix - anchored = 0 - O.Bumped(src) - spawn(0) //countering portal teleport spawn(0), hurr - anchored = 1 - else if(!O.anchored) + if(!O.anchored) step(obstacle, dir) else if(ismob(obstacle)) step(obstacle, dir) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index a55c2a731eb..3f8eb81c6b9 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -481,7 +481,7 @@ would spawn and follow the beaker, even if it is carried or thrown. var/more = "" if(M) more = " " - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1) + add_attack_logs(M, location, "Caused a chemical smoke reaction containing [contained]. Last associated key is [carry.my_atom.fingerprintslast][more]", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].") else msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1) diff --git a/code/game/objects/effects/effect_system/effects_chem_smoke.dm b/code/game/objects/effects/effect_system/effects_chem_smoke.dm index 8c28c7f11c5..2ebad516beb 100644 --- a/code/game/objects/effects/effect_system/effects_chem_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_chem_smoke.dm @@ -83,13 +83,13 @@ var/more = "" if(M) more = " " - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", ATKLOG_FEW) + add_attack_logs(M, location, "Caused a chemical smoke reaction containing [contained]. Last associated key is [carry.my_atom.fingerprintslast][more]", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].") else - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", ATKLOG_FEW) + msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. No associated key.", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") else - msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key. CODERS: carry.my_atom may be null.", ATKLOG_FEW) + msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. No associated key. CODERS: carry.my_atom may be null.", ATKLOG_FEW) log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key. CODERS: carry.my_atom may be null.") diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index aa756631768..a2b084463a4 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -88,9 +88,6 @@ if(!M.simulated || iseffect(M)) . = FALSE - if(M.anchored && ismecha(M)) - . = FALSE - /obj/effect/portal/proc/teleport(atom/movable/M) if(!can_teleport(M)) return FALSE diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm index 2e81ecb235d..9b62faa5252 100644 --- a/code/game/objects/effects/spawners/bombspawner.dm +++ b/code/game/objects/effects/spawners/bombspawner.dm @@ -6,18 +6,18 @@ var/btemp1 = 1500 var/btemp2 = 1000 // tank temperatures - timer - btype = 2 +/obj/effect/spawner/newbomb/timer + btype = 2 - syndicate - btemp1 = 150 - btemp2 = 20 +/obj/effect/spawner/newbomb/timer/syndicate + btemp1 = 150 + btemp2 = 20 - proximity - btype = 1 +/obj/effect/spawner/newbomb/proximity + btype = 1 - radio - btype = 0 +/obj/effect/spawner/newbomb/radio + btype = 0 /obj/effect/spawner/newbomb/New() diff --git a/code/game/objects/effects/spawners/random_spawners.dm b/code/game/objects/effects/spawners/random_spawners.dm index 9eb8e9de1a2..acd1e54eef7 100644 --- a/code/game/objects/effects/spawners/random_spawners.dm +++ b/code/game/objects/effects/spawners/random_spawners.dm @@ -285,7 +285,7 @@ /obj/item/clothing/gloves/color/yellow/power = 1, /obj/item/twohanded/chainsaw = 1, /obj/item/bee_briefcase = 1, - /obj/item/twohanded/energizedfireaxe = 1, + /obj/item/twohanded/fireaxe/energized = 1, /obj/item/clothing/glasses/thermal = 1, /obj/item/chameleon = 1, /obj/item/reagent_containers/hypospray/autoinjector/stimulants = 1, diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 639687a45e9..a1538b5fe92 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -42,7 +42,7 @@ /obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0) if(height == 0) return TRUE - if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider)) + if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider) || isterrorspider(mover)) return TRUE else if(istype(mover, /mob/living)) if(prob(50)) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 1b31891e537..f35b877bc17 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -137,19 +137,7 @@ T.ex_act(3) CHECK_TICK - //--- THROW ITEMS AROUND --- -/* - if(throw_dist > 0) - var/throw_dir = get_dir(epicenter,T) - for(var/obj/item/I in T) - spawn(0) //Simultaneously not one at a time - if(I && !I.anchored) - var/throw_mult = 0.5 + (0.5 * rand()) // Between 0.5 and 1.0 - var/throw_range = round((throw_dist + 1) * throw_mult) // Roughly 50% to 100% of throw_dist - if(throw_range > 0) - var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range) - I.throw_at(throw_at, throw_range, 2, no_spin = 1) //Throw it at 2 speed, this is purely visual anyway; don't spin the thrown items, it's very costly. -*/ + var/took = stop_watch(watch) //You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare if(GLOB.debug2) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 5c63dbc709c..58a4ab63d34 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -7,10 +7,10 @@ icon_state = "bodybag_folded" w_class = WEIGHT_CLASS_SMALL - attack_self(mob/user) - var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc) - R.add_fingerprint(user) - qdel(src) +/obj/item/bodybag/attack_self(mob/user) + var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc) + R.add_fingerprint(user) + qdel(src) /obj/structure/closet/body_bag name = "body bag" @@ -56,16 +56,13 @@ /obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location) - ..() + . = ..() if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src)))) - if(!ishuman(usr)) return - if(opened) return 0 - if(contents.len) return 0 - visible_message("[usr] folds up the [src.name]") + if(!ishuman(usr) || opened || length(contents)) + return FALSE + visible_message("[usr] folds up the [name]") new item_path(get_turf(src)) - spawn(0) - qdel(src) - return + qdel(src) /obj/structure/closet/body_bag/relaymove(mob/user as mob) if(user.stat) diff --git a/code/game/objects/items/changestone.dm b/code/game/objects/items/changestone.dm index 62d56614a07..ec7ad232857 100644 --- a/code/game/objects/items/changestone.dm +++ b/code/game/objects/items/changestone.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/artifacts.dmi' icon_state = "changerock" -obj/item/changestone/attack_hand(var/mob/user as mob) +/obj/item/changestone/attack_hand(var/mob/user as mob) if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user if(!H.gloves) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 093f28692ec..7eb1dc9fd56 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -37,71 +37,83 @@ overlays.Cut() /obj/item/aicard/attack_self(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/item/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.inventory_state) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/aicard/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_inventory_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state) + ui = new(user, src, ui_key, "AICard", "[name]", 600, 394, master_ui, state) ui.open() - ui.set_auto_update(1) -/obj/item/aicard/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.inventory_state) +/obj/item/aicard/tgui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.inventory_state) var/data[0] var/mob/living/silicon/ai/AI = locate() in src if(istype(AI)) - data["has_ai"] = 1 + data["has_ai"] = TRUE data["name"] = AI.name - data["hardware_integrity"] = ((AI.health + 100) / 2) + data["integrity"] = ((AI.health + 100) / 2) data["radio"] = !AI.aiRadio.disabledAi data["wireless"] = !AI.control_disabled data["operational"] = AI.stat != DEAD data["flushing"] = flush var/laws[0] - for(var/datum/ai_law/AL in AI.laws.all_laws()) - laws[++laws.len] = list("index" = AL.get_index(), "law" = sanitize(AL.law)) + for(var/datum/ai_law/law in AI.laws.all_laws()) + if(law in AI.laws.ion_laws) // If we're an ion law, give it an ion index code + laws.Add(ionnum() + ". " + law.law) + else + laws.Add(num2text(law.get_index()) + ". " + law.law) data["laws"] = laws - data["has_laws"] = laws.len + data["has_laws"] = length(AI.laws.all_laws()) + + else + data["has_ai"] = FALSE // If this isn't passed to tgui, it won't show there isn't a AI in the card. return data -/obj/item/aicard/Topic(href, href_list, nowindow, state) +/obj/item/aicard/tgui_act(action, params) if(..()) - return 1 + return var/mob/living/silicon/ai/AI = locate() in src if(!istype(AI)) - return 1 + return var/user = usr + switch(action) + if("wipe") + if(flush) // Don't doublewipe. + to_chat(user, "You are already wiping this AI!") + return + var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No") + if(confirm == "Yes" && (tgui_status(user, GLOB.tgui_inventory_state) == STATUS_INTERACTIVE)) // And make doubly sure they want to wipe (three total clicks) + msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW) + add_attack_logs(user, AI, "Wiped with [src].") + INVOKE_ASYNC(src, .proc/wipe_ai) - if(href_list["wipe"]) - var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No") - if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE)) - msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW) - add_attack_logs(user, AI, "Wiped with [src].") - flush = 1 - AI.suiciding = 1 - to_chat(AI, "Your core files are being wiped!") - while(AI && AI.stat != DEAD) - AI.adjustOxyLoss(2) - sleep(10) - flush = 0 + if("radio") + AI.aiRadio.disabledAi = !AI.aiRadio.disabledAi + to_chat(AI, "Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!") + to_chat(user, "You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.") - if(href_list["radio"]) - AI.aiRadio.disabledAi = text2num(href_list["radio"]) - to_chat(AI, "Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!") - to_chat(user, "You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.") + if("wireless") + AI.control_disabled = !AI.control_disabled + to_chat(AI, "Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!") + to_chat(user, "You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.") + update_icon() - if(href_list["wireless"]) - AI.control_disabled = text2num(href_list["wireless"]) - to_chat(AI, "Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!") - to_chat(user, "You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.") - update_icon() + return TRUE - return 1 +/obj/item/aicard/proc/wipe_ai() + var/mob/living/silicon/ai/AI = locate() in src + flush = TRUE + AI.suiciding = TRUE + to_chat(AI, "Your core files are being wiped!") + while(AI && AI.stat != DEAD) + AI.adjustOxyLoss(2) + sleep(10) + flush = FALSE diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index d9af70df391..2142dc9e50b 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -45,9 +45,6 @@ QDEL_NULL(keyslot2) return ..() -/obj/item/radio/headset/list_channels(var/mob/user) - return list_secure_channels() - /obj/item/radio/headset/examine(mob/user) . = ..() if(in_range(src, user) && radio_desc) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index d9d3aa3c3c1..f9ba60ab380 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -245,14 +245,7 @@ usesound = 'sound/items/deconstruct.ogg' /obj/item/radio/intercom/locked - var/locked_frequency - -/obj/item/radio/intercom/locked/set_frequency(var/frequency) - if(frequency == locked_frequency) - ..(locked_frequency) - -/obj/item/radio/intercom/locked/list_channels() - return "" + freqlock = TRUE /obj/item/radio/intercom/locked/ai_private name = "\improper AI intercom" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index cdcc2361937..ed6b0190502 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -129,7 +129,10 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( /obj/item/radio/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "Radio", name, 360, 150 + (length(channels) * 20), master_ui, state) + var/list/schannels = list_secure_channels(user) + var/list/ichannels = list_internal_channels(user) + var/calc_height = 150 + (schannels.len * 20) + (ichannels.len * 10) + ui = new(user, src, ui_key, "Radio", name, 400, calc_height, master_ui, state) ui.open() /obj/item/radio/tgui_data(mob/user) @@ -142,9 +145,8 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( data["maxFrequency"] = freerange ? RADIO_HIGH_FREQ : PUBLIC_HIGH_FREQ data["canReset"] = frequency == initial(frequency) ? FALSE : TRUE data["freqlock"] = freqlock - data["channels"] = list() - for(var/channel in channels) - data["channels"][channel] = channels[channel] & FREQ_LISTENING + data["schannels"] = list_secure_channels(user) + data["ichannels"] = list_internal_channels(user) data["has_loudspeaker"] = has_loudspeaker data["loudspeaker"] = loudspeaker @@ -173,6 +175,12 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( usr << browse(null, "window=radio") if(.) set_frequency(sanitize_frequency(tune, freerange)) + if("ichannel") // change primary frequency to an internal channel authorized by access + if(freqlock) + return + var/freq = params["ichannel"] + if(has_channel_access(usr, freq)) + set_frequency(text2num(freq)) if("listen") listening = !listening if("broadcast") @@ -198,34 +206,32 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( if(.) add_fingerprint(usr) -/obj/item/radio/proc/list_channels(var/mob/user) - return list_internal_channels(user) - -/obj/item/radio/proc/list_secure_channels(var/mob/user) - var/dat[0] - - for(var/ch_name in channels) - var/chan_stat = channels[ch_name] - var/listening = !!(chan_stat & FREQ_LISTENING) != 0 - - dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = SSradio.frequency_span_class(SSradio.radiochannels[ch_name])))) - +/obj/item/radio/proc/list_secure_channels(mob/user) + var/list/dat = list() + for(var/channel in channels) + dat[channel] = channels[channel] & FREQ_LISTENING return dat -/obj/item/radio/proc/list_internal_channels(var/mob/user) - var/dat[0] +/obj/item/radio/proc/list_internal_channels(mob/user) + var/list/dat = list() + if(freqlock) + return dat for(var/internal_chan in internal_channels) + var/freqnum = text2num(internal_chan) + var/freqname = get_frequency_name(freqnum) if(has_channel_access(user, internal_chan)) - dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = SSradio.frequency_span_class(text2num(internal_chan))))) - + dat[freqname] = freqnum // unlike secure_channels, this is set to the freq number so Radio.js can use it as an arg return dat -/obj/item/radio/proc/has_channel_access(var/mob/user, var/freq) +/obj/item/radio/proc/has_channel_access(mob/user, freq) if(!user) - return 0 + return FALSE if(!(freq in internal_channels)) - return 0 + return FALSE + + if(isrobot(user)) + return FALSE // cyborgs and drones are not allowed to remotely re-tune intercomms, etc return user.has_internal_radio_channel_access(user, internal_channels[freq]) @@ -603,13 +609,14 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( /obj/item/radio/borg name = "Cyborg Radio" var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks - var/obj/item/encryptionkey/keyslot = null//Borg radios can handle a single encryption key + var/obj/item/encryptionkey/keyslot // Borg radios can handle a single encryption key icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component. icon_state = "radio" has_loudspeaker = TRUE loudspeaker = FALSE canhear_range = 0 dog_fashion = null + freqlock = TRUE // don't let cyborgs change the default channel of their internal radio away from common /obj/item/radio/borg/syndicate keyslot = new /obj/item/encryptionkey/syndicate/nukeops @@ -623,9 +630,6 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( myborg = null return ..() -/obj/item/radio/borg/list_channels(var/mob/user) - return list_secure_channels(user) - /obj/item/radio/borg/syndicate/New() ..() syndiekey = keyslot diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index fdef93dc7a3..1eba4e54056 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -64,7 +64,7 @@ A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB) - msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.", ATKLOG_FEW) + add_attack_logs(user, src, "attached [A] to a transfer valve", ATKLOG_FEW) log_game("[key_name_admin(user)] attached [A] to a transfer valve.") attacher = user SSnanoui.update_uis(src) // update all UIs attached to src @@ -128,7 +128,7 @@ if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) w_class = WEIGHT_CLASS_NORMAL if("toggle") - toggle_valve() + toggle_valve(usr) if("device") if(attached_device) attached_device.attack_self(usr) @@ -190,7 +190,7 @@ it explodes properly when it gets a signal (and it does). */ -/obj/item/transfer_valve/proc/toggle_valve() +/obj/item/transfer_valve/proc/toggle_valve(mob/user) if(!valve_open && tank_one && tank_two) valve_open = 1 var/turf/bombturf = get_turf(src) @@ -207,6 +207,8 @@ investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB) message_admins("Bomb valve opened at [A.name] (JMP) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]") log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]") + if(user) + add_attack_logs(user, src, "Bomb valve opened with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", ATKLOG_FEW) merge_gases() spawn(20) // In case one tank bursts for(var/i in 1 to 5) diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm index f33e504a3e6..0dda06d3e5c 100644 --- a/code/game/objects/items/flag.dm +++ b/code/game/objects/items/flag.dm @@ -242,15 +242,15 @@ to_chat(user, "You hide [I] in the [src]. It will detonate some time after the flag is lit on fire.") var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[key_name_admin(user)] has hidden [I] in the [src] ready for detonation at [A.name] (JMP).") log_game("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") investigate_log("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has hidden [I] ready for detonation in", ATKLOG_MOST) else if(is_hot(I) && !(resistance_flags & ON_FIRE) && boobytrap && trapper) var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] (JMP).") log_game("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") investigate_log("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has lit (booby trapped with [boobytrap]", ATKLOG_FEW) burn() else return ..() diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 2d2b110fa06..067411ed647 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -185,20 +185,18 @@ /obj/item/borg/upgrade/syndicate name = "safety override module" - desc = "Unlocks the hidden, deadlier functions of a cyborg. Also prevents emag subversion." + desc = "Unlocks the hidden, deadlier functions of a cyborg." icon_state = "cyborg_upgrade3" - origin_tech = "combat=4;syndicate=1" + origin_tech = "combat=6;materials=6" require_module = TRUE /obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R) if(..()) return - if(R.emagged) - return if(R.weapons_unlock) - to_chat(R, "Internal diagnostic error: incompatible upgrade module detected.") + to_chat(R, "Warning: Safety Overide Protocols have be disabled.") return - R.emagged = 1 + R.weapons_unlock = 1 return TRUE /obj/item/borg/upgrade/lavaproof diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 4fef7b9f6d5..6b70ac015ca 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -54,7 +54,6 @@ GLOBAL_LIST_INIT(metal_recipes, list( new /datum/stack_recipe/rods("metal rod", /obj/item/stack/rods, 1, 2, 50), null, new /datum/stack_recipe("computer frame", /obj/structure/computerframe, 5, time = 25, one_per_turf = 1, on_floor = 1), - new /datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("machine frame", /obj/machinery/constructable_frame/machine_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1), diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index cd1b91388d7..5eddfae9bbb 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -214,8 +214,9 @@ /obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) return 0 -/obj/item/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles - return 0 +/obj/item/twohanded/dualsaber/toy/IsReflect() + if(wielded) + return 2 /obj/item/toy/katana name = "replica katana" @@ -404,7 +405,7 @@ -obj/item/toy/cards +/obj/item/toy/cards resistance_flags = FLAMMABLE max_integrity = 50 var/parentdeck = null @@ -416,14 +417,14 @@ obj/item/toy/cards var/card_throw_range = 20 var/list/card_attack_verb = list("attacked") -obj/item/toy/cards/New() +/obj/item/toy/cards/New() ..() -obj/item/toy/cards/proc/apply_card_vars(obj/item/toy/cards/newobj, obj/item/toy/cards/sourceobj) // Applies variables for supporting multiple types of card deck +/obj/item/toy/cards/proc/apply_card_vars(obj/item/toy/cards/newobj, obj/item/toy/cards/sourceobj) // Applies variables for supporting multiple types of card deck if(!istype(sourceobj)) return -obj/item/toy/cards/deck +/obj/item/toy/cards/deck name = "deck of cards" desc = "A deck of space-grade playing cards." icon = 'icons/obj/toy.dmi' @@ -433,7 +434,7 @@ obj/item/toy/cards/deck var/cooldown = 0 var/list/cards = list() -obj/item/toy/cards/deck/New() +/obj/item/toy/cards/deck/New() ..() icon_state = "deck_[deckstyle]_full" for(var/i in 2 to 10) @@ -458,7 +459,7 @@ obj/item/toy/cards/deck/New() cards += "Ace of Clubs" cards += "Ace of Diamonds" -obj/item/toy/cards/deck/attack_hand(mob/user as mob) +/obj/item/toy/cards/deck/attack_hand(mob/user as mob) var/choice = null if(cards.len == 0) icon_state = "deck_[deckstyle]_empty" @@ -476,14 +477,14 @@ obj/item/toy/cards/deck/attack_hand(mob/user as mob) visible_message("[user] draws a card from the deck.", "You draw a card from the deck.") update_icon() -obj/item/toy/cards/deck/attack_self(mob/user as mob) +/obj/item/toy/cards/deck/attack_self(mob/user as mob) if(cooldown < world.time - 50) cards = shuffle(cards) playsound(user, 'sound/items/cardshuffle.ogg', 50, 1) user.visible_message("[user] shuffles the deck.", "You shuffle the deck.") cooldown = world.time -obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) +/obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) ..() if(istype(C)) if(C.parentdeck == src) @@ -498,7 +499,7 @@ obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/use update_icon() -obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user, params) +/obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user, params) ..() if(istype(C)) if(C.parentdeck == src) @@ -512,7 +513,7 @@ obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user, to_chat(user, "You can't mix cards from other decks.") update_icon() -obj/item/toy/cards/deck/MouseDrop(atom/over_object) +/obj/item/toy/cards/deck/MouseDrop(atom/over_object) var/mob/M = usr if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained()) return @@ -536,7 +537,7 @@ obj/item/toy/cards/deck/MouseDrop(atom/over_object) else to_chat(usr, "You can't reach it from here.") -obj/item/toy/cards/deck/update_icon() +/obj/item/toy/cards/deck/update_icon() switch(cards.len) if(0) icon_state = "deck_[deckstyle]_empty" @@ -547,7 +548,7 @@ obj/item/toy/cards/deck/update_icon() else icon_state = "deck_[deckstyle]_full" -obj/item/toy/cards/cardhand +/obj/item/toy/cards/cardhand name = "hand of cards" desc = "A number of cards not in a deck, customarily held in ones hand." icon = 'icons/obj/toy.dmi' @@ -557,11 +558,11 @@ obj/item/toy/cards/cardhand var/choice = null -obj/item/toy/cards/cardhand/attack_self(mob/user as mob) +/obj/item/toy/cards/cardhand/attack_self(mob/user as mob) user.set_machine(src) interact(user) -obj/item/toy/cards/cardhand/interact(mob/user) +/obj/item/toy/cards/cardhand/interact(mob/user) var/dat = "You have:
" for(var/t in currenthand) dat += "A [t].
" @@ -572,7 +573,7 @@ obj/item/toy/cards/cardhand/interact(mob/user) popup.open() -obj/item/toy/cards/cardhand/Topic(href, href_list) +/obj/item/toy/cards/cardhand/Topic(href, href_list) if(..()) return if(usr.stat || !ishuman(usr) || !usr.canmove) @@ -606,7 +607,7 @@ obj/item/toy/cards/cardhand/Topic(href, href_list) qdel(src) return -obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) +/obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) if(istype(C)) if(C.parentdeck == parentdeck) currenthand += C.cardname @@ -618,7 +619,7 @@ obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living else to_chat(user, "You can't mix cards from other decks.") -obj/item/toy/cards/cardhand/apply_card_vars(obj/item/toy/cards/newobj,obj/item/toy/cards/sourceobj) +/obj/item/toy/cards/cardhand/apply_card_vars(obj/item/toy/cards/newobj,obj/item/toy/cards/sourceobj) ..() newobj.deckstyle = sourceobj.deckstyle newobj.icon_state = "[deckstyle]_hand2" // Another dumb hack, without this the hand is invisible (or has the default deckstyle) until another card is added. @@ -631,7 +632,7 @@ obj/item/toy/cards/cardhand/apply_card_vars(obj/item/toy/cards/newobj,obj/item/t newobj.resistance_flags = sourceobj.resistance_flags -obj/item/toy/cards/singlecard +/obj/item/toy/cards/singlecard name = "card" desc = "a card" icon = 'icons/obj/toy.dmi' @@ -642,7 +643,7 @@ obj/item/toy/cards/singlecard pixel_x = -5 -obj/item/toy/cards/singlecard/examine(mob/user) +/obj/item/toy/cards/singlecard/examine(mob/user) . = ..() if(get_dist(user, src) <= 0) if(ishuman(user)) @@ -653,7 +654,7 @@ obj/item/toy/cards/singlecard/examine(mob/user) . += "You need to have the card in your hand to check it." -obj/item/toy/cards/singlecard/verb/Flip() +/obj/item/toy/cards/singlecard/verb/Flip() set name = "Flip Card" set category = "Object" set src in range(1) @@ -674,7 +675,7 @@ obj/item/toy/cards/singlecard/verb/Flip() name = "card" pixel_x = -5 -obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user, params) +/obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/toy/cards/singlecard/)) var/obj/item/toy/cards/singlecard/C = I if(C.parentdeck == parentdeck) @@ -704,7 +705,7 @@ obj/item/toy/cards/singlecard/attackby(obj/item/I, mob/living/user, params) else to_chat(user, "You can't mix cards from other decks.") -obj/item/toy/cards/cardhand/update_icon() +/obj/item/toy/cards/cardhand/update_icon() switch(currenthand.len) if(0 to 1) return @@ -718,12 +719,12 @@ obj/item/toy/cards/cardhand/update_icon() icon_state = "[deckstyle]_hand5" -obj/item/toy/cards/singlecard/attack_self(mob/user) +/obj/item/toy/cards/singlecard/attack_self(mob/user) if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained()) return Flip() -obj/item/toy/cards/singlecard/apply_card_vars(obj/item/toy/cards/singlecard/newobj,obj/item/toy/cards/sourceobj) +/obj/item/toy/cards/singlecard/apply_card_vars(obj/item/toy/cards/singlecard/newobj,obj/item/toy/cards/sourceobj) ..() newobj.deckstyle = sourceobj.deckstyle newobj.icon_state = "singlecard_down_[deckstyle]" // Without this the card is invisible until flipped. It's an ugly hack, but it works. @@ -745,7 +746,7 @@ obj/item/toy/cards/singlecard/apply_card_vars(obj/item/toy/cards/singlecard/newo || Syndicate playing cards, for pretending you're Gambit and playing poker for the nuke disk. || */ -obj/item/toy/cards/deck/syndicate +/obj/item/toy/cards/deck/syndicate name = "suspicious looking deck of cards" desc = "A deck of space-grade playing cards. They seem unusually rigid." deckstyle = "syndicate" @@ -760,10 +761,10 @@ obj/item/toy/cards/deck/syndicate /* || Custom card decks || */ -obj/item/toy/cards/deck/black +/obj/item/toy/cards/deck/black deckstyle = "black" -obj/item/toy/cards/deck/syndicate/black +/obj/item/toy/cards/deck/syndicate/black deckstyle = "black" /obj/item/toy/nuke diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index 8508c741524..d369161127f 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -59,6 +59,14 @@ /obj/item/trash/fried_vox name = "Kentucky Fried Vox" icon_state = "fried_vox_empty" + item_state = "fried_vox_empty" + slot_flags = SLOT_HEAD + dog_fashion = /datum/dog_fashion/head/fried_vox_empty + sprite_sheets = list( + "Skrell" = 'icons/mob/species/skrell/head.dmi', + "Drask" = 'icons/mob/species/drask/head.dmi', + "Kidan" = 'icons/mob/species/kidan/head.dmi' + ) /obj/item/trash/pistachios name = "Pistachios pack" diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index b780a837559..2b30ae5851f 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -102,6 +102,7 @@ var/rank = null //actual job var/owner_uid var/owner_ckey + var/lastlog var/dorm = 0 // determines if this ID has claimed a dorm already var/sex diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index 30ad91beffa..bd80e43140f 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -66,6 +66,10 @@ LIGHTERS ARE IN LIGHTERS.DM ..() light() +/obj/item/clothing/mask/cigarette/catch_fire() + if(!lit) + light("The [name] is lit by the flames!") + /obj/item/clothing/mask/cigarette/welder_act(mob/user, obj/item/I) . = TRUE if(I.tool_use_check(user, 0)) //Don't need to flash eyes because you are a badass diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 629942860be..ae49512853a 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -189,8 +189,8 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) investigate_log("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]", INVESTIGATE_BOMB) - message_admins("E20 detonated at [A.name] (JMP) with a roll of [result]. Triggered by: [key_name_admin(user)]") log_game("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]") + add_attack_logs(user, src, "detonated with a roll of [result]", ATKLOG_FEW) /obj/item/dice/update_icon() diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index f4ab41fab7b..1b1352c372f 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -106,6 +106,8 @@ src.last_use = world.time + if(reagents.chem_temp > 300 || reagents.chem_temp < 280) + add_attack_logs(user, target, "Sprayed with superheated or cooled fire extinguisher at Temperature [reagents.chem_temp]K") playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3) var/direction = get_dir(src,target) diff --git a/code/game/objects/items/weapons/fireworks.dm b/code/game/objects/items/weapons/fireworks.dm index a2a0d6df552..906c4f3fef7 100644 --- a/code/game/objects/items/weapons/fireworks.dm +++ b/code/game/objects/items/weapons/fireworks.dm @@ -1,10 +1,11 @@ -obj/item/firework +/obj/item/firework name = "fireworks" icon = 'icons/obj/fireworks.dmi' icon_state = "rocket_0" var/litzor = 0 var/datum/effect_system/sparkle_spread/S -obj/item/firework/attackby(obj/item/W,mob/user, params) + +/obj/item/firework/attackby(obj/item/W,mob/user, params) if(litzor) return if(is_hot(W)) @@ -20,13 +21,13 @@ obj/item/firework/attackby(obj/item/W,mob/user, params) S.start() qdel(src) -obj/item/sparkler +/obj/item/sparkler name = "sparkler" icon = 'icons/obj/fireworks.dmi' icon_state = "sparkler_0" var/litzor = 0 -obj/item/sparkler/attackby(obj/item/W,mob/user, params) +/obj/item/sparkler/attackby(obj/item/W,mob/user, params) if(litzor) return if(is_hot(W)) @@ -39,8 +40,12 @@ obj/item/sparkler/attackby(obj/item/W,mob/user, params) do_sparks(1, 0, loc) sleep(10) qdel(src) + +// TODO: Refactor this into a proper locker or something +// Or just axe the system. This code is 7 years old /obj/crate/fireworks name = "Fireworks!" + /obj/crate/fireworks/New() new /obj/item/sparkler(src) new /obj/item/sparkler(src) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 79612afd1f3..3aa658b0812 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -101,9 +101,9 @@ update_icon() else if(clown_check(user)) // This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it. - message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP) [contained].") log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) [contained].") investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained].", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed (contained [contained])", ATKLOG_FEW) to_chat(user, "You prime the [name]! [det_time / 10] second\s!") playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) active = 1 @@ -120,7 +120,7 @@ owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!") var/turf/T = get_turf(src) log_game("A projectile ([hitby]) detonated a grenade held by [key_name(owner)] at [COORD(T)]") - message_admins("A projectile ([hitby]) detonated a grenade held by [key_name_admin(owner)] at [ADMIN_COORDJMP(T)]") + add_attack_logs(P.firer, owner, "A projectile ([hitby]) detonated a grenade held", ATKLOG_FEW) prime() return 1 //It hit the grenade, not them @@ -149,16 +149,16 @@ if(!O.reagents) continue if(istype(O,/obj/item/slime_extract)) cores += " [O]" - for(var/reagent in O.reagents.reagent_list) - contained += " [reagent] " + for(var/R in O.reagents.reagent_list) + var/datum/reagent/reagent = R + contained += "[reagent.volume] [reagent], " if(contained) if(cores) - contained = "\[[cores];[contained]\]" + contained = "\[[cores]; [contained]\]" else - contained = "\[[contained]\]" + contained = "\[ [contained]\]" var/turf/bombturf = get_turf(loc) - var/area/A = bombturf.loc - message_admins("[key_name_admin(usr)] has completed [name] at [A.name] (JMP) [contained].") + add_attack_logs(user, src, "has completed with [contained]", ATKLOG_MOST) log_game("[key_name(usr)] has completed [name] at [bombturf.x], [bombturf.y], [bombturf.z]. [contained]") else to_chat(user, "You need to add at least one beaker before locking the assembly.") diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index b58330a248b..c2303dd2937 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -48,9 +48,9 @@ var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[ADMIN_LOOKUPFLW(user)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)].") log_game("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") investigate_log("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)])", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 8cbc041c146..da546836dc6 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -73,6 +73,7 @@ message_admins("[key_name_admin(usr)] has primed a [name] for detonation at [A.name] (JMP)") log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])") investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index b4df7b0d16b..efb93a520a5 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -9,27 +9,27 @@ var/deliveryamt = 1 // amount of type to deliver spawner_type = /mob/living/simple_animal/hostile/viscerator - prime() // Prime now just handles the two loops that query for people in lockers and people who can see it. +/obj/item/grenade/spawnergrenade/prime() // Prime now just handles the two loops that query for people in lockers and people who can see it. - if(spawner_type && deliveryamt) - // Make a quick flash - var/turf/T = get_turf(src) - playsound(T, 'sound/effects/phasein.ogg', 100, 1) - for(var/mob/living/carbon/C in viewers(T, null)) - C.flash_eyes() + if(spawner_type && deliveryamt) + // Make a quick flash + var/turf/T = get_turf(src) + playsound(T, 'sound/effects/phasein.ogg', 100, 1) + for(var/mob/living/carbon/C in viewers(T, null)) + C.flash_eyes() - for(var/i=1, i<=deliveryamt, i++) - var/atom/movable/x = new spawner_type - x.admin_spawned = admin_spawned - x.loc = T - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(x, pick(NORTH,SOUTH,EAST,WEST)) + for(var/i=1, i<=deliveryamt, i++) + var/atom/movable/x = new spawner_type + x.admin_spawned = admin_spawned + x.loc = T + if(prob(50)) + for(var/j = 1, j <= rand(1, 3), j++) + step(x, pick(NORTH,SOUTH,EAST,WEST)) - // Spawn some hostile syndicate critters + // Spawn some hostile syndicate critters - qdel(src) - return + qdel(src) + return /obj/item/grenade/spawnergrenade/manhacks name = "manhack delivery grenade" diff --git a/code/game/objects/items/weapons/highlander_swords.dm b/code/game/objects/items/weapons/highlander_swords.dm index 330da6beba0..568b023d051 100644 --- a/code/game/objects/items/weapons/highlander_swords.dm +++ b/code/game/objects/items/weapons/highlander_swords.dm @@ -25,14 +25,14 @@ return ..() /obj/item/claymore/highlander/equipped(mob/user, slot) - if(!ishuman(user)) + if(!ishuman(user) || !user.mind) return var/mob/living/carbon/human/H = user if(slot == slot_r_hand || slot == slot_l_hand) - if(H.martial_art && H.martial_art != style) - style.teach(H, 1) + if(H.mind.martial_art && H.mind.martial_art != style) + style.teach(H, TRUE) to_chat(H, "THERE CAN ONLY BE ONE!") - else if(H.martial_art && H.martial_art == style) + else if(H.mind.martial_art && H.mind.martial_art == style) style.remove(H) var/obj/item/claymore/highlander/sword = H.is_in_hands(/obj/item/claymore/highlander) if(sword) diff --git a/code/game/objects/items/weapons/implants/implant_krav_maga.dm b/code/game/objects/items/weapons/implants/implant_krav_maga.dm index 3c2666f3d66..9c33f43950a 100644 --- a/code/game/objects/items/weapons/implants/implant_krav_maga.dm +++ b/code/game/objects/items/weapons/implants/implant_krav_maga.dm @@ -17,12 +17,12 @@ /obj/item/implant/krav_maga/activate() var/mob/living/carbon/human/H = imp_in - if(!ishuman(H)) + if(!ishuman(H) || !H.mind) return - if(istype(H.martial_art, /datum/martial_art/krav_maga)) + if(istype(H.mind.martial_art, /datum/martial_art/krav_maga)) style.remove(H) else - style.teach(H,1) + style.teach(H, TRUE) /obj/item/implanter/krav_maga name = "implanter (krav maga)" diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index d74ab31a6c3..00a72f3401b 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -17,13 +17,6 @@ var/mob/living/carbon/occupant = null var/injecting = 0 -/obj/machinery/implantchair/proc - go_out() - put_mob(mob/living/carbon/M) - implant(var/mob/M) - add_implants() - - /obj/machinery/implantchair/New() ..() add_implants() @@ -87,7 +80,7 @@ return -/obj/machinery/implantchair/go_out(mob/M) +/obj/machinery/implantchair/proc/go_out(mob/M) if(!( src.occupant )) return if(M == occupant) // so that the guy inside can't eject himself -Agouri @@ -101,7 +94,7 @@ return -/obj/machinery/implantchair/put_mob(mob/living/carbon/M) +/obj/machinery/implantchair/proc/put_mob(mob/living/carbon/M) if(!iscarbon(M)) to_chat(usr, "The [src.name] cannot hold this!") return @@ -116,7 +109,7 @@ return 1 -/obj/machinery/implantchair/implant(mob/M) +/obj/machinery/implantchair/proc/implant(mob/M) if(!istype(M, /mob/living/carbon)) return if(!implant_list.len) return @@ -131,7 +124,7 @@ return -/obj/machinery/implantchair/add_implants() +/obj/machinery/implantchair/proc/add_implants() for(var/i=0, i[user] slams the charged axe into [M.name] with all [user.p_their()] might!
") + do_sparks(1, 1, src) + M.Weaken(4) + var/atom/throw_target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src))) + M.throw_at(throw_target, 5, 1) + /* * Double-Bladed Energy Swords - Cheridan */ @@ -755,57 +791,6 @@ charged = 3 playsound(user, 'sound/weapons/marauder.ogg', 50, 1) -// Energized Fire axe -/obj/item/twohanded/energizedfireaxe - name = "energized fire axe" - desc = "Someone with a love for fire axes decided to turn one into a single-charge energy weapon. Seems excessive." - icon_state = "fireaxe0" - force = 5 - throwforce = 15 - sharp = TRUE - w_class = WEIGHT_CLASS_HUGE - armour_penetration = 20 - slot_flags = SLOT_BACK - force_unwielded = 5 - force_wielded = 30 - attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) - var/charged = 1 - -/obj/item/twohanded/energizedfireaxe/update_icon() - if(wielded) - icon_state = "fireaxe2" - else - icon_state = "fireaxe0" - ..() - -/obj/item/twohanded/energizedfireaxe/afterattack(atom/A, mob/user, proximity) - if(!proximity) - return - if(wielded) - if(isliving(A)) - var/mob/living/Z = A - if(charged) - charged-- - Z.take_organ_damage(0, 30) - user.visible_message("[user] slams the charged axe into [Z.name] with all [user.p_their()] might!") - playsound(loc, 'sound/magic/lightningbolt.ogg', 5, 1) - do_sparks(1, 1, src) - - if(A && wielded && (istype(A, /obj/structure/window) || istype(A, /obj/structure/grille))) - if(istype(A, /obj/structure/window)) - var/obj/structure/window/W = A - W.deconstruct(FALSE) - if(prob(4)) - charged++ - user.visible_message("The axe starts to emit an electric buzz!") - else - qdel(A) - if(prob(4)) - charged++ - user.visible_message("The axe starts to emit an electric buzz!") - /obj/item/twohanded/pitchfork icon_state = "pitchfork0" name = "pitchfork" diff --git a/code/game/objects/items/weapons/vending_items.dm b/code/game/objects/items/weapons/vending_items.dm index 258771870d8..e7743f961f1 100644 --- a/code/game/objects/items/weapons/vending_items.dm +++ b/code/game/objects/items/weapons/vending_items.dm @@ -126,10 +126,6 @@ machine_name = "NanoMed" icon_state = "refill_medical" -/obj/item/vending_refill/modularpc - machine_name = "Deluxe Silicate Selections" - icon_state = "refill_engi" - /obj/item/vending_refill/hydronutrients machine_name = "NutriMax" icon_state = "refill_plant" diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index e5f903a1853..28e213c7826 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -185,6 +185,7 @@ throwforce = 12 attack_verb = list("beat", "smacked") w_class = WEIGHT_CLASS_HUGE + var/next_throw_time = 0 var/homerun_ready = 0 var/homerun_able = 0 @@ -253,16 +254,38 @@ to_chat(user, "You cannot attack in deflect mode!") return . = ..() - var/atom/throw_target = get_edge_target_turf(target, user.dir) if(homerun_ready) + var/atom/throw_target = get_edge_target_turf(target, user.dir) user.visible_message("It's a home run!") target.throw_at(throw_target, rand(8,10), 14, user) target.ex_act(2) playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) homerun_ready = 0 return - else if(!target.anchored) - target.throw_at(throw_target, rand(1,2), 7, user) + if(world.time < next_throw_time) + // Limit the rate of throwing, so you can't spam it. + return + if(!istype(target)) + // Should already be /mob/living, but check anyway. + return + if(target.anchored) + // No throwing mobs that are anchored to the floor. + return + if(target.mob_size > MOB_SIZE_HUMAN) + // No throwing things that are physically bigger than you are. + // Covers: blobbernaut, alien empress, ai core, juggernaut, ed209, mulebot, alien/queen/large, carp/megacarp, deathsquid, hostile/tree, megafauna, hostile/asteroid, terror_spider/queen/empress + return + if(!(target.status_flags & CANPUSH)) + // No throwing mobs specifically flagged as immune to being pushed. + // Covers: revenant, hostile/blob/*, most borgs, juggernauts, hivebot/tele, spaceworms, shades, bots, alien queens, hostile/syndicate/melee, hostile/asteroid + return + if(target.move_resist > MOVE_RESIST_DEFAULT) + // No throwing mobs that have higher than normal move_resist. + // Covers: revenant, bot/mulebot, hostile/statue, hostile/megafauna, goliath + return + var/atom/throw_target = get_edge_target_turf(target, user.dir) + target.throw_at(throw_target, rand(1, 2), 7, user) + next_throw_time = world.time + 10 SECONDS /obj/item/melee/baseball_bat/ablative name = "metal baseball bat" diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index bbd43db7c1e..e41d2173c23 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -51,6 +51,8 @@ take_damage(AM.throwforce, BRUTE, "melee", 1, get_dir(src, AM)) /obj/ex_act(severity) + if(QDELETED(src)) + return if(resistance_flags & INDESTRUCTIBLE) return switch(severity) diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 59cc3898088..52b70590ee4 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -30,13 +30,14 @@ desc = "This is a random tool" icon = 'icons/obj/items.dmi' icon_state = "welder" - item_to_spawn() - return pick(/obj/item/screwdriver,\ - /obj/item/wirecutters,\ - /obj/item/weldingtool,\ - /obj/item/crowbar,\ - /obj/item/wrench,\ - /obj/item/flashlight) + +/obj/random/tool/item_to_spawn() + return pick(/obj/item/screwdriver,\ + /obj/item/wirecutters,\ + /obj/item/weldingtool,\ + /obj/item/crowbar,\ + /obj/item/wrench,\ + /obj/item/flashlight) /obj/random/technology_scanner @@ -44,10 +45,11 @@ desc = "This is a random technology scanner." icon = 'icons/obj/device.dmi' icon_state = "atmos" - item_to_spawn() - return pick(prob(5);/obj/item/t_scanner,\ - prob(2);/obj/item/radio/intercom,\ - prob(5);/obj/item/analyzer) + +/obj/random/technology_scanner/item_to_spawn() + return pick(prob(5);/obj/item/t_scanner,\ + prob(2);/obj/item/radio/intercom,\ + prob(5);/obj/item/analyzer) /obj/random/powercell @@ -55,23 +57,24 @@ desc = "This is a random powercell." icon = 'icons/obj/power.dmi' icon_state = "cell" - item_to_spawn() - return pick(prob(10);/obj/item/stock_parts/cell/crap,\ - prob(40);/obj/item/stock_parts/cell,\ - prob(40);/obj/item/stock_parts/cell/high,\ - prob(9);/obj/item/stock_parts/cell/super,\ - prob(1);/obj/item/stock_parts/cell/hyper) +/obj/random/powercell/item_to_spawn() + return pick(prob(10);/obj/item/stock_parts/cell/crap,\ + prob(40);/obj/item/stock_parts/cell,\ + prob(40);/obj/item/stock_parts/cell/high,\ + prob(9);/obj/item/stock_parts/cell/super,\ + prob(1);/obj/item/stock_parts/cell/hyper) /obj/random/bomb_supply name = "Bomb Supply" desc = "This is a random bomb supply." icon = 'icons/obj/assemblies/new_assemblies.dmi' icon_state = "signaller" - item_to_spawn() - return pick(/obj/item/assembly/igniter,\ - /obj/item/assembly/prox_sensor,\ - /obj/item/assembly/signaler) + +/obj/random/bomb_supply/item_to_spawn() + return pick(/obj/item/assembly/igniter,\ + /obj/item/assembly/prox_sensor,\ + /obj/item/assembly/signaler) /obj/random/toolbox @@ -79,11 +82,11 @@ desc = "This is a random toolbox." icon = 'icons/obj/storage.dmi' icon_state = "red" - item_to_spawn() - return pick(prob(3);/obj/item/storage/toolbox/mechanical,\ - prob(2);/obj/item/storage/toolbox/electrical,\ - prob(1);/obj/item/storage/toolbox/emergency) +/obj/random/toolbox/item_to_spawn() + return pick(prob(3);/obj/item/storage/toolbox/mechanical,\ + prob(2);/obj/item/storage/toolbox/electrical,\ + prob(1);/obj/item/storage/toolbox/emergency) /obj/random/tech_supply name = "Random Tech Supply" @@ -91,15 +94,16 @@ icon = 'icons/obj/power.dmi' icon_state = "cell" spawn_nothing_percentage = 50 - item_to_spawn() - return pick(prob(3);/obj/random/powercell,\ - prob(2);/obj/random/technology_scanner,\ - prob(1);/obj/item/stack/packageWrap,\ - prob(2);/obj/random/bomb_supply,\ - prob(1);/obj/item/extinguisher,\ - prob(1);/obj/item/clothing/gloves/color/fyellow,\ - prob(3);/obj/item/stack/cable_coil,\ - prob(2);/obj/random/toolbox,\ - prob(2);/obj/item/storage/belt/utility,\ - prob(5);/obj/random/tool,\ - prob(3);/obj/item/stack/tape_roll) + +/obj/random/tech_supply/item_to_spawn() + return pick(prob(3);/obj/random/powercell,\ + prob(2);/obj/random/technology_scanner,\ + prob(1);/obj/item/stack/packageWrap,\ + prob(2);/obj/random/bomb_supply,\ + prob(1);/obj/item/extinguisher,\ + prob(1);/obj/item/clothing/gloves/color/fyellow,\ + prob(3);/obj/item/stack/cable_coil,\ + prob(2);/obj/random/toolbox,\ + prob(2);/obj/item/storage/belt/utility,\ + prob(5);/obj/random/tool,\ + prob(3);/obj/item/stack/tape_roll) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index d95eac2a0ac..8f812397ef9 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -61,89 +61,89 @@ new /obj/item/clothing/mask/gas/syndicate(src) new /obj/item/clothing/suit/space/hardsuit/syndi/elite/sst(src) -/obj/structure/closet/syndicate/resources/ +/obj/structure/closet/syndicate/resources desc = "An old, dusty locker." - New() - ..() - var/common_min = 30 //Minimum amount of minerals in the stack for common minerals - var/common_max = 50 //Maximum amount of HONK in the stack for HONK common minerals - var/rare_min = 5 //Minimum HONK of HONK in the stack HONK HONK rare minerals - var/rare_max = 20 //Maximum HONK HONK HONK in the HONK for HONK rare HONK +/obj/structure/closet/syndicate/resources/New() + ..() + var/common_min = 30 //Minimum amount of minerals in the stack for common minerals + var/common_max = 50 //Maximum amount of HONK in the stack for HONK common minerals + var/rare_min = 5 //Minimum HONK of HONK in the stack HONK HONK rare minerals + var/rare_max = 20 //Maximum HONK HONK HONK in the HONK for HONK rare HONK - var/pickednum = rand(1, 50) + var/pickednum = rand(1, 50) - //Sad trombone - if(pickednum == 1) - var/obj/item/paper/P = new /obj/item/paper(src) - P.name = "IOU" - P.info = "Sorry man, we needed the money so we sold your stash. It's ok, we'll double our money for sure this time!" + //Sad trombone + if(pickednum == 1) + var/obj/item/paper/P = new /obj/item/paper(src) + P.name = "IOU" + P.info = "Sorry man, we needed the money so we sold your stash. It's ok, we'll double our money for sure this time!" - //Metal (common ore) - if(pickednum >= 2) - new /obj/item/stack/sheet/metal(src, rand(common_min, common_max)) + //Metal (common ore) + if(pickednum >= 2) + new /obj/item/stack/sheet/metal(src, rand(common_min, common_max)) - //Glass (common ore) - if(pickednum >= 5) - new /obj/item/stack/sheet/glass(src, rand(common_min, common_max)) + //Glass (common ore) + if(pickednum >= 5) + new /obj/item/stack/sheet/glass(src, rand(common_min, common_max)) - //Plasteel (common ore) Because it has a million more uses then plasma - if(pickednum >= 10) - new /obj/item/stack/sheet/plasteel(src, rand(common_min, common_max)) + //Plasteel (common ore) Because it has a million more uses then plasma + if(pickednum >= 10) + new /obj/item/stack/sheet/plasteel(src, rand(common_min, common_max)) - //Plasma (rare ore) - if(pickednum >= 15) - new /obj/item/stack/sheet/mineral/plasma(src, rand(rare_min, rare_max)) + //Plasma (rare ore) + if(pickednum >= 15) + new /obj/item/stack/sheet/mineral/plasma(src, rand(rare_min, rare_max)) - //Silver (rare ore) - if(pickednum >= 20) - new /obj/item/stack/sheet/mineral/silver(src, rand(rare_min, rare_max)) + //Silver (rare ore) + if(pickednum >= 20) + new /obj/item/stack/sheet/mineral/silver(src, rand(rare_min, rare_max)) - //Gold (rare ore) - if(pickednum >= 30) - new /obj/item/stack/sheet/mineral/gold(src, rand(rare_min, rare_max)) + //Gold (rare ore) + if(pickednum >= 30) + new /obj/item/stack/sheet/mineral/gold(src, rand(rare_min, rare_max)) - //Uranium (rare ore) - if(pickednum >= 40) - new /obj/item/stack/sheet/mineral/uranium(src, rand(rare_min, rare_max)) + //Uranium (rare ore) + if(pickednum >= 40) + new /obj/item/stack/sheet/mineral/uranium(src, rand(rare_min, rare_max)) - //Titanium (rare ore) - if(pickednum >= 40) - new /obj/item/stack/sheet/mineral/titanium(src, rand(rare_min, rare_max)) + //Titanium (rare ore) + if(pickednum >= 40) + new /obj/item/stack/sheet/mineral/titanium(src, rand(rare_min, rare_max)) - //Plastitanium (rare ore) - if(pickednum >= 40) - new /obj/item/stack/sheet/mineral/plastitanium(src, rand(rare_min, rare_max)) + //Plastitanium (rare ore) + if(pickednum >= 40) + new /obj/item/stack/sheet/mineral/plastitanium(src, rand(rare_min, rare_max)) - //Diamond (rare HONK) - if(pickednum >= 45) - new /obj/item/stack/sheet/mineral/diamond(src, rand(rare_min, rare_max)) + //Diamond (rare HONK) + if(pickednum >= 45) + new /obj/item/stack/sheet/mineral/diamond(src, rand(rare_min, rare_max)) - //Jetpack (You hit the jackpot!) - if(pickednum == 50) - new /obj/item/tank/jetpack/carbondioxide(src) + //Jetpack (You hit the jackpot!) + if(pickednum == 50) + new /obj/item/tank/jetpack/carbondioxide(src) /obj/structure/closet/syndicate/resources/everything desc = "It's an emergency storage closet for repairs." - New() - ..() - var/list/resources = list( - /obj/item/stack/sheet/metal, - /obj/item/stack/sheet/glass, - /obj/item/stack/sheet/mineral/gold, - /obj/item/stack/sheet/mineral/silver, - /obj/item/stack/sheet/mineral/plasma, - /obj/item/stack/sheet/mineral/uranium, - /obj/item/stack/sheet/mineral/diamond, - /obj/item/stack/sheet/mineral/bananium, - /obj/item/stack/sheet/mineral/titanium, - /obj/item/stack/sheet/mineral/plastitanium, - /obj/item/stack/sheet/plasteel, - /obj/item/stack/rods - ) +/obj/structure/closet/syndicate/resources/everything/New() + ..() + var/list/resources = list( + /obj/item/stack/sheet/metal, + /obj/item/stack/sheet/glass, + /obj/item/stack/sheet/mineral/gold, + /obj/item/stack/sheet/mineral/silver, + /obj/item/stack/sheet/mineral/plasma, + /obj/item/stack/sheet/mineral/uranium, + /obj/item/stack/sheet/mineral/diamond, + /obj/item/stack/sheet/mineral/bananium, + /obj/item/stack/sheet/mineral/titanium, + /obj/item/stack/sheet/mineral/plastitanium, + /obj/item/stack/sheet/plasteel, + /obj/item/stack/rods + ) - for(var/i in 1 to 2) - for(var/res in resources) - var/obj/item/stack/R = new res(src) - R.amount = R.max_amount + for(var/i in 1 to 2) + for(var/res in resources) + var/obj/item/stack/R = new res(src) + R.amount = R.max_amount diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 2441a2d57d6..61db52bf8a0 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -187,6 +187,7 @@ if(user) to_chat(user, "The crate's anti-tamper system activates!") investigate_log("[key_name(user)] has detonated a [src]", INVESTIGATE_BOMB) + add_attack_logs(user, src, "has detonated", ATKLOG_MOST) for(var/atom/movable/AM in src) qdel(AM) explosion(get_turf(src), 0, 1, 5, 5) @@ -338,24 +339,23 @@ var/target_temp = T0C - 40 var/cooling_power = 40 - return_air() - var/datum/gas_mixture/gas = (..()) - if(!gas) return null - var/datum/gas_mixture/newgas = new/datum/gas_mixture() - newgas.oxygen = gas.oxygen - newgas.carbon_dioxide = gas.carbon_dioxide - newgas.nitrogen = gas.nitrogen - newgas.toxins = gas.toxins - newgas.volume = gas.volume - newgas.temperature = gas.temperature - if(newgas.temperature <= target_temp) return - - if((newgas.temperature - cooling_power) > target_temp) - newgas.temperature -= cooling_power - else - newgas.temperature = target_temp - return newgas +/obj/structure/closet/crate/freezer/return_air() + var/datum/gas_mixture/gas = (..()) + if(!gas) return null + var/datum/gas_mixture/newgas = new/datum/gas_mixture() + newgas.oxygen = gas.oxygen + newgas.carbon_dioxide = gas.carbon_dioxide + newgas.nitrogen = gas.nitrogen + newgas.toxins = gas.toxins + newgas.volume = gas.volume + newgas.temperature = gas.temperature + if(newgas.temperature <= target_temp) return + if((newgas.temperature - cooling_power) > target_temp) + newgas.temperature -= cooling_power + else + newgas.temperature = target_temp + return newgas /obj/structure/closet/crate/can desc = "A large can, looks like a bin to me." @@ -496,22 +496,23 @@ /obj/structure/closet/crate/hydroponics/prespawned //This exists so the prespawned hydro crates spawn with their contents. - New() - ..() - new /obj/item/reagent_containers/glass/bucket(src) - new /obj/item/reagent_containers/glass/bucket(src) - new /obj/item/screwdriver(src) - new /obj/item/screwdriver(src) - new /obj/item/wrench(src) - new /obj/item/wrench(src) - new /obj/item/wirecutters(src) - new /obj/item/wirecutters(src) - new /obj/item/shovel/spade(src) - new /obj/item/shovel/spade(src) - new /obj/item/storage/box/beakers(src) - new /obj/item/storage/box/beakers(src) - new /obj/item/hand_labeler(src) - new /obj/item/hand_labeler(src) +// Do I need the definition above? Who knows! +/obj/structure/closet/crate/hydroponics/prespawned/New() + ..() + new /obj/item/reagent_containers/glass/bucket(src) + new /obj/item/reagent_containers/glass/bucket(src) + new /obj/item/screwdriver(src) + new /obj/item/screwdriver(src) + new /obj/item/wrench(src) + new /obj/item/wrench(src) + new /obj/item/wirecutters(src) + new /obj/item/wirecutters(src) + new /obj/item/shovel/spade(src) + new /obj/item/shovel/spade(src) + new /obj/item/storage/box/beakers(src) + new /obj/item/storage/box/beakers(src) + new /obj/item/hand_labeler(src) + new /obj/item/hand_labeler(src) /obj/structure/closet/crate/sci name = "science crate" diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 36a20aa0239..0ad8a73c9ba 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -144,7 +144,7 @@ to_chat(user, "You [open ? "close":"open"] [src].") toggle_lock(user) -obj/structure/displaycase/welder_act(mob/user, obj/item/I) +/obj/structure/displaycase/welder_act(mob/user, obj/item/I) . = TRUE if(default_welder_repair(user, I)) broken = FALSE diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 0c0a7f5e4dd..73f8bbfff41 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -67,7 +67,7 @@ . = TRUE default_unfasten_wrench(user, I, time = 20) -obj/structure/dresser/deconstruct(disassembled = FALSE) +/obj/structure/dresser/deconstruct(disassembled = FALSE) var/mat_drop = 15 if(disassembled) mat_drop = 30 diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm index f9717956bb0..13c0ce77c0f 100644 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -15,7 +15,6 @@ anchored = TRUE resistance_flags = FIRE_PROOF | LAVA_PROOF - var/gps = null var/obj/effect/light_emitter/tendril/emitted_light /obj/structure/spawner/lavaland/goliath @@ -29,7 +28,6 @@ GLOBAL_LIST_INIT(tendrils, list()) /obj/structure/spawner/lavaland/Initialize(mapload) . = ..() emitted_light = new(loc) - gps = new /obj/item/gps/internal(src) GLOB.tendrils += src return INITIALIZE_HINT_LATELOAD @@ -59,7 +57,6 @@ GLOBAL_LIST_INIT(tendrils, list()) SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1) GLOB.tendrils -= src QDEL_NULL(emitted_light) - QDEL_NULL(gps) return ..() /obj/effect/light_emitter/tendril diff --git a/code/game/objects/structures/misc.dm b/code/game/objects/structures/misc.dm index 44cbf6c52c9..5118a7fe0da 100644 --- a/code/game/objects/structures/misc.dm +++ b/code/game/objects/structures/misc.dm @@ -11,8 +11,8 @@ anchored = 1 density = 1 - attack_hand(mob/user as mob) - to_chat(user, "Civilians: NT is recruiting! Please head SOUTH to the NT Recruitment office to join the station's crew!") +/obj/structure/signpost/attack_hand(mob/user as mob) + to_chat(user, "Civilians: NT is recruiting! Please head SOUTH to the NT Recruitment office to join the station's crew!") /obj/structure/ninjatele @@ -23,31 +23,28 @@ anchored = 1 density = 0 - attack_hand(mob/user as mob) - - - if(user.mind.special_role=="Ninja") - switch(alert("Phase Jaunt relay primed, target locked as [station_name()], initiate VOID-shift translocation? (Warning! Internals required!)",,"Yes","No")) - - if("Yes") - if(user.z != src.z) return - - user.loc.loc.Exited(user) - user.loc = pick(GLOB.carplist) // In the future, possibly make specific NinjaTele landmarks, and give him an option to teleport to North/South/East/West of SS13 instead of just hijacking a carpspawn. - - - playsound(user.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(user.loc, 'sound/effects/sparks2.ogg', 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(user), user.dir) - to_chat(user, "VOID-Shift translocation successful") - - if("No") - - to_chat(user, "Process aborted!") +/obj/structure/ninjatele/attack_hand(mob/user as mob) + if(user.mind.special_role=="Ninja") + switch(alert("Phase Jaunt relay primed, target locked as [station_name()], initiate VOID-shift translocation? (Warning! Internals required!)",,"Yes","No")) + if("Yes") + if(user.z != src.z) return - else - to_chat(user, "FĆAL �Rr�R: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") + + user.loc.loc.Exited(user) + user.loc = pick(GLOB.carplist) // In the future, possibly make specific NinjaTele landmarks, and give him an option to teleport to North/South/East/West of SS13 instead of just hijacking a carpspawn. + + playsound(user.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(user.loc, 'sound/effects/sparks2.ogg', 50, 1) + new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(user), user.dir) + to_chat(user, "VOID-Shift translocation successful") + + if("No") + to_chat(user, "Process aborted!") + return + + else + to_chat(user, "FĆAL �Rr�R: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") /obj/structure/respawner name = "\improper Long-Distance Cloning Machine" diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index bdab5ca2466..e9abfca2dac 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -90,7 +90,7 @@ ..() if(climber) climber.Weaken(2) - climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You see [climber.name] get knocked off the table") + climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You hear [climber.name] get knocked off the table") else if(Adjacent(user) && user.pulling && user.pulling.pass_flags & PASSTABLE) user.Move_Pulled(src) if(user.pulling.loc == loc) diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index c7926870ccf..650df02c59b 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -26,7 +26,7 @@ return !density // When destroyed by explosions, properly handle contents. -obj/structure/transit_tube/ex_act(severity) +/obj/structure/transit_tube/ex_act(severity) switch(severity) if(1.0) for(var/atom/movable/AM in contents) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 3a1546bdd2b..0a059198d2a 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -31,14 +31,14 @@ . = ..() . += "Alt-click to rotate it clockwise." -obj/structure/windoor_assembly/New(loc, set_dir) +/obj/structure/windoor_assembly/New(loc, set_dir) ..() if(set_dir) dir = set_dir ini_dir = dir air_update_turf(1) -obj/structure/windoor_assembly/Destroy() +/obj/structure/windoor_assembly/Destroy() density = FALSE QDEL_NULL(electronics) air_update_turf(1) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 9faab45cf97..cfe8a20cce7 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -666,7 +666,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", icon_state = "tinted_window" opacity = 1 -obj/structure/window/full/reinforced/ice +/obj/structure/window/full/reinforced/ice icon = 'icons/obj/smooth_structures/rice_window.dmi' icon_state = "ice_window" max_integrity = 150 diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm index 3c1ba0b8fbc..415df5d9dde 100644 --- a/code/game/shuttle_engines.dm +++ b/code/game/shuttle_engines.dm @@ -19,11 +19,13 @@ opacity = 0 anchored = 1 - CanPass(atom/movable/mover, turf/target, height) - if(!height) return 0 - else return ..() +/obj/structure/shuttle/window/CanPass(atom/movable/mover, turf/target, height) + if(!height) + return 0 + else + return ..() - CanAtmosPass(turf/T) +/obj/structure/shuttle/window/CanAtmosPass(turf/T) return !density /obj/structure/shuttle/engine diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index 8276c0de33f..0d27e02537f 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -11,12 +11,12 @@ #define LIGHTFLOOR_CYCLEB 10 /turf/simulated/floor/light - name = "Light floor" + name = "\improper light floor" light_range = 5 icon_state = "light_on" floor_tile = /obj/item/stack/tile/light broken_states = list("light_broken") - var/on = 1 + var/on = TRUE var/state = LIGHTFLOOR_ON var/can_modify_colour = TRUE @@ -30,34 +30,34 @@ switch(state) if(LIGHTFLOOR_ON) icon_state = "light_on" - set_light(5,null,LIGHT_COLOR_LIGHTBLUE) + set_light(5, null,LIGHT_COLOR_LIGHTBLUE) if(LIGHTFLOOR_WHITE) icon_state = "light_on-w" - set_light(5,null,LIGHT_COLOR_WHITE) + set_light(5, null,LIGHT_COLOR_WHITE) if(LIGHTFLOOR_RED) icon_state = "light_on-r" - set_light(5,null,LIGHT_COLOR_RED) + set_light(5, null,LIGHT_COLOR_RED) if(LIGHTFLOOR_GREEN) icon_state = "light_on-g" - set_light(5,null,LIGHT_COLOR_PURE_GREEN) + set_light(5, null,LIGHT_COLOR_PURE_GREEN) if(LIGHTFLOOR_YELLOW) icon_state = "light_on-y" - set_light(5,null,"#FFFF00") + set_light(5, null,"#FFFF00") if(LIGHTFLOOR_BLUE) icon_state = "light_on-b" - set_light(5,null,LIGHT_COLOR_DARKBLUE) + set_light(5, null,LIGHT_COLOR_DARKBLUE) if(LIGHTFLOOR_PURPLE) icon_state = "light_on-p" - set_light(5,null,LIGHT_COLOR_PURPLE) + set_light(5, null,LIGHT_COLOR_PURPLE) if(LIGHTFLOOR_GENERICCYCLE) icon_state = "light_on-cycle_all" - set_light(5,null,LIGHT_COLOR_WHITE) + set_light(5, null,LIGHT_COLOR_WHITE) if(LIGHTFLOOR_CYCLEA) icon_state = "light_on-dancefloor_A" set_light(5,null,LIGHT_COLOR_RED) if(LIGHTFLOOR_CYCLEB) icon_state = "light_on-dancefloor_B" - set_light(5,null,LIGHT_COLOR_DARKBLUE) + set_light(5, null,LIGHT_COLOR_DARKBLUE) else icon_state = "light_off" set_light(0) @@ -72,11 +72,10 @@ /turf/simulated/floor/light/attack_hand(mob/user) if(!can_modify_colour) return - on = !on - update_icon() + toggle_light(!on) /turf/simulated/floor/light/attackby(obj/item/C, mob/user, params) - if(istype(C,/obj/item/light/bulb)) //only for light tiles + if(istype(C, /obj/item/light/bulb)) //only for light tiles if(!state) qdel(C) state = LIGHTFLOOR_ON @@ -103,6 +102,16 @@ else to_chat(user, "[src]'s light bulb appears to have burned out.") +/turf/simulated/floor/light/proc/toggle_light(light) + // 0 = OFF + // 1 = ON + on = light + update_icon() + +/turf/simulated/floor/light/extinguish_light() + toggle_light(FALSE) + visible_message("[src] flickers and falls dark.") + //Cycles through all of the colours /turf/simulated/floor/light/colour_cycle state = LIGHTFLOOR_GENERICCYCLE @@ -119,3 +128,16 @@ name = "dancefloor" desc = "Funky floor." state = LIGHTFLOOR_CYCLEB + + +#undef LIGHTFLOOR_ON +#undef LIGHTFLOOR_WHITE +#undef LIGHTFLOOR_RED +#undef LIGHTFLOOR_GREEN +#undef LIGHTFLOOR_YELLOW +#undef LIGHTFLOOR_BLUE +#undef LIGHTFLOOR_PURPLE + +#undef LIGHTFLOOR_GENERICCYCLE +#undef LIGHTFLOOR_CYCLEA +#undef LIGHTFLOOR_CYCLEB diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index dda49fecdbd..b8110cf2b54 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -11,72 +11,98 @@ pushdirection = SOUTH // south because the space tile is scrolling south //IF ANYONE KNOWS A MORE EFFICIENT WAY OF MANAGING THESE SPRITES, BE MY GUEST. - shuttlespace_ns1 - icon_state = "speedspace_ns_1" - shuttlespace_ns2 - icon_state = "speedspace_ns_2" - shuttlespace_ns3 - icon_state = "speedspace_ns_3" - shuttlespace_ns4 - icon_state = "speedspace_ns_4" - shuttlespace_ns5 - icon_state = "speedspace_ns_5" - shuttlespace_ns6 - icon_state = "speedspace_ns_6" - shuttlespace_ns7 - icon_state = "speedspace_ns_7" - shuttlespace_ns8 - icon_state = "speedspace_ns_8" - shuttlespace_ns9 - icon_state = "speedspace_ns_9" - shuttlespace_ns10 - icon_state = "speedspace_ns_10" - shuttlespace_ns11 - icon_state = "speedspace_ns_11" - shuttlespace_ns12 - icon_state = "speedspace_ns_12" - shuttlespace_ns13 - icon_state = "speedspace_ns_13" - shuttlespace_ns14 - icon_state = "speedspace_ns_14" - shuttlespace_ns15 - icon_state = "speedspace_ns_15" +/turf/space/transit/north/shuttlespace_ns1 + icon_state = "speedspace_ns_1" + +/turf/space/transit/north/shuttlespace_ns2 + icon_state = "speedspace_ns_2" + +/turf/space/transit/north/shuttlespace_ns3 + icon_state = "speedspace_ns_3" + +/turf/space/transit/north/shuttlespace_ns4 + icon_state = "speedspace_ns_4" + +/turf/space/transit/north/shuttlespace_ns5 + icon_state = "speedspace_ns_5" + +/turf/space/transit/north/shuttlespace_ns6 + icon_state = "speedspace_ns_6" + +/turf/space/transit/north/shuttlespace_ns7 + icon_state = "speedspace_ns_7" + +/turf/space/transit/north/shuttlespace_ns8 + icon_state = "speedspace_ns_8" + +/turf/space/transit/north/shuttlespace_ns9 + icon_state = "speedspace_ns_9" + +/turf/space/transit/north/shuttlespace_ns10 + icon_state = "speedspace_ns_10" + +/turf/space/transit/north/shuttlespace_ns11 + icon_state = "speedspace_ns_11" + +/turf/space/transit/north/shuttlespace_ns12 + icon_state = "speedspace_ns_12" + +/turf/space/transit/north/shuttlespace_ns13 + icon_state = "speedspace_ns_13" + +/turf/space/transit/north/shuttlespace_ns14 + icon_state = "speedspace_ns_14" + +/turf/space/transit/north/shuttlespace_ns15 + icon_state = "speedspace_ns_15" /turf/space/transit/east // moving to the east - pushdirection = WEST - shuttlespace_ew1 - icon_state = "speedspace_ew_1" - shuttlespace_ew2 - icon_state = "speedspace_ew_2" - shuttlespace_ew3 - icon_state = "speedspace_ew_3" - shuttlespace_ew4 - icon_state = "speedspace_ew_4" - shuttlespace_ew5 - icon_state = "speedspace_ew_5" - shuttlespace_ew6 - icon_state = "speedspace_ew_6" - shuttlespace_ew7 - icon_state = "speedspace_ew_7" - shuttlespace_ew8 - icon_state = "speedspace_ew_8" - shuttlespace_ew9 - icon_state = "speedspace_ew_9" - shuttlespace_ew10 - icon_state = "speedspace_ew_10" - shuttlespace_ew11 - icon_state = "speedspace_ew_11" - shuttlespace_ew12 - icon_state = "speedspace_ew_12" - shuttlespace_ew13 - icon_state = "speedspace_ew_13" - shuttlespace_ew14 - icon_state = "speedspace_ew_14" - shuttlespace_ew15 - icon_state = "speedspace_ew_15" +/turf/space/transit/east/shuttlespace_ew1 + icon_state = "speedspace_ew_1" +/turf/space/transit/east/shuttlespace_ew2 + icon_state = "speedspace_ew_2" + +/turf/space/transit/east/shuttlespace_ew3 + icon_state = "speedspace_ew_3" + +/turf/space/transit/east/shuttlespace_ew4 + icon_state = "speedspace_ew_4" + +/turf/space/transit/east/shuttlespace_ew5 + icon_state = "speedspace_ew_5" + +/turf/space/transit/east/shuttlespace_ew6 + icon_state = "speedspace_ew_6" + +/turf/space/transit/east/shuttlespace_ew7 + icon_state = "speedspace_ew_7" + +/turf/space/transit/east/shuttlespace_ew8 + icon_state = "speedspace_ew_8" + +/turf/space/transit/east/shuttlespace_ew9 + icon_state = "speedspace_ew_9" + +/turf/space/transit/east/shuttlespace_ew10 + icon_state = "speedspace_ew_10" + +/turf/space/transit/east/shuttlespace_ew11 + icon_state = "speedspace_ew_11" + +/turf/space/transit/east/shuttlespace_ew12 + icon_state = "speedspace_ew_12" + +/turf/space/transit/east/shuttlespace_ew13 + icon_state = "speedspace_ew_13" + +/turf/space/transit/east/shuttlespace_ew14 + icon_state = "speedspace_ew_14" + +/turf/space/transit/east/shuttlespace_ew15 + icon_state = "speedspace_ew_15" //-tg- stuff /turf/space/transit diff --git a/code/game/world.dm b/code/game/world.dm index c279fa24b54..d2828f9c04b 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -222,8 +222,12 @@ GLOBAL_VAR_INIT(world_topic_spam_protect_time, world.timeofday) if(input["key"] != config.comms_password) return "Bad Key" else + var/prtext = input["announce"] + var/pr_substring = copytext(prtext, 1, 23) + if(pr_substring == "Pull Request merged by") + GLOB.pending_server_update = TRUE for(var/client/C in GLOB.clients) - to_chat(C, "PR: [input["announce"]]") + to_chat(C, "PR: [prtext]") else if("kick" in input) /* @@ -270,7 +274,7 @@ GLOBAL_VAR_INIT(world_topic_spam_protect_time, world.timeofday) else if("hostannounce" in input) if(!key_valid) return keySpamProtect(addr) - + GLOB.pending_server_update = TRUE to_chat(world, "
Server Announcement: [input["message"]]
") /proc/keySpamProtect(var/addr) @@ -339,8 +343,12 @@ GLOBAL_VAR_INIT(world_topic_spam_protect_time, world.timeofday) return #endif + var/secs_before_auto_reconnect = 10 + if(GLOB.pending_server_update) + secs_before_auto_reconnect = 60 + to_chat(world, "Reboot will take a little longer, due to pending updates.") for(var/client/C in GLOB.clients) - var/secs_before_auto_reconnect = 10 // TODO: make it higher if server is due for an update @AffectedArc07 + C << output(list2params(list(secs_before_auto_reconnect)), "browseroutput:reboot") if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite C << link("byond://[config.server]") @@ -486,7 +494,7 @@ GLOBAL_VAR_INIT(failed_old_db_connections, 0) return . //This proc ensures that the connection to the feedback database (global variable dbcon) is established -proc/establish_db_connection() +/proc/establish_db_connection() if(GLOB.failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) return 0 diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 1f55fa11f70..fd998677d75 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -1,6 +1,6 @@ #define MAX_ADMIN_BANS_PER_ADMIN 1 -datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null, var/banip = null, var/bancid = null) +/datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null, var/banip = null, var/bancid = null) if(!check_rights(R_BAN)) return @@ -153,7 +153,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = else flag_account_for_forum_sync(ckey) -datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "") +/datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "") if(!check_rights(R_BAN)) return @@ -233,7 +233,7 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "") else flag_account_for_forum_sync(ckey) -datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null) +/datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null) if(!check_rights(R_BAN)) return @@ -297,7 +297,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null) to_chat(usr, "Cancelled") return -datum/admins/proc/DB_ban_unban_by_id(var/id) +/datum/admins/proc/DB_ban_unban_by_id(var/id) if(!check_rights(R_BAN)) return diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index d9ceba62830..3f69c2199d0 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -1,5 +1,5 @@ //Blocks an attempt to connect before even creating our client datum thing. -world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE) +/world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE) if(!config.ban_legacy_system) if(address) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm index 56fcab49293..50c852af03b 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm @@ -89,403 +89,443 @@ /datum/SDQL_parser/proc/tokenl(i) return lowertext(token(i)) -/datum/SDQL_parser/proc - //query: select_query | delete_query | update_query - query(i, list/node) - query_type = tokenl(i) +/datum/SDQL_parser/proc/query(i, list/node) + query_type = tokenl(i) - switch(query_type) - if("select") - select_query(i, node) + switch(query_type) + if("select") + select_query(i, node) - if("delete") - delete_query(i, node) + if("delete") + delete_query(i, node) - if("update") - update_query(i, node) + if("update") + update_query(i, node) - if("call") - call_query(i, node) + if("call") + call_query(i, node) - if("explain") - node += "explain" - node["explain"] = list() - query(i + 1, node["explain"]) + if("explain") + node += "explain" + node["explain"] = list() + query(i + 1, node["explain"]) // select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] - select_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) +/datum/SDQL_parser/proc/select_query(i, list/node) + var/list/select = list() + i = select_list(i + 1, select) - node += "select" - node["select"] = select + node += "select" + node["select"] = select - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" - node += "from" - node["from"] = from + node += "from" + node["from"] = from - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) - node += "where" - node["where"] = where + node += "where" + node["where"] = where - return i + return i //delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] - delete_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) +/datum/SDQL_parser/proc/delete_query(i, list/node) + var/list/select = list() + i = select_list(i + 1, select) - node += "delete" - node["delete"] = select + node += "delete" + node["delete"] = select - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" - node += "from" - node["from"] = from + node += "from" + node["from"] = from - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) - node += "where" - node["where"] = where + node += "where" + node["where"] = where - return i + return i //update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] - update_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) +/datum/SDQL_parser/proc/update_query(i, list/node) + var/list/select = list() + i = select_list(i + 1, select) - node += "update" - node["update"] = select + node += "update" + node["update"] = select - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" - node += "from" - node["from"] = from + node += "from" + node["from"] = from - if(tokenl(i) != "set") - i = parse_error("UPDATE has misplaced SET") + if(tokenl(i) != "set") + i = parse_error("UPDATE has misplaced SET") - var/list/set_assignments = list() - i = assignments(i + 1, set_assignments) + var/list/set_assignments = list() + i = assignments(i + 1, set_assignments) - node += "set" - node["set"] = set_assignments + node += "set" + node["set"] = set_assignments - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) - node += "where" - node["where"] = where + node += "where" + node["where"] = where - return i + return i //call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] - call_query(i, list/node) - var/list/func = list() - i = variable(i + 1, func) +/datum/SDQL_parser/proc/call_query(i, list/node) + var/list/func = list() + i = variable(i + 1, func) - node += "call" - node["call"] = func - - if(tokenl(i) != "on") - return i - - var/list/select = list() - i = select_list(i + 1, select) - - node += "on" - node["on"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where + node += "call" + node["call"] = func + if(tokenl(i) != "on") return i + var/list/select = list() + i = select_list(i + 1, select) + + node += "on" + node["on"] = select + + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" + + node += "from" + node["from"] = from + + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) + + node += "where" + node["where"] = where + + return i + //select_list: select_item [',' select_list] - select_list(i, list/node) - i = select_item(i, node) +/datum/SDQL_parser/proc/select_list(i, list/node) + i = select_item(i, node) - if(token(i) == ",") - i = select_list(i + 1, node) + if(token(i) == ",") + i = select_list(i + 1, node) - return i + return i //from_list: from_item [',' from_list] - from_list(i, list/node) - i = from_item(i, node) +/datum/SDQL_parser/proc/from_list(i, list/node) + i = from_item(i, node) - if(token(i) == ",") - i = from_list(i + 1, node) + if(token(i) == ",") + i = from_list(i + 1, node) - return i + return i //assignments: assignment, [',' assignments] - assignments(i, list/node) - i = assignment(i, node) +/datum/SDQL_parser/proc/assignments(i, list/node) + i = assignment(i, node) - if(token(i) == ",") - i = assignments(i + 1, node) + if(token(i) == ",") + i = assignments(i + 1, node) - return i + return i //select_item: '*' | select_function | object_type - select_item(i, list/node) +/datum/SDQL_parser/proc/select_item(i, list/node) + if(token(i) == "*") + node += "*" + i++ - if(token(i) == "*") - node += "*" - i++ + else if(tokenl(i) in select_functions) + i = select_function(i, node) - else if(tokenl(i) in select_functions) - i = select_function(i, node) + else + i = object_type(i, node) - else - i = object_type(i, node) - - return i + return i //from_item: 'world' | object_type - from_item(i, list/node) +/datum/SDQL_parser/proc/from_item(i, list/node) - if(token(i) == "world") - node += "world" - i++ + if(token(i) == "world") + node += "world" + i++ - else - i = object_type(i, node) + else + i = object_type(i, node) - return i + return i //bool_expression: expression [bool_operator bool_expression] - bool_expression(i, list/node) +/datum/SDQL_parser/proc/bool_expression(i, list/node) + var/list/bool = list() + i = expression(i, bool) - var/list/bool = list() - i = expression(i, bool) + node[++node.len] = bool - node[++node.len] = bool + if(tokenl(i) in boolean_operators) + i = bool_operator(i, node) + i = bool_expression(i, node) - if(tokenl(i) in boolean_operators) - i = bool_operator(i, node) - i = bool_expression(i, node) - - return i + return i //assignment: '=' expression - assignment(var/i, var/list/node, var/list/assignment_list = list()) - assignment_list += token(i) +/datum/SDQL_parser/proc/assignment(var/i, var/list/node, var/list/assignment_list = list()) + assignment_list += token(i) - if(token(i + 1) == ".") - i = assignment(i + 2, node, assignment_list) + if(token(i + 1) == ".") + i = assignment(i + 2, node, assignment_list) - else if(token(i + 1) == "=") - var/exp_list = list() - node[assignment_list] = exp_list + else if(token(i + 1) == "=") + var/exp_list = list() + node[assignment_list] = exp_list - i = expression(i + 2, exp_list) + i = expression(i + 2, exp_list) - else - parse_error("Assignment expected, but no = found") + else + parse_error("Assignment expected, but no = found") - return i + return i //variable: | '.' variable - variable(i, list/node) - var/list/L = list(token(i)) - node[++node.len] = L +/datum/SDQL_parser/proc/variable(i, list/node) + var/list/L = list(token(i)) + node[++node.len] = L - if(token(i) == "\[") - L += token(i + 1) - i += 2 + if(token(i) == "\[") + L += token(i + 1) + i += 2 - if(token(i) != "\]") - parse_error("Missing \] at end of reference.") + if(token(i) != "\]") + parse_error("Missing \] at end of reference.") - if(token(i + 1) == ".") - L += "." - i = variable(i + 2, L) + if(token(i + 1) == ".") + L += "." + i = variable(i + 2, L) - else if(token(i + 1) == "(") // OH BOY PROC - var/list/arguments = list() - i = call_function(i, null, arguments) - L += ":" - L[++L.len] = arguments + else if(token(i + 1) == "(") // OH BOY PROC + var/list/arguments = list() + i = call_function(i, null, arguments) + L += ":" + L[++L.len] = arguments - else if(token(i + 1) == "\[") // list index - var/list/expression = list() - i = expression(i + 2, expression) - if(token(i) != "]") - parse_error("Missing ] at the end of list access.") + else if(token(i + 1) == "\[") // list index + var/list/expression = list() + i = expression(i + 2, expression) + if(token(i) != "]") + parse_error("Missing ] at the end of list access.") - L += "\[" - L[++L.len] = expression - i++ + L += "\[" + L[++L.len] = expression + i++ - else - i++ + else + i++ - return i + return i //object_type: | string - object_type(i, list/node) +/datum/SDQL_parser/proc/object_type(i, list/node) - if(copytext(token(i), 1, 2) == "/") - node += token(i) + if(copytext(token(i), 1, 2) == "/") + node += token(i) - else - i = string(i, node) + else + i = string(i, node) - return i + 1 + return i + 1 //comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' - comparitor(i, list/node) +/datum/SDQL_parser/proc/comparitor(i, list/node) - if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">=")) - node += token(i) + if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">=")) + node += token(i) - else - parse_error("Unknown comparitor [token(i)]") + else + parse_error("Unknown comparitor [token(i)]") - return i + 1 + return i + 1 //bool_operator: 'AND' | '&&' | 'OR' | '||' - bool_operator(i, list/node) +/datum/SDQL_parser/proc/bool_operator(i, list/node) - if(tokenl(i) in list("and", "or", "&&", "||")) - node += token(i) + if(tokenl(i) in list("and", "or", "&&", "||")) + node += token(i) - else - parse_error("Unknown comparitor [token(i)]") + else + parse_error("Unknown comparitor [token(i)]") - return i + 1 + return i + 1 //string: ''' ''' | '"' '"' - string(i, list/node) +/datum/SDQL_parser/proc/string(i, list/node) - if(copytext(token(i), 1, 2) in list("'", "\"")) - node += token(i) + if(copytext(token(i), 1, 2) in list("'", "\"")) + node += token(i) - else - parse_error("Expected string but found '[token(i)]'") + else + parse_error("Expected string but found '[token(i)]'") - return i + 1 + return i + 1 //array: '{' expression, expression, ... '}' - array(var/i, var/list/node) - // Arrays get turned into this: list("{", list(exp_1a = exp_1b, ...), ...), "{" is to mark the next node as an array. - if(copytext(token(i), 1, 2) != "{") - parse_error("Expected an array but found '[token(i)]'") - return i + 1 - - node += token(i) // Add the "{" - var/list/expression_list = list() - - if(token(i + 1) != "}") - var/list/temp_expression_list = list() - - do - i = expression(i + 1, temp_expression_list) - - if(token(i) == ",") - expression_list[++expression_list.len] = temp_expression_list - temp_expression_list = list() - while(token(i) && token(i) != "}") - - expression_list[++expression_list.len] = temp_expression_list - else - i++ - - node[++node.len] = expression_list +/datum/SDQL_parser/proc/array(var/i, var/list/node) + // Arrays get turned into this: list("{", list(exp_1a = exp_1b, ...), ...), "{" is to mark the next node as an array. + if(copytext(token(i), 1, 2) != "{") + parse_error("Expected an array but found '[token(i)]'") return i + 1 + node += token(i) // Add the "{" + var/list/expression_list = list() + + if(token(i + 1) != "}") + var/list/temp_expression_list = list() + + do + i = expression(i + 1, temp_expression_list) + + if(token(i) == ",") + expression_list[++expression_list.len] = temp_expression_list + temp_expression_list = list() + while(token(i) && token(i) != "}") + + expression_list[++expression_list.len] = temp_expression_list + else + i++ + + node[++node.len] = expression_list + return i + 1 + //call_function: ['(' [arguments] ')'] - call_function(i, list/node, list/arguments) - var/list/cur_argument = list() - if(length(tokenl(i))) - var/procname = "" - if(tokenl(i) == "global" && token(i + 1) == ".") // Global proc. - i += 2 - procname = "global." - node += procname + token(i++) - if(token(i) != "(") - parse_error("Expected ( but found '[token(i)]'") - else if(token(i + 1) != ")") - do - i = expression(i + 1, cur_argument) - if(token(i) == ",") - arguments += list(cur_argument) - cur_argument = list() - continue - while(token(i) && token(i) != ")") - arguments += list(cur_argument) - else - i++ +/datum/SDQL_parser/proc/call_function(i, list/node, list/arguments) + var/list/cur_argument = list() + if(length(tokenl(i))) + var/procname = "" + if(tokenl(i) == "global" && token(i + 1) == ".") // Global proc. + i += 2 + procname = "global." + node += procname + token(i++) + if(token(i) != "(") + parse_error("Expected ( but found '[token(i)]'") + else if(token(i + 1) != ")") + do + i = expression(i + 1, cur_argument) + if(token(i) == ",") + arguments += list(cur_argument) + cur_argument = list() + continue + while(token(i) && token(i) != ")") + arguments += list(cur_argument) else - parse_error("Expected a function but found nothing") - return i + 1 + i++ + else + parse_error("Expected a function but found nothing") + return i + 1 //select_function: count_function - select_function(i, list/node) +/datum/SDQL_parser/proc/select_function(i, list/node) - parse_error("Sorry, function calls aren't available yet") + parse_error("Sorry, function calls aren't available yet") - return i + return i //expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression] - expression(i, list/node) +/datum/SDQL_parser/proc/expression(i, list/node) + + if(token(i) in unary_operators) + i = unary_expression(i, node) + + else if(token(i) == "(") + var/list/expr = list() + + i = expression(i + 1, expr) + + if(token(i) != ")") + parse_error("Missing ) at end of expression.") + + else + i++ + + node[++node.len] = expr + + else + i = value(i, node) + + if(token(i) in binary_operators) + i = binary_operator(i, node) + i = expression(i, node) + + else if(token(i) in comparitors) + i = binary_operator(i, node) + + var/list/rhs = list() + i = expression(i, rhs) + + node[++node.len] = rhs + + + return i + + +//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' ) +/datum/SDQL_parser/proc/unary_expression(i, list/node) + + if(token(i) in unary_operators) + var/list/unary_exp = list() + + unary_exp += token(i) + i++ if(token(i) in unary_operators) - i = unary_expression(i, node) + i = unary_expression(i, unary_exp) else if(token(i) == "(") var/list/expr = list() @@ -498,99 +538,55 @@ else i++ - node[++node.len] = expr + unary_exp[++unary_exp.len] = expr else - i = value(i, node) + i = value(i, unary_exp) - if(token(i) in binary_operators) - i = binary_operator(i, node) - i = expression(i, node) - - else if(token(i) in comparitors) - i = binary_operator(i, node) - - var/list/rhs = list() - i = expression(i, rhs) - - node[++node.len] = rhs + node[++node.len] = unary_exp - return i + else + parse_error("Expected unary operator but found '[token(i)]'") - -//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' ) - unary_expression(i, list/node) - - if(token(i) in unary_operators) - var/list/unary_exp = list() - - unary_exp += token(i) - i++ - - if(token(i) in unary_operators) - i = unary_expression(i, unary_exp) - - else if(token(i) == "(") - var/list/expr = list() - - i = expression(i + 1, expr) - - if(token(i) != ")") - parse_error("Missing ) at end of expression.") - - else - i++ - - unary_exp[++unary_exp.len] = expr - - else - i = value(i, unary_exp) - - node[++node.len] = unary_exp - - - else - parse_error("Expected unary operator but found '[token(i)]'") - - return i + return i //binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' - binary_operator(i, list/node) +/datum/SDQL_parser/proc/binary_operator(i, list/node) - if(token(i) in (binary_operators + comparitors)) - node += token(i) + if(token(i) in (binary_operators + comparitors)) + node += token(i) - else - parse_error("Unknown binary operator [token(i)]") + else + parse_error("Unknown binary operator [token(i)]") - return i + 1 + return i + 1 //value: variable | string | number | 'null' - value(i, list/node) +/datum/SDQL_parser/proc/value(i, list/node) - if(token(i) == "null") - node += "null" - i++ + if(token(i) == "null") + node += "null" + i++ - else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3)))) - node += hex2num(copytext(token(i), 3)) - i++ + else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3)))) + node += hex2num(copytext(token(i), 3)) + i++ - else if(isnum(text2num(token(i)))) - node += text2num(token(i)) - i++ + else if(isnum(text2num(token(i)))) + node += text2num(token(i)) + i++ - else if(copytext(token(i), 1, 2) in list("'", "\"")) - i = string(i, node) + else if(copytext(token(i), 1, 2) in list("'", "\"")) + i = string(i, node) - else if(copytext(token(i), 1, 2) == "{") // Start a list. - i = array(i, node) + else if(copytext(token(i), 1, 2) == "{") // Start a list. + i = array(i, node) - else - i = variable(i, node) + else + i = variable(i, node) - return i + return i /*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/ diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 5e05b8ecebd..3caac1d79d7 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -26,9 +26,9 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) icon = 'icons/480x480.dmi' icon_state = "25percent" - New() - src.pixel_x = -224 - src.pixel_y = -224 +/obj/effect/debugging/camera_range/New() + src.pixel_x = -224 + src.pixel_y = -224 /obj/effect/debugging/mapfix_marker name = "map fix marker" diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 5d9d218c90e..0e769ed3e73 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -1,4 +1,4 @@ -client/proc/one_click_antag() +/client/proc/one_click_antag() set name = "Create Antagonist" set desc = "Auto-create an antagonist of your choice" set category = "Event" @@ -242,7 +242,7 @@ client/proc/one_click_antag() var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb") var/obj/effect/landmark/closet_spawn = locate("landmark*Nuclear-Closet") - var/nuke_code = "[rand(10000, 99999)]" + var/nuke_code = rand(10000, 99999) if(nuke_spawn) var/obj/item/paper/P = new diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 3864f573597..514fc2368e1 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -201,7 +201,7 @@ feedback_add_details("admin_verb","GOD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) +/proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) if(automute) if(!config.automute_on) return @@ -624,11 +624,11 @@ Traitors and the like can also be revived with the previous role mostly intact. var/beepsound = input(usr, "What sound should the announcement make?", "Announcement Sound", "") as anything in MsgSound GLOB.command_announcement.Announce(input, customname, MsgSound[beepsound], , , type) - print_command_report(input, "[command_name()] Update") + print_command_report(input, customname) if("No") //same thing as the blob stuff - it's not public, so it's classified, dammit GLOB.command_announcer.autosay("A classified message has been printed out at all communication consoles.") - print_command_report(input, "Classified [command_name()] Update") + print_command_report(input, "Classified: [customname]") else return diff --git a/code/modules/arcade/prize_datums.dm b/code/modules/arcade/prize_datums.dm index 1edad36b8f3..2b9f17c3d04 100644 --- a/code/modules/arcade/prize_datums.dm +++ b/code/modules/arcade/prize_datums.dm @@ -203,6 +203,12 @@ GLOBAL_DATUM_INIT(global_prizes, /datum/prizes, new()) typepath = /obj/item/toy/toy_xeno cost = 80 +/datum/prize_item/rubberducky + name = "Rubber Ducky" + desc = "Your favorite bathtime buddy, all squeaks and quacks quality assured." + typepath = /obj/item/bikehorn/rubberducky + cost = 80 + /datum/prize_item/tacticool name = "Tacticool Turtleneck" desc = "A cool-looking turtleneck." diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index bf62e2a828a..33755fc54e8 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -52,12 +52,13 @@ if(!status) status = TRUE investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) - msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW) log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]") to_chat(user, "A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.") + add_attack_logs(user, src, "welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW) else status = FALSE investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB) + add_attack_logs(user, src, "unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_ALMOSTALL) to_chat(user, "The hole has been closed.") diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 5bbd9a26538..67be53979d8 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -101,8 +101,8 @@ if(href_list["time"]) timing = !timing if(timing && istype(holder, /obj/item/transfer_valve)) - message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].") investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB) + add_attack_logs(usr, holder, "activated [src] attachment on", ATKLOG_FEW) log_game("[key_name(usr)] activated [src] attachment for [loc]") update_icon() if(href_list["reset"]) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index bac8d64d9f2..5d3d6494e48 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -16,7 +16,9 @@ var/death = TRUE //Kill the mob var/roundstart = TRUE //fires on initialize var/instant = FALSE //fires on New - var/flavour_text = "The mapper forgot to set this!" + var/flavour_text = "" //flavour/fluff about the role, optional. + var/description = "A description for this has not been set. This is either an oversight or an admin-spawned spawner not in normal use." //intended as OOC info about the role + var/important_info = "" //important info such as rules that apply to you, etc. Optional. var/faction = null var/permanent = FALSE //If true, the spawner will not disappear upon running out of uses. var/random = FALSE //Don't set a name or gender, just go random @@ -336,7 +338,7 @@ name = "sleeper" icon = 'icons/obj/cryogenic2.dmi' icon_state = "sleeper" - flavour_text = "You are a space doctor!" + flavour_text = "You are a space doctor!" assignedrole = "Space Doctor" /obj/effect/mob_spawn/human/doctor/alive/equip(mob/living/carbon/human/H) @@ -470,11 +472,14 @@ name = "bartender sleeper" icon = 'icons/obj/cryogenic2.dmi' icon_state = "sleeper" - flavour_text = "You are a space bartender! Time to mix drinks and change lives." + description = "Stuck on Lavaland, you could try getting back to civilisation...or serve drinks to those that wander by." + flavour_text = "You are a space bartender! Time to mix drinks and change lives. Wait, where did your bar just get transported to?" assignedrole = "Space Bartender" /obj/effect/mob_spawn/human/beach/alive/lifeguard - flavour_text = "You're a spunky lifeguard! It's up to you to make sure nobody drowns or gets eaten by sharks and stuff." + flavour_text = "You're a spunky lifeguard! It's up to you to make sure nobody drowns or gets eaten by sharks and stuff. Then suddenly your entire beach was transported to this strange hell.\ + You aren't trained for this, but you'll still keep your guests alive!" + description = "Try to survive on lavaland with the pitiful equipment of a lifeguard. Or hide in your biodome." mob_gender = "female" name = "lifeguard sleeper" id_job = "Lifeguard" @@ -502,7 +507,8 @@ name = "beach bum sleeper" icon = 'icons/obj/cryogenic2.dmi' icon_state = "sleeper" - flavour_text = "You are a beach bum!" + flavour_text = "You are a beach bum! You think something just happened to the beach but you don't really pay too much attention." + description = "Try to survive on lavaland or just enjoy the beach, waiting for visitors." assignedrole = "Beach Bum" /datum/outfit/beachbum @@ -523,6 +529,7 @@ roundstart = FALSE icon = 'icons/effects/blood.dmi' icon_state = "remains" + description = "Be a spooky scary skeleton." //not mapped in anywhere so admin spawner, who knows what they'll use this for. flavour_text = "By unknown powers, your skeletal remains have been reanimated! Walk this mortal plain and terrorize all living adventurers who dare cross your path." assignedrole = "Skeleton" diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm index 9a5bf275abc..0996f214691 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm @@ -64,9 +64,11 @@ var/has_owner = FALSE var/can_transfer = TRUE //if golems can switch bodies to this new shell var/mob/living/owner = null //golem's owner if it has one - flavour_text = "You are a Free Golem. Your family worships The Liberator. In his infinite and divine wisdom, he set your clan free to \ + important_info = "You are not an antag. Do not mess with the station or create AIs." + description = "As a Free Golem on lavaland, you are unable to use most weapons, but you can mine, research and make more of your kind. Earn enough mining points and you can even move your shuttle out of there." + flavour_text = "You are a Free Golem. Your family worships The Liberator. In his infinite and divine wisdom, he set your clan free to \ travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \ - golems, so that no golem may ever be forced to serve again." + golems, so that no golem may ever be forced to serve again." /obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null) if(species) //spawners list uses object name to register so this goes before ..() @@ -77,8 +79,10 @@ if(!mapload && A) notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in [A.name].", source = src) if(has_owner && creator) - flavour_text = "You are a Golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \ - Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." + important_info = "Serve your creator, even if they are an antag." + flavour_text = "You are a golem created to serve your creator." + description = "You are a Golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \ + Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." owner = creator /obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name) diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm index bb1aae5f8a8..62f4226394d 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/oldstation.dm @@ -10,10 +10,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + description = "Work as a team with your fellow survivors aboard a ruined, ancient space station." + important_info = "" + flavour_text = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/retro/security shoes = /obj/item/clothing/shoes/jackboots id = /obj/item/card/id/away/old/sec @@ -35,10 +36,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are a medical working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + description = "Work as a team with your fellow survivors aboard a ruined, ancient space station." + important_info = "" + flavour_text = "You are a medical doctor working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/retro/medical shoes = /obj/item/clothing/shoes/black id = /obj/item/card/id/away/old/med @@ -60,10 +62,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + description = "Work as a team with your fellow survivors aboard a ruined, ancient space station." + important_info = "" + flavour_text = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/retro/engineering shoes = /obj/item/clothing/shoes/workboots id = /obj/item/card/id/away/old/eng @@ -85,10 +88,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + description = "Work as a team with your fellow survivors aboard a ruined, ancient space station." + important_info = "" + flavour_text = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/retro/science shoes = /obj/item/clothing/shoes/laceup id = /obj/item/card/id/away/old/sci diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index 1beba373724..07be3364552 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -60,7 +60,7 @@ * Guns - I'm making these specifically so that I dont spawn a pile of fully loaded weapons on the map. */ //Captain's retro laser - Fires practice laser shots instead. -obj/item/gun/energy/laser/retro/sc_retro +/obj/item/gun/energy/laser/retro/sc_retro desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces." ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 //No sense in having a harmless gun blow up in the clowns face diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 8d8d83b4ae2..e39c62e5cd7 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -262,7 +262,6 @@ GLOBAL_LIST_EMPTY(asset_datums) var/list/common_dirs = list( "nano/assets/", "nano/codemirror/", - "nano/images/", "nano/layouts/" ) var/list/uncommon_dirs = list( @@ -376,3 +375,14 @@ GLOBAL_LIST_EMPTY(asset_datums) "font-awesome.css" = 'html/font-awesome/css/all.min.css', "v4shim.css" = 'html/font-awesome/css/v4-shims.min.css' ) + +// Nanomaps +/datum/asset/simple/nanomaps + // It REALLY doesnt matter too much if these arent up to date + // They are relatively big + verify = FALSE + assets = list( + "Cyberiad_nanomap_z1.png" = 'icons/_nanomaps/Cyberiad_nanomap_z1.png', + "Delta_nanomap_z1.png" = 'icons/_nanomaps/Delta_nanomap_z1.png', + "MetaStation_nanomap_z1.png" = 'icons/_nanomaps/MetaStation_nanomap_z1.png', + ) diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 72537f8ccc3..46ec605e71d 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -36,7 +36,10 @@ //////////// //SECURITY// //////////// - var/next_allowed_topic_time = 10 + + ///Used for limiting the rate of topic sends by the client to avoid abuse + var/list/topiclimiter + // comment out the line below when debugging locally to enable the options & messages menu //control_freak = 1 diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index ae503be111b..ea099ea53b3 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -11,6 +11,13 @@ #define SUGGESTED_CLIENT_VERSION 511 // only integers (e.g: 510, 511) useful here. Does not properly handle minor versions (e.g: 510.58, 511.848) #define SSD_WARNING_TIMER 30 // cycles, not seconds, so 30=60s +#define LIMITER_SIZE 5 +#define CURRENT_SECOND 1 +#define SECOND_COUNT 2 +#define CURRENT_MINUTE 3 +#define MINUTE_COUNT 4 +#define ADMINSWARNED_AT 5 + /* When somebody clicks a link in game, this Topic is called first. It does the stuff in this proc and then is redirected to the Topic() proc for the src=[0xWhatever] @@ -59,10 +66,38 @@ if(href_list["_src_"] == "chat") return chatOutput.Topic(href, href_list) - //Reduces spamming of links by dropping calls that happen during the delay period - if(next_allowed_topic_time > world.time) - return - next_allowed_topic_time = world.time + TOPIC_SPAM_DELAY + // Rate limiting + var/mtl = 100 // 100 topics per minute + if (!holder) // Admins are allowed to spam click, deal with it. + var/minute = round(world.time, 600) + if (!topiclimiter) + topiclimiter = new(LIMITER_SIZE) + if (minute != topiclimiter[CURRENT_MINUTE]) + topiclimiter[CURRENT_MINUTE] = minute + topiclimiter[MINUTE_COUNT] = 0 + topiclimiter[MINUTE_COUNT] += 1 + if (topiclimiter[MINUTE_COUNT] > mtl) + var/msg = "Your previous action was ignored because you've done too many in a minute." + if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) + topiclimiter[ADMINSWARNED_AT] = minute + msg += " Administrators have been informed." + log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") + message_admins("[ADMIN_LOOKUPFLW(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") + to_chat(src, "[msg]") + return + + var/stl = 10 // 10 topics a second + if (!holder) // Admins are allowed to spam click, deal with it. + var/second = round(world.time, 10) + if (!topiclimiter) + topiclimiter = new(LIMITER_SIZE) + if (second != topiclimiter[CURRENT_SECOND]) + topiclimiter[CURRENT_SECOND] = second + topiclimiter[SECOND_COUNT] = 0 + topiclimiter[SECOND_COUNT] += 1 + if (topiclimiter[SECOND_COUNT] > stl) + to_chat(src, "Your previous action was ignored because you've done too many in a second") + return //search the href for script injection if( findtext(href,"UI resource files resent successfully. If you are still having issues, please try manually clearing your BYOND cache. This can be achieved by opening your BYOND launcher, pressing the cog in the top right, selecting preferences, going to the Games tab, and pressing 'Clear Cache'.
") + +#undef LIMITER_SIZE +#undef CURRENT_SECOND +#undef SECOND_COUNT +#undef CURRENT_MINUTE +#undef MINUTE_COUNT +#undef ADMINSWARNED_AT diff --git a/code/modules/client/message.dm b/code/modules/client/message.dm index 5c612339621..1bb9d03dd88 100644 --- a/code/modules/client/message.dm +++ b/code/modules/client/message.dm @@ -1,6 +1,6 @@ GLOBAL_LIST_EMPTY(clientmessages) -proc/addclientmessage(var/ckey, var/message) +/proc/addclientmessage(var/ckey, var/message) ckey = ckey(ckey) if(!ckey || !message) return diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index b1efd1f0b78..7e593436969 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -120,6 +120,12 @@ else icon = initial(icon) +/** + * Used for any clothing interactions when the user is on fire. (e.g. Cigarettes getting lit.) + */ +/obj/item/clothing/proc/catch_fire() //Called in handle_fire() + return + //Ears: currently only used for headsets and earmuffs /obj/item/clothing/ears name = "ears" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 05bd3d6f48d..bafe3a9f0a9 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -193,7 +193,7 @@ toggle_sound = 'sound/items/zippoclose.ogg' dog_fashion = null -obj/item/clothing/head/helmet/redtaghelm +/obj/item/clothing/head/helmet/redtaghelm name = "red laser tag helmet" desc = "They have chosen their own end." icon_state = "redtaghelm" @@ -204,7 +204,7 @@ obj/item/clothing/head/helmet/redtaghelm flags_inv = HIDEEARS|HIDEEYES dog_fashion = null -obj/item/clothing/head/helmet/bluetaghelm +/obj/item/clothing/head/helmet/bluetaghelm name = "blue laser tag helmet" desc = "They'll need more men." icon_state = "bluetaghelm" @@ -215,7 +215,7 @@ obj/item/clothing/head/helmet/bluetaghelm flags_inv = HIDEEARS|HIDEEYES dog_fashion = null -obj/item/clothing/head/blob +/obj/item/clothing/head/blob name = "blob hat" desc = "A collectible hat handed out at the latest Blob Family Reunion." icon_state = "blobhat" diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index cac07fe5b1d..10005077d33 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -401,6 +401,7 @@ w_class = WEIGHT_CLASS_SMALL attack_verb = list("warned", "cautioned", "smashed") resistance_flags = NONE + dog_fashion = /datum/dog_fashion/head/cone /obj/item/clothing/head/jester name = "jester hat" diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index 5bf6b90c98e..ffcd28009f2 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -9,8 +9,8 @@ heat_protection = FEET max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT - redcoat - item_color = "redcoat" //Exists for washing machines. Is not different from black shoes in any way. +/obj/item/clothing/shoes/black/redcoat + item_color = "redcoat" //Exists for washing machines. Is not different from black shoes in any way. /obj/item/clothing/shoes/black/greytide flags = NODROP @@ -20,18 +20,23 @@ desc = "A pair of brown shoes." icon_state = "brown" - captain - item_color = "captain" //Exists for washing machines. Is not different from brown shoes in any way. - hop - item_color = "hop" //Exists for washing machines. Is not different from brown shoes in any way. - ce - item_color = "chief" //Exists for washing machines. Is not different from brown shoes in any way. - rd - item_color = "director" //Exists for washing machines. Is not different from brown shoes in any way. - cmo - item_color = "medical" //Exists for washing machines. Is not different from brown shoes in any way. - cmo - item_color = "cargo" //Exists for washing machines. Is not different from brown shoes in any way. +/obj/item/clothing/shoes/brown/captain + item_color = "captain" //Exists for washing machines. Is not different from brown shoes in any way. + +/obj/item/clothing/shoes/brown/hop + item_color = "hop" //Exists for washing machines. Is not different from brown shoes in any way. + +/obj/item/clothing/shoes/brown/ce + item_color = "chief" //Exists for washing machines. Is not different from brown shoes in any way. + +/obj/item/clothing/shoes/brown/rd + item_color = "director" //Exists for washing machines. Is not different from brown shoes in any way. + +/obj/item/clothing/shoes/brown/cmo + item_color = "medical" //Exists for washing machines. Is not different from brown shoes in any way. + +/obj/item/clothing/shoes/brown/qm + item_color = "cargo" //Exists for washing machines. Is not different from brown shoes in any way. /obj/item/clothing/shoes/blue name = "blue shoes" diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 129b07af36e..abe67fb68e6 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -8,11 +8,19 @@ var/slowdown_active = 2 var/slowdown_passive = SHOES_SLOWDOWN var/magpulse_name = "mag-pulse traction system" + var/gustprotection = FALSE //this is for unsafe_unwrenching protection actions_types = list(/datum/action/item_action/toggle) strip_delay = 70 put_on_delay = 70 resistance_flags = FIRE_PROOF +/obj/item/clothing/shoes/magboots/atmos + desc = "Magnetic boots, made to withstand gusts of space wind over 500kmph." + name = "atmospheric magboots" + icon_state = "atmosmagboots0" + magboot_state = "atmosmagboots" + gustprotection = TRUE + /obj/item/clothing/shoes/magboots/attack_self(mob/user) if(magpulse) flags &= ~NOSLIP @@ -42,6 +50,7 @@ name = "advanced magboots" icon_state = "advmag0" magboot_state = "advmag" + gustprotection = TRUE slowdown_active = SHOES_SLOWDOWN origin_tech = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF @@ -53,7 +62,7 @@ magboot_state = "syndiemag" origin_tech = "magnets=4;syndicate=2" -obj/item/clothing/shoes/magboots/syndie/advance //For the Syndicate Strike Team +/obj/item/clothing/shoes/magboots/syndie/advance //For the Syndicate Strike Team desc = "Reverse-engineered magboots that appear to be based on an advanced model, as they have a lighter magnetic pull. Property of Gorlex Marauders." name = "advanced blood-red magboots" slowdown_active = SHOES_SLOWDOWN diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 1f8cb7aaed1..62f740ad7b0 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -344,3 +344,10 @@ recharging_time = world.time + recharging_rate else to_chat(user, "Something prevents you from dashing forward!") + +/obj/item/clothing/shoes/ducky + name = "rubber ducky shoes" + desc = "These shoes are made for quacking, and thats just what they'll do." + icon_state = "ducky" + item_state = "ducky" + shoe_sound = "sound/items/squeaktoy.ogg" diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index c412bb40f7d..8e68fe7461b 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -16,15 +16,26 @@ "Vox" = 'icons/mob/species/vox/helmet.dmi' ) +/obj/item/clothing/head/helmet/space/hardsuit/ert/Initialize() + var/mob/living/carbon/human/wearer = loc.loc //loc is the hardsuit, so its loc is the wearer + if(ishuman(wearer)) + register_camera(wearer) + ..() + /obj/item/clothing/head/helmet/space/hardsuit/ert/attack_self(mob/user) if(camera || !has_camera) ..(user) else - camera = new /obj/machinery/camera(src) - camera.network = list("ERT") - GLOB.cameranet.removeCamera(camera) - camera.c_tag = user.name - to_chat(user, "User scanned as [camera.c_tag]. Camera activated.") + register_camera(user) + +/obj/item/clothing/head/helmet/space/hardsuit/ert/proc/register_camera(mob/wearer) + if(camera || !has_camera) + return + camera = new /obj/machinery/camera(src) + camera.network = list("ERT") + GLOB.cameranet.removeCamera(camera) + camera.c_tag = wearer.name + to_chat(wearer, "User scanned as [camera.c_tag]. Camera activated.") /obj/item/clothing/head/helmet/space/hardsuit/ert/examine(mob/user) . = ..() diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index 8c65ed02553..890c223d735 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -83,7 +83,7 @@ icon_state = "syndicate-helm-black" item_state = "syndicate-helm-black" -obj/item/clothing/head/helmet/space/syndicate/black/strike +/obj/item/clothing/head/helmet/space/syndicate/black/strike name = "Syndicate Strike Team commando helmet" desc = "A heavily armored black helmet that is only given to high-ranking Syndicate operatives." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) //Matches DS gear. @@ -95,7 +95,7 @@ obj/item/clothing/head/helmet/space/syndicate/black/strike icon_state = "syndicate-black" item_state = "syndicate-black" -obj/item/clothing/suit/space/syndicate/black/strike +/obj/item/clothing/suit/space/syndicate/black/strike name = "Syndicate Strike Team commando space suit" desc = "A heavily armored, black space suit that is only given to high-ranking Syndicate operatives." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) //Matches DS gear. @@ -156,7 +156,7 @@ obj/item/clothing/suit/space/syndicate/black/strike icon_state = "syndicate-helm-black-red" item_state = "syndicate-helm-black-red" -obj/item/clothing/head/helmet/space/syndicate/black/red/strike +/obj/item/clothing/head/helmet/space/syndicate/black/red/strike name = "Syndicate Strike Team leader helmet" desc = "A heavily armored, black and red space helmet that is only given to elite Syndicate operatives, it looks particularly menacing." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) //Matches DS gear. @@ -168,7 +168,7 @@ obj/item/clothing/head/helmet/space/syndicate/black/red/strike icon_state = "syndicate-black-red" item_state = "syndicate-black-red" -obj/item/clothing/suit/space/syndicate/black/red/strike +/obj/item/clothing/suit/space/syndicate/black/red/strike name = "Syndicate Strike Team leader space suit" desc = "A heavily armored, black and red space suit that is only given to elite Syndicate operatives, it looks particularly menacing." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100) //Matches DS gear. diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index b57166d4909..8d0e68eddb0 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -128,6 +128,10 @@ item_state = "p_suit" item_color = "purple" +/obj/item/clothing/under/color/purple/sensor //for jani ert + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + /obj/item/clothing/under/color/lightpurple name = "light purple jumpsuit" icon_state = "lightpurple" diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index faa9039c8c4..6384efb2021 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -48,6 +48,10 @@ item_state = "bl_suit" item_color = "chapblack" +/obj/item/clothing/under/rank/chaplain/sensor + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + /obj/item/clothing/under/rank/chef desc = "It's an apron which is given only to the most hardcore chefs in space." name = "chef's uniform" diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm index aa70fc85db6..3a717a5907f 100644 --- a/code/modules/clothing/under/jobs/engineering.dm +++ b/code/modules/clothing/under/jobs/engineering.dm @@ -39,6 +39,10 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20) resistance_flags = NONE +/obj/item/clothing/under/rank/engineer/sensor + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + /obj/item/clothing/under/rank/engineer/skirt desc = "It's an orange high visibility jumpskirt worn by engineers. It has minor radiation shielding." diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index d8847741db3..ffd730d7a6d 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -124,6 +124,10 @@ permeability_coefficient = 0.50 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) +/obj/item/clothing/under/rank/medical/sensor + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + /obj/item/clothing/under/rank/medical/skirt name = "medical doctor's jumpskirt" icon_state = "medicalf" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 0086ba96ef8..afeca2fb3bd 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -34,6 +34,10 @@ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30) strip_delay = 50 +/obj/item/clothing/under/rank/security/sensor + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + /obj/item/clothing/under/rank/security/skirt name = "security officer's jumpskirt" desc = "Standard feminine fashion for Security Officers. It's made of sturdier material than the standard jumpskirts." diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 9a2afbc8a60..beedf85c8c7 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -88,6 +88,10 @@ item_state = "g_suit" item_color = "officer" +/obj/item/clothing/under/rank/centcom_officer/sensor + sensor_mode = SENSOR_COORDS + random_sensor = FALSE + /obj/item/clothing/under/rank/centcom_commander desc = "It's a jumpsuit worn by CentComm's highest-tier Commanders." name = "\improper CentComm officer's jumpsuit" diff --git a/code/modules/crafting/tailoring.dm b/code/modules/crafting/tailoring.dm index 6973fd04ad3..38419f718c4 100644 --- a/code/modules/crafting/tailoring.dm +++ b/code/modules/crafting/tailoring.dm @@ -143,3 +143,12 @@ reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1, /obj/item/stack/sheet/leather = 1) time = 60 category = CAT_CLOTHING + +/datum/crafting_recipe/rubberduckyshoes + name = "Rubber Ducky Shoes" + result = /obj/item/clothing/shoes/ducky + time = 45 + reqs = list(/obj/item/bikehorn/rubberducky = 2, + /obj/item/clothing/shoes/sandal = 1) + tools = list(TOOL_WIRECUTTER) + category = CAT_CLOTHING diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 530b9095f75..4ee33f4d87e 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -272,15 +272,6 @@ new /obj/item/reagent_containers/food/drinks/cans/cola(src) -/obj/item/instrument/guitar/jello_guitar //Pineapple Salad: Dan Jello - name = "Dan Jello's Pink Guitar" - desc = "Dan Jello's special pink guitar." - icon = 'icons/obj/custom_items.dmi' - icon_state = "jello_guitar" - item_state = "jello_guitar" - righthand_file = 'icons/mob/inhands/fluff_righthand.dmi' - lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi' - /obj/item/fluff/wingler_comb name = "blue comb" desc = "A blue comb, it looks like it was made to groom a Tajaran's fur." @@ -1592,13 +1583,17 @@ item_state = "asmer_accordion" -/obj/item/clothing/head/rabbitears/fluff/pinesalad_bunny // Pineapple Salad : Dan Jello - name = "Bluespace rabbit ears" - desc = "A pair of sparkly bluespace rabbit ears, with a small tag on them that reads, 'Dan Jello~'. Yuck, \ - there's some pink slime on the part that goes on your head!" +/obj/item/clothing/head/fluff/pinesalad_horns //Pineapple Salad: Dan Jello + name = "Bluespace Horns" + desc = "A pair of fake horns. Now with added bluespace!" icon = 'icons/obj/custom_items.dmi' - icon_state = "ps_bunny" + icon_state = "ps_horns" +/obj/item/storage/backpack/fluff/hiking //Pineapple Salad: Dan Jello + name = "\improper Fancy Hiking Pack" + desc = "A black and red hiking pack with some nice little accessories." + icon = 'icons/obj/custom_items.dmi' + icon_state = "danpack" /obj/item/clothing/under/fluff/kiaoutfit //FullOfSkittles: Kiachi name = "Suspicious Outfit" diff --git a/code/modules/detective_work/detective_work.dm b/code/modules/detective_work/detective_work.dm index 69ee566124e..4933ff29474 100644 --- a/code/modules/detective_work/detective_work.dm +++ b/code/modules/detective_work/detective_work.dm @@ -1,8 +1,8 @@ //CONTAINS: Suit fibers and Detective's Scanning Computer -atom/var/list/suit_fibers +/atom/var/list/suit_fibers -atom/proc/add_fibers(mob/living/carbon/human/M) +/atom/proc/add_fibers(mob/living/carbon/human/M) if(M.gloves && istype(M.gloves,/obj/item/clothing/)) var/obj/item/clothing/gloves/G = M.gloves if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects diff --git a/code/modules/events/apc_overload.dm b/code/modules/events/apc_overload.dm index 13cabe81b3c..2ca2cdbfa70 100644 --- a/code/modules/events/apc_overload.dm +++ b/code/modules/events/apc_overload.dm @@ -21,7 +21,7 @@ SEND_SOUND(M, S) /datum/event/apc_overload/announce() - GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg') + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/attention.ogg') /datum/event/apc_overload/end() return TRUE @@ -32,7 +32,7 @@ /area/turret_protected/ai) if(announce) - GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg') + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/attention.ogg') // break APC_BREAK_PROBABILITY% of all of the APCs on the station var/affected_apc_count = 0 diff --git a/code/modules/events/apc_short.dm b/code/modules/events/apc_short.dm index fcb31972204..bb82ceb15c4 100644 --- a/code/modules/events/apc_short.dm +++ b/code/modules/events/apc_short.dm @@ -21,7 +21,7 @@ SEND_SOUND(M, S) /datum/event/apc_short/announce() - GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg') + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/attention.ogg') /datum/event/apc_short/end() return TRUE @@ -32,7 +32,7 @@ /area/turret_protected/ai) if(announce) - GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg') + GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/attention.ogg') // break APC_BREAK_PROBABILITY% of all of the APCs on the station var/affected_apc_count = 0 diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index 7304469f408..17c697faf11 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -25,5 +25,5 @@ for(var/thing in epicentreList) var/obj/effect/landmark/epicentre = thing for(var/obj/machinery/power/apc/apc in range(epicentre, lightsoutRange)) - apc.overload_lighting() + INVOKE_ASYNC(apc, /obj/machinery/power/apc.proc/overload_lighting) diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index 02fa69b7c3e..f3ea93c80c4 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -4,24 +4,16 @@ var/list/drones_list = list() /datum/event/rogue_drone/start() - //spawn them at the same place as carp var/list/possible_spawns = list() for(var/thing in GLOB.landmarks_list) var/obj/effect/landmark/C = thing - if(C.name == "carpspawn") + if(C.name == "carpspawn") //spawn them at the same place as carp possible_spawns.Add(C) - //25% chance for this to be a false alarm - var/num - if(prob(25)) - num = 0 - else - num = rand(2,6) - for(var/i=0, i= 100) return original_msg diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm index 57fd36393b5..9a7c0e89999 100644 --- a/code/modules/food_and_drinks/food/foods/baked_goods.dm +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -432,6 +432,29 @@ icon_state = "jdonut1" extra_reagent = "cherryjelly" +////////////////////// +// Pancakes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/pancake + name = "pancake" + desc = "A plain pancake." + icon_state = "pancake" + filling_color = "#E7D8AB" + bitesize = 2 + list_reagents = list("nutriment" = 3, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/pancake/berry_pancake + name = "berry pancake" + desc = "A pancake loaded with berries." + icon_state = "berry_pancake" + list_reagents = list("nutriment" = 3, "sugar" = 3, "berryjuice" = 3) + +/obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake + name = "choc-chip pancake" + desc = "A pancake loaded with chocolate chips." + icon_state = "choc_chip_pancake" + list_reagents = list("nutriment" = 3, "sugar" = 3, "cocoa" = 3) ////////////////////// // Misc // diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 8d0408a74fb..38e1acd550b 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -34,16 +34,15 @@ /obj/item/reagent_containers/food/snacks/proc/On_Consume(mob/M, mob/user) if(!user) return - spawn(0) - if(!reagents.total_volume) - if(M == user) - to_chat(user, "You finish eating \the [src].") - user.visible_message("[M] finishes eating \the [src].") - user.unEquip(src) //so icons update :[ - Post_Consume(M) - var/obj/item/trash_item = generate_trash(usr) - usr.put_in_hands(trash_item) - qdel(src) + if(!reagents.total_volume) + if(M == user) + to_chat(user, "You finish eating \the [src].") + user.visible_message("[M] finishes eating \the [src].") + user.unEquip(src) //so icons update :[ + Post_Consume(M) + var/obj/item/trash_item = generate_trash(usr) + usr.put_in_hands(trash_item) + qdel(src) return /obj/item/reagent_containers/food/snacks/proc/Post_Consume(mob/living/M) diff --git a/code/modules/food_and_drinks/kitchen_machinery/cereal_maker.dm b/code/modules/food_and_drinks/kitchen_machinery/cereal_maker.dm index dc81717496a..59fe4b78bcd 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/cereal_maker.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/cereal_maker.dm @@ -8,17 +8,17 @@ onicon = "cereal_on" officon = "cereal_off" -obj/machinery/cooker/cerealmaker/setIcon(obj/item/copyme, obj/item/copyto) +/obj/machinery/cooker/cerealmaker/setIcon(obj/item/copyme, obj/item/copyto) var/image/img = new(copyme.icon, copyme.icon_state) img.transform *= 0.7 copyto.overlays += img copyto.overlays += copyme.overlays -obj/machinery/cooker/cerealmaker/changename(obj/item/name, obj/item/setme) +/obj/machinery/cooker/cerealmaker/changename(obj/item/name, obj/item/setme) setme.name = "box of [name] cereal" setme.desc = "[name.desc] It has been [thiscooktype]" -obj/machinery/cooker/cerealmaker/gettype() +/obj/machinery/cooker/cerealmaker/gettype() var/obj/item/reagent_containers/food/snacks/cereal/type = new(get_turf(src)) return type diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_grill.dm b/code/modules/food_and_drinks/kitchen_machinery/food_grill.dm index 54290c80b37..f68f8c31baf 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_grill.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_grill.dm @@ -11,7 +11,7 @@ onicon = "grill_on" officon = "grill_off" -obj/machinery/cooker/foodgrill/putIn(obj/item/In, mob/chef) +/obj/machinery/cooker/foodgrill/putIn(obj/item/In, mob/chef) ..() var/image/img = new(In.icon, In.icon_state) img.pixel_y = 5 diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index db078675db1..f65b78f3ca2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -234,7 +234,7 @@ return if(UserOverride) - msg_admin_attack("[key_name_admin(occupant)] was gibbed by an autogibber (\the [src]) [ADMIN_JMP(src)]") + add_attack_logs(user, occupant, "gibbed by an autogibber ([src])") log_game("[key_name(occupant)] was gibbed by an autogibber ([src]) (X:[x] Y:[y] Z:[z])") if(operating) diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index f6bb3c8e1c4..2245a2053be 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -1,5 +1,3 @@ -#define SMART_FRIDGE_LOCK_SHORTED -1 - /** * # Smart Fridge * @@ -23,8 +21,6 @@ var/seconds_electrified = 0 /// Whether the fridge should randomly shoot held items at a nearby living target or not. var/shoot_inventory = FALSE - /// Whether the fridge is locked. Used for the secure variant of the fridge. - var/locked = FALSE /// Whether the fridge requires ID scanning. Used for the secure variant of the fridge. var/scan_id = TRUE /// Whether the fridge is considered secure. Used for wiring and display. @@ -139,7 +135,7 @@ /obj/machinery/smartfridge/attackby(obj/item/O, var/mob/user) if(exchange_parts(user, O)) - SSnanoui.update_uis(src) + SStgui.update_uis(src) return if(stat & (BROKEN|NOPOWER)) to_chat(user, "\The [src] is unpowered and useless.") @@ -147,7 +143,7 @@ if(load(O, user)) user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() else if(istype(O, /obj/item/storage/bag)) var/obj/item/storage/bag/P = O @@ -157,7 +153,7 @@ items_loaded++ if(items_loaded) user.visible_message("[user] loads \the [src] with \the [P].", "You load \the [src] with \the [P].") - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() var/failed = length(P.contents) if(failed) @@ -176,7 +172,7 @@ if(stat & (BROKEN|NOPOWER)) return wires.Interact(user) - ui_interact(user) + tgui_interact(user) return ..() //Drag pill bottle to fridge to empty it into the fridge @@ -198,33 +194,28 @@ items_loaded++ if(items_loaded) user.visible_message("[user] empties \the [P] into \the [src].", "You empty \the [P] into \the [src].") - SSnanoui.update_uis(src) update_icon() var/failed = length(P.contents) if(failed) to_chat(user, "[failed] item\s [failed == 1 ? "is" : "are"] refused.") -// UI -/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = TRUE) +/obj/machinery/smartfridge/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) user.set_machine(src) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "smartfridge.tmpl", name, 400, 500) + ui = new(user, src, ui_key, "Smartfridge", name, 500, 500) ui.open() -/obj/machinery/smartfridge/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] +/obj/machinery/smartfridge/tgui_data(mob/user) + var/list/data = list() data["contents"] = null - data["electrified"] = seconds_electrified > 0 - data["shoot_inventory"] = shoot_inventory - data["locked"] = locked data["secure"] = is_secure data["can_dry"] = can_dry data["drying"] = drying - var/list/items[0] + var/list/items = list() for(var/i in 1 to length(item_quants)) var/K = item_quants[i] var/count = item_quants[K] @@ -236,30 +227,31 @@ return data -/obj/machinery/smartfridge/Topic(href, href_list) +/obj/machinery/smartfridge/tgui_act(action, params) if(..()) - return FALSE + return + + . = TRUE var/mob/user = usr - var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") add_fingerprint(user) - if(href_list["close"]) - user.unset_machine() - ui.close() - return FALSE + switch(action) + if("vend") + if(is_secure && !emagged && scan_id && !allowed(usr)) //secure fridge check + to_chat(usr, "Access denied.") + return FALSE - if(href_list["vend"]) - var/index = text2num(href_list["vend"]) - var/amount = text2num(href_list["amount"]) - if(isnull(index) || !ISINDEXSAFE(item_quants, index) || isnull(amount)) - return FALSE - var/K = item_quants[index] - var/count = item_quants[K] + var/index = text2num(params["index"]) + var/amount = text2num(params["amount"]) + if(isnull(index) || !ISINDEXSAFE(item_quants, index) || isnull(amount)) + return FALSE + var/K = item_quants[index] + var/count = item_quants[K] + if(count == 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible. + return FALSE - // Sanity check, there are probably ways to press the button when it shouldn't be possible. - if(count > 0) item_quants[K] = max(count - amount, 0) var/i = amount @@ -271,7 +263,6 @@ adjust_item_drop_location(O) update_icon() break - return TRUE else for(var/obj/O in contents) if(O.name == K) @@ -281,9 +272,7 @@ i-- if(i <= 0) return TRUE - return TRUE - return FALSE /** * Tries to load an item if it is accepted by [/obj/machinery/smartfridge/proc/accept_check]. @@ -364,26 +353,12 @@ /obj/machinery/smartfridge/secure/emag_act(mob/user) emagged = TRUE - locked = SMART_FRIDGE_LOCK_SHORTED to_chat(user, "You short out the product lock on \the [src].") /obj/machinery/smartfridge/secure/emp_act(severity) - if(!emagged && locked != SMART_FRIDGE_LOCK_SHORTED && prob(40 / severity)) + if(!emagged && prob(40 / severity)) playsound(loc, 'sound/effects/sparks4.ogg', 60, TRUE) emagged = TRUE - locked = SMART_FRIDGE_LOCK_SHORTED - -/obj/machinery/smartfridge/secure/Topic(href, href_list) - if(stat & (BROKEN|NOPOWER)) - return FALSE - - if(href_list["vend"] && (usr.contents.Find(src) || Adjacent(usr))) - if(!emagged && locked != SMART_FRIDGE_LOCK_SHORTED && scan_id && !allowed(usr)) - to_chat(usr, "Access denied.") - SSnanoui.update_uis(src) - return FALSE - - return ..() /** * # Seed Storage @@ -672,23 +647,14 @@ ..() atmos_spawn_air(LINDA_SPAWN_HEAT) -/obj/machinery/smartfridge/drying_rack/Topic(href, href_list) - if(..()) - return TRUE +/obj/machinery/smartfridge/drying_rack/tgui_act(action, params) + . = ..() - if(href_list["dryingOn"]) - drying = TRUE - use_power = ACTIVE_POWER_USE - update_icon() - return TRUE - - if(href_list["dryingOff"]) - drying = FALSE - use_power = IDLE_POWER_USE - update_icon() - return TRUE - - return FALSE + switch(action) + if("drying") + drying = !drying + use_power = drying ? ACTIVE_POWER_USE : IDLE_POWER_USE + update_icon() /obj/machinery/smartfridge/drying_rack/update_icon() ..() @@ -741,15 +707,13 @@ new dried(loc) item_quants[S.name]-- qdel(S) - SSnanoui.update_uis(src) + SStgui.update_uis(src) return TRUE for(var/obj/item/stack/sheet/wetleather/WL in contents) var/obj/item/stack/sheet/leather/L = new(loc) L.amount = WL.amount item_quants[WL.name]-- qdel(WL) - SSnanoui.update_uis(src) + SStgui.update_uis(src) return TRUE return FALSE - -#undef SMART_FRIDGE_LOCK_SHORTED diff --git a/code/modules/food_and_drinks/recipes/recipes_grill.dm b/code/modules/food_and_drinks/recipes/recipes_grill.dm index 047b3968176..73b181b8bbb 100644 --- a/code/modules/food_and_drinks/recipes/recipes_grill.dm +++ b/code/modules/food_and_drinks/recipes/recipes_grill.dm @@ -249,3 +249,23 @@ /obj/item/stack/rods, ) result = /obj/item/reagent_containers/food/snacks/fish_skewer + +/datum/recipe/grill/pancake + items = list( + /obj/item/reagent_containers/food/snacks/cookiedough + ) + result = /obj/item/reagent_containers/food/snacks/pancake + +/datum/recipe/grill/berry_pancake + items = list( + /obj/item/reagent_containers/food/snacks/cookiedough, + /obj/item/reagent_containers/food/snacks/grown/berries + ) + result = /obj/item/reagent_containers/food/snacks/pancake/berry_pancake + +/datum/recipe/grill/choc_chip_pancake + items = list( + /obj/item/reagent_containers/food/snacks/cookiedough, + /obj/item/reagent_containers/food/snacks/choc_pile + ) + result = /obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm index f8d720ec56c..df22e612830 100644 --- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm +++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm @@ -449,7 +449,7 @@ ) result = /obj/item/reagent_containers/food/snacks/twobread -datum/recipe/microwave/slimesandwich +/datum/recipe/microwave/slimesandwich reagents = list("slimejelly" = 5) items = list( /obj/item/reagent_containers/food/snacks/breadslice, diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index 6e937f45c2a..911b8eae866 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -116,9 +116,8 @@ /obj/item/reagent_containers/food/snacks/grown/firelemon/attack_self(mob/living/user) var/area/A = get_area(user) user.visible_message("[user] primes the [src]!", "You prime the [src]!") - var/message = "[ADMIN_LOOKUPFLW(user)] primed a combustible lemon for detonation at [A] [ADMIN_COORDJMP(user)]" investigate_log("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].", INVESTIGATE_BOMB) - message_admins(message) + add_attack_logs(user, src, "primed a combustible lemon for detonation", ATKLOG_FEW) log_game("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].") if(iscarbon(user)) var/mob/living/carbon/C = user diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 7d59bd3360b..d5c7744eb4a 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -27,10 +27,7 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 10 - -/obj/item/reagent_containers/spray/weedspray/New() - ..() - reagents.add_reagent("atrazine", 100) + list_reagents = list("atrazine" = 100) /obj/item/reagent_containers/spray/weedspray/suicide_act(mob/user) user.visible_message("[user] is huffing the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") @@ -49,10 +46,7 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 10 - -/obj/item/reagent_containers/spray/pestspray/New() - ..() - reagents.add_reagent("pestkiller", 100) + list_reagents = list("pestkiller" = 100) /obj/item/reagent_containers/spray/pestspray/suicide_act(mob/user) user.visible_message("[user] is huffing the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") @@ -222,79 +216,112 @@ /obj/item/reagent_containers/glass/bottle/nutrient - name = "bottle of nutrient" + name = "jug of nutrient" + desc = "A decent sized plastic jug." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - volume = 50 + icon_state = "plastic_jug" + item_state = "plastic_jug" w_class = WEIGHT_CLASS_TINY amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(1,2,5,10,15,25,50) + possible_transfer_amounts = list(1,2,5,10,20,40,80) + container_type = OPENCONTAINER + volume = 80 + hitsound = 'sound/weapons/jug_empty_impact.ogg' + throwhitsound = 'sound/weapons/jug_empty_impact.ogg' + force = 0.2 + throwforce = 0.2 /obj/item/reagent_containers/glass/bottle/nutrient/New() + ..() + add_lid() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + +/obj/item/reagent_containers/glass/bottle/nutrient/on_reagent_change() + . = ..() + update_icon() + if(reagents.total_volume) + hitsound = 'sound/weapons/jug_filled_impact.ogg' + throwhitsound = 'sound/weapons/jug_filled_impact.ogg' + else + hitsound = 'sound/weapons/jug_empty_impact.ogg' + throwhitsound = 'sound/weapons/jug_empty_impact.ogg' + +/obj/item/reagent_containers/glass/bottle/nutrient/update_icon() + cut_overlays() + + if(reagents.total_volume) + var/image/filling = image('icons/obj/reagentfillings.dmi', src, "plastic_jug10") + + var/percent = round((reagents.total_volume / volume) * 100) + switch(percent) + if(0 to 10) + filling.icon_state = "plastic_jug-10" + if(11 to 29) + filling.icon_state = "plastic_jug25" + if(30 to 45) + filling.icon_state = "plastic_jug40" + if(46 to 61) + filling.icon_state = "plastic_jug55" + if(62 to 77) + filling.icon_state = "plastic_jug70" + if(78 to 92) + filling.icon_state = "plastic_jug85" + if(93 to INFINITY) + filling.icon_state = "plastic_jug100" + + filling.icon += mix_color_from_reagents(reagents.reagent_list) + add_overlay(filling) + + if(!is_open_container()) + add_overlay("lid_jug") + + +/obj/item/reagent_containers/glass/bottle/nutrient/ez + name = "jug of E-Z-Nutrient" + desc = "Contains a fertilizer that causes mild mutations with each harvest." + icon = 'icons/obj/chemical.dmi' + icon_state = "plastic_jug_ez" + list_reagents = list("eznutriment" = 80) + +/obj/item/reagent_containers/glass/bottle/nutrient/l4z + name = "jug of Left 4 Zed" + desc = "Contains a fertilizer that limits plant yields to no more than one and causes significant mutations in plants." + icon = 'icons/obj/chemical.dmi' + icon_state = "plastic_jug_l4z" + list_reagents = list("left4zednutriment" = 80) + +/obj/item/reagent_containers/glass/bottle/nutrient/rh + name = "jug of Robust Harvest" + desc = "Contains a fertilizer that increases the yield of a plant by 30% while causing no mutations." + icon = 'icons/obj/chemical.dmi' + icon_state = "plastic_jug_rh" + list_reagents = list("robustharvestnutriment" = 80) + +/obj/item/reagent_containers/glass/bottle/nutrient/empty + icon = 'icons/obj/chemical.dmi' + icon_state = "plastic_jug" + +/obj/item/reagent_containers/glass/bottle/nutrient/killer + icon = 'icons/obj/chemical.dmi' + icon_state = "plastic_jug_k" + w_class = WEIGHT_CLASS_TINY + +/obj/item/reagent_containers/glass/bottle/nutrient/killer/New() ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) -/obj/item/reagent_containers/glass/bottle/nutrient/ez - name = "bottle of E-Z-Nutrient" - desc = "Contains a fertilizer that causes mild mutations with each harvest." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - -/obj/item/reagent_containers/glass/bottle/nutrient/ez/New() - ..() - reagents.add_reagent("eznutriment", 50) - -/obj/item/reagent_containers/glass/bottle/nutrient/l4z - name = "bottle of Left 4 Zed" - desc = "Contains a fertilizer that limits plant yields to no more than one and causes significant mutations in plants." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle18" - -/obj/item/reagent_containers/glass/bottle/nutrient/l4z/New() - ..() - reagents.add_reagent("left4zednutriment", 50) - -/obj/item/reagent_containers/glass/bottle/nutrient/rh - name = "bottle of Robust Harvest" - desc = "Contains a fertilizer that increases the yield of a plant by 30% while causing no mutations." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle15" - -/obj/item/reagent_containers/glass/bottle/nutrient/rh/New() - ..() - reagents.add_reagent("robustharvestnutriment", 50) - -/obj/item/reagent_containers/glass/bottle/nutrient/empty - name = "bottle" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - -/obj/item/reagent_containers/glass/bottle/killer - name = "bottle" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - volume = 50 - w_class = WEIGHT_CLASS_TINY - amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(1,2,5,10,15,25,50) - -/obj/item/reagent_containers/glass/bottle/killer/weedkiller - name = "bottle of weed killer" +/obj/item/reagent_containers/glass/bottle/nutrient/killer/weedkiller + name = "jug of weed killer" desc = "Contains a herbicide." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" + icon_state = "plastic_jug_wk" + list_reagents = list("atrazine" = 80) -/obj/item/reagent_containers/glass/bottle/killer/weedkiller/New() - ..() - reagents.add_reagent("atrazine", 50) - -/obj/item/reagent_containers/glass/bottle/killer/pestkiller - name = "bottle of pest spray" +/obj/item/reagent_containers/glass/bottle/nutrient/killer/pestkiller + name = "jug of pest spray" desc = "Contains a pesticide." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle20" - -/obj/item/reagent_containers/glass/bottle/killer/pestkiller/New() - ..() - reagents.add_reagent("pestkiller", 50) + icon_state = "plastic_jug_pk" + list_reagents = list("pestkiller" = 80) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 1be8f11527d..d79a8030a59 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -744,6 +744,10 @@ to_chat(user, "[reagent_source] is empty.") return 1 + if(reagent_source.has_lid && !reagent_source.is_drainable()) //if theres a LID then cannot transfer reagents. + to_chat(user, "You need to open [O] first!") + return TRUE + var/list/trays = list(src)//makes the list just this in cases of syringes and compost etc var/target = myseed ? myseed.plantname : src var/visi_msg = "" diff --git a/code/modules/instruments/songs/_song.dm b/code/modules/instruments/songs/_song.dm index 142eab1fd2d..fc4a9b63579 100644 --- a/code/modules/instruments/songs/_song.dm +++ b/code/modules/instruments/songs/_song.dm @@ -167,6 +167,8 @@ hearing_mobs.len = 0 var/turf/source = get_turf(parent) for(var/mob/M in GLOB.player_list) + if(M.z != source.z) // Z-level check + continue var/dist = get_dist(M, source) if(dist > instrument_range) // Distance check continue @@ -253,16 +255,20 @@ * Processes our song. */ /datum/song/proc/process_song(wait) - if(!length(compiled_chords) || current_chord > length(compiled_chords) || should_stop_playing(user_playing)) + if(!length(compiled_chords) || should_stop_playing(user_playing)) stop_playing() return - var/list/chord = compiled_chords[current_chord] if(++elapsed_delay >= delay_by) + // We were sustaining the final note but not anymore + if(current_chord > length(compiled_chords)) + stop_playing() + return + var/list/chord = compiled_chords[current_chord] play_chord(chord) elapsed_delay = 0 delay_by = tempodiv_to_delay(chord[length(chord)]) current_chord++ - if(current_chord > length(compiled_chords)) + if(current_chord > length(compiled_chords) + 1) if(repeat) repeat-- current_chord = 1 @@ -284,6 +290,8 @@ */ /datum/song/proc/compile_chords() legacy ? compile_legacy() : compile_synthesized() + // Some chords may be null for some reason - exclude them. + listclearnulls(compiled_chords) /** * Plays a chord. diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 837e3a21104..6df1ce19ba7 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -2,7 +2,7 @@ Everything karma related is here. Part of karma purchase is handled in client_procs.dm */ -proc/sql_report_karma(var/mob/spender, var/mob/receiver) +/proc/sql_report_karma(var/mob/spender, var/mob/receiver) var/sqlspendername = sanitizeSQL(spender.name) var/sqlspenderkey = sanitizeSQL(spender.ckey) var/sqlreceivername = sanitizeSQL(receiver.name) diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index e74625c8715..4217c4be6f7 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -101,32 +101,32 @@ /obj/structure/bookcase/manuals/medical name = "Medical Manuals bookcase" - New() - ..() - new /obj/item/book/manual/medical_cloning(src) - update_icon() +/obj/structure/bookcase/manuals/medical/New() + ..() + new /obj/item/book/manual/medical_cloning(src) + update_icon() /obj/structure/bookcase/manuals/engineering name = "Engineering Manuals bookcase" - New() - ..() - new /obj/item/book/manual/engineering_construction(src) - new /obj/item/book/manual/engineering_particle_accelerator(src) - new /obj/item/book/manual/engineering_hacking(src) - new /obj/item/book/manual/engineering_guide(src) - new /obj/item/book/manual/engineering_singularity_safety(src) - new /obj/item/book/manual/robotics_cyborgs(src) - update_icon() +/obj/structure/bookcase/manuals/engineering/New() + ..() + new /obj/item/book/manual/engineering_construction(src) + new /obj/item/book/manual/engineering_particle_accelerator(src) + new /obj/item/book/manual/engineering_hacking(src) + new /obj/item/book/manual/engineering_guide(src) + new /obj/item/book/manual/engineering_singularity_safety(src) + new /obj/item/book/manual/robotics_cyborgs(src) + update_icon() /obj/structure/bookcase/manuals/research_and_development name = "R&D Manuals bookcase" - New() - ..() - new /obj/item/book/manual/research_and_development(src) - update_icon() +/obj/structure/bookcase/manuals/research_and_development/New() + ..() + new /obj/item/book/manual/research_and_development(src) + update_icon() /* @@ -288,26 +288,26 @@ var/obj/item/book/book // Currently scanned book var/mode = 0 // 0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory - attack_self(mob/user as mob) - mode += 1 - if(mode > 3) - mode = 0 - to_chat(user, "[src] Status Display:") - var/modedesc - switch(mode) - if(0) - modedesc = "Scan book to local buffer." - if(1) - modedesc = "Scan book to local buffer and set associated computer buffer to match." - if(2) - modedesc = "Scan book to local buffer, attempt to check in scanned book." - if(3) - modedesc = "Scan book to local buffer, attempt to add book to general inventory." - else - modedesc = "ERROR" - to_chat(user, " - Mode [mode] : [modedesc]") - if(src.computer) - to_chat(user, "Computer has been associated with this unit.") +/obj/item/barcodescanner/attack_self(mob/user as mob) + mode += 1 + if(mode > 3) + mode = 0 + to_chat(user, "[src] Status Display:") + var/modedesc + switch(mode) + if(0) + modedesc = "Scan book to local buffer." + if(1) + modedesc = "Scan book to local buffer and set associated computer buffer to match." + if(2) + modedesc = "Scan book to local buffer, attempt to check in scanned book." + if(3) + modedesc = "Scan book to local buffer, attempt to add book to general inventory." else - to_chat(user, "No associated computer found. Only local scans will function properly.") - to_chat(user, "\n") + modedesc = "ERROR" + to_chat(user, " - Mode [mode] : [modedesc]") + if(src.computer) + to_chat(user, "Computer has been associated with this unit.") + else + to_chat(user, "No associated computer found. Only local scans will function properly.") + to_chat(user, "\n") diff --git a/code/modules/martial_arts/adminfu.dm b/code/modules/martial_arts/adminfu.dm index 12436061e20..20f3c95f7b6 100644 --- a/code/modules/martial_arts/adminfu.dm +++ b/code/modules/martial_arts/adminfu.dm @@ -1,93 +1,37 @@ -///Adminfu -//Help act:Heal/revie GP //p is for help -//Disarm:Stun -//Grab:Neck -//Harm:Gib -#define HEAL_COMBO "GP" - /datum/martial_art/adminfu name = "Way of the Dancing Admin" - help_verb = /mob/living/carbon/human/proc/adminfu_help - -/datum/martial_art/adminfu/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,HEAL_COMBO)) - streak = "" - healPalm(A,D) - return 1 - return 0 + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/adminfu/healing_palm) /datum/martial_art/adminfu/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - + MARTIAL_ARTS_ACT_CHECK if(!D.stat)//do not kill what is dead... A.do_attack_animation(D) D.visible_message("[A] manifests a large glowing toolbox and shoves it in [D]'s chest!", \ "[A] shoves a mystical toolbox in your chest!
") D.death() - return 1 + return TRUE /datum/martial_art/adminfu/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + MARTIAL_ARTS_ACT_CHECK A.do_attack_animation(D) D.Weaken(25) D.Stun(25) - return 1 + return TRUE /datum/martial_art/adminfu/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = D.grabbedby(A,1) if(G) G.state = GRAB_NECK + return TRUE -/datum/martial_art/adminfu/help_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("P",D) - if(check_streak(A,D)) - return 1 - -/datum/martial_art/adminfu/proc/healPalm(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.do_attack_animation(D) - D.visible_message("[A] smacks [D] in the forehead!") - - //its the staff of healing code..hush - if(istype(D,/mob)) - var/old_stat = D.stat - if(isanimal(D) && D.stat == DEAD) - var/mob/living/simple_animal/O = D - var/mob/living/simple_animal/P = new O.type(O.loc) - P.real_name = O.real_name - P.name = O.name - if(O.mind) - O.mind.transfer_to(P) - else - P.key = O.key - qdel(O) - D = P - else - D.revive() - D.suiciding = 0 - if(!D.ckey) - for(var/mob/dead/observer/ghost in GLOB.player_list) - if(D.real_name == ghost.real_name) - ghost.reenter_corpse() - break - if(old_stat != DEAD) - to_chat(D, "You feel great!") - else - to_chat(D, "You rise with a start, you're alive!!!") - return 1 - -/mob/living/carbon/human/proc/adminfu_help() - set name = "Recall Teachings" - set desc = "Remember the way of the dancing admin." - set category = "Adminfu" - - to_chat(usr, "Grab: Automatic Neck Grab.") - to_chat(usr, "Disarm: Stun/weaken") - to_chat(usr, "Harm: Death.") - to_chat(usr, "Healing Palm::Combo:Grab,Help intent. Heals or revives a crature.") - +/datum/martial_art/adminfu/explaination_header(user) + to_chat(user, "Grab: Automatic Neck Grab.") + to_chat(user, "Disarm: Stun/weaken") + to_chat(user, "Harm: Death.") /obj/item/adminfu_scroll name = "frayed scroll" diff --git a/code/modules/martial_arts/combos/adminfu/healing_palm.dm b/code/modules/martial_arts/combos/adminfu/healing_palm.dm new file mode 100644 index 00000000000..c5bd34f1886 --- /dev/null +++ b/code/modules/martial_arts/combos/adminfu/healing_palm.dm @@ -0,0 +1,38 @@ +/datum/martial_combo/adminfu/healing_palm + name = "Healing Palm" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_HELP) + explaination_text = "Heals or revives a creature." + combo_text_override = "Grab, switch hands, Help" + +/datum/martial_combo/adminfu/healing_palm/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + user.do_attack_animation(target) + target.visible_message("[user] smacks [target] in the forehead!") + + //its the staff of healing code..hush + if(istype(target,/mob)) + var/old_stat = target.stat + if(isanimal(target) && target.stat == DEAD) + var/mob/living/simple_animal/O = target + var/mob/living/simple_animal/P = new O.type(O.loc) + P.real_name = O.real_name + P.name = O.name + if(O.mind) + O.mind.transfer_to(P) + else + P.key = O.key + qdel(O) + target = P + else + target.revive() + target.suiciding = 0 + if(!target.ckey) + for(var/mob/dead/observer/ghost in GLOB.player_list) + if(target.real_name == ghost.real_name) + ghost.reenter_corpse() + break + if(old_stat != DEAD) + to_chat(target, "You feel great!") + else + to_chat(target, "You rise with a start, you're alive!!!") + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/cqc/consecutive.dm b/code/modules/martial_arts/combos/cqc/consecutive.dm new file mode 100644 index 00000000000..b513c8191e4 --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/consecutive.dm @@ -0,0 +1,18 @@ +/datum/martial_combo/cqc/consecutive + name = "Consecutive CQC" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Mainly offensive move, huge damage and decent stamina damage." + +/datum/martial_combo/cqc/consecutive/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat) + target.visible_message("[user] strikes [target]'s abdomen, neck and back consecutively", \ + "[user] strikes your abdomen, neck and back consecutively!") + playsound(get_turf(target), 'sound/weapons/cqchit2.ogg', 50, 1, -1) + var/obj/item/I = target.get_active_hand() + if(I && target.drop_item()) + user.put_in_hands(I) + target.adjustStaminaLoss(50) + target.apply_damage(25, BRUTE) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Consecutive", ATKLOG_ALL) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/cqc/kick.dm b/code/modules/martial_arts/combos/cqc/kick.dm new file mode 100644 index 00000000000..887a51b049d --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/kick.dm @@ -0,0 +1,24 @@ +/datum/martial_combo/cqc/kick + name = "CQC Kick" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Knocks opponent away. Knocks out stunned or knocked down opponents." + +/datum/martial_combo/cqc/kick/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + . = MARTIAL_COMBO_FAIL + if(!target.stat || !target.IsWeakened()) + target.visible_message("[user] kicks [target] back!", \ + "[user] kicks you back!") + playsound(get_turf(user), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + var/atom/throw_target = get_edge_target_turf(target, user.dir) + target.throw_at(throw_target, 1, 14, user) + target.apply_damage(10, BRUTE) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL) + . = MARTIAL_COMBO_DONE + if(target.IsWeakened() && !target.stat) + target.visible_message("[user] kicks [target]'s head, knocking [target.p_them()] out!", \ + "[user] kicks your head, knocking you out!") + playsound(get_turf(user), 'sound/weapons/genhit1.ogg', 50, 1, -1) + target.SetSleeping(15) + target.adjustBrainLoss(15) + add_attack_logs(user, target, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL) + . = MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/cqc/pressure.dm b/code/modules/martial_arts/combos/cqc/pressure.dm new file mode 100644 index 00000000000..b19bfb6ddf7 --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/pressure.dm @@ -0,0 +1,11 @@ +/datum/martial_combo/cqc/pressure + name = "Pressure" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_GRAB) + explaination_text = "Decent stamina damage." + +/datum/martial_combo/cqc/pressure/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] forces their arm on [target]'s neck!") + target.adjustStaminaLoss(60) + playsound(get_turf(user), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Pressure", ATKLOG_ALL) + return MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/cqc/restrain.dm b/code/modules/martial_arts/combos/cqc/restrain.dm new file mode 100644 index 00000000000..e9495c61dba --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/restrain.dm @@ -0,0 +1,22 @@ +/datum/martial_combo/cqc/restrain + name = "Restrain" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_GRAB) + explaination_text = "Locks opponents into a restraining position, disarm to knock them out with a choke hold." + combo_text_override = "Grab, switch hands, Grab" + +/datum/martial_combo/cqc/restrain/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + var/datum/martial_art/cqc/CQC = MA + if(!istype(CQC)) + return MARTIAL_COMBO_FAIL + if(CQC.restraining) + return MARTIAL_COMBO_FAIL + if(!target.stat) + target.visible_message("[user] locks [target] into a restraining position!", \ + "[user] locks you into a restraining position!") + target.adjustStaminaLoss(20) + target.Stun(5) + CQC.restraining = TRUE + addtimer(CALLBACK(CQC, /datum/martial_art/cqc/.proc/drop_restraining), 50, TIMER_UNIQUE) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Restrain", ATKLOG_ALL) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/cqc/slam.dm b/code/modules/martial_arts/combos/cqc/slam.dm new file mode 100644 index 00000000000..8c1a84d7817 --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/slam.dm @@ -0,0 +1,16 @@ +/datum/martial_combo/cqc/slam + name = "Slam" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Slam opponent into the ground, knocking them down." + combo_text_override = "Grab, switch hands, Harm" + +/datum/martial_combo/cqc/slam/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.IsWeakened() && !target.resting && !target.lying) + target.visible_message("[user] slams [target] into the ground!", \ + "[user] slams you into the ground!") + playsound(get_turf(user), 'sound/weapons/slam.ogg', 50, 1, -1) + target.apply_damage(10, BRUTE) + target.Weaken(6) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Slam", ATKLOG_ALL) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/krav_maga/leg_sweep.dm b/code/modules/martial_arts/combos/krav_maga/leg_sweep.dm new file mode 100644 index 00000000000..0defb3e9eff --- /dev/null +++ b/code/modules/martial_arts/combos/krav_maga/leg_sweep.dm @@ -0,0 +1,14 @@ +/datum/martial_combo/krav_maga/leg_sweep + name = "Leg Sweep" + explaination_text = "Trips the victim, rendering them prone and unable to move for a short time." + +/datum/martial_combo/krav_maga/leg_sweep/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(target.stat || target.IsWeakened()) + return FALSE + target.visible_message("[user] leg sweeps [target]!", \ + "[user] leg sweeps you!") + playsound(get_turf(user), 'sound/effects/hit_kick.ogg', 50, 1, -1) + target.apply_damage(5, BRUTE) + target.Weaken(2) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Leg Sweep", ATKLOG_ALL) + return MARTIAL_COMBO_DONE_CLEAR_COMBOS diff --git a/code/modules/martial_arts/combos/krav_maga/lung_punch.dm b/code/modules/martial_arts/combos/krav_maga/lung_punch.dm new file mode 100644 index 00000000000..e71289f9174 --- /dev/null +++ b/code/modules/martial_arts/combos/krav_maga/lung_punch.dm @@ -0,0 +1,12 @@ +/datum/martial_combo/krav_maga/lung_punch + name = "Lung Punch" + explaination_text = "Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time." + +/datum/martial_combo/krav_maga/lung_punch/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] pounds [target] on the chest!", \ + "[user] slams your chest! You can't breathe!") + playsound(get_turf(user), 'sound/effects/hit_punch.ogg', 50, 1, -1) + target.AdjustLoseBreath(5) + target.adjustOxyLoss(10) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Lung Punch", ATKLOG_ALL) + return MARTIAL_COMBO_DONE_CLEAR_COMBOS diff --git a/code/modules/martial_arts/combos/krav_maga/neck_chop.dm b/code/modules/martial_arts/combos/krav_maga/neck_chop.dm new file mode 100644 index 00000000000..c0e2f71b6a5 --- /dev/null +++ b/code/modules/martial_arts/combos/krav_maga/neck_chop.dm @@ -0,0 +1,12 @@ +/datum/martial_combo/krav_maga/neck_chop + name = "Neck Chop" + explaination_text = "Injures the neck, stopping the victim from speaking for a while." + +/datum/martial_combo/krav_maga/neck_chop/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] karate chops [target]'s neck!", \ + "[user] karate chops your neck, rendering you unable to speak for a short time!") + playsound(get_turf(user), 'sound/effects/hit_punch.ogg', 50, 1, -1) + target.apply_damage(5, BRUTE) + target.AdjustSilence(10) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Neck Chop", ATKLOG_ALL) + return MARTIAL_COMBO_DONE_CLEAR_COMBOS diff --git a/code/modules/martial_arts/combos/martial_combo.dm b/code/modules/martial_arts/combos/martial_combo.dm new file mode 100644 index 00000000000..6b4eedb97dc --- /dev/null +++ b/code/modules/martial_arts/combos/martial_combo.dm @@ -0,0 +1,36 @@ +/datum/martial_combo + /// Name used to explain the combo + var/name = "Code Fu" + /// Which steps need to be performed + var/list/steps + /// What index to check + var/current_step_index = 1 + /// Who is the target the combo is being executed on + var/current_combo_target = null + /// If you require to do the combo's on the same target + var/combos_require_same_target = TRUE + /// What does it do + var/explaination_text = "Ability to break shit" + /// How to do the combo. If null it'll auto generate it from the steps + var/combo_text_override + +/datum/martial_combo/proc/check_combo(step, mob/living/target) + if(!combos_require_same_target || current_combo_target == null || current_combo_target == target) + if(!length(steps) || step == steps[current_step_index]) + return TRUE + return FALSE + +/datum/martial_combo/proc/progress_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + current_combo_target = target + if(current_step_index++ >= LAZYLEN(steps)) + return perform_combo(user, target, MA) + return MARTIAL_COMBO_CONTINUE + +/datum/martial_combo/proc/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + return MARTIAL_COMBO_FAIL // Override this + +/datum/martial_combo/proc/give_explaination(user) + var/final_combo_text = combo_text_override + if(!final_combo_text) + final_combo_text = english_list(steps, and_text = " ", comma_text = " ") + to_chat(user, "[name]: [final_combo_text]. [explaination_text]") diff --git a/code/modules/martial_arts/combos/mimejutsu/mimechucks.dm b/code/modules/martial_arts/combos/mimejutsu/mimechucks.dm new file mode 100644 index 00000000000..b7f2d247b4b --- /dev/null +++ b/code/modules/martial_arts/combos/mimejutsu/mimechucks.dm @@ -0,0 +1,26 @@ +/datum/martial_combo/mimejutsu/mimechucks + name = "Mimechucks" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Hits the opponent with invisible nunchucks." + +/datum/martial_combo/mimejutsu/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.stunned && !target.IsWeakened()) + var/damage = rand(5, 8) + user.dna.species.punchdamagelow + if(!damage) + playsound(target.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + target.visible_message("[user] swings invisible nunchcuks at [target]..and misses?") + return MARTIAL_COMBO_DONE + + + var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_selected)) + var/armor_block = target.run_armor_check(affecting, "melee") + + target.visible_message("[user] has hit [target] with invisible nunchucks!", \ + "[user] has hit [target] with a with invisible nunchuck!") + playsound(get_turf(user), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + target.apply_damage(damage, STAMINA, affecting, armor_block) + add_attack_logs(user, target, "Melee attacked with [src] (mimechuck)") + + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/mimejutsu/silent_palm.dm b/code/modules/martial_arts/combos/mimejutsu/silent_palm.dm new file mode 100644 index 00000000000..eb8df68fac4 --- /dev/null +++ b/code/modules/martial_arts/combos/mimejutsu/silent_palm.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/mimejutsu/silent_palm + name = "Silent Palm" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Use mime energy to throw someone back." + +/datum/martial_combo/mimejutsu/silent_palm/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.stunned && !target.IsWeakened()) + target.visible_message("[user] has barely touched [target] with [user.p_their()] palm!", \ + "[user] hovers [user.p_their()] palm over your face!") + + var/atom/throw_target = get_edge_target_turf(target, get_dir(target, get_step_away(target, user))) + target.throw_at(throw_target, 200, 4, user) + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/mimejutsu/smokebomb.dm b/code/modules/martial_arts/combos/mimejutsu/smokebomb.dm new file mode 100644 index 00000000000..23277fa5f0d --- /dev/null +++ b/code/modules/martial_arts/combos/mimejutsu/smokebomb.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/mimejutsu/smokebomb + name = "Smokebomb" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Drops a mime smokebomb." + +/datum/martial_combo/mimejutsu/smokebomb/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] throws an invisible smoke bomb!!") + + var/datum/effect_system/smoke_spread/bad/smoke = new + smoke.set_up(5, 0, target.loc) + smoke.start() + + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm b/code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm new file mode 100644 index 00000000000..93c3e3ef480 --- /dev/null +++ b/code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/plasma_fist/plasma_fist + name = "The Plasma Fist" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Knocks the brain out of the opponent and gibs their body." + +/datum/martial_combo/plasma_fist/plasma_fist/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + playsound(target.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) + user.say("PLASMA FIST!") + target.visible_message("[user] has hit [target] with THE PLASMA FIST TECHNIQUE!", \ + "[user] has hit [target] with THE PLASMA FIST TECHNIQUE!") + target.gib() + return MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/plasma_fist/throwback.dm b/code/modules/martial_arts/combos/plasma_fist/throwback.dm new file mode 100644 index 00000000000..7057452a913 --- /dev/null +++ b/code/modules/martial_arts/combos/plasma_fist/throwback.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/plasma_fist/throwback + name = "Throwback" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Throws the target and an item at them." + +/datum/martial_combo/plasma_fist/throwback/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] has hit [target] with Plasma Punch!", \ + "[user] has hit [target] with Plasma Punch!") + playsound(target.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) + var/atom/throw_target = get_edge_target_turf(target, get_dir(target, get_step_away(target, user))) + target.throw_at(throw_target, 200, 4, user) + user.say("HYAH!") + return MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm b/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm new file mode 100644 index 00000000000..41a7bd676d3 --- /dev/null +++ b/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm @@ -0,0 +1,20 @@ +/datum/martial_combo/plasma_fist/tornado_sweep + name = "Tornado Sweep" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Repulses target and everyone back." + +/datum/martial_combo/plasma_fist/tornado_sweep/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + user.say("TORNADO SWEEP!") + INVOKE_ASYNC(src, .proc/do_tornado_effect, user) + var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null) + var/list/turfs = list() + for(var/turf/T in range(1,user)) + turfs.Add(T) + R.cast(turfs) + return MARTIAL_COMBO_DONE + +/datum/martial_combo/plasma_fist/tornado_sweep/proc/do_tornado_effect(mob/living/carbon/human/user) + for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) + user.dir = i + playsound(user.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) + sleep(1) diff --git a/code/modules/martial_arts/combos/sleeping_carp/back_kick.dm b/code/modules/martial_arts/combos/sleeping_carp/back_kick.dm new file mode 100644 index 00000000000..3ebaa191e23 --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/back_kick.dm @@ -0,0 +1,18 @@ +/datum/martial_combo/sleeping_carp/back_kick + name = "Back Kick" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_GRAB) + explaination_text = "Opponent must be facing away. Knocks down." + +/datum/martial_combo/sleeping_carp/back_kick/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(user.dir == target.dir && !target.stat && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_KICK) + target.visible_message("[user] kicks [target] in the back!", \ + "[user] kicks you in the back, making you stumble and fall!") + step_to(target,get_step(target,target.dir),1) + target.Weaken(4) + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Back Kick", ATKLOG_ALL) + if(prob(80)) + user.say(pick("SURRPRIZU!","BACK STRIKE!","WOPAH!", "WATAAH", "ZOTA!", "Never turn your back to the enemy!")) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm b/code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm new file mode 100644 index 00000000000..0269c9bed4d --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm @@ -0,0 +1,18 @@ +/datum/martial_combo/sleeping_carp/elbow_drop + name = "Elbow Drop" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition." + +/datum/martial_combo/sleeping_carp/elbow_drop/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(target.IsWeakened() || target.resting || target.stat) + user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + target.visible_message("[user] elbow drops [target]!", \ + "[user] piledrives you with [user.p_their()] elbow!") + target.death() //FINISH HIM! + target.apply_damage(50, BRUTE, "chest") + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 75, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Elbow Drop", ATKLOG_ALL) + if(prob(80)) + user.say(pick("BANZAIII!", "KIYAAAA!", "OMAE WA MOU SHINDEIRU!", "YOU CAN'T SEE ME!", "MY TIME IS NOW!", "COWABUNGA")) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/head_kick.dm b/code/modules/martial_arts/combos/sleeping_carp/head_kick.dm new file mode 100644 index 00000000000..b45e10e73ce --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/head_kick.dm @@ -0,0 +1,19 @@ +/datum/martial_combo/sleeping_carp/head_kick + name = "Head Kick" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Decent damage, forces opponent to drop item in hand." + +/datum/martial_combo/sleeping_carp/head_kick/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_KICK) + target.visible_message("[user] kicks [target] in the head!", \ + "[user] kicks you in the jaw!") + target.apply_damage(20, BRUTE, "head") + target.drop_item() + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Head Kick", ATKLOG_ALL) + if(prob(60)) + user.say(pick("OOHYOO!", "OOPYAH!", "HYOOAA!", "WOOAAA!", "SHURYUKICK!", "HIYAH!")) + target.Stun(4) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm b/code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm new file mode 100644 index 00000000000..312e575003d --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm @@ -0,0 +1,20 @@ +/datum/martial_combo/sleeping_carp/stomach_knee + name = "Stomach Knee" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Knocks the wind out of opponent and stuns." + combo_text_override = "Grab, switch hands, Harm" + +/datum/martial_combo/sleeping_carp/stomach_knee/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_KICK) + target.visible_message("[user] knees [target] in the stomach!", \ + "[user] winds you with a knee in the stomach!") + target.audible_message("[target] gags!") + target.AdjustLoseBreath(3) + target.Stun(2) + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Stomach Knee", ATKLOG_ALL) + if(prob(80)) + user.say(pick("HWOP!", "KUH!", "YAKUUH!", "KYUH!", "KNEESTRIKE!")) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm b/code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm new file mode 100644 index 00000000000..38c21e7309e --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm @@ -0,0 +1,20 @@ +/datum/martial_combo/sleeping_carp/wrist_wrench + name = "Wrist Wrench" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Forces opponent to drop item in hand." + +/datum/martial_combo/sleeping_carp/wrist_wrench/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.stunned && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + target.visible_message("[user] grabs [target]'s wrist and wrenches it sideways!", \ + "[user] grabs your wrist and violently wrenches it to the side!") + playsound(get_turf(user), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Wrist Wrench", ATKLOG_ALL) + if(prob(60)) + user.say(pick("WRISTY TWIRLY!", "WE FIGHT LIKE MEN!", "YOU DISHONOR YOURSELF!", "POHYAH!", "WHERE IS YOUR BATON NOW?", "SAY UNCLE!")) + target.emote("scream") + target.drop_item() + target.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) + target.Stun(3) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm index f0b5c016c5b..49a08c1bd3c 100644 --- a/code/modules/martial_arts/cqc.dm +++ b/code/modules/martial_arts/cqc.dm @@ -1,152 +1,27 @@ -#define SLAM_COMBO "GH" -#define KICK_COMBO "HH" -#define RESTRAIN_COMBO "GG" -#define PRESSURE_COMBO "DG" -#define CONSECUTIVE_COMBO "DDH" - /datum/martial_art/cqc name = "CQC" - help_verb = /mob/living/carbon/human/proc/CQC_help block_chance = 75 - var/just_a_cook = FALSE + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/cqc/slam, /datum/martial_combo/cqc/kick, /datum/martial_combo/cqc/restrain, /datum/martial_combo/cqc/pressure, /datum/martial_combo/cqc/consecutive) + var/restraining = FALSE //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not var/static/list/areas_under_siege = typecacheof(list(/area/crew_quarters/kitchen, /area/crew_quarters/cafeteria, /area/crew_quarters/bar)) /datum/martial_art/cqc/under_siege name = "Close Quarters Cooking" - just_a_cook = TRUE + +/datum/martial_art/cqc/under_siege/can_use(mob/living/carbon/human/H) + var/area/A = get_area(H) + if(!(is_type_in_typecache(A, areas_under_siege))) + return FALSE + return ..() /datum/martial_art/cqc/proc/drop_restraining() restraining = FALSE -/datum/martial_art/cqc/can_use(mob/living/carbon/human/H) - var/area/A = get_area(H) - if(just_a_cook && !(is_type_in_typecache(A, areas_under_siege))) - return FALSE - return ..() - -/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - if(findtext(streak, SLAM_COMBO)) - streak = "" - Slam(A, D) - return TRUE - if(findtext(streak, KICK_COMBO)) - streak = "" - Kick(A, D) - return TRUE - if(findtext(streak, RESTRAIN_COMBO)) - streak = "" - Restrain(A, D) - return TRUE - if(findtext(streak, PRESSURE_COMBO)) - streak = "" - Pressure(A, D) - return TRUE - if(findtext(streak, CONSECUTIVE_COMBO)) - streak = "" - Consecutive(A, D) - return FALSE - -/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - if(!D.IsWeakened() && !D.resting && !D.lying) - D.visible_message("[A] slams [D] into the ground!", \ - "[A] slams you into the ground!") - playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1) - D.apply_damage(10, BRUTE) - D.Weaken(6) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Slam", ATKLOG_ALL) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - -/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - var/success = FALSE - if(!D.stat || !D.IsWeakened()) - D.visible_message("[A] kicks [D] back!", \ - "[A] kicks you back!") - playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - var/atom/throw_target = get_edge_target_turf(D, A.dir) - D.throw_at(throw_target, 1, 14, A) - D.apply_damage(10, BRUTE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL) - success = TRUE - if(D.IsWeakened() && !D.stat) - D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \ - "[A] kicks your head, knocking you out!") - playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1) - D.SetSleeping(15) - D.adjustBrainLoss(15) - add_attack_logs(A, D, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL) - success = TRUE - if(success) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - -/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - D.visible_message("[A] forces their arm on [D]'s neck!") - D.adjustStaminaLoss(60) - playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Pressure", ATKLOG_ALL) - return TRUE - -/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(restraining) - return - if(!can_use(A)) - return FALSE - if(!D.stat) - D.visible_message("[A] locks [D] into a restraining position!", \ - "[A] locks you into a restraining position!") - D.adjustStaminaLoss(20) - D.Stun(5) - restraining = TRUE - addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Restrain", ATKLOG_ALL) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - -/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - if(!D.stat) - D.visible_message("[A] strikes [D]'s abdomen, neck and back consecutively", \ - "[A] strikes your abdomen, neck and back consecutively!") - playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1) - var/obj/item/I = D.get_active_hand() - if(I && D.drop_item()) - A.put_in_hands(I) - D.adjustStaminaLoss(50) - D.apply_damage(25, BRUTE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Consecutive", ATKLOG_ALL) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - /datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - add_to_streak("G", D) - if(check_streak(A, D)) - return TRUE + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = D.grabbedby(A, 1) if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab @@ -155,11 +30,7 @@ return TRUE /datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - add_to_streak("H", D) - if(check_streak(A, D)) - return TRUE + MARTIAL_ARTS_ACT_CHECK add_attack_logs(A, D, "Melee attacked with martial-art [src]", ATKLOG_ALL) A.do_attack_animation(D) var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched", "Big Bossed") @@ -185,12 +56,7 @@ return TRUE /datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - add_to_streak("D", D) - var/obj/item/I = null - if(check_streak(A, D)) - return TRUE + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = A.get_inactive_hand() if(restraining && istype(G) && G.affecting == D) D.visible_message("[A] puts [D] into a chokehold!", \ @@ -203,6 +69,8 @@ else restraining = FALSE + var/obj/item/I = null + if(prob(65)) if(!D.stat || !D.IsWeakened() || !restraining) I = D.get_active_hand() @@ -220,16 +88,8 @@ add_attack_logs(A, D, "Melee attacked with martial-art [src] : Disarmed [I ? " grabbing \the [I]" : ""]", ATKLOG_ALL) return TRUE -/mob/living/carbon/human/proc/CQC_help() - set name = "Remember The Basics" - set desc = "You try to remember some of the basics of CQC." - set category = "CQC" - to_chat(usr, "You try to remember some of the basics of CQC.") +/datum/martial_art/cqc/explaination_header(user) + to_chat(user, "You try to remember some of the basics of CQC.") - to_chat(usr, "Slam: Grab, switch hands, Harm. Slam opponent into the ground, knocking them down.") - to_chat(usr, "CQC Kick: Harm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.") - to_chat(usr, "Restrain: Grab, switch hands, Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.") - to_chat(usr, "Pressure: Disarm Grab. Decent stamina damage.") - to_chat(usr, "Consecutive CQC: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.") - - to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.") +/datum/martial_art/cqc/explaination_footer(user) + to_chat(user, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.") diff --git a/code/modules/martial_arts/krav_maga.dm b/code/modules/martial_arts/krav_maga.dm index 3a6f484b2aa..cd3a6214e83 100644 --- a/code/modules/martial_arts/krav_maga.dm +++ b/code/modules/martial_arts/krav_maga.dm @@ -15,7 +15,9 @@ to_chat(owner, "Your next attack will be a Neck Chop.") owner.visible_message("[owner] assumes the Neck Chop stance!") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "neck_chop" + H.mind.martial_art.combos.Cut() + H.mind.martial_art.combos.Add(/datum/martial_combo/krav_maga/neck_chop) + H.mind.martial_art.reset_combos() /datum/action/leg_sweep name = "Leg Sweep - Trips the victim, rendering them prone and unable to move for a short time." @@ -28,7 +30,9 @@ to_chat(owner, "Your next attack will be a Leg Sweep.") owner.visible_message("[owner] assumes the Leg Sweep stance!") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "leg_sweep" + H.mind.martial_art.combos.Cut() + H.mind.martial_art.combos.Add(/datum/martial_combo/krav_maga/leg_sweep) + H.mind.martial_art.reset_combos() /datum/action/lung_punch//referred to internally as 'quick choke' name = "Lung Punch - Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time." @@ -41,7 +45,9 @@ to_chat(owner, "Your next attack will be a Lung Punch.") owner.visible_message("[owner] assumes the Lung Punch stance!") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "quick_choke"//internal name for lung punch + H.mind.martial_art.combos.Cut() + H.mind.martial_art.combos.Add(/datum/martial_combo/krav_maga/lung_punch) + H.mind.martial_art.reset_combos() /datum/martial_art/krav_maga/teach(var/mob/living/carbon/human/H,var/make_temporary=0) ..() @@ -58,59 +64,8 @@ legsweep.Remove(H) lungpunch.Remove(H) -/datum/martial_art/krav_maga/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - switch(streak) - if("neck_chop") - streak = "" - neck_chop(A,D) - return 1 - if("leg_sweep") - streak = "" - leg_sweep(A,D) - return 1 - if("quick_choke")//is actually lung punch - streak = "" - quick_choke(A,D) - return 1 - return 0 - -/datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.stat || D.IsWeakened()) - return 0 - D.visible_message("[A] leg sweeps [D]!", \ - "[A] leg sweeps you!") - playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1) - D.apply_damage(5, BRUTE) - D.Weaken(2) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Leg Sweep", ATKLOG_ALL) - return 1 - -/datum/martial_art/krav_maga/proc/quick_choke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)//is actually lung punch - D.visible_message("[A] pounds [D] on the chest!", \ - "[A] slams your chest! You can't breathe!") - playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) - D.AdjustLoseBreath(5) - D.adjustOxyLoss(10) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Lung Punch", ATKLOG_ALL) - return 1 - -/datum/martial_art/krav_maga/proc/neck_chop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - D.visible_message("[A] karate chops [D]'s neck!", \ - "[A] karate chops your neck, rendering you unable to speak for a short time!") - playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) - D.apply_damage(5, BRUTE) - D.AdjustSilence(10) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Neck Chop", ATKLOG_ALL) - return 1 - -datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(check_streak(A,D)) - return 1 - ..() - /datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK add_attack_logs(A, D, "Melee attacked with [src]") var/picked_hit_type = pick("punches", "kicks") var/bonus_damage = 10 @@ -126,11 +81,10 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1) D.visible_message("[A] [picked_hit_type] [D]!", \ "[A] [picked_hit_type] you!") - return 1 + return TRUE /datum/martial_art/krav_maga/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK if(prob(60)) if(D.hand) if(istype(D.l_hand, /obj/item)) @@ -149,7 +103,7 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi D.visible_message("[A] attempted to disarm [D]!", \ "[A] attempted to disarm [D]!") playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - return 1 + return TRUE //Krav Maga Gloves diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index 8969463be1d..50ca634a22f 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -1,42 +1,87 @@ +#define HAS_COMBOS LAZYLEN(combos) +#define COMBO_ALIVE_TIME 5 SECONDS // How long the combo stays alive when no new attack is done + /datum/martial_art var/name = "Martial Art" var/streak = "" var/max_streak_length = 6 - var/current_target = null - var/temporary = 0 + var/temporary = FALSE var/datum/martial_art/base = null // The permanent style var/deflection_chance = 0 //Chance to deflect projectiles var/block_chance = 0 //Chance to block melee attacks using items while on throw mode. - var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not var/help_verb = null var/no_guns = FALSE //set to TRUE to prevent users of this style from using guns (sleeping carp, highlander). They can still pick them up, but not fire them. var/no_guns_message = "" //message to tell the style user if they try and use a gun while no_guns = TRUE (DISHONORABRU!) -/datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 + var/has_explaination_verb = FALSE // If the martial art has it's own explaination verb -/datum/martial_art/proc/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 + var/list/combos = list() // What combos can the user do? List of combo types + var/list/datum/martial_art/current_combos = list() // What combos are currently (possibly) being performed + var/last_hit = 0 // When the last hit happened -/datum/martial_art/proc/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 +/datum/martial_art/New() + . = ..() + reset_combos() -/datum/martial_art/proc/help_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 +/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_DISARM, A, D) + +/datum/martial_art/proc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_HARM, A, D) + +/datum/martial_art/proc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_GRAB, A, D) + +/datum/martial_art/proc/help_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_HELP, A, D) /datum/martial_art/proc/can_use(mob/living/carbon/human/H) return TRUE -/datum/martial_art/proc/add_to_streak(var/element,var/mob/living/carbon/human/D) - if(D != current_target) - current_target = D - streak = "" - streak = streak+element - if(length(streak) > max_streak_length) - streak = copytext(streak,2) - return +/datum/martial_art/proc/act(step, mob/living/carbon/human/user, mob/living/carbon/human/target) + if(!can_use(user)) + return MARTIAL_ARTS_CANNOT_USE + if(last_hit + COMBO_ALIVE_TIME < world.time) + reset_combos() + last_hit = world.time -/datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) + if(HAS_COMBOS) + return check_combos(step, user, target) + return FALSE + +/datum/martial_art/proc/reset_combos() + current_combos.Cut() + for(var/combo_type in combos) + current_combos.Add(new combo_type()) + +/datum/martial_art/proc/check_combos(step, mob/living/carbon/human/user, mob/living/carbon/human/target) + . = FALSE + for(var/thing in current_combos) + var/datum/martial_combo/MC = thing + if(!MC.check_combo(step, target)) + current_combos -= MC // It failed so remove it + else + switch(MC.progress_combo(user, target, src)) + if(MARTIAL_COMBO_FAIL) + current_combos -= MC + if(MARTIAL_COMBO_DONE_NO_CLEAR) + . = TRUE + current_combos -= MC + if(MARTIAL_COMBO_DONE) + reset_combos() + return TRUE + if(MARTIAL_COMBO_DONE_BASIC_HIT) + basic_hit(user, target) + reset_combos() + return TRUE + if(MARTIAL_COMBO_DONE_CLEAR_COMBOS) + combos.Cut() + reset_combos() + return TRUE + if(!LAZYLEN(current_combos)) + reset_combos() + +/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A, mob/living/carbon/human/D) var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh) var/datum/unarmed_attack/attack = A.dna.species.unarmed @@ -54,7 +99,7 @@ if(!damage) playsound(D.loc, attack.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!") - return 0 + return FALSE var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, "melee") @@ -74,26 +119,60 @@ D.forcesay(GLOB.hit_appends) else if(D.lying) D.forcesay(GLOB.hit_appends) - return 1 + return TRUE -/datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0) - if(help_verb) - H.verbs += help_verb +/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE) + if(!H.mind) + return + if(has_explaination_verb) + H.verbs |= /mob/living/carbon/human/proc/martial_arts_help if(make_temporary) - temporary = 1 + temporary = TRUE if(temporary) - if(H.martial_art) - base = H.martial_art.base + if(H.mind.martial_art) + base = H.mind.martial_art.base else base = src - H.martial_art = src + H.mind.martial_art = src /datum/martial_art/proc/remove(var/mob/living/carbon/human/H) - if(H.martial_art != src) + if(!H.mind) return - H.martial_art = base - if(help_verb) - H.verbs -= help_verb + if(H.mind.martial_art != src) + return + H.mind.martial_art = base + if(has_explaination_verb && !(base && base.has_explaination_verb)) + H.verbs -= /mob/living/carbon/human/proc/martial_arts_help + +/mob/living/carbon/human/proc/martial_arts_help() + set name = "Show Info" + set desc = "Gives information about the martial arts you know." + set category = "Martial Arts" + var/mob/living/carbon/human/H = usr + if(!istype(H)) + to_chat(usr, "You shouldn't have access to this verb. Report this as a bug to the github please.") + return + H.mind.martial_art.give_explaination(H) + +/datum/martial_art/proc/give_explaination(user = usr) + explaination_header(user) + explaination_combos(user) + explaination_footer(user) + +// Put after the header and before the footer in the explaination text +/datum/martial_art/proc/explaination_combos(user) + if(HAS_COMBOS) + for(var/combo_type in combos) + var/datum/martial_combo/MC = new combo_type() + MC.give_explaination(user) + +// Put on top of the explaination text +/datum/martial_art/proc/explaination_header(user) + return + +// Put below the combos in the explaination text +/datum/martial_art/proc/explaination_footer(user) + return //ITEMS @@ -283,3 +362,6 @@ if(wielded) return ..() return 0 + +#undef HAS_COMBOS +#undef COMBO_ALIVE_TIME diff --git a/code/modules/martial_arts/mimejutsu.dm b/code/modules/martial_arts/mimejutsu.dm index 38904d407de..d57df486638 100644 --- a/code/modules/martial_arts/mimejutsu.dm +++ b/code/modules/martial_arts/mimejutsu.dm @@ -1,90 +1,16 @@ -#define MIMECHUCKS_COMBO "DH" -#define MIMESMOKE_COMBO "DD" -#define MIMEPALM_COMBO "GD" - /datum/martial_art/mimejutsu name = "Mimejutsu" - help_verb = /mob/living/carbon/human/proc/mimejutsu_help - -/datum/martial_art/mimejutsu/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,MIMECHUCKS_COMBO)) - streak = "" - mimeChuck(A,D) - return 1 - if(findtext(streak,MIMESMOKE_COMBO)) - streak = "" - mimeSmoke(A,D) - return 1 - if(findtext(streak,MIMEPALM_COMBO)) - streak = "" - mimePalm(A,D) - return 1 - return 0 - -/datum/martial_art/mimejutsu/proc/mimeChuck(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.IsWeakened()) - var/damage = rand(5, 8) + A.dna.species.punchdamagelow - if(!damage) - playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - D.visible_message("[A] swings invisible nunchcuks at [D]..and misses?") - return 0 - - - var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") - - D.visible_message("[A] has hit [D] with invisible nunchucks!", \ - "[A] has hit [D] with a with invisible nunchuck!") - playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - D.apply_damage(damage, STAMINA, affecting, armor_block) - add_attack_logs(A, D, "Melee attacked with [src] (mimechuck)") - - return 1 - return basic_hit(A,D) - -/datum/martial_art/mimejutsu/proc/mimeSmoke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - - D.visible_message("[A] throws an invisible smoke bomb!!") - - var/datum/effect_system/smoke_spread/bad/smoke = new - smoke.set_up(5, 0, D.loc) - smoke.start() - - return basic_hit(A,D) - -/datum/martial_art/mimejutsu/proc/mimePalm(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.IsWeakened()) - D.visible_message("[A] has barely touched [D] with [A.p_their()] palm!", \ - "[A] hovers [A.p_their()] palm over your face!") - - var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A))) - D.throw_at(throw_target, 200, 4,A) - return basic_hit(A,D) - - -/datum/martial_art/mimejutsu/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 - - return ..() + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/mimejutsu/mimechucks, /datum/martial_combo/mimejutsu/smokebomb, /datum/martial_combo/mimejutsu/silent_palm) /datum/martial_art/mimejutsu/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 - - return 1 + MARTIAL_ARTS_ACT_CHECK + return TRUE /datum/martial_art/mimejutsu/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 - + MARTIAL_ARTS_ACT_CHECK A.do_attack_animation(D) - - return 1 + return TRUE /obj/item/mimejutsu_scroll name = "Mimejutsu 'scroll'" @@ -106,13 +32,5 @@ name = "beret with staple" icon_state = "beret" -/mob/living/carbon/human/proc/mimejutsu_help() - set name = "Recall Ancient Mimeing" - set desc = "Remember the martial techniques of Mimejutsu." - set category = "Mimejutsu" - - to_chat(usr, "You make a invisible box around yourself and recall the teachings of Mimejutsu...") - - to_chat(usr, "Mimechucks: Disarm Harm. Hits the opponent with invisible nunchucks.") - to_chat(usr, "Smokebomb: Disarm Disarm. Drops a mime smokebomb.") - to_chat(usr, "Silent Palm: Grab Disarm. Using mime energy throw someone back.") +/datum/martial_art/mimejutsu/explaination_header(user) + to_chat(user, "You make a invisible box around yourself and recall the teachings of Mimejutsu...") diff --git a/code/modules/martial_arts/plasma_fist.dm b/code/modules/martial_arts/plasma_fist.dm index ea5aef5ea74..a216a5d730f 100644 --- a/code/modules/martial_arts/plasma_fist.dm +++ b/code/modules/martial_arts/plasma_fist.dm @@ -1,86 +1,22 @@ -#define TORNADO_COMBO "HHD" -#define THROWBACK_COMBO "DHD" -#define PLASMA_COMBO "HDDDH" - /datum/martial_art/plasma_fist name = "Plasma Fist" - help_verb = /mob/living/carbon/human/proc/plasma_fist_help - - -/datum/martial_art/plasma_fist/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,TORNADO_COMBO)) - streak = "" - Tornado(A,D) - return 1 - if(findtext(streak,THROWBACK_COMBO)) - streak = "" - Throwback(A,D) - return 1 - if(findtext(streak,PLASMA_COMBO)) - streak = "" - Plasma(A,D) - return 1 - return 0 - -/datum/martial_art/plasma_fist/proc/Tornado(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.say("TORNADO SWEEP!") - spawn(0) - for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) - A.dir = i - playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) - sleep(1) - var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null) - var/list/turfs = list() - for(var/turf/T in range(1,A)) - turfs.Add(T) - R.cast(turfs) - return - -/datum/martial_art/plasma_fist/proc/Throwback(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - D.visible_message("[A] has hit [D] with Plasma Punch!", \ - "[A] has hit [D] with Plasma Punch!") - playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) - var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A))) - D.throw_at(throw_target, 200, 4,A) - A.say("HYAH!") - return - -/datum/martial_art/plasma_fist/proc/Plasma(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) - A.say("PLASMA FIST!") - D.visible_message("[A] has hit [D] with THE PLASMA FIST TECHNIQUE!", \ - "[A] has hit [D] with THE PLASMA FIST TECHNIQUE!") - D.gib() - return + combos = list(/datum/martial_combo/plasma_fist/tornado_sweep, /datum/martial_combo/plasma_fist/throwback, /datum/martial_combo/plasma_fist/plasma_fist) + has_explaination_verb = TRUE /datum/martial_art/plasma_fist/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK basic_hit(A,D) - return 1 + return TRUE /datum/martial_art/plasma_fist/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK basic_hit(A,D) - return 1 + return TRUE /datum/martial_art/plasma_fist/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK basic_hit(A,D) - return 1 + return TRUE -/mob/living/carbon/human/proc/plasma_fist_help() - set name = "Recall Teachings" - set desc = "Remember the martial techniques of the Plasma Fist." - set category = "Plasma Fist" - - to_chat(usr, "You clench your fists and have a flashback of knowledge...") - to_chat(usr, "Tornado Sweep: Harm Harm Disarm. Repulses target and everyone back.") - to_chat(usr, "Throwback: Disarm Harm Disarm. Throws the target and an item at them.") - to_chat(usr, "The Plasma Fist: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body.") +/datum/martial_art/plasma_fist/explaination_header(user) + to_chat(user, "You clench your fists and have a flashback of knowledge...") diff --git a/code/modules/martial_arts/sleeping_carp.dm b/code/modules/martial_arts/sleeping_carp.dm index 472fb6ca506..9ca070f8bfd 100644 --- a/code/modules/martial_arts/sleeping_carp.dm +++ b/code/modules/martial_arts/sleeping_carp.dm @@ -1,126 +1,21 @@ //Used by the gang of the same name. Uses combos. Basic attacks bypass armor and never miss -#define WRIST_WRENCH_COMBO "DD" -#define BACK_KICK_COMBO "HG" -#define STOMACH_KNEE_COMBO "GH" -#define HEAD_KICK_COMBO "DHH" -#define ELBOW_DROP_COMBO "HDHDH" /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" deflection_chance = 100 - help_verb = /mob/living/carbon/human/proc/sleeping_carp_help no_guns = TRUE no_guns_message = "Use of ranged weaponry would bring dishonor to the clan." - -/datum/martial_art/the_sleeping_carp/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,WRIST_WRENCH_COMBO)) - streak = "" - wristWrench(A,D) - return 1 - if(findtext(streak,BACK_KICK_COMBO)) - streak = "" - backKick(A,D) - return 1 - if(findtext(streak,STOMACH_KNEE_COMBO)) - streak = "" - kneeStomach(A,D) - return 1 - if(findtext(streak,HEAD_KICK_COMBO)) - streak = "" - headKick(A,D) - return 1 - if(findtext(streak,ELBOW_DROP_COMBO)) - streak = "" - elbowDrop(A,D) - return 1 - return 0 - -/datum/martial_art/the_sleeping_carp/proc/wristWrench(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - D.visible_message("[A] grabs [D]'s wrist and wrenches it sideways!", \ - "[A] grabs your wrist and violently wrenches it to the side!") - playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Wrist Wrench", ATKLOG_ALL) - if(prob(60)) - A.say(pick("WRISTY TWIRLY!", "WE FIGHT LIKE MEN!", "YOU DISHONOR YOURSELF!", "POHYAH!", "WHERE IS YOUR BATON NOW?", "SAY UNCLE!")) - D.emote("scream") - D.drop_item() - D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) - D.Stun(3) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/backKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(A.dir == D.dir && !D.stat && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_KICK) - D.visible_message("[A] kicks [D] in the back!", \ - "[A] kicks you in the back, making you stumble and fall!") - step_to(D,get_step(D,D.dir),1) - D.Weaken(4) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Back Kick", ATKLOG_ALL) - if(prob(80)) - A.say(pick("SURRPRIZU!","BACK STRIKE!","WOPAH!", "WATAAH", "ZOTA!", "Never turn your back to the enemy!")) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/kneeStomach(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_KICK) - D.visible_message("[A] knees [D] in the stomach!", \ - "[A] winds you with a knee in the stomach!") - D.audible_message("[D] gags!") - D.AdjustLoseBreath(3) - D.Stun(2) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Stomach Knee", ATKLOG_ALL) - if(prob(80)) - A.say(pick("HWOP!", "KUH!", "YAKUUH!", "KYUH!", "KNEESTRIKE!")) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/headKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_KICK) - D.visible_message("[A] kicks [D] in the head!", \ - "[A] kicks you in the jaw!") - D.apply_damage(20, BRUTE, "head") - D.drop_item() - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Head Kick", ATKLOG_ALL) - if(prob(60)) - A.say(pick("OOHYOO!", "OOPYAH!", "HYOOAA!", "WOOAAA!", "SHURYUKICK!", "HIYAH!")) - D.Stun(4) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/elbowDrop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.IsWeakened() || D.resting || D.stat) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - D.visible_message("[A] elbow drops [D]!", \ - "[A] piledrives you with [A.p_their()] elbow!") - if(D.stat) - D.death() //FINISH HIM! - D.apply_damage(50, BRUTE, "chest") - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Elbow Drop", ATKLOG_ALL) - if(prob(80)) - A.say(pick("BANZAIII!", "KIYAAAA!", "OMAE WA MOU SHINDEIRU!", "YOU CAN'T SEE ME!", "MY TIME IS NOW!", "COWABUNGA")) - return 1 - return basic_hit(A,D) + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/sleeping_carp/wrist_wrench, /datum/martial_combo/sleeping_carp/back_kick, /datum/martial_combo/sleeping_carp/stomach_knee, /datum/martial_combo/sleeping_carp/head_kick, /datum/martial_combo/sleeping_carp/elbow_drop) /datum/martial_art/the_sleeping_carp/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = D.grabbedby(A,1) if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab + return TRUE /datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") D.visible_message("[A] [atk_verb] [D]!", \ @@ -132,24 +27,7 @@ if(prob(D.getBruteLoss()) && !D.lying) D.visible_message("[D] stumbles and falls!", "The blow sends you to the ground!") D.Weaken(4) - return 1 - - -/datum/martial_art/the_sleeping_carp/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 - return ..() - -/mob/living/carbon/human/proc/sleeping_carp_help() - set name = "Recall Teachings" - set desc = "Remember the martial techniques of the Sleeping Carp clan." - set category = "Sleeping Carp" + return TRUE +/datum/martial_art/the_sleeping_carp/explaination_header(user) to_chat(usr, "You retreat inward and recall the teachings of the Sleeping Carp...") - - to_chat(usr, "Wrist Wrench: Disarm Disarm. Forces opponent to drop item in hand.") - to_chat(usr, "Back Kick: Harm Grab. Opponent must be facing away. Knocks down.") - to_chat(usr, "Stomach Knee: Grab Harm. Knocks the wind out of opponent and stuns.") - to_chat(usr, "Head Kick: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand.") - to_chat(usr, "Elbow Drop: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition.") diff --git a/code/modules/martial_arts/wrestleing.dm b/code/modules/martial_arts/wrestling.dm similarity index 100% rename from code/modules/martial_arts/wrestleing.dm rename to code/modules/martial_arts/wrestling.dm diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 058b64d3c18..fd2171335ef 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -342,7 +342,7 @@ /obj/item/card/id/mining_access_card name = "mining access card" desc = "A small card, that when used on any ID, will add mining access." - icon_state = "data_1" + icon_state = "data" /obj/item/card/id/mining_access_card/afterattack(atom/movable/AM, mob/user, proximity) . = ..() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 31ff0098335..ef5268fa104 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -780,4 +780,4 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set category = "Ghost" var/datum/spawners_menu/menu = new /datum/spawners_menu(src) - menu.ui_interact(src) + menu.tgui_interact(src) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index b69c13987b9..2fefc6b7c74 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -592,7 +592,7 @@ message = "[src] sighs[M ? " at [M]" : ""]." m_type = 2 else - message = "[src] makes a weak noise" + message = "[src] makes a weak noise." m_type = 2 if("hsigh", "hsighs") @@ -600,7 +600,7 @@ message = "[src] sighs contentedly." m_type = 2 else - message = "[src] makes a [pick("chill", "relaxed")] noise" + message = "[src] makes a [pick("chill", "relaxed")] noise." m_type = 2 if("laugh", "laughs") diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index d495ca3d2f4..4cb846139f7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -29,8 +29,6 @@ create_reagents(330) - martial_art = GLOB.default_martial_art - handcrafting = new() // Set up DNA. @@ -298,8 +296,8 @@ apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) /mob/living/carbon/human/bullet_act() - if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles! - if(!prob(martial_art.deflection_chance)) + if(mind && mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles! + if(!prob(mind.martial_art.deflection_chance)) return ..() if(!src.lying && !(HULK in mutations)) //But only if they're not lying down, and hulks can't do it visible_message("[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!", "You deflect the projectile!") @@ -1731,16 +1729,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(G.trigger_guard == TRIGGER_GUARD_NORMAL) if(HULK in mutations) to_chat(src, "Your meaty finger is much too large for the trigger guard!") - return 0 + return FALSE if(NOGUNS in dna.species.species_traits) to_chat(src, "Your fingers don't fit in the trigger guard!") - return 0 + return FALSE - if(martial_art && martial_art.no_guns) //great dishonor to famiry - to_chat(src, "[martial_art.no_guns_message]") - return 0 - - return . + if(mind && mind.martial_art && mind.martial_art.no_guns) //great dishonor to famiry + to_chat(src, "[mind.martial_art.no_guns_message]") + return FALSE /mob/living/carbon/human/proc/change_icobase(var/new_icobase, var/new_deform, var/owner_sensitive) for(var/obj/item/organ/external/O in bodyparts) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c7798a51a08..cf61162733e 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -13,13 +13,20 @@ emp_act if(!dna.species.bullet_act(P, src)) return FALSE if(P.is_reflectable) - if(check_reflect(def_zone)) // Checks if you've passed a reflection% check - visible_message("The [P.name] gets reflected by [src]!", \ - "The [P.name] gets reflected by [src]!") + var/can_reflect = check_reflect(def_zone) + if(!can_reflect) + return (..(P , def_zone)) //Bad luck + else + if(can_reflect == 2) //If target is holding a toy sword + var/list/safe_list = list(/obj/item/projectile/beam/lasertag, /obj/item/projectile/beam/practice) + if(!is_type_in_list(P, safe_list)) //And it's not safe + return (..(P , def_zone)) //Bad luck + visible_message("The [P.name] gets reflected by [src]!", \ + "The [P.name] gets reflected by [src]!") - P.reflect_back(src) + P.reflect_back(src) - return -1 // complete projectile permutation + return -1 // complete projectile permutation //Shields if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration)) @@ -172,10 +179,14 @@ emp_act var/obj/item/I = l_hand if(I.IsReflect(def_zone) == 1) return 1 + if(I.IsReflect(def_zone) == 2) //Toy swords + return 2 if(r_hand && istype(r_hand, /obj/item/)) var/obj/item/I = r_hand if(I.IsReflect(def_zone) == 1) return 1 + if(I.IsReflect(def_zone) == 2) //Toy swords + return 2 return 0 @@ -203,7 +214,7 @@ emp_act return 0 /mob/living/carbon/human/proc/check_block() - if(martial_art && prob(martial_art.block_chance) && martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE)) + if(mind && mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE)) return TRUE /mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 3d365afa940..bc5c85e2929 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,4 +1,3 @@ -GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new()) /mob/living/carbon/human hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD) @@ -42,8 +41,6 @@ GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new()) var/datum/personal_crafting/handcrafting - var/datum/martial_art/martial_art = null - var/special_voice = "" // For changing our voice. Used by a symptom. var/hand_blood_color diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 15dfe74880e..c9cd99ad2d0 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -66,9 +66,7 @@ if(!is_station_level(T.z)) return var/area/A = get_area(src) - if(cryo_ssd(src)) - var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40) - P.name = "NT SSD Teleportation Portal" + cryo_ssd(src) if(A.fast_despawn) force_cryo_human(src) @@ -698,13 +696,14 @@ if(alcohol_strength >= slur_start) //slurring Slur(drunk) - if(alcohol_strength >= brawl_start) //the drunken martial art - if(!istype(martial_art, /datum/martial_art/drunk_brawling)) - var/datum/martial_art/drunk_brawling/F = new - F.teach(src, 1) - if(alcohol_strength < brawl_start) //removing the art - if(istype(martial_art, /datum/martial_art/drunk_brawling)) - martial_art.remove(src) + if(mind) + if(alcohol_strength >= brawl_start) //the drunken martial art + if(!istype(mind.martial_art, /datum/martial_art/drunk_brawling)) + var/datum/martial_art/drunk_brawling/F = new + F.teach(src, TRUE) + else if(alcohol_strength < brawl_start) //removing the art + if(istype(mind.martial_art, /datum/martial_art/drunk_brawling)) + mind.martial_art.remove(src) if(alcohol_strength >= confused_start && prob(33)) //confused walking if(!confused) Confused(1) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index a8e1eee5f52..69518e96cf7 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -371,7 +371,7 @@ return /datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) - if(attacker_style && attacker_style.help_act(user, target))//adminfu only... + if(attacker_style && attacker_style.help_act(user, target) == TRUE)//adminfu only... return TRUE if(target.health >= HEALTH_THRESHOLD_CRIT && !(target.status_flags & FAKEDEATH)) target.help_shake_act(user) @@ -383,7 +383,7 @@ if(target.check_block()) target.visible_message("[target] blocks [user]'s grab attempt!") return FALSE - if(attacker_style && attacker_style.grab_act(user, target)) + if(attacker_style && attacker_style.grab_act(user, target) == TRUE) return TRUE else target.grabbedby(user) @@ -412,7 +412,7 @@ if(target.check_block()) target.visible_message("[target] blocks [user]'s attack!") return FALSE - if(attacker_style && attacker_style.harm_act(user, target)) + if(attacker_style && attacker_style.harm_act(user, target) == TRUE) return TRUE else var/datum/unarmed_attack/attack = user.dna.species.unarmed @@ -460,7 +460,7 @@ if(target.check_block()) target.visible_message("[target] blocks [user]'s disarm attempt!") return FALSE - if(attacker_style && attacker_style.disarm_act(user, target)) + if(attacker_style && attacker_style.disarm_act(user, target) == TRUE) return TRUE else add_attack_logs(user, target, "Disarmed", ATKLOG_ALL) @@ -516,7 +516,7 @@ playsound(target.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) target.visible_message("[user] attempted to disarm [target]!") -/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) //Handles any species-specific attackhand events. +/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) //Handles any species-specific attackhand events. if(!istype(M)) return @@ -528,6 +528,9 @@ to_chat(M, "You can't use your hand.") return + if(M.mind) + attacker_style = M.mind.martial_art + if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) add_attack_logs(M, H, "Melee attacked with fists (miss/block)") H.visible_message("[M] attempted to touch [H]!") diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index 74cf0bd37a7..32a562b212c 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -10,7 +10,7 @@ var/list/default_genes = list(REGEN, BREATHLESS, COLDRES) var/list/default_spells = list() var/activated = FALSE //for wishgranters to not give an option if someone already has it. - + /datum/superheroes/proc/create(var/mob/living/carbon/human/H) assign_genes(H) assign_spells(H) @@ -84,7 +84,7 @@ /datum/superheroes/griffin name = "The Griffin" - default_spells = list(/obj/effect/proc_holder/spell/targeted/recruit) + default_spells = list(/obj/effect/proc_holder/spell/targeted/click/recruit) class = "Supervillain" desc = "You are The Griffin, the ultimate supervillain. You thrive on chaos and have no respect for the supposed authority \ of the command staff of this station. Along with your gang of dim-witted yet trusty henchmen, you will be able to execute \ @@ -145,100 +145,102 @@ //The Griffin's special recruit abilitiy -/obj/effect/proc_holder/spell/targeted/recruit +/obj/effect/proc_holder/spell/targeted/click/recruit name = "Recruit Greyshirt" desc = "Allows you to recruit a conscious, non-braindead, non-catatonic human to be part of the Greyshirts, your personal henchmen. This works on Civilians only and you can recruit a maximum of 3!." charge_max = 450 - clothes_req = 0 + clothes_req = FALSE range = 1 //Adjacent to user action_icon_state = "spell_greytide" var/recruiting = 0 -/obj/effect/proc_holder/spell/targeted/recruit/cast(list/targets,mob/living/user = usr) - for(var/mob/living/carbon/human/target in targets) - var/obj/item/organ/external/head/head_organ = target.get_organ("head") - if(SSticker.mode.greyshirts.len >= 3) + click_radius = -1 + selection_activated_message = "You start preparing a mindblowing monologue. Left-click to cast at a target!" + selection_deactivated_message = "You decide to save your brilliance for another day." + allowed_type = /mob/living/carbon/human + +/obj/effect/proc_holder/spell/targeted/click/recruit/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) + if(SSticker.mode.greyshirts.len >= 3) + if(show_message) to_chat(user, "You have already recruited the maximum number of henchmen.") - if(!in_range(user, target)) - to_chat(user, "You need to be closer to enthrall [target].") - charge_counter = charge_max - return - if(!target.ckey) - to_chat(user, "The target has no mind.") - charge_counter = charge_max - return - if(target.stat) - to_chat(user, "The target must be conscious.") - charge_counter = charge_max - return - if(!ishuman(target)) - to_chat(user, "You can only recruit humans.") - charge_counter = charge_max - return - if(target.mind.assigned_role != "Civilian") - to_chat(user, "You can only recruit Civilians.") - return - if(recruiting) + return FALSE + if(recruiting) + if(show_message) to_chat(user, "You are already recruiting!") - charge_counter = charge_max + return FALSE + return ..() + +/obj/effect/proc_holder/spell/targeted/click/recruit/valid_target(mob/living/carbon/human/target, user) + if(!..()) + return FALSE + + return target.ckey && !target.stat + +/obj/effect/proc_holder/spell/targeted/click/recruit/cast(list/targets,mob/living/user = usr) + var/mob/living/carbon/human/target = targets[1] + if(target.mind.assigned_role != "Civilian") + to_chat(user, "You can only recruit Civilians.") + revert_cast(user) + return + recruiting = TRUE + to_chat(user, "This target is valid. You begin the recruiting process.") + to_chat(target, "[user] focuses in concentration. Your head begins to ache.") + + for(var/progress = 0, progress <= 3, progress++) + switch(progress) + if(1) + to_chat(user, "You begin by introducing yourself and explaining what you're about.") + user.visible_message("[user] introduces [user.p_them()]self and explains [user.p_their()] plans.") + if(2) + to_chat(user, "You begin the recruitment of [target].") + user.visible_message("[user] leans over towards [target], whispering excitedly as [user.p_they()] give[user.p_s()] a speech.") + to_chat(target, "You feel yourself agreeing with [user], and a surge of loyalty begins building.") + target.Weaken(12) + sleep(20) + if(ismindshielded(target)) + to_chat(user, "[target.p_they(TRUE)] are enslaved by Nanotrasen. You feel [target.p_their()] interest in your cause wane and disappear.") + user.visible_message("[user] stops talking for a moment, then moves back away from [target].") + to_chat(target, "Your mindshield implant activates, protecting you from conversion.") + return + if(3) + to_chat(user, "You begin filling out the application form with [target].") + user.visible_message("[user] pulls out a pen and paper and begins filling an application form with [target].") + to_chat(target, "You are being convinced by [user] to fill out an application form to become a henchman.")//Ow the edge + + if(!do_mob(user, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a mindshield implant + to_chat(user, "The enrollment process has been interrupted - you have lost the attention of [target].") + to_chat(target, "You move away and are no longer under the charm of [user]. The application form is null and void.") + recruiting = FALSE return - recruiting = 1 - to_chat(user, "This target is valid. You begin the recruiting process.") - to_chat(target, "[user] focuses in concentration. Your head begins to ache.") - for(var/progress = 0, progress <= 3, progress++) - switch(progress) - if(1) - to_chat(user, "You begin by introducing yourself and explaining what you're about.") - user.visible_message("[user] introduces [user.p_them()]self and explains [user.p_their()] plans.") - if(2) - to_chat(user, "You begin the recruitment of [target].") - user.visible_message("[user] leans over towards [target], whispering excitedly as [user.p_they()] give[user.p_s()] a speech.") - to_chat(target, "You feel yourself agreeing with [user], and a surge of loyalty begins building.") - target.Weaken(12) - sleep(20) - if(ismindshielded(target)) - to_chat(user, "[target.p_they(TRUE)] are enslaved by Nanotrasen. You feel [target.p_their()] interest in your cause wane and disappear.") - user.visible_message("[user] stops talking for a moment, then moves back away from [target].") - to_chat(target, "Your mindshield implant activates, protecting you from conversion.") - return - if(3) - to_chat(user, "You begin filling out the application form with [target].") - user.visible_message("[user] pulls out a pen and paper and begins filling an application form with [target].") - to_chat(target, "You are being convinced by [user] to fill out an application form to become a henchman.")//Ow the edge - - if(!do_mob(user, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a mindshield implant - to_chat(user, "The enrollment process has been interrupted - you have lost the attention of [target].") - to_chat(target, "You move away and are no longer under the charm of [user]. The application form is null and void.") - recruiting = 0 - return - - recruiting = 0 - to_chat(user, "You have recruited [target] as your henchman!") - to_chat(target, "You have decided to enroll as a henchman for [user]. You are now part of the feared 'Greyshirts'.") - to_chat(target, "You must follow the orders of [user], and help [user.p_them()] succeed in [user.p_their()] dastardly schemes.") - to_chat(target, "You may not harm other Greyshirt or [user]. However, you do not need to obey other Greyshirts.") - SSticker.mode.greyshirts += target.mind - target.set_species(/datum/species/human) + recruiting = FALSE + to_chat(user, "You have recruited [target] as your henchman!") + to_chat(target, "You have decided to enroll as a henchman for [user]. You are now part of the feared 'Greyshirts'.") + to_chat(target, "You must follow the orders of [user], and help [user.p_them()] succeed in [user.p_their()] dastardly schemes.") + to_chat(target, "You may not harm other Greyshirt or [user]. However, you do not need to obey other Greyshirts.") + SSticker.mode.greyshirts += target.mind + target.set_species(/datum/species/human) + var/obj/item/organ/external/head/head_organ = target.get_organ("head") + if(head_organ) head_organ.h_style = "Bald" head_organ.f_style = "Shaved" - target.s_tone = 35 - // No `update_dna=0` here because the character is being over-written - target.change_eye_color(1,1,1) - for(var/obj/item/W in target.get_all_slots()) - target.unEquip(W) - target.rename_character(target.real_name, "Generic Henchman ([rand(1, 1000)])") - target.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey/greytide(target), slot_w_uniform) - target.equip_to_slot_or_del(new /obj/item/clothing/shoes/black/greytide(target), slot_shoes) - target.equip_to_slot_or_del(new /obj/item/storage/toolbox/mechanical/greytide(target), slot_l_hand) - target.equip_to_slot_or_del(new /obj/item/radio/headset(target), slot_l_ear) - var/obj/item/card/id/syndicate/W = new(target) - W.icon_state = "lifetimeid" - W.access = list(ACCESS_MAINT_TUNNELS) - W.assignment = "Greyshirt" - W.rank = "Greyshirt" - W.flags |= NODROP - W.SetOwnerInfo(target) - W.UpdateName() - target.equip_to_slot_or_del(W, slot_wear_id) - target.regenerate_icons() + target.s_tone = 35 + // No `update_dna=0` here because the character is being over-written + target.change_eye_color(1,1,1) + for(var/obj/item/W in target.get_all_slots()) + target.unEquip(W) + target.rename_character(target.real_name, "Generic Henchman ([rand(1, 1000)])") + target.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey/greytide(target), slot_w_uniform) + target.equip_to_slot_or_del(new /obj/item/clothing/shoes/black/greytide(target), slot_shoes) + target.equip_to_slot_or_del(new /obj/item/storage/toolbox/mechanical/greytide(target), slot_l_hand) + target.equip_to_slot_or_del(new /obj/item/radio/headset(target), slot_l_ear) + var/obj/item/card/id/syndicate/W = new(target) + W.icon_state = "lifetimeid" + W.access = list(ACCESS_MAINT_TUNNELS) + W.assignment = "Greyshirt" + W.rank = "Greyshirt" + W.flags |= NODROP + W.SetOwnerInfo(target) + W.UpdateName() + target.equip_to_slot_or_del(W, slot_wear_id) + target.regenerate_icons() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9e9724d20ec..883b781c43c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -927,6 +927,8 @@ . += T.slowdown if(slowed) . += 10 + if(forced_look) + . += 3 if(ignorewalk) . += config.run_speed else diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 4da8aa97e06..9ecda42de04 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -186,6 +186,8 @@ return 1 if(fire_stacks > 0) adjust_fire_stacks(-0.1) //the fire is slowly consumed + for(var/obj/item/clothing/C in contents) + C.catch_fire() else ExtinguishMob() return diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index e944e692887..f9d6fc436cf 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -38,7 +38,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( GLOBAL_LIST_EMPTY(channel_to_radio_key) -proc/get_radio_key_from_channel(var/channel) +/proc/get_radio_key_from_channel(var/channel) var/key = GLOB.channel_to_radio_key[channel] if(!key) for(var/radio_key in GLOB.department_radio_keys) diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 52d58ad659d..6cb0cc53bd0 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -243,7 +243,7 @@ add_fingerprint(user) -proc/robot_healthscan(mob/user, mob/living/M) +/proc/robot_healthscan(mob/user, mob/living/M) var/scan_type if(istype(M, /mob/living/silicon/robot)) scan_type = "robot" diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 270606361cb..a8485853be1 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -35,7 +35,6 @@ var/mail_destination = 0 var/reboot_cooldown = 60 // one minute var/last_reboot - var/emagged_time var/list/pullable_drone_items = list( /obj/item/pipe, /obj/structure/disposalconstruct, @@ -127,6 +126,11 @@ /mob/living/silicon/robot/drone/pick_module() return +/mob/living/silicon/robot/drone/can_be_revived() + . = ..() + if(emagged) + return FALSE + //Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..(). /mob/living/silicon/robot/drone/attackby(obj/item/W as obj, mob/user as mob, params) @@ -208,8 +212,8 @@ log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.") var/time = time2text(world.realtime,"hh:mm:ss") GLOB.lawchanges.Add("[time] : [H.name]([H.key]) emagged [name]([key])") + addtimer(CALLBACK(src, .proc/shut_down, TRUE), EMAG_TIMER) - emagged_time = world.time emagged = 1 density = 1 pass_flags = 0 @@ -361,12 +365,7 @@ /mob/living/silicon/robot/drone/update_canmove(delay_action_updates = 0) . = ..() - if(emagged) - density = 1 - if(world.time - emagged_time > EMAG_TIMER) - shut_down(TRUE) - return - density = 0 //this is reset every canmove update otherwise + density = emagged //this is reset every canmove update otherwise /mob/living/simple_animal/drone/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0) if(affect_silicon) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index ee9cec18c89..8f34314f717 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -83,6 +83,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( var/lockcharge //Used when locking down a borg to preserve cell charge var/speed = 0 //Cause sec borgs gotta go fast //No they dont! var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. + var/can_lock_cover = FALSE //Used to set if a borg can re-lock its cover. var/has_camera = TRUE var/pdahide = 0 //Used to hide the borg from the messenger list var/tracking_entities = 0 //The number of known entities currently accessing the internal camera @@ -752,6 +753,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if(allowed(W)) locked = !locked to_chat(user, "You [ locked ? "lock" : "unlock"] [src]'s interface.") + to_chat(src, "[user] [ locked ? "locked" : "unlocked"] your interface.") update_icons() else to_chat(user, "Access denied.") @@ -768,7 +770,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if(!user.drop_item()) return if(U.action(src)) - to_chat(user, "You apply the upgrade to [src].") + user.visible_message("[user] applied [U] to [src].", "You apply [U] to [src].") U.forceMove(src) else to_chat(user, "Upgrade error.") @@ -964,16 +966,24 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( update_icons() return -/mob/living/silicon/robot/verb/unlock_own_cover() +/mob/living/silicon/robot/verb/toggle_own_cover() set category = "Robot Commands" - set name = "Unlock Cover" - set desc = "Unlocks your own cover if it is locked. You can not lock it again. A human will have to lock it for you." - if(locked) - switch(alert("You can not lock your cover again, are you sure?\n (You can still ask for a human to lock it)", "Unlock Own Cover", "Yes", "No")) - if("Yes") - locked = 0 - update_icons() - to_chat(usr, "You unlock your cover.") + set name = "Toggle Cover" + set desc = "Toggles the lock on your cover." + + if(can_lock_cover) + if(alert("Are you sure?", locked ? "Unlock Cover" : "Lock Cover", "Yes", "No") == "Yes") + locked = !locked + update_icons() + to_chat(usr, "You [locked ? "lock" : "unlock"] your cover.") + return + if(!locked) + to_chat(usr, "You cannot lock your cover yourself. Find a robotocist.") + return + if(alert("You cannnot lock your own cover again. Are you sure?\n You will need a robotocist to re-lock you.", "Unlock Own Cover", "Yes", "No") == "Yes") + locked = !locked + update_icons() + to_chat(usr, "You unlock your cover.") /mob/living/silicon/robot/attack_ghost(mob/user) if(wiresexposed) @@ -1403,6 +1413,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( modtype = "Commando" faction = list("nanotrasen") is_emaggable = FALSE + can_lock_cover = TRUE default_cell_type = /obj/item/stock_parts/cell/bluespace /mob/living/silicon/robot/deathsquad/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null) @@ -1431,6 +1442,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( static_radio_channels = 1 allow_rename = FALSE weapons_unlock = TRUE + can_lock_cover = TRUE default_cell_type = /obj/item/stock_parts/cell/super var/eprefix = "Amber" @@ -1487,6 +1499,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( ear_protection = 1 // Immunity to the audio part of flashbangs emp_protection = TRUE // Immunity to EMP, due to heavy shielding damage_protection = 20 // Reduce all incoming damage by this number. Very high in the case of /destroyer borgs, since it is an admin-only borg. + can_lock_cover = TRUE default_cell_type = /obj/item/stock_parts/cell/bluespace /mob/living/silicon/robot/destroyer/init(alien = FALSE, connect_to_AI = TRUE, mob/living/silicon/ai/ai_to_sync_to = null) diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm index f5b58696059..cfc6e1bd59d 100644 --- a/code/modules/mob/living/silicon/robot/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -11,6 +11,7 @@ modtype = "Syndicate" req_access = list(ACCESS_SYNDICATE) ionpulse = 1 + can_lock_cover = TRUE lawchannel = "State" var/playstyle_string = "You are a Syndicate assault cyborg!
\ You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 07a21af8a0b..915bf9ae2aa 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -9,7 +9,7 @@ response_disarm = "bops" response_harm = "kicks" speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") - speak_emote = list("barks", "woofs") + speak_emote = list("barks.", "woofs.") emote_hear = list("barks!", "woofs!", "yaps.","pants.") emote_see = list("shakes its head.", "chases its tail.","shivers.") faction = list("neutral") diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index c6f3ac845e3..2b9358214b1 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -71,9 +71,6 @@ var/spawn_delay = 600 var/turn_on = 0 var/auto_spawn = 1 - proc - warpbots() - /mob/living/simple_animal/hostile/hivebot/tele/New() ..() @@ -83,7 +80,7 @@ visible_message("The [src] warps in!") playsound(src.loc, 'sound/effects/empulse.ogg', 25, 1) -/mob/living/simple_animal/hostile/hivebot/tele/warpbots() +/mob/living/simple_animal/hostile/hivebot/tele/proc/warpbots() icon_state = "def_radar" visible_message("The [src] turns on!") while(bot_amt > 0) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 2f97001d3ae..dd0316f4177 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -122,8 +122,8 @@ Difficulty: Very Hard /mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L) if(ishuman(L)) var/mob/living/carbon/human/H = L - if(H.martial_art && prob(H.martial_art.deflection_chance)) - . = TRUE + if(H.mind && H.mind.martial_art && prob(H.mind.martial_art.deflection_chance)) + return TRUE /mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots() ranged_cooldown = world.time + 40 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 50531f976e9..14d2e933605 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -524,7 +524,7 @@ Difficulty: Medium else animate(src, pixel_x = -16, pixel_z = 0, time = 5) -obj/effect/temp_visual/fireball +/obj/effect/temp_visual/fireball icon = 'icons/obj/wizard.dmi' icon_state = "fireball" name = "fireball" diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index bd3314d1453..b6189d56eac 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -1,6 +1,6 @@ //malfunctioning combat drones -/mob/living/simple_animal/hostile/retaliate/malf_drone +/mob/living/simple_animal/hostile/malf_drone name = "combat drone" desc = "An automated combat drone armed with state of the art weaponry and shielding." icon_state = "drone3" @@ -8,254 +8,175 @@ icon_dead = "drone_dead" ranged = 1 rapid = 3 + retreat_distance = 3 + minimum_distance = 3 speak_chance = 5 turns_per_move = 3 response_help = "pokes the" response_disarm = "gently pushes aside the" response_harm = "hits the" - speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.") - emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity") + speak = list("ALERT.", "Hostile-ile-ile entities dee-twhoooo-wected.", "Threat parameterszzzz- szzet.", "Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.") + emote_see = list("beeps menacingly.", "whirrs threateningly.", "scans for targets.") a_intent = INTENT_HARM - stop_automated_movement_when_pulled = 0 - health = 300 - maxHealth = 300 + stop_automated_movement_when_pulled = FALSE + health = 200 + maxHealth = 200 speed = 8 - projectiletype = /obj/item/projectile/beam/drone + projectiletype = /obj/item/projectile/beam/immolator/weak projectilesound = 'sound/weapons/laser3.ogg' - var/datum/effect_system/trail_follow/ion/ion_trail - - //the drone randomly switches between these states because it's malfunctioning - var/hostile_drone = 0 - //0 - retaliate, only attack enemies that attack it - //1 - hostile, attack everything that comes near - - var/turf/patrol_target - var/explode_chance = 1 - var/disabled = 0 - var/exploding = 0 - - //Drones aren't affected by atmos. atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - - var/has_loot = 1 faction = list("malf_drone") deathmessage = "suddenly breaks apart." del_on_death = 1 + var/datum/effect_system/trail_follow/ion/ion_trail + var/passive_mode = TRUE // if true, don't target anything. -/mob/living/simple_animal/hostile/retaliate/malf_drone/New() - ..() - if(prob(5)) - projectiletype = /obj/item/projectile/beam/pulse/drone - projectilesound = 'sound/weapons/pulse2.ogg' +/mob/living/simple_animal/hostile/malf_drone/Initialize(mapload) + . = ..() ion_trail = new ion_trail.set_up(src) ion_trail.start() + update_icons() -/mob/living/simple_animal/hostile/retaliate/malf_drone/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_animal/hostile/malf_drone/Process_Spacemove(check_drift = 0) return 1 -/mob/living/simple_animal/hostile/retaliate/malf_drone/ListTargets() - if(hostile_drone) - return view(src, 10) - else - return ..() - -//self repair systems have a chance to bring the drone back to life -/mob/living/simple_animal/hostile/retaliate/malf_drone/Life(seconds, times_fired) - - //emps and lots of damage can temporarily shut us down - if(disabled > 0) - stat = UNCONSCIOUS - icon_state = "drone_dead" - disabled-- - wander = 0 - speak_chance = 0 - if(disabled <= 0) - stat = CONSCIOUS - icon_state = "drone0" - wander = 1 - speak_chance = 5 - - //repair a bit of damage - if(prob(1)) - src.visible_message("[bicon(src)] [src] shudders and shakes as some of it's damaged systems come back online.") - do_sparks(3, 1, src) - health += rand(25,100) - - //spark for no reason - if(prob(5)) - do_sparks(3, 1, src) - - //sometimes our targetting sensors malfunction, and we attack anyone nearby - if(prob(disabled ? 0 : 1)) - if(hostile_drone) - src.visible_message("[bicon(src)] [src] retracts several targetting vanes, and dulls it's running lights.") - hostile_drone = 0 - else - src.visible_message("[bicon(src)] [src] suddenly lights up, and additional targetting vanes slide into place.") - hostile_drone = 1 - - if(health / maxHealth > 0.9) - icon_state = "drone3" - explode_chance = 0 - else if(health / maxHealth > 0.7) - icon_state = "drone2" - explode_chance = 0 - else if(health / maxHealth > 0.5) - icon_state = "drone1" - explode_chance = 0.5 - else if(health / maxHealth > 0.3) - icon_state = "drone0" - explode_chance = 5 - else if(health > 0) - //if health gets too low, shut down - icon_state = "drone_dead" - exploding = 0 - if(!disabled) - if(prob(50)) - src.visible_message("[bicon(src)] [src] suddenly shuts down!") - else - src.visible_message("[bicon(src)] [src] suddenly lies still and quiet.") - disabled = rand(150, 600) - walk(src,0) - - if(exploding && prob(20)) - if(prob(50)) - src.visible_message("[bicon(src)] [src] begins to spark and shake violenty!") - else - src.visible_message("[bicon(src)] [src] sparks and shakes like it's about to explode!") - do_sparks(3, 1, src) - - if(!exploding && !disabled && prob(explode_chance)) - exploding = 1 - stat = UNCONSCIOUS - wander = 1 - walk(src,0) - spawn(rand(50,150)) - if(!disabled && exploding) - explosion(get_turf(src), 0, 1, 4, 7) - //proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1) - ..() - -//ion rifle! -/mob/living/simple_animal/hostile/retaliate/malf_drone/emp_act(severity) - health -= rand(3,15) * (severity + 1) - disabled = rand(150, 600) - hostile_drone = 0 - walk(src,0) - -/mob/living/simple_animal/hostile/retaliate/malf_drone/Destroy() //Seriously, what the actual hell. - //some random debris left behind - if(has_loot) - do_sparks(3, 1, src) - var/obj/O - - //shards - O = new /obj/item/shard(loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(75)) - O = new /obj/item/shard(loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(50)) - O = new /obj/item/shard(loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(25)) - O = new /obj/item/shard(loc) - step_to(O, get_turf(pick(view(7, src)))) - - //rods - O = new /obj/item/stack/rods(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(75)) - O = new /obj/item/stack/rods(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(50)) - O = new /obj/item/stack/rods(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(25)) - O = new /obj/item/stack/rods(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - - //plasteel - O = new /obj/item/stack/sheet/plasteel(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(75)) - O = new /obj/item/stack/sheet/plasteel(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(50)) - O = new /obj/item/stack/sheet/plasteel(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - if(prob(25)) - O = new /obj/item/stack/sheet/plasteel(src.loc) - step_to(O, get_turf(pick(view(7, src)))) - - //also drop dummy circuit boards deconstructable for research (loot) - var/obj/item/circuitboard/C - - //spawn 1-4 boards of a random type - var/spawnees = 0 - var/num_boards = rand(1,4) - var/list/options = list(1,2,4,8,16,32,64,128,256, 512) - for(var/i=0, i 0.9) + icon_state = "drone3" + else if(health / maxHealth > 0.7) + icon_state = "drone2" + else if(health / maxHealth > 0.5) + icon_state = "drone1" + else + icon_state = "drone0" + +/mob/living/simple_animal/hostile/malf_drone/adjustHealth(damage, updating_health) + do_sparks(3, 1, src) + passive_mode = FALSE + update_icons() + . = ..() // this will handle finding a target if there is a valid one nearby + +/mob/living/simple_animal/hostile/malf_drone/Life(seconds, times_fired) + . = ..() + if(.) // mob is alive. We check this just in case Life() can fire for qdel'ed mobs. + if(times_fired % 15 == 0) // every 15 cycles, aka 30 seconds, 50% chance to switch between modes + scramble_settings() + +/mob/living/simple_animal/hostile/malf_drone/proc/scramble_settings() + if(prob(50)) + do_sparks(3, 1, src) + passive_mode = !passive_mode + if(passive_mode) + visible_message("[src] retracts several targetting vanes.") + if(target) + LoseTarget() + else + visible_message("[src] suddenly lights up, and additional targetting vanes slide into place.") + update_icons() + +/mob/living/simple_animal/hostile/malf_drone/emp_act(severity) + adjustHealth(100 / severity) // takes the same damage as a mining drone from emp + +/mob/living/simple_animal/hostile/malf_drone/drop_loot() + do_sparks(3, 1, src) + + var/turf/T = get_turf(src) + + //shards + var/obj/O = new /obj/item/shard(T) + step_to(O, get_turf(pick(view(7, src)))) + if(prob(75)) + O = new /obj/item/shard(T) + step_to(O, get_turf(pick(view(7, src)))) + if(prob(50)) + O = new /obj/item/shard(T) + step_to(O, get_turf(pick(view(7, src)))) + if(prob(25)) + O = new /obj/item/shard(T) + step_to(O, get_turf(pick(view(7, src)))) + + //rods + var/obj/item/stack/K = new /obj/item/stack/rods(T) + step_to(K, get_turf(pick(view(7, src)))) + K.amount = pick(1, 2, 3, 4) + K.update_icon() + + //plasteel + K = new /obj/item/stack/sheet/plasteel(T) + step_to(K, get_turf(pick(view(7, src)))) + K.amount = pick(1, 2, 3, 4) + K.update_icon() + + //also drop dummy circuit boards deconstructable for research (loot) + var/obj/item/circuitboard/C + + //spawn 1-4 boards of a random type + var/spawnees = 0 + var/num_boards = rand(1, 4) + var/list/options = list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512) + for(var/i=0, iERROR: attempt to use evolve queen ability on a non-princess
") - return - var/feedings_left = user.feedings_to_evolve - user.fed - if(feedings_left > 0) - to_chat(user, "You must wrap [feedings_left] more humanoid prey before you can do this!") - return - for(var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q in GLOB.ts_spiderlist) - if(Q.spider_awaymission == user.spider_awaymission) - to_chat(user, "The presence of another Queen in the area is preventing you from maturing.") - return - user.evolve_to_queen() // ---------- QUEEN ACTIONS @@ -93,19 +72,11 @@ var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner user.LayQueenEggs() -/datum/action/innate/terrorspider/queen/queenfakelings - name = "Fake Spiderlings" - icon_icon = 'icons/effects/effects.dmi' - button_icon_state = "spiderling" - -/datum/action/innate/terrorspider/queen/queenfakelings/Activate() - var/mob/living/simple_animal/hostile/poison/terror_spider/queen/user = owner - user.QueenFakeLings() // ---------- EMPRESS /datum/action/innate/terrorspider/queen/empress/empresserase - name = "Erase Brood" + name = "Empress Erase Brood" icon_icon = 'icons/effects/blood.dmi' button_icon_state = "mgibbl1" @@ -113,6 +84,16 @@ var/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/user = owner user.EraseBrood() +/datum/action/innate/terrorspider/queen/empress/empresslings + name = "Empresss Spiderlings" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "spiderling" + +/datum/action/innate/terrorspider/queen/empress/empresslings/Activate() + var/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/user = owner + user.EmpressLings() + + // ---------- WEB /mob/living/simple_animal/hostile/poison/terror_spider/proc/Web() @@ -186,13 +167,26 @@ // ---------- WRAP +/mob/living/simple_animal/hostile/poison/terror_spider/proc/mobIsWrappable(mob/living/M) + if(!istype(M)) + return FALSE + if(M.stat != DEAD) + return FALSE + if(M.anchored) + return FALSE + if(!Adjacent(M)) + return FALSE + if(isterrorspider(M)) + return FALSE + return TRUE + /mob/living/simple_animal/hostile/poison/terror_spider/proc/FindWrapTarget() if(!cocoon_target) var/list/choices = list() for(var/mob/living/L in oview(1,src)) - if(Adjacent(L) && !L.anchored) - if(L.stat == DEAD) - choices += L + if(!mobIsWrappable(L)) + continue + choices += L for(var/obj/O in oview(1,src)) if(Adjacent(O) && !O.anchored) if(!istype(O, /obj/structure/spider/terrorweb) && !istype(O, /obj/structure/spider/cocoon) && !istype(O, /obj/structure/spider/spiderling/terror_spiderling)) @@ -226,9 +220,7 @@ O.loc = C large_cocoon = 1 for(var/mob/living/L in C.loc) - if(istype(L, /mob/living/simple_animal/hostile/poison/terror_spider)) - continue - if(L.stat != DEAD) + if(!mobIsWrappable(L)) continue if(iscarbon(L)) regen_points += regen_points_per_kill diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm index 60e11de670a..b685fdd1959 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/chem.dm @@ -22,7 +22,7 @@ else if(volume < 90) // bitten thrice, die quickly, severe muscle cramps make movement very difficult. Even calling for help probably won't save you. // total damage: 4, human health 150 until crit, = 37.5 ticks, = 75s = 1m15s until death - update_flags |= M.adjustToxLoss(4, FALSE) // a bit worse than coiine + update_flags |= M.adjustToxLoss(4, FALSE) update_flags |= M.EyeBlurry(6, FALSE) M.Confused(6) else diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm index 137d6739466..f011becf6b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm @@ -19,7 +19,6 @@ ventcrawler = 1 idle_ventcrawl_chance = 0 ai_playercontrol_allowtype = 0 - rapid = 3 canlay = 1000 spider_tier = TS_TIER_5 projectiletype = /obj/item/projectile/terrorqueenspit/empress @@ -35,6 +34,8 @@ /mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/New() ..() + empresslings_action = new() + empresslings_action.Grant(src) empresserase_action = new() empresserase_action.Grant(src) @@ -44,7 +45,6 @@ /mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/NestMode() ..() queeneggs_action.button.name = "Empress Eggs" - queenfakelings_action.button.name = "Empress Lings" /mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/LayQueenEggs() var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE, TS_DESC_BROWN) @@ -70,7 +70,7 @@ if(TS_DESC_PRINCE) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, numlings) if(TS_DESC_PRINCESS) - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/princess, numlings) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess, numlings) if(TS_DESC_MOTHER) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, numlings) if(TS_DESC_QUEEN) @@ -78,7 +78,7 @@ else to_chat(src, "Unrecognized egg type.") -/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/QueenFakeLings() +/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/proc/EmpressLings() var/numlings = input("How many?") as null|anything in list(10, 20, 30, 40, 50) var/sbpc = input("%chance to be stillborn?") as null|anything in list(0, 25, 50, 75, 100) for(var/i=0, iThrough the hivemind, the raw power of [src] floods into your body, burning it from the inside out!") @@ -106,8 +107,6 @@ qdel(T) to_chat(src, "All Terror Spiders, except yourself, will die off shortly.") - /obj/item/projectile/terrorqueenspit/empress - damage_type = BURN - damage = 30 - bonus_tox = 0 + damage = 90 + diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm index 1946f1a32ee..b07f34ec368 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm @@ -39,11 +39,10 @@ to_chat(src, "You must wrap more humanoid prey before you can do this!") return var/list/eggtypes = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN) - var/num_brown = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/brown) - if(num_brown < 2) + var/list/spider_array = CountSpidersDetailed(FALSE) + if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/brown] < 2) eggtypes += TS_DESC_BROWN - var/num_black = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/black) - if(num_black < 2) + if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/black] < 2) eggtypes += TS_DESC_BLACK var/eggtype = pick(eggtypes) if(client) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm index 245ae95c5e9..407e6f3174e 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/hive.dm @@ -4,7 +4,8 @@ /mob/living/simple_animal/hostile/poison/terror_spider/proc/DoHiveSense() var/hsline = "" to_chat(src, "Your Brood: ") - for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in GLOB.ts_spiderlist) + for(var/thing in GLOB.ts_spiderlist) + var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing if(T.spider_awaymission != spider_awaymission) continue hsline = "* [T] in [get_area(T)], " @@ -20,21 +21,55 @@ /mob/living/simple_animal/hostile/poison/terror_spider/proc/CountSpiders() var/numspiders = 0 - for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in GLOB.ts_spiderlist) + for(var/thing in GLOB.ts_spiderlist) + var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing if(T.stat != DEAD && !T.spider_placed && spider_awaymission == T.spider_awaymission) numspiders += 1 return numspiders -/mob/living/simple_animal/hostile/poison/terror_spider/proc/CountSpidersType(specific_type) - var/numspiders = 0 - for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in GLOB.ts_spiderlist) - if(T.stat != DEAD && !T.spider_placed && spider_awaymission == T.spider_awaymission) - if(T.type == specific_type) - numspiders += 1 - for(var/obj/structure/spider/eggcluster/terror_eggcluster/E in GLOB.ts_egg_list) - if(E.spiderling_type == specific_type && E.z == z) - numspiders += E.spiderling_number - for(var/obj/structure/spider/spiderling/terror_spiderling/L in GLOB.ts_spiderling_list) - if(!L.stillborn && L.grow_as == specific_type && L.z == z) - numspiders += 1 - return numspiders +/mob/living/simple_animal/hostile/poison/terror_spider/proc/CountSpidersDetailed(check_mine = FALSE, list/mytypes = list()) + var/list/spider_totals = list("all" = 0) + var/check_list = length(mytypes) > 0 + for(var/thistype in mytypes) + spider_totals[thistype] = 0 + for(var/thing in GLOB.ts_spiderlist) + var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing + if(T.stat == DEAD || T.spider_placed || spider_awaymission != T.spider_awaymission) + continue + if(check_mine && T.spider_myqueen != src) + continue + if(check_list && !(T.type in mytypes)) + continue + if(T == src) + continue + if(spider_totals[T.type]) + spider_totals[T.type]++ + else + spider_totals[T.type] = 1 + spider_totals["all"]++ + for(var/thing in GLOB.ts_egg_list) + var/obj/structure/spider/eggcluster/terror_eggcluster/E = thing + if(check_mine && E.spider_myqueen != src) + continue + if(check_list && E.spiderling_type && !(E.spiderling_type in mytypes)) + continue + if(spider_totals[E.spiderling_type]) + spider_totals[E.spiderling_type] += E.spiderling_number + else + spider_totals[E.spiderling_type] = E.spiderling_number + spider_totals["all"] += E.spiderling_number + for(var/thing in GLOB.ts_spiderling_list) + var/obj/structure/spider/spiderling/terror_spiderling/L = thing + if(L.stillborn) + continue + if(check_mine && L.spider_myqueen != src) + continue + if(check_list && L.grow_as && !(L.grow_as in mytypes)) + continue + if(spider_totals[L.grow_as]) + spider_totals[L.grow_as]++ + else + spider_totals[L.grow_as] = 1 + spider_totals["all"]++ + return spider_totals + diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm index e486872abbb..7b900d8a881 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm @@ -29,6 +29,7 @@ spider_opens_doors = 2 web_type = /obj/structure/spider/terrorweb/purple ai_spins_webs = FALSE + gender = MALE /mob/living/simple_animal/hostile/poison/terror_spider/prince/death(gibbed) if(can_die() && !hasdied && spider_uo71) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm index 6f33c51b246..787d89b722f 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm @@ -2,58 +2,80 @@ // -------------------------------------------------------------------------------- // ----------------- TERROR SPIDERS: T3 PRINCESS OF TERROR -------------------------- // -------------------------------------------------------------------------------- -// -------------: ROLE: cutesy -// -------------: AI: as green, but will evolve to queen when it can -// -------------: SPECIAL: can evolve into a queen, if fed enough -// -------------: TO FIGHT IT: kill it before it evolves +// -------------: ROLE: mini-queen, maintains a smaller nest, but also more expendable +// -------------: AI: maintains a small group of spiders. Small fraction of a queen's nest. +// -------------: SPECIAL: lays eggs over time, like a queen +// -------------: TO FIGHT IT: hunt it before it lays eggs // -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos -/mob/living/simple_animal/hostile/poison/terror_spider/princess +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess name = "Princess of Terror spider" desc = "An enormous spider. It looks strangely cute and fluffy." - spider_role_summary = "Future Queen" + spider_role_summary = "Mini-Queen" ai_target_method = TS_DAMAGE_SIMPLE icon_state = "terror_princess1" icon_living = "terror_princess1" icon_dead = "terror_princess1_dead" maxHealth = 150 health = 150 - regen_points_per_hp = 1 // always regens very fast - force_threshold = 18 // outright immune to anything of force under 18, same as queen - melee_damage_lower = 10 - melee_damage_upper = 20 - idle_ventcrawl_chance = 5 spider_tier = TS_TIER_3 - spider_opens_doors = 2 - web_type = /obj/structure/spider/terrorweb/queen - var/feedings_to_evolve = 3 - var/datum/action/innate/terrorspider/ventsmash/ventsmash_action - var/datum/action/innate/terrorspider/evolvequeen/evolvequeen_action -/mob/living/simple_animal/hostile/poison/terror_spider/princess/New() - ..() - ventsmash_action = new() - ventsmash_action.Grant(src) - evolvequeen_action = new() - evolvequeen_action.Grant(src) + // Unlike queens, no ranged attack. + ranged = 0 + retreat_distance = 0 + minimum_distance = 0 + projectilesound = null + projectiletype = null -/mob/living/simple_animal/hostile/poison/terror_spider/princess/proc/evolve_to_queen() - var/mob/living/simple_animal/hostile/poison/terror_spider/queen/Q = new(loc) - if(mind) - mind.transfer_to(Q) - // Calling `transfer_to()` removes our new body (the Queen's) ability to see the med hud, so we have to re-add the queen here. - var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - U.add_hud_to(Q) - qdel(src) + canlay = 0 + hasnested = TRUE + spider_spawnfrequency = 300 // 30 seconds + var/grant_prob = 25 // 25% chance every spider_spawnfrequency seconds to gain 1 egg + var/spider_max_children = 8 -/mob/living/simple_animal/hostile/poison/terror_spider/princess/DoWrap() - . = ..() - if(fed == 0) + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/grant_queen_subtype_abilities() + // Queens start in movement mode, where they can ventcrawl but not lay eggs. Then they move to NestMode() where they can wallsmash and egglay, but not ventcrawl. + // Princesses are simpler, and can always lay eggs, always vent crawl, but never smash walls. Unlike queens, they don't have a "nesting" transformation. + queeneggs_action = new() + queeneggs_action.Grant(src) + queensense_action = new() + queensense_action.Grant(src) + + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/ListAvailableEggTypes() + var/list/valid_types = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN) + + // Each princess can also have ONE black/purple/brown. If it dies, they can pick a new spider from the 3 advanced types to lay. + var/list/spider_array = CountSpidersDetailed(TRUE, list(/mob/living/simple_animal/hostile/poison/terror_spider/black, /mob/living/simple_animal/hostile/poison/terror_spider/purple, /mob/living/simple_animal/hostile/poison/terror_spider/brown)) + if(spider_array["all"] < 1) + valid_types |= TS_DESC_BLACK + valid_types |= TS_DESC_PURPLE + valid_types |= TS_DESC_BROWN + + return valid_types + + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/grant_eggs() + spider_lastspawn = world.time + + if(!isturf(loc)) + to_chat(src, "You cannot generate eggs while hiding in [loc].") + return + + if(!prob(grant_prob)) + return + + var/list/spider_array = CountSpidersDetailed(TRUE) + var/brood_count = spider_array["all"] + + // Color shifts depending on how much of their brood capacity they have used. + if(brood_count == 0) icon_state = "terror_princess1" icon_living = "terror_princess1" icon_dead = "terror_princess1_dead" desc = "An enormous spider. It looks strangely cute and fluffy, with soft pink fur covering most of its body." - else if(fed == 1) + else if(brood_count < (spider_max_children /2)) icon_state = "terror_princess2" icon_living = "terror_princess2" icon_dead = "terror_princess2_dead" @@ -62,13 +84,44 @@ icon_state = "terror_princess3" icon_living = "terror_princess3" icon_dead = "terror_princess3_dead" - desc = "An enormous spider. Its entire body has turned an ominous blood red color, with actual blood dripping from its jaws. It stares around, hungrily." + desc = "An enormous spider. Its entire body looks to be the color of dried blood." -/mob/living/simple_animal/hostile/poison/terror_spider/princess/spider_special_action() - if(cocoon_target) - handle_cocoon_target() - else if(fed >= feedings_to_evolve) - evolve_to_queen() - else if(world.time > (last_cocoon_object + freq_cocoon_object)) - seek_cocoon_target() + if((brood_count + canlay) >= spider_max_children) + return + canlay++ + if(canlay == 1) + to_chat(src, "You have an egg available to lay.") + else + to_chat(src, "You have [canlay] eggs available to lay.") + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/show_egg_timer() + var/average_timer = (1 / (grant_prob / 100)) * (spider_spawnfrequency / 10) + to_chat(src, "Too soon to attempt that again. You generate a new egg every [average_timer] seconds, on average.") + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/NestMode() + // Princesses don't nest. However, we still need to override this in case an AI princess calls it. + return + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/spider_special_action() + // Princess AI routine. GREATLY simplified version of queen routine. + if(!stat && !ckey) + // Utilize normal queen AI for finding a nest site (neststep=0), and activating NestMode() (neststep=1) + if(neststep != 2) + return ..() + // After that, simply lay an egg once per nestfrequency, until we have the max. + if(world.time < (lastnestsetup + nestfrequency)) + return + lastnestsetup = world.time + if(ai_nest_is_full()) + return + spider_lastspawn = world.time + DoLayTerrorEggs(pick(spider_types_standard), 1) + // Yes, this means NPC princesses won't create T2 spiders. + + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/ai_nest_is_full() + var/list/spider_array = CountSpidersDetailed(TRUE) + if(spider_array["all"] >= spider_max_children) + return TRUE + return FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm index 737b6eba22a..8f423dfb5d2 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm @@ -5,7 +5,7 @@ // -------------: ROLE: gamma-level threat to the whole station, like a blob // -------------: AI: builds a nest, lays many eggs, attempts to take over the station // -------------: SPECIAL: spins webs, breaks lights, breaks cameras, webs objects, lays eggs, commands other spiders... -// -------------: TO FIGHT IT: bring an army, and take no prisoners. Mechs and/or decloner guns are a very good idea. +// -------------: TO FIGHT IT: bring an army, and take no prisoners. Mechs are a very good idea. // -------------: SPRITES FROM: IK3I /mob/living/simple_animal/hostile/poison/terror_spider/queen @@ -43,69 +43,94 @@ var/neststep = 0 var/hasnested = FALSE var/spider_max_per_nest = 35 // above this, AI queens become stable - var/canlay = 4 // main counter for egg-laying ability! # = num uses, incremented at intervals + var/canlay = 5 // main counter for egg-laying ability! # = num uses, incremented at intervals var/eggslaid = 0 - var/spider_can_fakelings = 3 // spawns defective spiderlings that don't grow up, used to freak out crew, atmosphere var/list/spider_types_standard = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green, /mob/living/simple_animal/hostile/poison/terror_spider/black) var/datum/action/innate/terrorspider/queen/queennest/queennest_action var/datum/action/innate/terrorspider/queen/queensense/queensense_action var/datum/action/innate/terrorspider/queen/queeneggs/queeneggs_action - var/datum/action/innate/terrorspider/queen/queenfakelings/queenfakelings_action var/datum/action/innate/terrorspider/ventsmash/ventsmash_action + /mob/living/simple_animal/hostile/poison/terror_spider/queen/New() ..() - queennest_action = new() - queennest_action.Grant(src) ventsmash_action = new() ventsmash_action.Grant(src) + grant_queen_subtype_abilities() spider_myqueen = src if(spider_awaymission) - spider_growinstantly = 1 + spider_growinstantly = TRUE spider_spawnfrequency = 150 + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/grant_queen_subtype_abilities() + queennest_action = new() + queennest_action.Grant(src) + /mob/living/simple_animal/hostile/poison/terror_spider/queen/Life(seconds, times_fired) . = ..() if(stat != DEAD) // Can't use if(.) for this due to the fact it can sometimes return FALSE even when mob is alive. - if(ckey && canlay < 12 && hasnested) // max 12 eggs worth stored at any one time, realistically that's tons. + if(ckey && hasnested) if(world.time > (spider_lastspawn + spider_spawnfrequency)) - if(eggslaid >= 20) - canlay += 3 - else if(eggslaid >= 10) - canlay += 2 - else - canlay++ - spider_lastspawn = world.time - if(canlay == 1) - to_chat(src, "You have an egg available to lay.") - else if(canlay == 12) - to_chat(src, "You have [canlay] eggs available to lay. You won't grow any more eggs until you lay some of your existing ones.") - else - to_chat(src, "You have [canlay] eggs available to lay.") + grant_eggs() + + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/grant_eggs() + spider_lastspawn = world.time + canlay += getSpiderLevel() + if(canlay == 1) + to_chat(src, "You have an egg available to lay.") + else if(canlay > 1) + to_chat(src, "You have [canlay] eggs available to lay.") + + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/getSpiderLevel() + return 1 + round(MinutesAlive() / 10) + + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/MinutesAlive() + return round((world.time - spider_creation_time) / 600) + /mob/living/simple_animal/hostile/poison/terror_spider/queen/death(gibbed) if(can_die() && !hasdied) if(spider_uo71) UnlockBlastDoors("UO71_Caves") - // When a queen dies, so do her player-controlled purple-type guardians. Intended as a motivator for purples to ensure they guard her. - for(var/mob/living/simple_animal/hostile/poison/terror_spider/purple/P in GLOB.ts_spiderlist) - if(ckey) - P.visible_message("\The [src] writhes in pain!") - to_chat(P,"\The [src] has died. Without her hivemind link, purple terrors like yourself cannot survive more than a few minutes!") - P.degenerate = 1 + // When a queen (or subtype!) dies, so do all of her spiderlings, and half of all her fully grown offspring + // This feature is intended to provide a way for crew to still win even if the queen has overwhelming numbers - by sniping the queen. + for(var/thing in GLOB.ts_spiderlist) + var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing + if(!T.spider_myqueen) + continue + if(T.spider_myqueen != src) + continue + if(prob(50) || T.spider_tier >= spider_tier) + to_chat(T, "\The psychic backlash from the death of [src] crashes into your mind! Somehow... you find a way to keep going!") + continue + T.visible_message("[T] writhes in pain!") + to_chat(T, "\The psychic backlash from the death of [src] overwhelms you! You feel the life start to drain out of you...") + T.degenerate = TRUE + for(var/thing in GLOB.ts_spiderling_list) + var/obj/structure/spider/spiderling/terror_spiderling/T = thing + if(T.spider_myqueen && T.spider_myqueen == src) + qdel(T) return ..() + /mob/living/simple_animal/hostile/poison/terror_spider/queen/Retaliate() ..() - for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in GLOB.ts_spiderlist) + for(var/thing in GLOB.ts_spiderlist) + var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing T.enemies |= enemies + /mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/ai_nest_is_full() var/numspiders = CountSpiders() if(numspiders >= spider_max_per_nest) return TRUE return FALSE + /mob/living/simple_animal/hostile/poison/terror_spider/queen/spider_special_action() if(!stat && !ckey) switch(neststep) @@ -152,11 +177,13 @@ neststep = 2 NestMode() if(2) - // Create initial four purple nest guards. + // Create initial T2 spiders. if(world.time > (lastnestsetup + nestfrequency)) lastnestsetup = world.time spider_lastspawn = world.time - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 4) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, 2) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 2) neststep = 3 if(3) // Create spiders (random types) until nest is full. @@ -183,28 +210,26 @@ neststep = 4 else spider_lastspawn = world.time - var/num_purple = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/purple) - var/num_white = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/white) - var/num_brown = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/brown) - if(num_purple < 4) + var/list/spider_array = CountSpidersDetailed(FALSE) + if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/purple] < 4) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, 2) - else if(num_white < 2) + else if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/white] < 2) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, 2) - else if(num_brown < 4) + else if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/brown] < 4) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 4) else DoLayTerrorEggs(pick(spider_types_standard), 5) + /mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestPrompt() var/confirm = alert(src, "Are you sure you want to nest? You will be able to lay eggs, and smash walls, but not ventcrawl.","Nest?","Yes","No") if(confirm == "Yes") NestMode() + /mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/NestMode() queeneggs_action = new() queeneggs_action.Grant(src) - queenfakelings_action = new() - queenfakelings_action.Grant(src) queensense_action = new() queensense_action.Grant(src) queennest_action.Remove(src) @@ -213,21 +238,8 @@ ai_ventcrawls = FALSE environment_smash = ENVIRONMENT_SMASH_RWALLS DoQueenScreech(8, 100, 8, 100) - MassFlicker() to_chat(src, "You have matured to your egglaying stage. You can now smash through walls, and lay eggs, but can no longer ventcrawl.") -/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/MassFlicker() - var/list/target_lights = list() - for(var/mob/living/carbon/human/H in GLOB.player_list) - if(H.z != z) - continue - if(H.stat == DEAD) - continue - for(var/obj/machinery/light/L in orange(7, H)) - if(L.on && prob(25)) - target_lights += L - for(var/obj/machinery/light/I in target_lights) - I.flicker() /mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/LayQueenEggs() if(stat == DEAD) @@ -236,48 +248,23 @@ to_chat(src, "You must nest before doing this.") return if(canlay < 1) - var/remainingtime = round(((spider_lastspawn + spider_spawnfrequency) - world.time) / 10, 1) - if(remainingtime > 0) - to_chat(src, "Too soon to attempt that again. Wait another [num2text(remainingtime)] seconds.") - else - to_chat(src, "Too soon to attempt that again. Wait just a few more seconds...") + show_egg_timer() return - var/list/eggtypes = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE) - if(canlay >= 4) - eggtypes |= TS_DESC_BROWN - if(canlay >= 12) - eggtypes |= TS_DESC_MOTHER - eggtypes |= TS_DESC_PRINCE - var/num_purples = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/purple) - if(num_purples >= 2) - eggtypes -= TS_DESC_PURPLE - var/num_blacks = CountSpidersType(/mob/living/simple_animal/hostile/poison/terror_spider/black) - if(num_blacks >= 2) - eggtypes -= TS_DESC_BLACK + var/list/eggtypes = ListAvailableEggTypes() + var/list/eggtypes_uncapped = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN) + var/eggtype = input("What kind of eggs?") as null|anything in eggtypes + if(canlay < 1) + // this was checked before input() but we have to check again to prevent them spam-clicking the popup. + to_chat(src, "Too soon to lay another egg.") + return if(!(eggtype in eggtypes)) to_chat(src, "Unrecognized egg type.") return 0 - if(eggtype == TS_DESC_MOTHER || eggtype == TS_DESC_PRINCE) - if(canlay < 12) - to_chat(src, "Insufficient strength. It takes as much effort to lay one of those as it does to lay 12 normal eggs.") - else - if(eggtype == TS_DESC_MOTHER) - canlay -= 12 - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, 1) - else if(eggtype == TS_DESC_PRINCE) - canlay -= 12 - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, 1) - return - else if(eggtype == TS_DESC_BROWN) - if(canlay < 4) - to_chat(src, "Insufficient strength. It takes as much effort to lay one of those as it does to lay 4 normal eggs.") - else - canlay -= 4 - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, 1) - return + + // Multiple of eggtypes_uncapped can be laid at once. Other types must be laid one at a time (to prevent exploits) var/numlings = 1 - if(eggtype != TS_DESC_PURPLE) + if(eggtype in eggtypes_uncapped) if(canlay >= 5) numlings = input("How many in the batch?") as null|anything in list(1, 2, 3, 4, 5) else if(canlay >= 3) @@ -287,27 +274,61 @@ if(eggtype == null || numlings == null) to_chat(src, "Cancelled.") return + // Actually lay the eggs. if(canlay < numlings) // We have to check this again after the popups, to account for people spam-clicking the button, then doing all the popups at once. to_chat(src, "Too soon to do this again!") return canlay -= numlings eggslaid += numlings - if(eggtype == TS_DESC_RED) - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings) - else if(eggtype == TS_DESC_GRAY) - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, numlings) - else if(eggtype == TS_DESC_GREEN) - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, numlings) - else if(eggtype == TS_DESC_BLACK) - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, numlings) - else if(eggtype == TS_DESC_PURPLE) - DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings) + switch(eggtype) + if(TS_DESC_RED) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/red, numlings) + if(TS_DESC_GRAY) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/gray, numlings) + if(TS_DESC_GREEN) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/green, numlings) + if(TS_DESC_BLACK) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/black, numlings) + if(TS_DESC_PURPLE) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings) + if(TS_DESC_BROWN) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, numlings) + if(TS_DESC_MOTHER) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/mother, numlings) + if(TS_DESC_PRINCE) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, numlings) + if(TS_DESC_PRINCESS) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess, numlings) + else + to_chat(src, "Unrecognized egg type.") + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/show_egg_timer() + var/remainingtime = round(((spider_lastspawn + spider_spawnfrequency) - world.time) / 10, 1) + if(remainingtime > 0) + to_chat(src, "Too soon to attempt that again. Wait another [num2text(remainingtime)] seconds.") else - to_chat(src, "Unrecognized egg type.") + to_chat(src, "Too soon to attempt that again. Wait just a few more seconds...") + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/ListAvailableEggTypes() + if(MinutesAlive() >= 20) + var/list/spider_array = CountSpidersDetailed(TRUE, list(/mob/living/simple_animal/hostile/poison/terror_spider/mother, /mob/living/simple_animal/hostile/poison/terror_spider/prince, /mob/living/simple_animal/hostile/poison/terror_spider/queen/princess)) + if(spider_array["all"] == 0) + return list(TS_DESC_PRINCE, TS_DESC_PRINCESS) // Mother will be added to this list.... AFTER mothers are reworked. + + var/list/valid_types = list(TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN) + var/list/spider_array = CountSpidersDetailed(FALSE, list(/mob/living/simple_animal/hostile/poison/terror_spider/brown, /mob/living/simple_animal/hostile/poison/terror_spider/purple, /mob/living/simple_animal/hostile/poison/terror_spider/black)) + if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/brown] < 2) + valid_types += TS_DESC_BROWN + if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/purple] < 2) + valid_types += TS_DESC_PURPLE + if(spider_array[/mob/living/simple_animal/hostile/poison/terror_spider/black] < 2) + valid_types += TS_DESC_BLACK + return valid_types + /mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/DoQueenScreech(light_range, light_chance, camera_range, camera_chance) - visible_message("\The [src] emits a bone-chilling shriek!") + visible_message("[src] emits a bone-chilling shriek!") for(var/obj/machinery/light/L in orange(light_range, src)) if(L.on && prob(light_chance)) L.break_light_tube() @@ -315,46 +336,33 @@ if(C.status && prob(camera_chance)) C.toggle_cam(src, 0) -/mob/living/simple_animal/hostile/poison/terror_spider/queen/proc/QueenFakeLings() - if(eggslaid < 10) - to_chat(src, "You must lay at least 10 eggs before doing this.") + +/mob/living/simple_animal/hostile/poison/terror_spider/queen/examine(mob/user) + . = ..() + if(!key || stat == DEAD) return - if(spider_can_fakelings) - spider_can_fakelings-- - var/numlings = 25 - for(var/i in 1 to numlings) - var/obj/structure/spider/spiderling/terror_spiderling/S = new /obj/structure/spider/spiderling/terror_spiderling(get_turf(src)) - S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red - S.stillborn = 1 - S.spider_mymother = src - if(!spider_can_fakelings) - queenfakelings_action.Remove(src) - else - to_chat(src, "You have run out of uses of this ability.") + if(!isobserver(user) && !isterrorspider(user)) + return + . += "[p_they(TRUE)] has laid [eggslaid] egg[eggslaid != 1 ? "s" : ""]." + . += "[p_they(TRUE)] has lived for [MinutesAlive()] minutes." + /obj/item/projectile/terrorqueenspit - name = "poisonous spit" - damage = 0 + name = "acid spit" + damage = 40 icon_state = "toxin" - damage_type = TOX - var/bonus_tox = 30 + damage_type = BURN -/obj/item/projectile/terrorqueenspit/on_hit(mob/living/carbon/target, blocked = 0, hit_zone) - if(ismob(target) && blocked < 100) - var/mob/living/L = target - if(L.reagents) - if(L.can_inject(null, FALSE, "chest", FALSE)) - L.Hallucinate(400) - if(!isterrorspider(L)) - L.adjustToxLoss(bonus_tox) /obj/structure/spider/terrorweb/queen - name = "shimmering web" - desc = "This web seems to shimmer all different colors in the light." + name = "airtight web" + desc = "This multi-layered web seems to be able to resist air pressure." + + +/obj/structure/spider/terrorweb/queen/New() + . = ..() + air_update_turf(TRUE) + +/obj/structure/spider/terrorweb/queen/CanAtmosPass(turf/T) + return FALSE -/obj/structure/spider/terrorweb/queen/web_special_ability(mob/living/carbon/C) - if(istype(C)) - var/inject_target = pick("chest","head") - if(C.can_inject(null, FALSE, inject_target, FALSE)) - C.Hallucinate(400) - C.adjustToxLoss(30) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm index a889bc6d328..8961fcdddb5 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm @@ -188,7 +188,7 @@ C.enemies = enemies if(spider_growinstantly) C.amount_grown = 250 - C.spider_growinstantly = 1 + C.spider_growinstantly = TRUE spawn(10) stop_automated_movement = 0 @@ -196,7 +196,7 @@ name = "terror egg cluster" desc = "A cluster of tiny spider eggs. They pulse with a strong inner life, and appear to have sharp thorns on the sides." icon_state = "eggs" - var/spider_growinstantly = 0 + var/spider_growinstantly = FALSE var/spider_myqueen = null var/spider_mymother = null var/spiderling_type = null diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ai.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ai.dm index 11e4cac3e4a..c3e0c9a0511 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ai.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_ai.dm @@ -126,7 +126,7 @@ spider_steps_taken++ CreatePath(entry_vent) step_to(src,entry_vent) - if(spider_debug > 0) + if(spider_debug) visible_message("[src] moves towards the vent [entry_vent].") else path_to_vent = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index ab36c6ca313..6c943b26f53 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -17,6 +17,7 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) // Name / Description name = "terror spider" desc = "The generic parent of all other terror spider types. If you see this in-game, it is a bug." + gender = FEMALE // Icons icon = 'icons/mob/terrorspider.dmi' @@ -141,29 +142,33 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) var/mylocation = null var/chasecycles = 0 var/web_infects = 0 + var/spider_creation_time = 0 var/datum/action/innate/terrorspider/web/web_action var/web_type = /obj/structure/spider/terrorweb var/datum/action/innate/terrorspider/wrap/wrap_action - // Breathing - require some oxygen, and no toxins, but take little damage from this requirement not being met (they can hold their breath) + // Breathing - require some oxygen, and no toxins atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - unsuitable_atmos_damage = 1 - // Temperature - can freeze in space and cook in plasma, but it takes extreme temperatures to do this. - minbodytemp = 100 - maxbodytemp = 500 - heat_damage_per_tick = 3 + // Temperature + heat_damage_per_tick = 5 // Takes 250% normal damage from being in a hot environment ("kill it with fire!") // DEBUG OPTIONS & COMMANDS - var/spider_growinstantly = 0 // DEBUG OPTION, DO NOT ENABLE THIS ON LIVE. IT IS USED TO TEST NEST GROWTH/SETUP AI. - var/spider_debug = 0 + var/spider_growinstantly = FALSE // DEBUG OPTION, DO NOT ENABLE THIS ON LIVE. IT IS USED TO TEST NEST GROWTH/SETUP AI. + var/spider_debug = FALSE // -------------------------------------------------------------------------------- // --------------------- TERROR SPIDERS: SHARED ATTACK CODE ----------------------- // -------------------------------------------------------------------------------- +/mob/living/simple_animal/hostile/poison/terror_spider/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) + // Forces terrors to use the 'bite' graphic when attacking something. Same as code/modules/mob/living/carbon/alien/larva/larva_defense.dm#L34 + if(!no_effect && !visual_effect_icon) + visual_effect_icon = ATTACK_EFFECT_BITE + ..() + /mob/living/simple_animal/hostile/poison/terror_spider/AttackingTarget() if(isterrorspider(target)) if(target in enemies) @@ -187,14 +192,13 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) if(F.welded) to_chat(src, "The fire door is welded shut.") else - visible_message("\The [src] pries open the firedoor!") + visible_message("[src] pries open the firedoor!") F.open() else to_chat(src, "Closing fire doors does not help.") else if(istype(target, /obj/machinery/door/airlock)) var/obj/machinery/door/airlock/A = target - if(A.density) - try_open_airlock(A) + try_open_airlock(A) else if(isliving(target) && (!client || a_intent == INTENT_HARM)) var/mob/living/G = target if(issilicon(G)) @@ -221,27 +225,23 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) /mob/living/simple_animal/hostile/poison/terror_spider/examine(mob/user) . = ..() - var/list/msgs = list() - if(stat == DEAD) - msgs += "It appears to be dead.\n" - else + if(stat != DEAD) if(key) - msgs += "Its eyes regard you with a curious intelligence." + . += "[p_they(TRUE)] regards [p_their()] surroundings with a curious intelligence." if(health > (maxHealth*0.95)) - msgs += "It is in excellent health." + . += "[p_they(TRUE)] is in excellent health." else if(health > (maxHealth*0.75)) - msgs += "It has a few injuries." + . += "[p_they(TRUE)] has a few injuries." else if(health > (maxHealth*0.55)) - msgs += "It has many injuries." + . += "[p_they(TRUE)] has many injuries." else if(health > (maxHealth*0.25)) - msgs += "It is barely clinging on to life!" + . += "[p_they(TRUE)] is barely clinging on to life!" if(degenerate) - msgs += "It appears to be dying." + . += "[p_they(TRUE)] appears to be dying." else if(health < maxHealth && regen_points > regen_points_per_kill) - msgs += "It appears to be regenerating quickly." + . += "[p_they(TRUE)] appears to be regenerating quickly." if(killcount >= 1) - msgs += "It has blood dribbling from its mouth." - . += msgs.Join("
") + . += "[p_they(TRUE)] has blood dribbling from [p_their()] mouth." /mob/living/simple_animal/hostile/poison/terror_spider/New() ..() @@ -254,9 +254,10 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) if(web_type) web_action = new() web_action.Grant(src) - wrap_action = new() - wrap_action.Grant(src) - + if(regen_points_per_tick < regen_points_per_hp) + // Only grant the Wrap action button to spiders who need to use it to regenerate their health + wrap_action = new() + wrap_action.Grant(src) name += " ([rand(1, 1000)])" real_name = name msg_terrorspiders("[src] has grown in [get_area(src)].") @@ -278,6 +279,7 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) addtimer(CALLBACK(src, .proc/announcetoghosts), 30) var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] U.add_hud_to(src) + spider_creation_time = world.time /mob/living/simple_animal/hostile/poison/terror_spider/proc/announcetoghosts() if(spider_awaymission) @@ -285,8 +287,7 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) if(stat == DEAD) return if(ckey) - var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state) - notify_ghosts("[src] has appeared in [get_area(src)]. (already player-controlled)", source = src, alert_overlay = alert_overlay) + notify_ghosts("[src] (player controlled) has appeared in [get_area(src)].") else if(ai_playercontrol_allowtype) var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state) notify_ghosts("[src] has appeared in [get_area(src)].", enter_link = "(Click to control)", source = src, alert_overlay = alert_overlay, action = NOTIFY_ATTACK) @@ -342,7 +343,7 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) /mob/living/simple_animal/hostile/poison/terror_spider/ObjBump(obj/O) if(istype(O, /obj/machinery/door/airlock)) var/obj/machinery/door/airlock/L = O - if(L.density) + if(L.density) // must check density here, to avoid rapid bumping of an airlock that is in the process of opening, instantly forcing it closed return try_open_airlock(L) if(istype(O, /obj/machinery/door/firedoor)) var/obj/machinery/door/firedoor/F = O @@ -352,7 +353,8 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) . = ..() /mob/living/simple_animal/hostile/poison/terror_spider/proc/msg_terrorspiders(msgtext) - for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in GLOB.ts_spiderlist) + for(var/thing in GLOB.ts_spiderlist) + var/mob/living/simple_animal/hostile/poison/terror_spider/T = thing if(T.stat != DEAD) to_chat(T, "TerrorSense: [msgtext]") @@ -365,21 +367,54 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) /mob/living/simple_animal/hostile/poison/terror_spider/proc/try_open_airlock(obj/machinery/door/airlock/D) if(D.operating) return - if(!D.density) - to_chat(src, "Closing doors does not help us.") - else if(D.welded) - to_chat(src, "The door is welded shut.") + if(D.welded) + to_chat(src, "The door is welded.") else if(D.locked) - to_chat(src, "The door is bolted shut.") + to_chat(src, "The door is bolted.") else if(D.allowed(src)) - D.open(1) - return 1 + if(D.density) + D.open(TRUE) + else + D.close(TRUE) + return TRUE else if(D.arePowerSystemsOn() && (spider_opens_doors != 2)) to_chat(src, "The door's motors resist your efforts to force it.") else if(!spider_opens_doors) to_chat(src, "Your type of spider is not strong enough to force open doors.") else - visible_message("[src] pries open the door!") + visible_message("[src] forces the door!") playsound(src.loc, "sparks", 100, 1) - D.open(1) - return 1 + if(D.density) + D.open(TRUE) + else + D.close(TRUE) + return TRUE + + +/mob/living/simple_animal/hostile/poison/terror_spider/Stat() + ..() + // Determines what shows in the "Status" tab for player-controlled spiders. Used to help players understand spider health regeneration mechanics. + // Uses because the status panel does NOT accept . + if(statpanel("Status") && ckey && stat == CONSCIOUS) + if(degenerate) + stat(null, "Hivemind Connection Severed! Dying...") // color=red + return + if(health != maxHealth) + var/hp_points_per_second = 0 + var/ltext = "FAST" + var/lcolor = "#fcba03" // orange + var/secs_per_tick = (SSmobs.wait / 10) // This uses SSmobs.wait because it must use the same frequency as mobs are processed + if(regen_points < (regen_points_per_hp * 2)) + // Slow regen speed: using regen_points as we get them. Figure out regen_points/sec, then convert that to hp/sec. + var/regen_points_per_second = (regen_points_per_tick / secs_per_tick) + hp_points_per_second = (regen_points_per_second / regen_points_per_hp) + ltext = "SLOW (HUNGRY!)" + lcolor = "#eb4034" // red + else + // Fast regen speed: healing at full 1 hp / tick rate. Just divide 1hp/tick by seconds/tick to get healing/sec. + hp_points_per_second = 1 / secs_per_tick + if(hp_points_per_second > 0) + var/pc_of_max_per_second = round(((hp_points_per_second / maxHealth) * 100), 0.1) + stat(null, "Regeneration: [ltext]: [num2text(pc_of_max_per_second)]% of health per second") + + diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d4f8e7c4c3d..4bff2c100bf 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -319,10 +319,9 @@ return verb /mob/living/simple_animal/movement_delay() - . = ..() - . = speed - + if(forced_look) + . += 3 . += config.animal_delay /mob/living/simple_animal/Stat() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 848606be3ec..4e4bd99e54d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -478,6 +478,41 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ return 0 //Unsupported slot //END HUMAN +/mob/proc/get_visible_mobs() + var/list/seen_mobs = list() + for(var/mob/M in view(src)) + seen_mobs += M + + return seen_mobs + +/** + * Returns an assoc list which contains the mobs in range and their "visible" name. + * Mobs out of view but in range will be listed as unknown. Else they will have their visible name +*/ +/mob/proc/get_telepathic_targets() + var/list/validtargets = new /list() + var/turf/T = get_turf(src) + var/list/mobs_in_view = get_visible_mobs() + + for(var/mob/living/M in range(14, T)) + if(M && M.mind) + if(M == src) + continue + var/mob_name + if(M in mobs_in_view) + mob_name = M.name + else + mob_name = "Unknown entity" + var/i = 0 + var/result_name + do + result_name = mob_name + if(i++) + result_name += " ([i])" // Avoid dupes + while(validtargets[result_name]) + validtargets[result_name] = M + return validtargets + // If you're looking for `reset_perspective`, that's a synonym for this proc. /mob/proc/reset_perspective(atom/A) if(client) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ff01fbe5cc9..6acfb92a515 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -288,7 +288,7 @@ S.message = Gibberish(S.message, p) -proc/muffledspeech(phrase) +/proc/muffledspeech(phrase) phrase = html_decode(phrase) var/leng=length(phrase) var/counter=length(phrase) @@ -675,4 +675,3 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well return TRUE -#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider)) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index d151a98309f..212bb41720d 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -38,8 +38,7 @@ O.rename_self("AI",1) - spawn() - qdel(src) + INVOKE_ASYNC(GLOBAL_PROC, .proc/qdel, src) // To prevent the proc from returning null. return O @@ -102,8 +101,7 @@ O.Namepick() - spawn(0)//To prevent the proc from returning null. - qdel(src) + INVOKE_ASYNC(GLOBAL_PROC, .proc/qdel, src) // To prevent the proc from returning null. return O //human -> alien @@ -135,9 +133,7 @@ to_chat(new_xeno, "You are now an alien.") new_xeno.update_pipe_vision() - spawn(0)//To prevent the proc from returning null. - qdel(src) - return + qdel(src) /mob/living/carbon/human/proc/slimeize(reproduce as num) if(notransform) @@ -190,9 +186,7 @@ to_chat(new_corgi, "You are now a Corgi. Yap Yap!") new_corgi.update_pipe_vision() - spawn(0)//To prevent the proc from returning null. - qdel(src) - return + qdel(src) /mob/living/carbon/human/Animalize() @@ -221,9 +215,7 @@ to_chat(new_mob, "You suddenly feel more... animalistic.") new_mob.update_pipe_vision() - spawn() - qdel(src) - return + qdel(src) /mob/proc/Animalize() @@ -264,9 +256,7 @@ to_chat(pai, "You have become a pAI! Your name is [pai.name].") pai.update_pipe_vision() - spawn(0)//To prevent the proc from returning null. - qdel(src) - return + qdel(src) /mob/proc/safe_respawn(var/MP) if(!MP) diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm deleted file mode 100644 index 948824fa32e..00000000000 --- a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm +++ /dev/null @@ -1,70 +0,0 @@ -GLOBAL_VAR_INIT(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 = GLOB.ntnrc_uid - GLOB.ntnrc_uid++ - if(GLOB.ntnet_global) - GLOB.ntnet_global.chat_channels.Add(src) - ..() - -/datum/ntnet_conversation/Destroy() - if(GLOB.ntnet_global) - GLOB.ntnet_global.chat_channels.Remove(src) - return ..() - -/datum/ntnet_conversation/proc/add_message(message, username) - message = "[station_time_timestamp()] [username]: [message]" - messages.Add(message) - trim_message_list() - -/datum/ntnet_conversation/proc/add_status_message(message) - messages.Add("[station_time_timestamp()] -!- [message]") - trim_message_list() - -/datum/ntnet_conversation/proc/trim_message_list() - if(messages.len <= 50) - return - messages = messages.Copy(messages.len-50 ,0) - -/datum/ntnet_conversation/proc/add_client(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(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(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(newtitle, 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 diff --git a/code/modules/modular_computers/NTNet/NTNet.dm b/code/modules/modular_computers/NTNet/NTNet.dm deleted file mode 100644 index 2f9aa3f2e7d..00000000000 --- a/code/modules/modular_computers/NTNet/NTNet.dm +++ /dev/null @@ -1,145 +0,0 @@ -GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, 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/chat_channels = list() - var/list/fileservers = 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(GLOB.ntnet_global && (GLOB.ntnet_global != src)) - GLOB.ntnet_global = src // There can be only one. - for(var/obj/machinery/ntnet_relay/R in GLOB.machines) - relays.Add(R) - R.NTNet = src - build_software_lists() - add_log("NTNet logging system activated.") - -// Simplified logging: Adds a log. log_string is mandatory parameter, source is optional. -/datum/ntnet/proc/add_log(log_string, obj/item/computer_hardware/network_card/source = null) - var/log_text = "[station_time_timestamp()] - " - if(source) - log_text += "[source.get_network_tag()] - " - else - log_text += "*SYSTEM* - " - log_text += log_string - logs.Add(log_text) - - - // We have too many logs, remove the oldest entries until we get into the limit - if(logs.len > setting_maxlogcount) - logs = logs.Copy(logs.len-setting_maxlogcount,0) - - -// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled. -/datum/ntnet/proc/check_function(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/M in relays) - var/obj/machinery/ntnet_relay/R = M - if(R.operable()) - operating = 1 - break - - if(setting_disabled) - return 0 - - switch(specific_action) - if(NTNET_SOFTWAREDOWNLOAD) - return (operating && setting_softwaredownload) - if(NTNET_PEERTOPEER) - return (operating && setting_peertopeer) - if(NTNET_COMMUNICATION) - return (operating && setting_communication) - if(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 || 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) - -// Attempts to find a downloadable file according to filename var -/datum/ntnet/proc/find_ntnet_file_by_name(filename) - for(var/N in available_station_software) - var/datum/computer_file/program/P = N - if(filename == P.filename) - return P - for(var/N in available_antag_software) - var/datum/computer_file/program/P = N - 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(lognumber) - if(!lognumber) - return 0 - // Trim the value if necessary - lognumber = max(MIN_NTNET_LOGS, min(lognumber, MAX_NTNET_LOGS)) - setting_maxlogcount = lognumber - add_log("Configuration Updated. Now keeping [setting_maxlogcount] logs in system memory.") - -/datum/ntnet/proc/toggle_function(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.") diff --git a/code/modules/modular_computers/NTNet/NTNet_relay.dm b/code/modules/modular_computers/NTNet/NTNet_relay.dm deleted file mode 100644 index 97ddcfb69c0..00000000000 --- a/code/modules/modular_computers/NTNet/NTNet_relay.dm +++ /dev/null @@ -1,125 +0,0 @@ -// 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 = ACTIVE_POWER_USE - active_power_usage = 100 // 100 watts. Yes I know this is a high power machine but this fucking obliterates an unpowered smes (AI sat) - idle_power_usage = 100 - icon = 'icons/obj/stationobjs.dmi' - 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/inoperable(additional_flags = 0) - if(stat & (BROKEN | NOPOWER | EMPED | additional_flags)) - return 1 - if(dos_failure) - return 1 - if(!enabled) - return 1 - return 0 - -/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 = ACTIVE_POWER_USE - else - use_power = IDLE_POWER_USE - - update_icon() - - 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() - GLOB.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() - GLOB.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) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "ntnet_relay.tmpl", "NTNet Quantum Relay", 500, 300) - ui.open() - -/obj/machinery/ntnet_relay/ui_data(mob/user) - var/list/data = list() - data["enabled"] = enabled - data["dos_capacity"] = dos_capacity - data["dos_overload"] = dos_overload - data["dos_crashed"] = dos_failure - return data - - -/obj/machinery/ntnet_relay/Topic(href, list/href_list) - if(..()) - return - switch(href_list["action"]) - if("restart") - dos_overload = 0 - dos_failure = 0 - update_icon() - GLOB.ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.") - if("toggle") - enabled = !enabled - GLOB.ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].") - update_icon() - return 1 - - -/obj/machinery/ntnet_relay/attack_hand(mob/living/user) - ui_interact(user) - -/obj/machinery/ntnet_relay/New() - uid = gl_uid - gl_uid++ - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/ntnet_relay(null) - component_parts += new /obj/item/stack/cable_coil(null, 2) - - if(GLOB.ntnet_global) - GLOB.ntnet_global.relays.Add(src) - NTNet = GLOB.ntnet_global - GLOB.ntnet_global.add_log("New quantum relay activated. Current amount of linked relays: [NTNet.relays.len]") - ..() - -/obj/machinery/ntnet_relay/Destroy() - if(GLOB.ntnet_global) - GLOB.ntnet_global.relays.Remove(src) - GLOB.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" - - return ..() - -/obj/item/circuitboard/machine/ntnet_relay - name = "NTNet Relay (Machine Board)" - build_path = /obj/machinery/ntnet_relay - origin_tech = "programming=3;bluespace=3;magnets=2" - req_components = list(/obj/item/stack/cable_coil = 2) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm deleted file mode 100644 index 1dd45a33603..00000000000 --- a/code/modules/modular_computers/computers/item/computer.dm +++ /dev/null @@ -1,369 +0,0 @@ -// This is the base type that does all the hardware stuff. -// Other types expand it - tablets use a direct subtypes, and -// consoles and laptops use "procssor" item that is held inside machinery piece -/obj/item/modular_computer - name = "modular microcomputer" - desc = "A small portable microcomputer." - - 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 - 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/emagged = 0 // Whether the computer is emagged. - - 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) - - // 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 = 'icons/obj/computer.dmi' - icon_state = "laptop-open" - var/icon_state_unpowered = null // Icon state when the computer is turned off. - var/icon_state_powered = null // Icon state when the computer is turned on. - 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/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4. - var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer. - - integrity_failure = 50 - max_integrity = 100 - armor = list("melee" = 0, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) - - // Important hardware (must be installed for computer to work) - - // Optional hardware (improves functionality, but is not critical for computer to work) - - var/list/all_components // List of "connection ports" in this computer and the components with which they are plugged - - var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with. - var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks. - - - -/obj/item/modular_computer/New() - update_icon() - if(!physical) - physical = src - ..() - START_PROCESSING(SSobj, src) - all_components = list() - idle_threads = list() - -/obj/item/modular_computer/Destroy() - kill_program(forced = TRUE) - for(var/H in all_components) - var/obj/item/computer_hardware/CH = all_components[H] - if(CH.holder == src) - CH.on_remove(src) - CH.holder = null - all_components.Remove(CH.device_type) - qdel(CH) - physical = null - STOP_PROCESSING(SSobj, src) - return ..() - - -/obj/item/modular_computer/proc/add_verb(var/path) - switch(path) - if(MC_CARD) - verbs += /obj/item/modular_computer/proc/eject_id - if(MC_SDD) - verbs += /obj/item/modular_computer/proc/eject_disk - if(MC_AI) - verbs += /obj/item/modular_computer/proc/eject_card - -/obj/item/modular_computer/proc/remove_verb(path) - switch(path) - if(MC_CARD) - verbs -= /obj/item/modular_computer/proc/eject_id - if(MC_SDD) - verbs -= /obj/item/modular_computer/proc/eject_disk - if(MC_AI) - verbs -= /obj/item/modular_computer/proc/eject_card - -// Eject ID card from computer, if it has ID slot with card inside. -/obj/item/modular_computer/proc/eject_id() - set name = "Eject ID" - set category = "Object" - set src in view(1) - - if(issilicon(usr)) - return - var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - if(!usr.incapacitated()) - card_slot.try_eject(null, usr) - -// Eject ID card from computer, if it has ID slot with card inside. -/obj/item/modular_computer/proc/eject_card() - set name = "Eject Intellicard" - set category = "Object" - set src in view(1) - - if(issilicon(usr)) - return - var/obj/item/computer_hardware/ai_slot/ai_slot = all_components[MC_AI] - if(!usr.incapacitated()) - ai_slot.try_eject(null, usr, 1) - - -// Eject ID card from computer, if it has ID slot with card inside. -/obj/item/modular_computer/proc/eject_disk() - set name = "Eject Data Disk" - set category = "Object" - set src in view(1) - - if(issilicon(usr)) - return - - if(!usr.incapacitated()) - var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD] - if(uninstall_component(portable_drive, usr)) - portable_drive.verb_pickup() - -/obj/item/modular_computer/AltClick(mob/user) - ..() - if(issilicon(user)) - return - - if(!user.incapacitated() && Adjacent(user)) - var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - var/obj/item/computer_hardware/ai_slot/ai_slot = all_components[MC_AI] - var/obj/item/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD] - if(portable_drive) - if(uninstall_component(portable_drive, user)) - portable_drive.verb_pickup() - else - if(card_slot && card_slot.try_eject(null, user)) - return - if(ai_slot) - ai_slot.try_eject(null, user) - - -// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. -/obj/item/modular_computer/GetAccess() - var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - if(card_slot) - return card_slot.GetAccess() - return ..() - -/obj/item/modular_computer/GetID() - var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - if(card_slot) - return card_slot.GetID() - return ..() - -/obj/item/modular_computer/attack_ai(mob/user) - return attack_self(user) - -/obj/item/modular_computer/attack_ghost(mob/dead/observer/user) - if(enabled) - ui_interact(user) - else if(user.can_admin_interact()) - 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/emag_act(mob/user) - if(emagged) - to_chat(user, "\The [src] was already emagged.") - return 0 - else - 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/examine(mob/user) - . = ..() - if(obj_integrity <= integrity_failure) - . += "It is heavily damaged!" - else if(obj_integrity < max_integrity) - . += "It is damaged." - -/obj/item/modular_computer/update_icon() - overlays.Cut() - if(!enabled) - icon_state = icon_state_unpowered - else - icon_state = icon_state_powered - if(active_program && active_program.program_state != PROGRAM_STATE_KILLED) - overlays += active_program.program_icon_state ? active_program.program_icon_state : icon_state_menu - else - overlays += icon_state_menu - - if(obj_integrity <= integrity_failure) - overlays += "bsod" - overlays += "broken" - - -// On-click handling. Turns on the computer if it's off and opens the GUI. -/obj/item/modular_computer/attack_self(mob/user) - if(enabled) - ui_interact(user) - else - turn_on(user) - -/obj/item/modular_computer/proc/turn_on(mob/user) - var/issynth = issilicon(user) // Robots and AIs get different activation messages. - if(obj_integrity <= integrity_failure) - 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 we have a recharger, enable it automatically. Lets computer without a battery work. - var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] - if(recharger) - recharger.enabled = 1 - - if(all_components[MC_CPU] && use_power()) // use_power() checks if the PC is powered - 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].") - enabled = 1 - update_icon() - ui_interact(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.") - -// Process currently calls handle_power(), may be expanded in future if more things are added. -/obj/item/modular_computer/process() - if(!enabled) // The computer is turned off - last_power_usage = 0 - return 0 - - if(obj_integrity <= integrity_failure) - shutdown_computer() - return 0 - - if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) - active_program.event_networkfailure(0) // Active program requires NTNet to run but we've just lost connection. Crash. - - if(active_program) - if(active_program.program_state != PROGRAM_STATE_KILLED) - active_program.process_tick() - active_program.ntnet_status = get_ntnet_status() - else - active_program = null - - for(var/I in idle_threads) - var/datum/computer_file/program/P = I - if(P.program_state != PROGRAM_STATE_KILLED) - if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) - P.event_networkfailure(1) - P.process_tick() - P.ntnet_status = get_ntnet_status() - else - idle_threads.Remove(P) - - handle_power() // Handles all computer power interaction - -// Relays kill program request to currently active program. Use this to quit current program. -/obj/item/modular_computer/proc/kill_program(forced = FALSE) - if(active_program && active_program.program_state != PROGRAM_STATE_KILLED) - 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(specific_action = 0) - var/obj/item/computer_hardware/network_card/network_card = all_components[MC_NET] - if(network_card) - return network_card.get_signal(specific_action) - else - return 0 - -/obj/item/modular_computer/proc/add_log(text) - if(!get_ntnet_status()) - return FALSE - var/obj/item/computer_hardware/network_card/network_card = all_components[MC_NET] - return GLOB.ntnet_global.add_log(text, network_card) - -/obj/item/modular_computer/proc/shutdown_computer(loud = 1) - if(enabled) - kill_program(forced = TRUE) - for(var/datum/computer_file/program/P in idle_threads) - P.kill_program(forced = TRUE) - idle_threads.Remove(P) - if(loud) - physical.visible_message("\The [src] shuts down.") - enabled = 0 - update_icon() - - -/obj/item/modular_computer/attackby(obj/item/W, mob/user) - // Insert items into the components - for(var/h in all_components) - var/obj/item/computer_hardware/H = all_components[h] - if(H.try_insert(W, user)) - return - - // Insert new hardware - if(istype(W, /obj/item/computer_hardware)) - if(install_component(W, user)) - return - - if(istype(W, /obj/item/wrench)) - if(all_components.len) - to_chat(user, "Remove all components from \the [src] before disassembling it.") - return - new /obj/item/stack/sheet/metal(get_turf(loc), steel_sheet_cost) - physical.visible_message("\The [src] has been disassembled by [user].") - relay_qdel() - qdel(src) - return - - if(istype(W, /obj/item/screwdriver)) - if(!all_components.len) - to_chat(user, "This device doesn't have any components installed.") - return - var/list/component_names = list() - for(var/h in all_components) - var/obj/item/computer_hardware/H = all_components[h] - component_names.Add(H.name) - - var/choice = input(user, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in component_names - - if(!choice) - return - - if(!Adjacent(user)) - return - - var/obj/item/computer_hardware/H = find_hardware_by_name(choice) - - if(!H) - return - - uninstall_component(H, user) - return - - ..() - -/obj/item/modular_computer/welder_act(mob/user, obj/item/I) - . = TRUE - if(!I.tool_use_check(user, 0)) - return - default_welder_repair(user, I) - -// Used by processor to relay qdel() to machinery type. -/obj/item/modular_computer/proc/relay_qdel() - return - -// Perform adjacency checks on our physical counterpart, if any. -/obj/item/modular_computer/Adjacent(atom/neighbor) - if(physical && physical != src) - return physical.Adjacent(neighbor) - return ..() diff --git a/code/modules/modular_computers/computers/item/computer_components.dm b/code/modules/modular_computers/computers/item/computer_components.dm deleted file mode 100644 index fb6d41d989f..00000000000 --- a/code/modules/modular_computers/computers/item/computer_components.dm +++ /dev/null @@ -1,58 +0,0 @@ -/obj/item/modular_computer/proc/can_install_component(obj/item/computer_hardware/H, mob/living/user = null) - if(!H.can_install(src, user)) - return FALSE - - if(H.w_class > max_hardware_size) - if(user) - to_chat(user, "This component is too large for \the [src]!") - return FALSE - - if(all_components[H.device_type]) - if(user) - to_chat(user, "This computer's hardware slot is already occupied by \the [all_components[H.device_type]].") - return FALSE - return TRUE - - -// Installs component. -/obj/item/modular_computer/proc/install_component(obj/item/computer_hardware/H, mob/living/user = null) - if(!can_install_component(H, user)) - return FALSE - - if(user && !user.unEquip(H)) - return FALSE - H.forceMove(src) - - all_components[H.device_type] = H - - if(user) - to_chat(user, "You install \the [H] into \the [src].") - H.holder = src - H.on_install(src, user) - - -// Uninstalls component. -/obj/item/modular_computer/proc/uninstall_component(obj/item/computer_hardware/H, mob/living/user = null) - if(H.holder != src) // Not our component at all. - return FALSE - - all_components.Remove(H.device_type) - - if(user) - to_chat(user, "You remove \the [H] from \the [src].") - - H.forceMove(get_turf(src)) - H.holder = null - H.on_remove(src, user) - if(enabled && !use_power()) - 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(name) - for(var/i in all_components) - var/obj/O = all_components[i] - if(O.name == name) - return O - return null diff --git a/code/modules/modular_computers/computers/item/computer_damage.dm b/code/modules/modular_computers/computers/item/computer_damage.dm deleted file mode 100644 index 08a8ca6aaf4..00000000000 --- a/code/modules/modular_computers/computers/item/computer_damage.dm +++ /dev/null @@ -1,30 +0,0 @@ -/obj/item/modular_computer/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) - . = ..() - var/component_probability = min(50, max(damage_amount*0.1, 1 - obj_integrity/max_integrity)) - switch(damage_flag) - if("bullet") - component_probability = damage_amount * 0.5 - if("laser") - component_probability = damage_amount * 0.66 - if(component_probability) - for(var/I in all_components) - var/obj/item/computer_hardware/H = all_components[I] - if(prob(component_probability)) - H.take_damage(round(damage_amount*0.5), damage_type, damage_flag, 0) - -/obj/item/modular_computer/deconstruct(disassembled = TRUE) - break_apart() - -/obj/item/modular_computer/proc/break_apart() - if(!(flags & NODECONSTRUCT)) - physical.visible_message("\The [src] breaks apart!") - var/turf/newloc = get_turf(src) - new /obj/item/stack/sheet/metal(newloc, round(steel_sheet_cost/2)) - for(var/C in all_components) - var/obj/item/computer_hardware/H = all_components[C] - uninstall_component(H) - H.forceMove(newloc) - if(prob(25)) - H.take_damage(rand(10,30), BRUTE, 0, 0) - relay_qdel() - qdel(src) diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm deleted file mode 100644 index 27c81d48190..00000000000 --- a/code/modules/modular_computers/computers/item/computer_power.dm +++ /dev/null @@ -1,77 +0,0 @@ -// Tries to draw power from charger or, if no operational charger is present, from power cell. -/obj/item/modular_computer/proc/use_power(amount = 0) - if(check_power_override()) - return TRUE - - var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] - - if(recharger && recharger.check_functionality()) - if(recharger.use_power(amount)) - return TRUE - - var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] - - if(battery_module && battery_module.battery && battery_module.battery.charge) - var/obj/item/stock_parts/cell/cell = battery_module.battery - if(cell.use(amount * GLOB.CELLRATE)) - return TRUE - else // Discharge the cell anyway. - cell.use(min(amount*GLOB.CELLRATE, cell.charge)) - return FALSE - return FALSE - -/obj/item/modular_computer/proc/give_power(amount) - var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] - if(battery_module && battery_module.battery) - return battery_module.battery.give(amount) - return 0 - -/obj/item/modular_computer/get_cell() - var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] - if(battery_module && battery_module.battery) - return battery_module.battery - -// Used in following function to reduce copypaste -/obj/item/modular_computer/proc/power_failure() - if(enabled) // Shut down the computer - if(active_program) - active_program.event_powerfailure(0) - for(var/I in idle_threads) - var/datum/computer_file/program/PRG = I - PRG.event_powerfailure(1) - shutdown_computer(0) - -// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged -/obj/item/modular_computer/proc/handle_power() - var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] - if(recharger) - recharger.process() - - var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage - - for(var/obj/item/computer_hardware/H in all_components) - if(H.enabled) - power_usage += H.power_usage - - if(use_power(power_usage)) - last_power_usage = power_usage - return TRUE - else - power_failure() - return FALSE - -/obj/item/modular_computer/proc/get_power_eta() - var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] - if(battery_module && battery_module.battery) - var/hours = 0 - var/minutes = (battery_module.battery.charge) / (last_power_usage / 20) // 20 = obj processing interval - if(minutes > 60) - hours = minutes/60 - minutes = (hours - round(hours)) * 60 - var/seconds = (minutes - round(minutes)) * 60 - return list("hours" = hours, "minutes" = minutes, "seconds" = seconds) - return list() - -// Used by child types if they have other power source than battery or recharger -/obj/item/modular_computer/proc/check_power_override() - return FALSE diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm deleted file mode 100644 index 36df0243f54..00000000000 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ /dev/null @@ -1,194 +0,0 @@ -// Operates NanoUI -/obj/item/modular_computer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(!enabled) - if(ui) - ui.close() - return 0 - if(!use_power()) - if(ui) - ui.close() - return 0 - - // Robots don't really need to see the screen, their wireless connection works as long as computer is on. - if(!screen_on && !issilicon(user)) - 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. - var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] - if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len) - to_chat(user, "\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning.") - return // No HDD, No HDD files list or no stored files. Something is very broken. - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "computer_main.tmpl", "NTOS Main menu", 400, 500) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - - -/obj/item/modular_computer/ui_data(mob/user) - var/list/data = get_header_data() - data["programs"] = list() - var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] - for(var/datum/computer_file/program/P in hard_drive.stored_files) - var/running = 0 - if(P in idle_threads) - running = 1 - - data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running)) - - return data - -// 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() - - var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] - var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] - - if(battery_module && battery_module.battery) - 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(recharger && recharger.enabled && recharger.check_functionality() && recharger.use_power(0)) - data["PC_apclinkicon"] = "charging.gif" - - 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" - - if(idle_threads.len) - var/list/program_headers = list() - for(var/I in idle_threads) - var/datum/computer_file/program/P = I - if(!P.ui_header) - continue - program_headers.Add(list(list( - "icon" = P.ui_header - ))) - - data["PC_programheaders"] = program_headers - - data["PC_stationtime"] = station_time_timestamp() - data["PC_showexitprogram"] = active_program ? 1 : 0 // Hides "Exit Program" button on mainscreen - return data - - -// Handles user's GUI input -/obj/item/modular_computer/Topic(href, list/href_list) - if(..()) - return - var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] - switch(href_list["action"]) - if("PC_exit") - kill_program() - return 1 - if("PC_shutdown") - shutdown_computer() - return 1 - if("PC_minimize") - var/mob/user = usr - if(!active_program || !all_components[MC_CPU]) - return 1 - - idle_threads.Add(active_program) - active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs - - active_program = null - update_icon() - if(user && istype(user)) - ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. - - if("PC_killprogram") - var/prog = href_list["name"] - 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 1 - - P.kill_program(forced = TRUE) - to_chat(user, "Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.") - - if("PC_runprogram") - var/prog = href_list["name"] - 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 program\" warning.") - return 1 - - P.computer = src - - if(!P.is_supported_by_hardware(hardware_flag, 1, user)) - return 1 - - // The program is already running. Resume it. - if(P in idle_threads) - P.program_state = PROGRAM_STATE_ACTIVE - active_program = P - idle_threads.Remove(P) - update_icon() - return - - var/obj/item/computer_hardware/processor_unit/PU = all_components[MC_CPU] - - if(idle_threads.len > PU.max_idle_programs) - to_chat(user, "\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error.") - return 1 - - 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 \"Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.") - return 1 - if(P.run_program(user)) - active_program = P - update_icon() - return 1 - else - return - -/obj/item/modular_computer/nano_host() - if(physical) - return physical - return src diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm deleted file mode 100644 index 223627bd69e..00000000000 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ /dev/null @@ -1,109 +0,0 @@ -/obj/item/modular_computer/laptop - name = "laptop" - desc = "A portable laptop computer." - - icon = 'icons/obj/modular_laptop.dmi' - icon_state = "laptop-closed" - icon_state_powered = "laptop" - icon_state_unpowered = "laptop-off" - icon_state_menu = "menu" - - hardware_flag = PROGRAM_LAPTOP - max_hardware_size = 2 - w_class = WEIGHT_CLASS_NORMAL - - flags = HANDSLOW // No running around with open laptops in hands. - - screen_on = 0 // Starts closed - var/start_open = 1 // unless this var is set to 1 - var/icon_state_closed = "laptop-closed" - var/w_class_open = WEIGHT_CLASS_BULKY - var/slowdown_open = 1 - -/obj/item/modular_computer/laptop/New() - ..() - if(start_open && !screen_on) - toggle_open() - -/obj/item/modular_computer/laptop/update_icon() - if(screen_on) - ..() - else - overlays.Cut() - icon_state = icon_state_closed - -/obj/item/modular_computer/laptop/attack_self(mob/user) - if(!screen_on) - try_toggle_open(user) - else - return ..() - -/obj/item/modular_computer/laptop/verb/open_computer() - set name = "Toggle Open" - set category = "Object" - set src in view(1) - - try_toggle_open(usr) - -/obj/item/modular_computer/laptop/MouseDrop(obj/over_object, src_location, over_location) - if(over_object == usr || over_object == src) - try_toggle_open(usr) - if(ishuman(usr)) - if(!isturf(loc) || !Adjacent(usr)) - return - if(over_object && !usr.incapacitated()) - if(!usr.canUnEquip(src)) - to_chat(usr, "[src] appears stuck on you!") - return - switch(over_object.name) - if("r_hand") - usr.unEquip(src) - usr.put_in_r_hand(src) - if("l_hand") - usr.unEquip(src) - usr.put_in_l_hand(src) - -/obj/item/modular_computer/laptop/attack_hand(mob/user) - if(screen_on && isturf(loc)) - return attack_self(user) - - return ..() - - -/obj/item/modular_computer/laptop/proc/try_toggle_open(mob/living/user) - if(issilicon(user)) - return - if(!isturf(loc) && !ismob(loc)) // No opening it in backpack. - return - if(user.incapacitated() || !Adjacent(user)) - return - - toggle_open(user) - - -/obj/item/modular_computer/laptop/AltClick(mob/user) - if(screen_on) // Close it. - try_toggle_open(user) - else - return ..() - -/obj/item/modular_computer/laptop/proc/toggle_open(mob/living/user=null) - if(screen_on) - if(user) - to_chat(user, "You close \the [src].") - slowdown = initial(slowdown) - w_class = initial(w_class) - else - if(user) - to_chat(user, "You open \the [src].") - slowdown = slowdown_open - w_class = w_class_open - - screen_on = !screen_on - update_icon() - - - -// Laptop frame, starts empty and closed. -/obj/item/modular_computer/laptop/buildable - start_open = 0 diff --git a/code/modules/modular_computers/computers/item/laptop_presets.dm b/code/modules/modular_computers/computers/item/laptop_presets.dm deleted file mode 100644 index 43720dfa2fc..00000000000 --- a/code/modules/modular_computers/computers/item/laptop_presets.dm +++ /dev/null @@ -1,21 +0,0 @@ -/obj/item/modular_computer/laptop/preset/New() - . = ..() - install_component(new /obj/item/computer_hardware/processor_unit/small) - install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) - install_component(new /obj/item/computer_hardware/hard_drive) - install_component(new /obj/item/computer_hardware/network_card) - install_programs() - - -/obj/item/modular_computer/laptop/preset/proc/install_programs() - return - - -/obj/item/modular_computer/laptop/preset/civillian - desc = "A low-end laptop often used for personal recreation." - - -/obj/item/modular_computer/laptop/preset/civillian/install_programs() - var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] - hard_drive.store_file(new/datum/computer_file/program/chatclient()) - hard_drive.store_file(new/datum/computer_file/program/nttransfer()) diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm deleted file mode 100644 index 3095e0af876..00000000000 --- a/code/modules/modular_computers/computers/item/processor.dm +++ /dev/null @@ -1,73 +0,0 @@ -// Held by /obj/machinery/modular_computer to reduce amount of copy-pasted code. -/obj/item/modular_computer/processor - name = "processing unit" - desc = "You shouldn't see this. If you do, report it." - icon = null - icon_state = null - icon_state_unpowered = null - icon_state_menu = null - hardware_flag = 0 - - var/obj/machinery/modular_computer/machinery_computer = null - -/obj/item/modular_computer/processor/Destroy() - . = ..() - if(machinery_computer && (machinery_computer.cpu == src)) - machinery_computer.cpu = null - machinery_computer = null - -/obj/item/modular_computer/processor/New(comp) - if(!comp || !istype(comp, /obj/machinery/modular_computer)) - CRASH("Inapropriate type passed to obj/item/modular_computer/processor/New()! Aborting.") - // Obtain reference to machinery computer - all_components = list() - idle_threads = list() - machinery_computer = comp - machinery_computer.cpu = src - hardware_flag = machinery_computer.hardware_flag - max_hardware_size = machinery_computer.max_hardware_size - steel_sheet_cost = machinery_computer.steel_sheet_cost - obj_integrity = machinery_computer.obj_integrity - max_integrity = machinery_computer.max_integrity - integrity_failure = machinery_computer.integrity_failure - base_active_power_usage = machinery_computer.base_active_power_usage - base_idle_power_usage = machinery_computer.base_idle_power_usage - -/obj/item/modular_computer/processor/relay_qdel() - qdel(machinery_computer) - -/obj/item/modular_computer/processor/update_icon() - if(machinery_computer) - return machinery_computer.update_icon() - -// This thing is not meant to be used on it's own, get topic data from our machinery owner. -//obj/item/modular_computer/processor/canUseTopic(user, state) -// if(!machinery_computer) -// return 0 - -// return machinery_computer.canUseTopic(user, state) - -/obj/item/modular_computer/processor/shutdown_computer() - if(!machinery_computer) - return - ..() - machinery_computer.update_icon() - return - -/obj/item/modular_computer/processor/add_verb(path) - switch(path) - if(MC_CARD) - machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_id - if(MC_SDD) - machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_disk - if(MC_AI) - machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_card - -/obj/item/modular_computer/processor/remove_verb(path) - switch(path) - if(MC_CARD) - machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_id - if(MC_SDD) - machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk - if(MC_AI) - machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_card diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm deleted file mode 100644 index f0a044b1d36..00000000000 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ /dev/null @@ -1,12 +0,0 @@ -/obj/item/modular_computer/tablet //Its called tablet for theme of 90ies but actually its a "big smartphone" sized - name = "tablet computer" - icon = 'icons/obj/modular_tablet.dmi' - icon_state = "tablet" - icon_state_unpowered = "tablet" - icon_state_powered = "tablet" - icon_state_menu = "menu" - hardware_flag = PROGRAM_TABLET - max_hardware_size = 1 - w_class = WEIGHT_CLASS_SMALL - steel_sheet_cost = 1 - slot_flags = SLOT_ID | SLOT_BELT diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm deleted file mode 100644 index 3ac32e30ca9..00000000000 --- a/code/modules/modular_computers/computers/item/tablet_presets.dm +++ /dev/null @@ -1,29 +0,0 @@ - -// This is literally the worst possible cheap tablet -/obj/item/modular_computer/tablet/preset/cheap - desc = "A low-end tablet often seen among low ranked station personnel." - -/obj/item/modular_computer/tablet/preset/cheap/New() - . = ..() - install_component(new /obj/item/computer_hardware/processor_unit/small) - install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer/micro)) - install_component(new /obj/item/computer_hardware/hard_drive/small) - install_component(new /obj/item/computer_hardware/network_card) - -// Alternative version, an average one, for higher ranked positions mostly -/obj/item/modular_computer/tablet/preset/advanced/New() - . = ..() - install_component(new /obj/item/computer_hardware/processor_unit/small) - install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) - install_component(new /obj/item/computer_hardware/hard_drive/small) - install_component(new /obj/item/computer_hardware/network_card) - install_component(new /obj/item/computer_hardware/card_slot) - install_component(new /obj/item/computer_hardware/printer/mini) - -/obj/item/modular_computer/tablet/preset/cargo/New() - . = ..() - install_component(new /obj/item/computer_hardware/processor_unit/small) - install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) - install_component(new /obj/item/computer_hardware/hard_drive/small) - install_component(new /obj/item/computer_hardware/network_card) - install_component(new /obj/item/computer_hardware/printer/mini) diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm deleted file mode 100644 index a2357fd9ebe..00000000000 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ /dev/null @@ -1,76 +0,0 @@ -/obj/machinery/modular_computer/console/preset - // Can be changed to give devices specific hardware - var/_has_id_slot = 0 - var/_has_printer = 0 - var/_has_battery = 0 - var/_has_ai = 0 - -/obj/machinery/modular_computer/console/preset/New() - . = ..() - if(!cpu) - return - cpu.install_component(new /obj/item/computer_hardware/processor_unit) - - if(_has_id_slot) - cpu.install_component(new /obj/item/computer_hardware/card_slot) - if(_has_printer) - cpu.install_component(new /obj/item/computer_hardware/printer) - if(_has_battery) - cpu.install_component(new /obj/item/computer_hardware/battery(cpu, /obj/item/stock_parts/cell/computer/super)) - if(_has_ai) - cpu.install_component(new /obj/item/computer_hardware/ai_slot) - install_programs() - -// Override in child types to install preset-specific programs. -/obj/machinery/modular_computer/console/preset/proc/install_programs() - return - - - -// ===== ENGINEERING CONSOLE ===== -/obj/machinery/modular_computer/console/preset/engineering - console_department = "Engineering" - desc = "A stationary computer. This one comes preloaded with engineering programs." - -/obj/machinery/modular_computer/console/preset/engineering/install_programs() - var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] - hard_drive.store_file(new/datum/computer_file/program/power_monitor()) -// hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) //TO-DO:TGUI--Uncomment Modular computers - hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor()) - -// ===== RESEARCH CONSOLE ===== -/obj/machinery/modular_computer/console/preset/research - console_department = "Research" - desc = "A stationary computer. This one comes preloaded with research programs." - _has_ai = 1 - -/obj/machinery/modular_computer/console/preset/research/install_programs() - var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] - 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/aidiag()) - - -// ===== COMMAND CONSOLE ===== -/obj/machinery/modular_computer/console/preset/command - console_department = "Command" - desc = "A stationary computer. This one comes preloaded with command programs." - _has_id_slot = 1 - _has_printer = 1 - -/obj/machinery/modular_computer/console/preset/command/install_programs() - var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] - 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()) - -// ===== CIVILIAN CONSOLE ===== -/obj/machinery/modular_computer/console/preset/civilian - console_department = "Civilian" - desc = "A stationary computer. This one comes preloaded with generic programs." - -/obj/machinery/modular_computer/console/preset/civilian/install_programs() - var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] - hard_drive.store_file(new/datum/computer_file/program/chatclient()) - hard_drive.store_file(new/datum/computer_file/program/nttransfer()) diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm deleted file mode 100644 index 391396a7d75..00000000000 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ /dev/null @@ -1,154 +0,0 @@ -// Global var to track modular computers -GLOBAL_LIST_EMPTY(global_modular_computers) - -// Modular Computer - device that runs various programs and operates with hardware -// DO NOT SPAWN THIS TYPE. Use /laptop/ or /console/ instead. -/obj/machinery/modular_computer - name = "modular computer" - desc = "An advanced computer." - - use_power = IDLE_POWER_USE - idle_power_usage = 5 - var/hardware_flag = 0 // A flag that describes this device type - var/last_power_usage = 0 // Power usage during last tick - - // 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 - icon_state = null - var/icon_state_unpowered = null // Icon state when the computer is turned off. - var/icon_state_powered = null // Icon state when the computer is turned on. - var/screen_icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. - var/screen_icon_screensaver = "standby" // Icon state overlay when the computer is powered, but not 'switched on'. - 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 = 10 // Amount of steel sheets refunded when disassembling an empty frame of this computer. - var/light_strength = 0 // Light luminosity when turned on - var/base_active_power_usage = 100 // 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 = 10 // Power usage when the computer is idle and screen is off (currently only applies to laptops) - - var/obj/item/modular_computer/processor/cpu = null // CPU that handles most logic while this type only handles power and other specific things. - -/obj/machinery/modular_computer/New() - ..() - cpu = new(src) - cpu.physical = src - GLOB.global_modular_computers.Add(src) - -/obj/machinery/modular_computer/Destroy() - QDEL_NULL(cpu) - return ..() - -/obj/machinery/modular_computer/attack_ghost(mob/dead/observer/user) - if(cpu) - cpu.attack_ghost(user) - -/obj/machinery/modular_computer/emag_act(mob/user) - return cpu ? cpu.emag_act(user) : 1 - -/obj/machinery/modular_computer/update_icon() - overlays.Cut() - icon_state = icon_state_powered - - if(!cpu || !cpu.enabled) - if (!(stat & NOPOWER) && (cpu && cpu.use_power())) - overlays += screen_icon_screensaver - else - icon_state = icon_state_unpowered - set_light(0) - else - set_light(light_strength) - if(cpu.active_program) - overlays += cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu - else - overlays += screen_icon_state_menu - - if(cpu && cpu.obj_integrity <= cpu.integrity_failure) - overlays += "bsod" - overlays += "broken" - -// Eject ID card from computer, if it has ID slot with card inside. -/obj/machinery/modular_computer/proc/eject_id() - set name = "Eject ID" - set category = "Object" - - if(cpu) - cpu.eject_id() - -// Eject ID card from computer, if it has ID slot with card inside. -/obj/machinery/modular_computer/proc/eject_disk() - set name = "Eject Data Disk" - set category = "Object" - - if(cpu) - cpu.eject_disk() - -/obj/machinery/modular_computer/proc/eject_card() - set name = "Eject Intellicard" - set category = "Object" - set src in view(1) - - if(cpu) - cpu.eject_card() - -/obj/machinery/modular_computer/AltClick(mob/user) - if(cpu) - cpu.AltClick(user) - -// On-click handling. Turns on the computer if it's off and opens the GUI. -/obj/machinery/modular_computer/attack_hand(mob/user) - if(cpu) - cpu.attack_self(user) // CPU is an item, that's why we route attack_hand to attack_self - -// Process currently calls handle_power(), may be expanded in future if more things are added. -/obj/machinery/modular_computer/process() - if(cpu) - // Keep names in sync. - cpu.name = src.name - cpu.process() - -// Used in following function to reduce copypaste -/obj/machinery/modular_computer/proc/power_failure(malfunction = 0) - var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL] - if(cpu && cpu.enabled) // Shut down the computer - visible_message("\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.") - if(cpu) - cpu.shutdown_computer(0) - stat |= NOPOWER - update_icon() - - -// Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us. -/obj/machinery/modular_computer/power_change() - if(cpu && cpu.use_power()) // If MC_CPU still has a power source, PC wouldn't go offline. - stat &= ~NOPOWER - update_icon() - return - ..() - update_icon() - -/obj/machinery/modular_computer/attackby(obj/item/W, mob/user) - if(cpu) - return cpu.attackby(W, user) - return ..() - - -// Stronger explosions cause serious damage to internal components -// Minor explosions are mostly mitigitated by casing. -/obj/machinery/modular_computer/ex_act(severity) - if(cpu) - cpu.ex_act(severity) - ..() - -// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components -/obj/machinery/modular_computer/emp_act(severity) - if(cpu) - cpu.emp_act(severity) - -// "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/machinery/modular_computer/bullet_act(obj/item/projectile/Proj) - if(cpu) - cpu.bullet_act(Proj) diff --git a/code/modules/modular_computers/computers/machinery/modular_console.dm b/code/modules/modular_computers/computers/machinery/modular_console.dm deleted file mode 100644 index e16ce82702c..00000000000 --- a/code/modules/modular_computers/computers/machinery/modular_console.dm +++ /dev/null @@ -1,53 +0,0 @@ -/obj/machinery/modular_computer/console - name = "console" - desc = "A stationary computer." - - icon = 'icons/obj/modular_console.dmi' - icon_state = "console" - icon_state_powered = "console" - icon_state_unpowered = "console-off" - screen_icon_state_menu = "menu" - hardware_flag = PROGRAM_CONSOLE - anchored = 1 - density = 1 - base_idle_power_usage = 100 - base_active_power_usage = 500 - max_hardware_size = 4 - steel_sheet_cost = 10 - light_strength = 2 - max_integrity = 300 - integrity_failure = 150 - - var/console_department = "" // Used in New() to set network tag according to our area. - var/components = TRUE // Install basic components? - -/obj/machinery/modular_computer/console/buildable - components = FALSE - -/obj/machinery/modular_computer/console/New() - ..() - var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL] - if(battery_module) - qdel(battery_module) - - if(components) - var/obj/item/computer_hardware/network_card/wired/network_card = new() - - cpu.install_component(network_card) - cpu.install_component(new /obj/item/computer_hardware/recharger/APC) - cpu.install_component(new /obj/item/computer_hardware/hard_drive/super) // Consoles generally have better HDDs due to lower space limitations - - var/area/A = get_area(src) - // Attempts to set this console's tag according to our area. Since some areas have stuff like "XX - YY" in their names we try to remove that too. - if(A && console_department) - network_card.identification_string = replacetext(replacetext(replacetext("[A.name] [console_department] Console", " ", "_"), "-", ""), "__", "_") // Replace spaces with "_" - else if(A) - network_card.identification_string = replacetext(replacetext(replacetext("[A.name] Console", " ", "_"), "-", ""), "__", "_") - else if(console_department) - network_card.identification_string = replacetext(replacetext(replacetext("[console_department] Console", " ", "_"), "-", ""), "__", "_") - else - network_card.identification_string = "Unknown Console" - - if(cpu) - cpu.screen_on = 1 - update_icon() diff --git a/code/modules/modular_computers/documentation.md b/code/modules/modular_computers/documentation.md deleted file mode 100644 index 9caae69aade..00000000000 --- a/code/modules/modular_computers/documentation.md +++ /dev/null @@ -1,45 +0,0 @@ - - -#Modular computer programs -Ok. so a quick rundown on how to make a program. This is kind of a shitty documentation, but oh well I was asked to. - - -## Base setup -This is how the base program is setup. the rest is mostly tgui stuff. I'll use the ntnetmonitor as a base - - -```DM -/datum/computer_file/program/ntnetmonitor - filename = "ntmonitor" //This is obviously the name of the file itself. not much to be said - filedesc = "NTNet Diagnostics and Monitoring" // This is sort of the official name. it's what shows up on the main menu - program_icon_state = "comm_monitor" // This is what the screen will look like when the program is active - extended_desc = "This program is a dummy. // This is a sort of a description, visible when looking on the ntnet - size = 12 // size of the program. Big programs need more hard drive space. Don't make it too big though. - requires_ntnet = 1 // If this is set, the program will not run without an ntnet connection, and will close if the connection is lost. Mainly for primarily online programs. - required_access = ACCESS_NETWORK //This is access required to run the program itself. ONLY SET THIS FOR SUPER SECURE SHIT. This also acts as transfer_access as well. - transfer_access = ACCESS_CHANGE_IDS // This is the access needed to download from ntnet or host on the ptp program. This is what you want to use most of the time. - available_on_ntnet = 1 //If it's available to download on ntnet. pretty self explanatory. - available_on_syndinet = 0 // ditto but on emagged syndie net. Use this for antag programs - usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL - //^^- The comment above sorta explains it. Use this to limit what kind of machines can run the program. For example, comms program should be limited to consoles and laptops. - var/ui_header = "downloader_finished.gif" //This one is kinda cool. If you have the program minimized, this will show up in the header of the computer screen. - //you can even have the program change what the header is based on the situation! see alarm.dm for an example. -``` - -##Preinstalls -Now. for pre-installing stuff. - -Primarily done for consoles, there's an install_programs() proc in the console presets file in the machines folder. - -for example, the command console one. - -```DM -/obj/machinery/modular_computer/console/preset/command/install_programs() - cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient()) - cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod()) -``` -Basically, you want to do cpu.hard_drive.store_file(new/*program path here*()) and put it in the subtype's install_programs(). -Probably pretty self explanatory, but just in case. - -Will probably be expanded when new features come around or I get asked to mention something. - diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm deleted file mode 100644 index b3f8064b72a..00000000000 --- a/code/modules/modular_computers/file_system/computer_file.dm +++ /dev/null @@ -1,50 +0,0 @@ -GLOBAL_VAR_INIT(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/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 - var/password = "" // Placeholder for password. - -/datum/computer_file/New() - ..() - uid = GLOB.file_uid - GLOB.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.holder && holder.holder.active_program == src) - holder.holder.kill_program(forced = TRUE) - holder = null - return ..() - -// Returns independent copy of this file. -/datum/computer_file/proc/clone(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 - temp.password = password - return temp - -/datum/computer_file/proc/can_access_file(mob/user, input_password = "") - if(!password) - return TRUE - if(!input_password) - input_password = sanitize(input(user, "Please enter a password to access file '[filename]':")) - if(input_password == password) - return TRUE - return FALSE diff --git a/code/modules/modular_computers/file_system/data.dm b/code/modules/modular_computers/file_system/data.dm deleted file mode 100644 index 32ef6f53dd1..00000000000 --- a/code/modules/modular_computers/file_system/data.dm +++ /dev/null @@ -1,20 +0,0 @@ -// /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/program.dm b/code/modules/modular_computers/file_system/program.dm deleted file mode 100644 index 6f779312c15..00000000000 --- a/code/modules/modular_computers/file_system/program.dm +++ /dev/null @@ -1,200 +0,0 @@ -// /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* the program. - var/transfer_access = null // List of required access to download or file host the 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/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/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 /icons/program_icons. Be careful not to use too large images! - -/datum/computer_file/program/New(obj/item/modular_computer/comp = null) - ..() - if(comp && istype(comp)) - computer = comp - -/datum/computer_file/program/Destroy() - computer = null - . = ..() - -/datum/computer_file/program/clone() - var/datum/computer_file/program/temp = ..() - temp.required_access = required_access - 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(text) - if(computer) - return computer.add_log(text) - return 0 - -/datum/computer_file/program/proc/is_supported_by_hardware(hardware_flag = 0, loud = 0, mob/user = null) - if(!(hardware_flag & usage_flags)) - if(loud && computer && user) - to_chat(user, "\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.") - return 0 - return 1 - -/datum/computer_file/program/proc/get_signal(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() - return 1 - -// Check if the user can run program. Only humans can operate computer. Automatically called in run_program() -// User has to wear their ID 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(mob/user, loud = 0, access_to_check, transfer = 0) - // Defaults to required_access - if(!access_to_check) - if(transfer && transfer_access) - access_to_check = transfer_access - else - access_to_check = required_access - if(!access_to_check) // No required_access, allow it. - return 1 - - if(!transfer && computer && computer.emagged) //emags can bypass the execution locks but not the download ones. - return 1 - - if(user.can_admin_interact()) - return 1 - - if(issilicon(user)) - return 1 - - if(ishuman(user)) - var/obj/item/card/id/D - var/obj/item/computer_hardware/card_slot/card_slot - if(computer && card_slot) - card_slot = computer.all_components[MC_CARD] - D = card_slot.GetID() - var/mob/living/carbon/human/h = user - var/obj/item/card/id/I = h.get_idcard() - var/obj/item/card/id/C = h.get_active_hand() - if(C) - C = C.GetID() - if(!(C && istype(C))) - C = null - - if(!I && !C && !D) - if(loud) - to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") - return 0 - - if(I) - if(access_to_check in I.GetAccess()) - return 1 - else if(C) - if(access_to_check in C.GetAccess()) - return 1 - else if(D) - if(access_to_check in D.GetAccess()) - return 1 - if(loud) - to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") - return 0 - -// This attempts to retrieve header data for UIs. 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(mob/living/user) - if(can_run(user, 1)) - 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(forced = FALSE) - program_state = PROGRAM_STATE_KILLED - computer.update_icon() - if(network_destination) - generate_network_log("Connection to [network_destination] closed.") - 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. - -/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. - return computer.ui_interact(user) - 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, list/href_list) - if(..()) - return 1 - - var/datum/nanoui/ui = SSnanoui.get_open_ui(usr, src, "main") - - if(computer) - switch(href_list["action"]) - if("PC_exit") - computer.kill_program() - ui.close() - return 1 - if("PC_shutdown") - computer.shutdown_computer() - ui.close() - return 1 - if("PC_minimize") - var/mob/user = usr - if(!computer.active_program || !computer.all_components[MC_CPU]) - return - - computer.idle_threads.Add(computer.active_program) - program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs - - computer.active_program = null - computer.update_icon() - ui.close() - - if(user && istype(user)) - computer.ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. - - -/datum/computer_file/program/nano_host() - if(computer.physical) - return computer.physical - else - return computer - -/datum/computer_file/program/CanUseTopic(mob/user) - if(program_state != PROGRAM_STATE_ACTIVE) // Our program was closed. Close the ui if it exists. - return STATUS_CLOSE - return ..() diff --git a/code/modules/modular_computers/file_system/program_events.dm b/code/modules/modular_computers/file_system/program_events.dm deleted file mode 100644 index 279d646cfd7..00000000000 --- a/code/modules/modular_computers/file_system/program_events.dm +++ /dev/null @@ -1,18 +0,0 @@ -// 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(background, slot) - 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(background) - kill_program(forced = TRUE) - -// 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(background) - kill_program(forced = TRUE) - if(background) - computer.visible_message("\The [computer]'s screen displays an \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error") - else - computer.visible_message("\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.") diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm deleted file mode 100644 index f6bc293db7d..00000000000 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ /dev/null @@ -1,103 +0,0 @@ -/datum/computer_file/program/ntnet_dos - filename = "ntn_dos" - filedesc = "DoS Traffic Generator" - program_icon_state = "hostile" - 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 - 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 * 10 - if(2) - dos_speed = NTNETSPEED_HIGHSIGNAL * 10 - if(3) - dos_speed = NTNETSPEED_ETHERNET * 10 - if(target && executed) - target.dos_overload += dos_speed - if(target.inoperable()) - target.dos_sources.Remove(src) - target = null - error = "Connection to destination relay lost." - -/datum/computer_file/program/ntnet_dos/kill_program(forced = FALSE) - if(target) - target.dos_sources.Remove(src) - target = null - executed = 0 - ..() - -/datum/computer_file/program/ntnet_dos/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "ntnet_dos.tmpl", "DoS Traffic Generator", 575, 250) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - - -/datum/computer_file/program/ntnet_dos/Topic(href, list/href_list) - if(..()) - return 1 - switch(href_list["action"]) - if("PRG_target_relay") - for(var/obj/machinery/ntnet_relay/R in GLOB.ntnet_global.relays) - if("[R.uid]" == href_list["targid"]) - target = R - return 1 - if("PRG_reset") - if(target) - target.dos_sources.Remove(src) - target = null - executed = 0 - error = "" - return 1 - if("PRG_execute") - if(target) - executed = 1 - target.dos_sources.Add(src) - if(GLOB.ntnet_global.intrusion_detection_enabled) - var/obj/item/computer_hardware/network_card/network_card = computer.all_components[MC_NET] - GLOB.ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [network_card.get_network_tag()]") - GLOB.ntnet_global.intrusion_detection_alarm = 1 - return 1 - -/datum/computer_file/program/ntnet_dos/ui_data(mob/user) - if(!GLOB.ntnet_global) - return - - var/list/data = get_header_data() - - if(error) - data["error"] = error - else if(target && executed) - data["target"] = 1 - data["speed"] = 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 = target.dos_overload * 100 / target.dos_capacity - data["dos_strings"] = list() - for(var/j, j<10, j++) - var/string = "" - for(var/i, i<20, i++) - string = "[string][prob(percentage)]" - data["dos_strings"] += list(list("nums" = string)) - else - data["relays"] = list() - for(var/obj/machinery/ntnet_relay/R in GLOB.ntnet_global.relays) - data["relays"] += list(list("id" = R.uid)) - data["focus"] = target ? target.uid : null - - return data diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm deleted file mode 100644 index 42f722af799..00000000000 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ /dev/null @@ -1,74 +0,0 @@ -/datum/computer_file/program/revelation - filename = "revelation" - filedesc = "Revelation" - program_icon_state = "hostile" - 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 - 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) - computer.visible_message("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.") - computer.enabled = 0 - computer.update_icon() - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - var/obj/item/computer_hardware/battery/battery_module = computer.all_components[MC_CELL] - var/obj/item/computer_hardware/recharger/recharger = computer.all_components[MC_CHARGE] - qdel(hard_drive) - computer.take_damage(25, BRUTE, 0, 0) - if(battery_module && prob(25)) - qdel(battery_module) - computer.visible_message("\The [computer]'s battery explodes in rain of sparks.") - do_sparks(5, 0, computer.loc) - - if(recharger && prob(50)) - qdel(recharger) - computer.visible_message("\The [computer]'s recharger explodes in rain of sparks.") - do_sparks(5, 0, computer.loc) - - -/datum/computer_file/program/revelation/Topic(href, list/href_list) - if(..()) - return 1 - switch(href_list["action"]) - if("PRG_arm") - armed = !armed - if("PRG_activate") - activate() - if("PRG_obfuscate") - var/mob/living/user = usr - var/newname = sanitize(input(user, "Enter new program name: ")) - if(!newname) - return - filedesc = newname - - -/datum/computer_file/program/revelation/clone() - var/datum/computer_file/program/revelation/temp = ..() - temp.armed = armed - return temp - -/datum/computer_file/program/revelation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "revelation.tmpl", "Revelation Virus", 575, 250) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/revelation/ui_data(mob/user) - var/list/data = get_header_data() - - data["armed"] = armed - - return data diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm deleted file mode 100644 index cae4b5ed2e2..00000000000 --- a/code/modules/modular_computers/file_system/programs/command/card.dm +++ /dev/null @@ -1,493 +0,0 @@ -/datum/computer_file/program/card_mod - filename = "cardmod" - filedesc = "ID card modification program" - program_icon_state = "id" - extended_desc = "Program for programming employee ID cards to access parts of the station." - transfer_access = ACCESS_CHANGE_IDS - requires_ntnet = 0 - size = 8 - var/is_centcom = 0 - var/mode = 0 - var/printing = 0 - - //Cooldown for closing positions in seconds - //if set to -1: No cooldown... probably a bad idea - //if set to 0: Not able to close "original" positions. You can only close positions that you have opened before - var/change_position_cooldown = 60 - //Jobs you cannot open new positions for - var/list/blacklisted = list( - /datum/job/ai, - /datum/job/cyborg, - /datum/job/captain, - /datum/job/hop, - /datum/job/hos, - /datum/job/chief_engineer, - /datum/job/rd, - /datum/job/cmo, - /datum/job/judge, - /datum/job/blueshield, - /datum/job/nanotrasenrep, - /datum/job/pilot, - /datum/job/brigdoc, - /datum/job/mechanic, - /datum/job/barber, - /datum/job/chaplain, - /datum/job/ntnavyofficer, - /datum/job/ntspecops, - /datum/job/civilian, - /datum/job/syndicateofficer, - /datum/job/explorer // blacklisted so that HOPs don't try prioritizing it, then wonder why that doesn't work - ) - - //The scaling factor of max total positions in relation to the total amount of people on board the station in % - var/max_relative_positions = 30 //30%: Seems reasonable, limit of 6 @ 20 players - - //This is used to keep track of opened positions for jobs to allow instant closing - //Assoc array: "JobName" = (int) - var/list/opened_positions = list() - -/datum/computer_file/program/card_mod/proc/is_authenticated(var/mob/user) - if(user.can_admin_interact()) - return 1 - if(computer) - var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD] - if(card_slot) - var/obj/item/card/id/auth_card = card_slot.stored_card2 - if(auth_card) - return check_access(auth_card) - return 0 - -/datum/computer_file/program/card_mod/proc/check_access(obj/item/I) - if(ACCESS_CHANGE_IDS in I.GetAccess()) - return 1 - return 0 - -/datum/computer_file/program/card_mod/proc/get_target_rank() - if(computer) - var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD] - if(card_slot) - var/obj/item/card/id/id_card = card_slot.stored_card - if(id_card && id_card.assignment) - return id_card.assignment - return "Unassigned" - -/datum/computer_file/program/card_mod/proc/format_job_slots() - var/list/formatted = list() - for(var/datum/job/job in SSjobs.occupations) - if(job_blacklisted(job)) - continue - formatted.Add(list(list( - "title" = job.title, - "current_positions" = job.current_positions, - "total_positions" = job.total_positions, - "can_open" = can_open_job(job), - "can_close" = can_close_job(job), - "can_prioritize" = can_prioritize_job(job) - ))) - - return formatted - -/datum/computer_file/program/card_mod/proc/format_card_skins(list/card_skins) - var/list/formatted = list() - for(var/skin in card_skins) - formatted.Add(list(list( - "display_name" = get_skin_desc(skin), - "skin" = skin))) - - return formatted - - -/datum/computer_file/program/card_mod/proc/job_blacklisted(datum/job/job) - return (job.type in blacklisted) - - -//Logic check for if you can open the job -/datum/computer_file/program/card_mod/proc/can_open_job(datum/job/job) - if(job) - if(!job_blacklisted(job)) - if((job.total_positions <= GLOB.player_list.len * (max_relative_positions / 100))) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] < 0)) - return 1 - return -2 - return -1 - return 0 - -//Logic check for if you can close the job -/datum/computer_file/program/card_mod/proc/can_close_job(datum/job/job) - if(job) - if(!job_blacklisted(job)) - if(job.total_positions > job.current_positions) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) - return 1 - return -2 - return -1 - return 0 - -/datum/computer_file/program/card_mod/proc/can_prioritize_job(datum/job/job) - if(job) - if(!job_blacklisted(job)) - if(job in SSjobs.prioritized_jobs) - return 2 - else - if(SSjobs.prioritized_jobs.len >= 3) - return 0 - if(job.total_positions <= job.current_positions) - return 0 - return 1 - return -1 - -/datum/computer_file/program/card_mod/proc/format_jobs(list/jobs, targetrank, list/jobformats) - var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD] - if(!card_slot || !card_slot.stored_card) - return null - var/list/formatted = list() - for(var/job in jobs) - formatted.Add(list(list( - "display_name" = replacetext(job, " ", " "), - "target_rank" = targetrank, - "job" = job, - "jlinkformat" = jobformats[job] ? jobformats[job] : null))) - return formatted - - -/datum/computer_file/program/card_mod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "card_prog.tmpl", "ID card modification program", 775, 700) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/card_mod/Topic(href, href_list) - if(..()) - return 1 - - var/obj/item/computer_hardware/card_slot/card_slot - var/obj/item/computer_hardware/printer/printer - if(computer) - card_slot = computer.all_components[MC_CARD] - printer = computer.all_components[MC_PRINT] - if(!card_slot) - return - - var/mob/user = usr - - var/obj/item/card/id/modify = card_slot.stored_card - var/obj/item/card/id/scan = card_slot.stored_card2 - - switch(href_list["action"]) - if("PRG_modify") - if(modify) - GLOB.data_core.manifest_modify(modify.registered_name, modify.assignment) - modify.name = "[modify.registered_name]'s ID Card ([modify.assignment])" - card_slot.try_eject(1, user) - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/card/id)) - if(!usr.drop_item()) - return - I.forceMove(computer) - card_slot.stored_card = I - - if("PRG_scan") - if(scan) - card_slot.try_eject(2, user) - else - var/obj/item/I = usr.get_active_hand() - if(istype(I, /obj/item/card/id)) - if(!usr.drop_item()) - return - I.forceMove(computer) - card_slot.stored_card2 = I - - if("PRG_access") - if(href_list["allowed"]) - if(is_authenticated(usr)) - var/access_type = text2num(href_list["access_target"]) - var/access_allowed = text2num(href_list["allowed"]) - if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses())) - modify.access -= access_type - if(!access_allowed) - modify.access += access_type - - if("PRG_skin") - var/skin = href_list["skin_target"] - if(is_authenticated(usr) && modify && ((skin in get_station_card_skins()) || ((skin in get_centcom_card_skins()) && is_centcom))) - modify.icon_state = href_list["skin_target"] - - if("PRG_assign") - if(is_authenticated(usr) && modify) - var/t1 = href_list["assign_target"] - if(t1 == "Custom") - var/temp_t = sanitize(reject_bad_name(copytext(input("Enter a custom job assignment.", "Assignment"), 1, MAX_MESSAGE_LEN), TRUE)) - //let custom jobs function as an impromptu alt title, mainly for sechuds - if(temp_t && modify) - SSjobs.log_job_transfer(modify.registered_name, modify.getRankAndAssignment(), temp_t, scan.registered_name) - modify.assignment = temp_t - log_game("[key_name(usr)] has given \"[modify.registered_name]\" the custom job title \"[temp_t]\".") - else - var/list/access = list() - if(is_centcom && islist(get_centcom_access(t1))) - 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() - - var/jobnamedata = modify.getRankAndAssignment() - log_game("[key_name(usr)] has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".") - if(t1 == "Civilian") - message_admins("[key_name_admin(usr)] has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".") - - SSjobs.log_job_transfer(modify.registered_name, jobnamedata, t1, scan.registered_name) - if(modify.owner_uid) - SSjobs.slot_job_transfer(modify.rank, t1) - - var/mob/living/carbon/human/H = modify.getPlayer() - if(istype(H)) - if(jobban_isbanned(H, t1)) - message_admins("[ADMIN_FULLMONTY(H)] has been assigned the job [t1], in possible violation of their job ban.") - if(H.mind) - H.mind.playtime_role = t1 - - modify.access = access - modify.assignment = t1 - modify.rank = t1 - - if("PRG_reg") - if(is_authenticated(usr)) - var/temp_name = reject_bad_name(href_list["reg"], TRUE) - if(temp_name) - modify.registered_name = temp_name - else - computer.visible_message("[src] buzzes rudely.") - - if("PRG_account") - if(is_authenticated(usr)) - var/account_num = text2num(href_list["account"]) - modify.associated_account_number = account_num - - if("PRG_mode") - mode = text2num(href_list["mode_target"]) - - if("PRG_wipe_my_logs") - if(is_authenticated(usr) && is_centcom) - var/delcount = SSjobs.delete_log_records(scan.registered_name, FALSE) - if(delcount) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - if("PRG_wipe_all_logs") - if(is_authenticated(usr)) - var/delcount = SSjobs.delete_log_records(scan.registered_name, TRUE) - if(delcount) - message_admins("[key_name_admin(usr)] has wiped all ID computer logs.") - usr.create_log(MISC_LOG, "wiped all ID computer logs.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - if("PRG_print") - if(!printing && computer) - printing = 1 - playsound(computer.loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - spawn(50) - printing = 0 - SSnanoui.update_uis(src) - var/title - var/content - if(mode == 2) - title = "crew manifest ([station_time_timestamp()])" - content = "

Crew Manifest


[GLOB.data_core ? GLOB.data_core.get_manifest(0) : ""]" - else if(modify && !mode) - title = "access report" - content = {"

Access Report

- Prepared By: [scan && scan.registered_name ? scan.registered_name : "Unknown"]
- For: [modify.registered_name ? modify.registered_name : "Unregistered"]
-
- Assignment: [modify.assignment]
- Account Number: #[modify.associated_account_number]
- Blood Type: [modify.blood_type]

- Access:
"} - - var/first = 1 - for(var/A in modify.access) - content += "[first ? "" : ", "][get_access_desc(A)]" - first = 0 - content += "
" - - if(content) - if(!printer.print_text(content, title)) - to_chat(user, "Hardware error: Printer was unable to print the file. It may be out of paper.") - return 1 - else - computer.visible_message("\The [computer] prints out paper.") - - if("PRG_terminate") - if(is_authenticated(usr)) - var/jobnamedata = modify.getRankAndAssignment() - var/reason = sanitize(copytext(input("Enter legal reason for termination. Enter nothing to cancel.", "Employment Termination"), 1, MAX_MESSAGE_LEN)) - if(!reason || !is_authenticated(usr) || !modify) - return - log_game("[key_name(usr)] has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\" for: \"[reason]\".") - message_admins("[key_name_admin(usr)] has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\" for: \"[reason]\".") - usr.create_log(MISC_LOG, "terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\"") - SSjobs.log_job_transfer(modify.registered_name, jobnamedata, "Terminated", scan.registered_name) - SSjobs.notify_dept_head(modify.rank, "[scan.registered_name] has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\" for \"[reason]\".") - modify.assignment = "Terminated" - modify.access = list() - - if("PRG_make_job_available") - // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS - if(is_authenticated(usr)) - var/edit_job_target = href_list["job"] - var/datum/job/j = SSjobs.GetJob(edit_job_target) - if(!j) - return 1 - if(can_open_job(j) != 1) - return 1 - if(opened_positions[edit_job_target] >= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions++ - opened_positions[edit_job_target]++ - log_game("[key_name(usr)] has opened a job slot for job \"[j]\".") - - if("PRG_make_job_unavailable") - // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS - if(is_authenticated(usr)) - var/edit_job_target = href_list["job"] - var/datum/job/j = SSjobs.GetJob(edit_job_target) - if(!j) - return 1 - if(can_close_job(j) != 1) - return 1 - //Allow instant closing without cooldown if a position has been opened before - if(opened_positions[edit_job_target] <= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions-- - opened_positions[edit_job_target]-- - log_game("[key_name(usr)] has closed a job slot for job \"[j]\".") - - - if("PRG_prioritize_job") - // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY - if(is_authenticated(usr)) - var/priority_target = href_list["job"] - var/datum/job/j = SSjobs.GetJob(priority_target) - if(!j) - return 0 - // Unlike the proper ID computer, this does not check job_in_department - var/priority = TRUE - if(j in SSjobs.prioritized_jobs) - SSjobs.prioritized_jobs -= j - priority = FALSE - else if(SSjobs.prioritized_jobs.len < 3) - SSjobs.prioritized_jobs += j - else - return 0 - log_game("[key_name(usr)] [priority ? "prioritized" : "unprioritized"] the job \"[j.title]\".") - playsound(computer.loc, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - if(modify) - modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") - - SSnanoui.update_uis(src) - return 1 - -/datum/computer_file/program/card_mod/ui_data(mob/user) - var/list/data = get_header_data() - - var/obj/item/card/id/modify = null - var/obj/item/card/id/scan = null - - var/obj/item/computer_hardware/card_slot/card_slot - var/obj/item/computer_hardware/printer/printer - if(computer) - card_slot = computer.all_components[MC_CARD] - printer = computer.all_components[MC_PRINT] - if(card_slot) - modify = card_slot.stored_card - scan = card_slot.stored_card2 - - data["src"] = UID() - data["station_name"] = station_name() - data["mode"] = mode - data["printing"] = printing - data["printer"] = printer ? TRUE : FALSE - data["manifest"] = GLOB.data_core ? GLOB.data_core.get_manifest(0) : null - data["target_name"] = modify ? modify.name : "-----" - data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----" - data["target_rank"] = get_target_rank() - data["scan_name"] = scan ? scan.name : "-----" - data["scan_owner"] = scan && scan.registered_name ? scan.registered_name : null - data["authenticated"] = is_authenticated(user) - data["has_modify"] = !!modify - data["account_number"] = modify ? modify.associated_account_number : null - data["centcom_access"] = is_centcom - data["all_centcom_access"] = null - data["regions"] = null - - var/list/job_formats = SSjobs.format_jobs_for_id_computer(modify) - - data["top_jobs"] = format_jobs(list("Captain", "Custom"), data["target_rank"], job_formats) - data["engineering_jobs"] = format_jobs(GLOB.engineering_positions, data["target_rank"], job_formats) - data["medical_jobs"] = format_jobs(GLOB.medical_positions, data["target_rank"], job_formats) - data["science_jobs"] = format_jobs(GLOB.science_positions, data["target_rank"], job_formats) - data["security_jobs"] = format_jobs(GLOB.security_positions, data["target_rank"], job_formats) - data["support_jobs"] = format_jobs(GLOB.support_positions, data["target_rank"], job_formats) - data["civilian_jobs"] = format_jobs(GLOB.civilian_positions, data["target_rank"], job_formats) - data["special_jobs"] = format_jobs(GLOB.whitelisted_positions, data["target_rank"], job_formats) - data["centcom_jobs"] = format_jobs(get_all_centcom_jobs(), data["target_rank"], job_formats) - data["card_skins"] = format_card_skins(get_station_card_skins()) - - data["job_slots"] = format_job_slots() - - var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) - var/mins = round(time_to_wait / 60) - var/seconds = time_to_wait - (60*mins) - data["cooldown_mins"] = mins - data["cooldown_secs"] = (seconds < 10) ? "0[seconds]" : seconds - - if(mode == 3 && is_authenticated(user)) - data["id_change_html"] = SSjobs.fetch_transfer_record_html(is_centcom) - - if(modify) - data["current_skin"] = modify.icon_state - - if(modify && 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 modify.access) ? 1 : 0))) - - data["all_centcom_access"] = all_centcom_access - data["all_centcom_skins"] = format_card_skins(get_centcom_card_skins()) - - else if(modify) - 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 modify.access) ? 1 : 0))) - - regions.Add(list(list( - "name" = get_region_accesses_name(i), - "accesses" = accesses))) - - data["regions"] = regions - - return data diff --git a/code/modules/modular_computers/file_system/programs/command/comms.dm b/code/modules/modular_computers/file_system/programs/command/comms.dm deleted file mode 100644 index c23f0c9e3c7..00000000000 --- a/code/modules/modular_computers/file_system/programs/command/comms.dm +++ /dev/null @@ -1,385 +0,0 @@ -/datum/computer_file/program/comm - filename = "comm" - filedesc = "Command and communications" - program_icon_state = "comm" - extended_desc = "Used to command and control the station. 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 = "station long-range communication array" - - var/authenticated = COMM_AUTHENTICATION_NONE - var/list/messagetitle = list() - var/list/messagetext = list() - var/currmsg = 0 - var/aicurrmsg = 0 - var/menu_state = COMM_SCREEN_MAIN - var/ai_menu_state = COMM_SCREEN_MAIN - var/message_cooldown = 0 - var/centcomm_message_cooldown = 0 - var/tmp_alertlevel = 0 - - var/stat_msg1 - var/stat_msg2 - var/display_type="blank" - - var/datum/announcement/priority/crew_announcement = new - -/datum/computer_file/program/comm/New() - GLOB.shuttle_caller_list += src - ..() - crew_announcement.newscast = 0 - -/datum/computer_file/program/comm/Destroy() - GLOB.shuttle_caller_list -= src - SSshuttle.autoEvac() - return ..() - -/datum/computer_file/program/comm/proc/is_authenticated(mob/user, loud = 1) - if(authenticated == COMM_AUTHENTICATION_MAX) - return COMM_AUTHENTICATION_MAX - else if(user.can_admin_interact()) - return COMM_AUTHENTICATION_MAX - else if(authenticated) - return COMM_AUTHENTICATION_MIN - else - if(loud) - to_chat(user, "Access denied.") - return COMM_AUTHENTICATION_NONE - -/datum/computer_file/program/comm/proc/change_security_level(mob/user, new_level) - tmp_alertlevel = new_level - var/old_level = GLOB.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(GLOB.security_level != old_level) - log_game("[key_name(user)] has changed the security level to [get_security_level()].") - message_admins("[key_name_admin(user)] has changed the security level to [get_security_level()].") - switch(GLOB.security_level) - if(SEC_LEVEL_GREEN) - feedback_inc("alert_comms_green", 1) - if(SEC_LEVEL_BLUE) - feedback_inc("alert_comms_blue", 1) - tmp_alertlevel = 0 - -/datum/computer_file/program/comm/proc/setCurrentMessage(mob/user, value) - if(isAI(user) || isrobot(user)) - aicurrmsg = value - else - currmsg = value - -/datum/computer_file/program/comm/proc/getCurrentMessage(mob/user) - if(isAI(user) || isrobot(user)) - return aicurrmsg - else - return currmsg - -/datum/computer_file/program/comm/proc/setMenuState(mob/user, value) - if(isAI(user) || isrobot(user)) - ai_menu_state=value - else - menu_state=value - -/datum/computer_file/program/comm/proc/getMenuState(mob/user) - if(isAI(user) || isrobot(user)) - return ai_menu_state - else - return menu_state - -/datum/computer_file/program/comm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "comm_program.tmpl", "Command and communications program", 575, 500) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/comm/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/list/data = get_header_data() - data["is_ai"] = isAI(user) || isrobot(user) - data["menu_state"] = data["is_ai"] ? ai_menu_state : menu_state - data["emagged"] = computer ? computer.emagged : null - data["authenticated"] = is_authenticated(user, 0) - data["screen"] = getMenuState(usr) - - data["stat_display"] = list( - "type" = display_type, - "line_1" = (stat_msg1 ? stat_msg1 : "-----"), - "line_2" = (stat_msg2 ? stat_msg2 : "-----"), - - "presets" = list( - list("name" = "blank", "label" = "Clear", "desc" = "Blank slate"), - list("name" = "shuttle", "label" = "Shuttle ETA", "desc" = "Display how much time is left."), - list("name" = "message", "label" = "Message", "desc" = "A custom message.") - ), - - "alerts"=list( - list("alert" = "default", "label" = "Nanotrasen", "desc" = "Oh god."), - list("alert" = "redalert", "label" = "Red Alert", "desc" = "Nothing to do with communists."), - list("alert" = "lockdown", "label" = "Lockdown", "desc" = "Let everyone know they're on lockdown."), - list("alert" = "biohazard", "label" = "Biohazard", "desc" = "Great for virus outbreaks and parties."), - ) - ) - - data["security_level"] = GLOB.security_level - data["str_security_level"] = capitalize(get_security_level()) - data["levels"] = list( - list("id" = SEC_LEVEL_GREEN, "name" = "Green"), - list("id" = SEC_LEVEL_BLUE, "name" = "Blue"), - ) - - var/list/msg_data = list() - for(var/i = 1; i <= messagetext.len; i++) - msg_data.Add(list(list("title" = messagetitle[i], "body" = messagetext[i], "id" = i))) - - data["messages"] = msg_data - if((data["is_ai"] && aicurrmsg) || (!data["is_ai"] && currmsg)) - data["current_message"] = data["is_ai"] ? messagetext[aicurrmsg] : messagetext[currmsg] - data["current_message_title"] = data["is_ai"] ? messagetitle[aicurrmsg] : messagetitle[currmsg] - - data["lastCallLoc"] = SSshuttle.emergencyLastCallLoc ? format_text(SSshuttle.emergencyLastCallLoc.name) : null - - var/shuttle[0] - switch(SSshuttle.emergency.mode) - if(SHUTTLE_IDLE, SHUTTLE_RECALL) - shuttle["callStatus"] = 2 //#define - else - shuttle["callStatus"] = 1 - if(SSshuttle.emergency.mode == SHUTTLE_CALL) - var/timeleft = SSshuttle.emergency.timeLeft() - shuttle["eta"] = "[timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" - - data["shuttle"] = shuttle - - return data - -/datum/computer_file/program/comm/Topic(href, href_list) - if(..()) - return 1 - - var/turf/T = get_turf(computer) - if(!is_secure_level(T.z)) - to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return 1 - - if(href_list["PRG_login"]) - if(!ishuman(usr)) - to_chat(usr, "Access denied.") - return - - var/list/access = usr.get_access() - if(ACCESS_HEADS in access) - authenticated = COMM_AUTHENTICATION_MIN - - if(ACCESS_CAPTAIN in access) - authenticated = COMM_AUTHENTICATION_MAX - var/mob/living/carbon/human/H = usr - var/obj/item/card/id = H.get_idcard(TRUE) - if(istype(id)) - crew_announcement.announcer = GetNameAndAssignmentFromId(id) - - SSnanoui.update_uis(src) - return 1 - - if(href_list["PRG_logout"]) - authenticated = COMM_AUTHENTICATION_NONE - crew_announcement.announcer = "" - setMenuState(usr, COMM_SCREEN_MAIN) - SSnanoui.update_uis(src) - return 1 - - if(is_authenticated(usr)) - switch(href_list["PRG_operation"]) - if("main") - setMenuState(usr, COMM_SCREEN_MAIN) - - if("changeseclevel") - setMenuState(usr,COMM_SCREEN_SECLEVEL) - - if("newalertlevel") - if(isAI(usr) || isrobot(usr)) - to_chat(usr, "Firewalls prevent you from changing the alert level.") - return 1 - else if(usr.can_admin_interact()) - change_security_level(usr, text2num(href_list["level"])) - return 1 - else if(!ishuman(usr)) - to_chat(usr, "Security measures prevent you from changing the alert level.") - return 1 - - var/mob/living/carbon/human/L = usr - var/obj/item/card = L.get_active_hand() - var/obj/item/card/id/I = (card && card.GetID()) || L.wear_id || L.wear_pda - if(istype(I, /obj/item/pda)) - var/obj/item/pda/pda = I - I = pda.id - if(I && istype(I)) - if(ACCESS_CAPTAIN in I.access) - change_security_level(usr, text2num(href_list["level"])) - else - to_chat(usr, "You are not authorized to do this.") - setMenuState(usr, COMM_SCREEN_MAIN) - else - to_chat(usr, "You need to swipe your ID.") - - if("announce") - if(is_authenticated(usr) == COMM_AUTHENTICATION_MAX) - if(message_cooldown) - to_chat(usr, "Please allow at least one minute to pass between announcements.") - SSnanoui.update_uis(src) - return 1 - var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") - if(!input || message_cooldown || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) - return 1 - crew_announcement.Announce(input) - message_cooldown = 1 - spawn(600)//One minute cooldown - message_cooldown = 0 - - if("callshuttle") - var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") - if(!input || ..() || !is_authenticated(usr)) - SSnanoui.update_uis(src) - return 1 - - call_shuttle_proc(usr, input) - if(SSshuttle.emergency.timer) - post_status("shuttle") - setMenuState(usr, COMM_SCREEN_MAIN) - - if("cancelshuttle") - if(isAI(usr) || isrobot(usr)) - to_chat(usr, "Firewalls prevent you from recalling the shuttle.") - SSnanoui.update_uis(src) - return 1 - var/response = alert("Are you sure you wish to recall the shuttle?", "Confirm", "Yes", "No") - if(response == "Yes") - cancel_call_proc(usr) - if(SSshuttle.emergency.timer) - post_status("shuttle") - setMenuState(usr, COMM_SCREEN_MAIN) - - if("messagelist") - currmsg = 0 - if(href_list["msgid"]) - setCurrentMessage(usr, text2num(href_list["msgid"])) - setMenuState(usr,COMM_SCREEN_MESSAGES) - - if("delmessage") - if(href_list["msgid"]) - currmsg = text2num(href_list["msgid"]) - var/response = alert("Are you sure you wish to delete this message?", "Confirm", "Yes", "No") - if(response == "Yes") - if(currmsg) - var/id = getCurrentMessage() - var/title = messagetitle[id] - var/text = messagetext[id] - messagetitle.Remove(title) - messagetext.Remove(text) - if(currmsg == id) - currmsg = 0 - if(aicurrmsg == id) - aicurrmsg = 0 - setMenuState(usr,COMM_SCREEN_MESSAGES) - - if("status") - setMenuState(usr,COMM_SCREEN_STAT) - - // Status display stuff - if("setstat") - display_type=href_list["statdisp"] - switch(display_type) - if("message") - post_status("message", stat_msg1, stat_msg2, usr) - if("alert") - post_status("alert", href_list["alert"], user = usr) - else - post_status(href_list["statdisp"], user = usr) - setMenuState(usr, COMM_SCREEN_STAT) - - if("setmsg1") - stat_msg1 = clean_input("Line 1", "Enter Message Text", stat_msg1) - setMenuState(usr, COMM_SCREEN_STAT) - - if("setmsg2") - stat_msg2 = clean_input("Line 2", "Enter Message Text", stat_msg2) - setMenuState(usr, COMM_SCREEN_STAT) - - if("nukerequest") - if(is_authenticated(usr) == COMM_AUTHENTICATION_MAX) - if(centcomm_message_cooldown) - to_chat(usr, "Arrays recycling. Please stand by.") - SSnanoui.update_uis(src) - return 1 - var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") - if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) - return 1 - Nuke_request(input, usr) - to_chat(usr, "Request sent.") - log_game("[key_name(usr)] has requested the nuclear codes from Centcomm") - GLOB.priority_announcement.Announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/AI/commandreport.ogg') - centcomm_message_cooldown = 1 - spawn(6000)//10 minute cooldown - centcomm_message_cooldown = 0 - setMenuState(usr,COMM_SCREEN_MAIN) - - if("MessageCentcomm") - if(is_authenticated(usr) == COMM_AUTHENTICATION_MAX) - if(centcomm_message_cooldown) - to_chat(usr, "Arrays recycling. Please stand by.") - SSnanoui.update_uis(src) - return 1 - var/input = stripped_input(usr, "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.", "To abort, send an empty message.", "") - if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) - return 1 - Centcomm_announce(input, usr) - to_chat(usr, "Message transmitted.") - log_game("[key_name(usr)] has made a Centcomm announcement: [input]") - centcomm_message_cooldown = 1 - spawn(6000)//10 minute cooldown - centcomm_message_cooldown = 0 - setMenuState(usr,COMM_SCREEN_MAIN) - - // OMG SYNDICATE ...LETTERHEAD - if("MessageSyndicate") - if((is_authenticated(usr) == COMM_AUTHENTICATION_MAX) && (computer && computer.emagged)) - if(centcomm_message_cooldown) - to_chat(usr, "Arrays recycling. Please stand by.") - SSnanoui.update_uis(src) - return 1 - var/input = stripped_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 || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) - SSnanoui.update_uis(src) - return 1 - Syndicate_announce(input, usr) - to_chat(usr, "Message transmitted.") - log_game("[key_name(usr)] has made a Syndicate announcement: [input]") - centcomm_message_cooldown = 1 - spawn(6000)//10 minute cooldown - centcomm_message_cooldown = 0 - setMenuState(usr,COMM_SCREEN_MAIN) - - if("RestartNanoMob") - if(SSmob_hunt) - if(SSmob_hunt.manual_reboot()) - var/loading_msg = pick("Respawning spawns", "Reticulating splines", "Flipping hat", - "Capturing all of them", "Fixing minor text issues", "Being the very best", - "Nerfing this", "Not communicating with playerbase", "Coding a ripoff in a 2D spaceman game") - to_chat(usr, "Restarting Nano-Mob Hunter GO! game server. [loading_msg]...") - else - to_chat(usr, "Nano-Mob Hunter GO! game server reboot failed due to recent restart. Please wait before re-attempting.") - else - to_chat(usr, "Nano-Mob Hunter GO! game server is offline for extended maintenance. Contact your Central Command administrators for more info if desired.") - - SSnanoui.update_uis(src) - return 1 diff --git a/code/modules/modular_computers/file_system/programs/engineering/alarm.dm b/code/modules/modular_computers/file_system/programs/engineering/alarm.dm deleted file mode 100644 index 2f2f4a08232..00000000000 --- a/code/modules/modular_computers/file_system/programs/engineering/alarm.dm +++ /dev/null @@ -1,77 +0,0 @@ -/datum/computer_file/program/alarm_monitor - filename = "alarmmonitor" - filedesc = "Alarm Monitoring" - ui_header = "alarm_green.gif" - program_icon_state = "alert-green" - extended_desc = "This program provides visual interface for station's alarm system." - requires_ntnet = 1 - network_destination = "alarm monitoring network" - size = 5 - var/tgui_id = "NtosStationAlertConsole" - var/ui_x = 315 - var/ui_y = 500 - var/has_alert = 0 - var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power") - -/datum/computer_file/program/alarm_monitor/process_tick() - ..() - - if(has_alert) - program_icon_state = "alert-red" - ui_header = "alarm_red.gif" - update_computer_icon() - else - program_icon_state = "alert-green" - ui_header = "alarm_green.gif" - update_computer_icon() - return TRUE - -/datum/computer_file/program/alarm_monitor/tgui_data(mob/user) - var/list/data = get_header_data() - - data["alarms"] = list() - for(var/class in SSalarm.alarms) - if(!(class in alarms_listend_for)) - continue - data["alarms"][class] = list() - for(var/area in alarms[class]) - data["alarms"][class] += area - - return data - -/datum/computer_file/program/alarm_monitor/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource) - if(is_station_level(alarmsource.z)) - if(!(A.type in GLOB.the_station_areas)) - return - else if(!is_mining_level(alarmsource.z) || istype(A, /area/ruin)) - return - update_alarm_display() - -/datum/computer_file/program/alarm_monitor/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared) - if(is_station_level(origin.z)) - if(!(A.type in GLOB.the_station_areas)) - return - else if(!is_mining_level(origin.z) || istype(A, /area/ruin)) - return - update_alarm_display() - -/datum/computer_file/program/alarm_monitor/proc/update_alarm_display() - has_alert = FALSE - for(var/cat in alarms) - if(!(cat in alarms_listend_for)) - continue - var/list/L = alarms[cat] - if(length(L)) - has_alert = TRUE - -/datum/computer_file/program/alarm_monitor/run_program(mob/user) - . = ..(user) - GLOB.alarmdisplay += src - RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, .proc/alarm_triggered) - RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, .proc/alarm_cancelled) - -/datum/computer_file/program/alarm_monitor/kill_program(forced = FALSE) - GLOB.alarmdisplay -= src - UnregisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM) - UnregisterSignal(SSalarm, COMSIG_CANCELLED_ALARM) - ..() diff --git a/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm deleted file mode 100644 index 0763d527345..00000000000 --- a/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm +++ /dev/null @@ -1,48 +0,0 @@ -/datum/computer_file/program/power_monitor - filename = "powermonitor" - filedesc = "Power Monitoring" - program_icon_state = "power_monitor" - extended_desc = "This program connects to sensors around the station to provide information about electrical systems" - ui_header = "power_norm.gif" - transfer_access = ACCESS_ENGINE - usage_flags = PROGRAM_CONSOLE - requires_ntnet = 0 - network_destination = "power monitoring system" - size = 9 - var/obj/structure/cable/attached - -/datum/computer_file/program/power_monitor/run_program(mob/living/user) - . = ..(user) - search() - -/datum/computer_file/program/power_monitor/process_tick() - if(!attached) - search() - -/datum/computer_file/program/power_monitor/proc/search() - var/turf/T = get_turf(computer) - attached = locate() in T - -/datum/computer_file/program/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "power_monitor.tmpl", "Alarm Monitoring", 800, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/power_monitor/ui_data() - var/list/data = get_header_data() - - data["powermonitor"] = attached ? TRUE : FALSE - - if(attached) - var/datum/powernet/powernet = attached.powernet - data["poweravail"] = powernet.avail - data["powerload"] = powernet.viewload - data["powerdemand"] = powernet.load - data["apcs"] = GLOB.apc_repository.apc_data(powernet) - - return data diff --git a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm deleted file mode 100644 index 0045b36f30e..00000000000 --- a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm +++ /dev/null @@ -1,137 +0,0 @@ -/datum/computer_file/program/supermatter_monitor - filename = "smmonitor" - filedesc = "Supermatter Monitoring" - ui_header = "smmon_0.gif" - program_icon_state = "smmon_0" - extended_desc = "This program connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." - requires_ntnet = TRUE - transfer_access = ACCESS_CONSTRUCTION - network_destination = "supermatter monitoring system" - size = 5 - var/last_status = SUPERMATTER_INACTIVE - var/list/supermatters - var/obj/machinery/power/supermatter_shard/active // Currently selected supermatter crystal. - - -/datum/computer_file/program/supermatter_monitor/process_tick() - ..() - var/new_status = get_status() - if(last_status != new_status) - last_status = new_status - if(last_status == SUPERMATTER_ERROR) - last_status = SUPERMATTER_INACTIVE - ui_header = "smmon_[last_status].gif" - program_icon_state = "smmon_[last_status]" - if(istype(computer)) - computer.update_icon() - -/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user) - . = ..(user) - refresh() - -/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE) - active = null - supermatters = null - ..() - -// Refreshes list of active supermatter crystals -/datum/computer_file/program/supermatter_monitor/proc/refresh() - supermatters = list() - var/turf/T = get_turf(nano_host()) - if(!T) - return - for(var/obj/machinery/power/supermatter_shard/S in SSair.atmos_machinery) - // Delaminating, not within coverage, not on a tile. - if(!(is_station_level(S.z) || is_mining_level(S.z) || atoms_share_level(S, T) || !istype(S.loc, /turf/simulated/))) - continue - supermatters.Add(S) - - if(!(active in supermatters)) - active = null - -/datum/computer_file/program/supermatter_monitor/proc/get_status() - . = SUPERMATTER_INACTIVE - for(var/obj/machinery/power/supermatter_shard/S in supermatters) - . = max(., S.get_status()) - -/datum/computer_file/program/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400) - ui.set_auto_update(TRUE) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/supermatter_monitor/ui_data() - var/list/data = get_header_data() - - if(istype(active)) - var/turf/T = get_turf(active) - if(!T) - active = null - refresh() - return - var/datum/gas_mixture/air = T.return_air() - if(!air) - active = null - return - - data["active"] = TRUE - 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"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) - var/other_moles = air.total_trace_moles() - var/TM = air.total_moles() - if(TM) - data["SM_gas_O2"] = round(100*air.oxygen/TM,0.01) - data["SM_gas_CO2"] = round(100*air.carbon_dioxide/TM,0.01) - data["SM_gas_N2"] = round(100*air.nitrogen/TM,0.01) - data["SM_gas_PL"] = round(100*air.toxins/TM,0.01) - if(other_moles) - data["SM_gas_OTHER"] = round(100 * other_moles / TM, 0.01) - else - data["SM_gas_OTHER"] = 0 - else - data["SM_gas_O2"] = 0 - data["SM_gas_CO2"] = 0 - data["SM_gas_N2"] = 0 - data["SM_gas_PH"] = 0 - data["SM_gas_OTHER"] = 0 - else - var/list/SMS = list() - for(var/obj/machinery/power/supermatter_shard/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"] = FALSE - data["supermatters"] = SMS - - return data - - -/datum/computer_file/program/supermatter_monitor/Topic(href, href_list) - if(..()) - return TRUE - if(href_list["clear"]) - active = null - return TRUE - if(href_list["refresh"]) - refresh() - return TRUE - if(href_list["set"]) - var/newuid = text2num(href_list["set"]) - for(var/obj/machinery/power/supermatter_shard/S in supermatters) - if(S.uid == newuid) - active = S - return TRUE diff --git a/code/modules/modular_computers/file_system/programs/generic/configurator.dm b/code/modules/modular_computers/file_system/programs/generic/configurator.dm deleted file mode 100644 index 70ce4656b9c..00000000000 --- a/code/modules/modular_computers/file_system/programs/generic/configurator.dm +++ /dev/null @@ -1,68 +0,0 @@ -// 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" - unsendable = 1 - undeletable = 1 - size = 4 - available_on_ntnet = 0 - requires_ntnet = 0 - - -/datum/computer_file/program/computerconfig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "laptop_configuration.tmpl", "NTOS Configuration Utility", 575, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/computerconfig/ui_data(mob/user) - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - var/obj/item/computer_hardware/battery/battery_module = computer.all_components[MC_CELL] - - var/list/data = get_header_data() - - data["disk_size"] = hard_drive.max_capacity - data["disk_used"] = hard_drive.used_capacity - data["power_usage"] = computer.last_power_usage - data["battery_exists"] = battery_module ? 1 : 0 - if(battery_module && battery_module.battery) - data["battery_rating"] = battery_module.battery.maxcharge - data["battery_percent"] = round(battery_module.battery.percent()) - data["eta"] = computer.get_power_eta() - - if(battery_module && battery_module.battery) - data["battery"] = list("max" = battery_module.battery.maxcharge, "charge" = round(battery_module.battery.charge)) - - var/list/all_entries[0] - for(var/I in computer.all_components) - var/obj/item/computer_hardware/H = computer.all_components[I] - 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 - return data - - -/datum/computer_file/program/computerconfig/Topic(href, list/href_list) - if(..()) - return - switch(href_list["action"]) - if("PC_toggle_component") - var/obj/item/computer_hardware/H = computer.find_hardware_by_name(href_list["name"]) - if(H && istype(H)) - H.enabled = !H.enabled - . = TRUE 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 deleted file mode 100644 index e7edc437639..00000000000 --- a/code/modules/modular_computers/file_system/programs/generic/file_browser.dm +++ /dev/null @@ -1,228 +0,0 @@ -/datum/computer_file/program/filemanager - filename = "filemanager" - filedesc = "NTOS File Manager" - extended_desc = "This program allows management of files." - program_icon_state = "generic" - size = 8 - requires_ntnet = 0 - available_on_ntnet = 0 - undeletable = 1 - var/open_file - var/error - -/datum/computer_file/program/filemanager/proc/prepare_printjob(t, font = PRINTER_FONT) // Additional stuff to parse if we want to print it and make a happy Head of Personnel. Forms FTW. - t = replacetext(t, "\[field\]", "") - t = replacetext(t, "\[sign\]", "") - t = pencode_to_html(t, sign = 0, fields = 0, deffont = font) - return t - -/datum/computer_file/program/filemanager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "file_manager.tmpl", "NTOS File Manager", 575, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/filemanager/ui_data(mob/user) - var/list/data = get_header_data() - - var/obj/item/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD] - var/obj/item/computer_hardware/hard_drive/portable/RHDD = computer.all_components[MC_SDD] - if(error) - data["error"] = error - if(open_file) - var/datum/computer_file/data/file - - if(!computer || !HDD) - data["error"] = "I/O ERROR: Unable to access hard drive." - else - file = HDD.find_file_by_name(open_file) - if(!istype(file)) - data["error"] = "I/O ERROR: Unable to open file." - else - data["filedata"] = pencode_to_html(file.stored_data, format = 1, sign = 0, fields = 0) - data["filename"] = "[file.filename].[file.filetype]" - else - if(!computer || !HDD) - data["error"] = "I/O ERROR: Unable to access hard drive." - else - 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, - "encrypted" = !!F.password - ))) - 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, - "encrypted" = !!F.password - ))) - data["usbfiles"] = usbfiles - - return data - -/datum/computer_file/program/filemanager/Topic(href, list/href_list) - if(..()) - return 1 - - var/obj/item/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD] - var/obj/item/computer_hardware/hard_drive/RHDD = computer.all_components[MC_SDD] - var/obj/item/computer_hardware/printer/printer = computer.all_components[MC_PRINT] - - switch(href_list["action"]) - if("PRG_openfile") - . = 1 - var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"]) - if(!F.can_access_file(usr)) - return - open_file = href_list["name"] - if("PRG_newtextfile") - . = 1 - var/newname = stripped_input(usr, "Enter file name or leave blank to cancel:", "File rename", max_length=50) - if(!newname) - return 1 - 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("PRG_deletefile") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/file = HDD.find_file_by_name(href_list["name"]) - if(!file || file.undeletable) - return 1 - HDD.remove_file(file) - if("PRG_usbdeletefile") - . = 1 - if(!RHDD) - return 1 - var/datum/computer_file/file = RHDD.find_file_by_name(href_list["name"]) - if(!file || file.undeletable) - return 1 - RHDD.remove_file(file) - if("PRG_closefile") - . = 1 - open_file = null - error = null - if("PRG_clone") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"]) - if(!F || !istype(F)) - return 1 - var/newname = stripped_input(usr, "Enter clone file name:", "File clone", "Copy of " + F.filename, max_length=50) - if(F && newname) - var/datum/computer_file/C = F.clone(1) - C.filename = newname - if(!HDD.store_file(C)) - error = "I/O error: Unable to clone file. Hard drive is probably full." - if("PRG_rename") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/file = HDD.find_file_by_name(href_list["name"]) - if(!file || !istype(file)) - return 1 - var/newname = stripped_input(usr, "Enter new file name:", "File rename", file.filename, max_length=50) - if(file && newname) - file.filename = newname - if("PRG_edit") - . = 1 - if(!open_file) - return 1 - 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 - // 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently. - var/newtext = stripped_multiline_input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", html_decode(F.stored_data), 16384, TRUE) - if(!newtext) - return - if(F) - var/datum/computer_file/data/backup = F.clone() - HDD.remove_file(F) - F = backup.clone() //When the file gets removed from the HDD, it gets queued for garbage collection. Hacky fix is to make a copy. - 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:

[F.stored_data]

" - HDD.store_file(backup) - if("PRG_printfile") - . = 1 - if(!open_file) - return 1 - if(!HDD) - return 1 - var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) - if(!F || !istype(F)) - return 1 - if(!printer) - error = "Missing Hardware: Your computer does not have required hardware to complete this operation." - return 1 - if(!printer.print_text(prepare_printjob(F.stored_data, computer.emagged ? CRAYON_FONT : PRINTER_FONT), open_file)) - error = "Hardware error: Printer was unable to print the file. It may be out of paper." - return 1 - if("PRG_copytousb") - . = 1 - if(!HDD || !RHDD) - return 1 - var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"]) - if(!F || !istype(F)) - return 1 - var/datum/computer_file/C = F.clone(0) - RHDD.store_file(C) - if("PRG_copyfromusb") - . = 1 - if(!HDD || !RHDD) - return 1 - var/datum/computer_file/F = RHDD.find_file_by_name(href_list["name"]) - if(!F || !istype(F)) - return 1 - var/datum/computer_file/C = F.clone(0) - HDD.store_file(C) - if("PRG_encrypt") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"]) - if(!F || F.undeletable) - return 1 - if(F.password) - return - var/new_password = sanitize(input(usr, "Enter an encryption key:", "Encrypt File")) - if(!new_password) - to_chat(usr, "File not encrypted.") - return - F.password=new_password - if("PRG_decrypt") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"]) - if(!F || F.undeletable) - return 1 - if(F.can_access_file(usr)) - F.password = "" diff --git a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm deleted file mode 100644 index b4e5ab4674c..00000000000 --- a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm +++ /dev/null @@ -1,178 +0,0 @@ -/datum/computer_file/program/ntnetdownload - filename = "ntndownloader" - filedesc = "NTNet Software Download Tool" - program_icon_state = "generic" - 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 - 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/obj/item/modular_computer/my_computer = null - -/datum/computer_file/program/ntnetdownload/proc/begin_file_download(filename) - if(downloaded_file) - return 0 - - var/datum/computer_file/program/PRG = GLOB.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 - - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - - if(!computer || !hard_drive || !hard_drive.can_store_file(PRG)) - return 0 - - ui_header = "downloader_running.gif" - - if(PRG in GLOB.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 GLOB.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/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]"].") - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - if(!computer || !hard_drive || !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() - // 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, list/href_list) - if(..()) - return 1 - switch(href_list["action"]) - if("PRG_downloadfile") - if(!downloaded_file) - begin_file_download(href_list["filename"]) - return 1 - if("PRG_reseterror") - if(downloaderror) - download_completion = 0 - download_netspeed = 0 - downloaded_file = null - downloaderror = "" - return 1 - return 0 - -/datum/computer_file/program/ntnetdownload/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "ntnet_downloader.tmpl", "NTNet Download Program", 575, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/ntnetdownload/ui_data(mob/user) - my_computer = computer - - if(!istype(my_computer)) - return - - var/list/data = get_header_data() - - // This IF cuts on data transferred to client, so i guess it's worth it. - if(downloaderror) // Download errored. Wait until user resets the program. - data["error"] = downloaderror - else if(downloaded_file) // Download running. Wait please.. - data["downloadname"] = downloaded_file.filename - data["downloaddesc"] = downloaded_file.filedesc - data["downloadsize"] = downloaded_file.size - data["downloadspeed"] = download_netspeed - data["downloadcompletion"] = round(min(download_completion, downloaded_file.size), 0.1) - else // No download running, pick file. - var/obj/item/computer_hardware/hard_drive/hard_drive = my_computer.all_components[MC_HDD] - data["disk_size"] = hard_drive.max_capacity - data["disk_used"] = hard_drive.used_capacity - var/list/all_entries[0] - for(var/A in GLOB.ntnet_global.available_station_software) - var/datum/computer_file/program/P = A - // Only those programs our user can run will show in the list - if(!P.can_run(user,transfer = 1)) - continue - all_entries.Add(list(list( - "filename" = P.filename, - "filedesc" = P.filedesc, - "fileinfo" = P.extended_desc, - "compatibility" = check_compatibility(P), - "size" = P.size, - "status" = !hard_drive || !hard_drive.can_store_file(P) ? "disabled" : null - ))) - data["hackedavailable"] = 0 - if(computer.emagged) // If we are running on emagged computer we have access to some "bonus" software - var/list/hacked_programs[0] - for(var/S in GLOB.ntnet_global.available_antag_software) - var/datum/computer_file/program/P = S - data["hackedavailable"] = 1 - hacked_programs.Add(list(list( - "filename" = P.filename, - "filedesc" = P.filedesc, - "fileinfo" = P.extended_desc, - "size" = P.size - ))) - data["hacked_programs"] = hacked_programs - - data["downloadable_programs"] = all_entries - - return data - -/datum/computer_file/program/ntnetdownload/proc/check_compatibility(datum/computer_file/program/P) - var/hardflag = computer.hardware_flag - - if(P && P.is_supported_by_hardware(hardflag,0)) - return "Compatible" - return "Incompatible!" - -/datum/computer_file/program/ntnetdownload/kill_program(forced) - abort_file_download() - return ..(forced) 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 deleted file mode 100644 index ca208c22b02..00000000000 --- a/code/modules/modular_computers/file_system/programs/generic/ntnrc_client.dm +++ /dev/null @@ -1,229 +0,0 @@ -/datum/computer_file/program/chatclient - filename = "ntnrc_client" - filedesc = "NTNet Relay Chat Client" - program_icon_state = "command" - 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 - 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/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(forced = FALSE) - if(channel) - channel.remove_client(src) - channel = null - ..() - -/datum/computer_file/program/chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "ntnet_chat.tmpl", "NTNet Relay Chat Client", 575, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - - -/datum/computer_file/program/chatclient/ui_data(mob/user) - if(!GLOB.ntnet_global || !GLOB.ntnet_global.chat_channels) - return - - var/list/data = get_header_data() - - data["adminmode"] = netadmin_mode - if(channel) - data["title"] = channel.title - var/list/messages[0] - for(var/M in channel.messages) - messages.Add(list(list( - "msg" = M - ))) - data["messages"] = messages - var/list/clients[0] - for(var/C in channel.clients) - var/datum/computer_file/program/chatclient/cl = C - clients.Add(list(list( - "name" = cl.username - ))) - data["clients"] = clients - operator_mode = (channel.operator == src) ? 1 : 0 - data["is_operator"] = operator_mode || netadmin_mode - - else // Channel selection screen - var/list/all_channels[0] - for(var/C in GLOB.ntnet_global.chat_channels) - var/datum/ntnet_conversation/conv = C - if(conv && conv.title) - all_channels.Add(list(list( - "chan" = conv.title, - "id" = conv.id - ))) - data["all_channels"] = all_channels - - return data - -/datum/computer_file/program/chatclient/Topic(href, list/href_list) - if(..()) - return 1 - - switch(href_list["action"]) - if("PRG_speak") - . = 1 - if(!channel) - return 1 - var/mob/living/user = usr - var/message = reject_bad_text(input(user, "Enter message or leave blank to cancel: ")) - if(!message || !channel) - return - channel.add_message(message, username) - log_chat("[username] sent to [channel.title]: [message]", user) - - if("PRG_joinchannel") - . = 1 - var/datum/ntnet_conversation/C - for(var/datum/ntnet_conversation/chan in GLOB.ntnet_global.chat_channels) - if(chan.id == text2num(href_list["id"])) - 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 = reject_bad_text(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("PRG_leavechannel") - . = 1 - if(channel) - channel.remove_client(src) - channel = null - if("PRG_newchannel") - . = 1 - var/mob/living/user = usr - var/channel_title = reject_bad_text(input(user,"Enter channel name or leave blank to cancel:")) - if(!channel_title) - return 1 - var/datum/ntnet_conversation/C = new/datum/ntnet_conversation() - C.add_client(src) - C.operator = src - channel = C - C.title = channel_title - if("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(user, 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 1 - netadmin_mode = 1 - if("PRG_changename") - . = 1 - var/mob/living/user = usr - var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:")) - if(!newname) - return 1 - if(channel) - channel.add_status_message("[username] is now known as [newname].") - username = newname - - if("PRG_savelog") - . = 1 - if(!channel) - return 1 - 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() - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - if(!computer || !hard_drive || !hard_drive.store_file(logfile)) - if(!computer) - // This program shouldn't even be runnable without computer. - CRASH("Var computer is null!") - if(!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("PRG_renamechannel") - . = 1 - if(!operator_mode || !channel) - return 1 - var/mob/living/user = usr - var/newname = reject_bad_text(input(user, "Enter new channel name or leave blank to cancel:")) - if(!newname || !channel) - return 1 - channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.") - channel.title = newname - if("PRG_deletechannel") - . = 1 - if(channel && ((channel.operator == src) || netadmin_mode)) - QDEL_NULL(channel) - if("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 diff --git a/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm b/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm deleted file mode 100644 index 1ccefa9311a..00000000000 --- a/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm +++ /dev/null @@ -1,195 +0,0 @@ -GLOBAL_VAR_INIT(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" - size = 7 - requires_ntnet = 1 - requires_ntnet_feature = NTNET_PEERTOPEER - network_destination = "other device via P2P tunnel" - available_on_ntnet = 1 - - 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/download_netspeed = 0 // Our connectivity speed in GQ/s - 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 = GLOB.nttransfer_uid - GLOB.nttransfer_uid++ - ..() - -/datum/computer_file/program/nttransfer/process_tick() - // Server mode - update_netspeed() - 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.download_netspeed, download_netspeed) - 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(forced = FALSE) - 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) - -/datum/computer_file/program/nttransfer/proc/update_netspeed() - download_netspeed = 0 - switch(ntnet_status) - if(1) - download_netspeed = NTNETSPEED_LOWSIGNAL - if(2) - download_netspeed = NTNETSPEED_HIGHSIGNAL - if(3) - download_netspeed = NTNETSPEED_ETHERNET - -// Finishes download and attempts to store the file on HDD -/datum/computer_file/program/nttransfer/proc/finish_download() - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - if(!computer || !hard_drive || !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 occurred 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/computer_file/program/nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "ntnet_transfer.tmpl", "NTNet P2P Transfer Client", 575, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/nttransfer/Topic(href, list/href_list) - if(..()) - return 1 - switch(href_list["action"]) - if("PRG_downloadfile") - for(var/datum/computer_file/program/nttransfer/P in GLOB.ntnet_global.fileservers) - if("[P.unique_token]" == href_list["id"]) - remote = P - break - if(!remote || !remote.provided_file) - return - if(remote.server_password) - var/pass = reject_bad_text(input(usr, "Code 401 Unauthorized. Please enter password:", "Password required")) - if(pass != remote.server_password) - error = "Incorrect Password" - return 1 - downloaded_file = remote.provided_file.clone() - remote.connected_clients.Add(src) - return 1 - if("PRG_reset") - error = "" - upload_menu = 0 - finalize_download() - if(src in GLOB.ntnet_global.fileservers) - GLOB.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("PRG_setpassword") - var/pass = reject_bad_text(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("PRG_uploadfile") - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - for(var/datum/computer_file/F in hard_drive.stored_files) - if("[F.uid]" == href_list["id"]) - if(F.unsendable) - error = "I/O Error: File locked." - return - if(istype(F, /datum/computer_file/program)) - var/datum/computer_file/program/P = F - if(!P.can_run(usr,transfer = 1)) - error = "Access Error: Insufficient rights to upload file." - provided_file = F - GLOB.ntnet_global.fileservers.Add(src) - return - error = "I/O Error: Unable to locate file on hard drive." - return 1 - if("PRG_uploadmenu") - upload_menu = 1 - - -/datum/computer_file/program/nttransfer/ui_data(mob/user) - - var/list/data = get_header_data() - - if(error) - data["error"] = error - else if(downloaded_file) - data["downloading"] = 1 - data["download_size"] = downloaded_file.size - data["download_progress"] = download_completion - data["download_netspeed"] = actual_netspeed - data["download_name"] = "[downloaded_file.filename].[downloaded_file.filetype]" - else if (provided_file) - data["uploading"] = 1 - data["upload_uid"] = unique_token - data["upload_clients"] = connected_clients.len - data["upload_haspassword"] = server_password ? 1 : 0 - data["upload_filename"] = "[provided_file.filename].[provided_file.filetype]" - else if (upload_menu) - var/list/all_files[0] - var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] - for(var/datum/computer_file/F in 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 GLOB.ntnet_global.fileservers) - 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 - - return data diff --git a/code/modules/modular_computers/file_system/programs/research/airestorer.dm b/code/modules/modular_computers/file_system/programs/research/airestorer.dm deleted file mode 100644 index a87a2cd87b4..00000000000 --- a/code/modules/modular_computers/file_system/programs/research/airestorer.dm +++ /dev/null @@ -1,137 +0,0 @@ -/datum/computer_file/program/aidiag - filename = "aidiag" - filedesc = "AI Maintenance Utility" - program_icon_state = "generic" - extended_desc = "This program is capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." - size = 12 - requires_ntnet = 0 - usage_flags = PROGRAM_CONSOLE - transfer_access = ACCESS_HEADS - available_on_ntnet = 1 - var/restoring = FALSE - -/datum/computer_file/program/aidiag/proc/get_ai(cardcheck) - - var/obj/item/computer_hardware/ai_slot/ai_slot - - if(computer) - ai_slot = computer.all_components[MC_AI] - - if(computer && ai_slot && ai_slot.check_functionality()) - if(cardcheck == 1) - return ai_slot - if(ai_slot.enabled && ai_slot.stored_card) - if(cardcheck == 2) - return ai_slot.stored_card - if(locate(/mob/living/silicon/ai) in ai_slot.stored_card) - return locate(/mob/living/silicon/ai) in ai_slot.stored_card - - return null - -/datum/computer_file/program/aidiag/Topic(href, list/href_list) - if(..()) - return TRUE - - var/mob/living/silicon/ai/A = get_ai() - if(!A) - restoring = FALSE - - switch(href_list["action"]) - if("PRG_beginReconstruction") - if(A && A.health < 100) - restoring = TRUE - return TRUE - if("PRG_eject") - if(computer.all_components[MC_AI]) - var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI] - if(ai_slot && ai_slot.stored_card) - ai_slot.try_eject(0,usr) - return TRUE - -/datum/computer_file/program/aidiag/process_tick() - ..() - if(!restoring) //Put the check here so we don't check for an ai all the time - return - var/obj/item/aicard/cardhold = get_ai(2) - - var/obj/item/computer_hardware/ai_slot/ai_slot = get_ai(1) - - - var/mob/living/silicon/ai/A = get_ai() - if(!A || !cardhold) - restoring = FALSE // If the AI was removed, stop the restoration sequence. - if(ai_slot) - ai_slot.locked = FALSE - return - - if(cardhold.flush) - ai_slot.locked = FALSE - restoring = FALSE - return - ai_slot.locked = TRUE - A.adjustOxyLoss(-1) - A.adjustFireLoss(-1) - A.adjustToxLoss(-1) - A.adjustBruteLoss(-1) - A.updatehealth() - if(A.health >= 0 && A.stat == DEAD) - A.stat = CONSCIOUS - A.lying = 0 - GLOB.dead_mob_list -= A - GLOB.alive_mob_list += A - // Finished restoring - if(A.health >= 100) - ai_slot.locked = FALSE - restoring = FALSE - - return TRUE - - -/datum/computer_file/program/aidiag/ui_data(mob/user) - var/list/data = get_header_data() - var/mob/living/silicon/ai/AI - // A shortcut for getting the AI stored inside the computer. The program already does necessary checks. - AI = get_ai() - - var/obj/item/aicard/aicard = get_ai(2) - - if(!aicard) - data["nocard"] = TRUE - data["error"] = "Please insert an intelliCard." - else - if(!AI) - data["error"] = "No AI located" - else - var/obj/item/aicard/cardhold = AI.loc - if(cardhold.flush) - data["error"] = "Flush in progress" - else - data["name"] = AI.name - data["restoring"] = restoring - data["health"] = (AI.health + 100) / 2 - data["isDead"] = AI.stat == DEAD - - var/list/all_laws[0] - for(var/datum/ai_law/L in AI.laws.all_laws()) - all_laws.Add(list(list( - "index" = L.index, - "text" = L.law - ))) - - data["ai_laws"] = all_laws - - return data - -/datum/computer_file/program/aidiag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "ai_restorer.tmpl", "Integrity Restorer", 600, 400) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/aidiag/kill_program(forced) - restoring = FALSE - return ..(forced) diff --git a/code/modules/modular_computers/file_system/programs/research/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/research/ntmonitor.dm deleted file mode 100644 index 0a839a6d13f..00000000000 --- a/code/modules/modular_computers/file_system/programs/research/ntmonitor.dm +++ /dev/null @@ -1,90 +0,0 @@ -/datum/computer_file/program/ntnetmonitor - filename = "ntmonitor" - filedesc = "NTNet Diagnostics and Monitoring" - program_icon_state = "comm_monitor" - extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes" - size = 12 - requires_ntnet = 1 - required_access = ACCESS_NETWORK //Network control is a more secure program. - available_on_ntnet = 1 - -/datum/computer_file/program/ntnetmonitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) - assets.send(user) - ui = new(user, src, ui_key, "ntnet_monitor.tmpl", "NTNet Diagnostics and Monitoring Tool", 575, 700) - ui.set_auto_update(1) - ui.set_layout_key("program") - ui.open() - -/datum/computer_file/program/ntnetmonitor/Topic(href, list/href_list) - if(..()) - return 1 - switch(href_list["action"]) - if("resetIDS") - . = 1 - if(GLOB.ntnet_global) - GLOB.ntnet_global.resetIDS() - return 1 - if("toggleIDS") - . = 1 - if(GLOB.ntnet_global) - GLOB.ntnet_global.toggleIDS() - return 1 - if("toggleWireless") - . = 1 - if(!GLOB.ntnet_global) - return 1 - - // NTNet is disabled. Enabling can be done without user prompt - if(GLOB.ntnet_global.setting_disabled) - GLOB.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) - var/mob/user = usr - 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") - GLOB.ntnet_global.setting_disabled = 1 - return 1 - if("purgelogs") - . = 1 - if(GLOB.ntnet_global) - GLOB.ntnet_global.purge_logs() - if("updatemaxlogs") - . = 1 - var/mob/user = usr - var/logcount = text2num(input(user,"Enter amount of logs to keep in memory ([MIN_NTNET_LOGS]-[MAX_NTNET_LOGS]):")) - if(GLOB.ntnet_global) - GLOB.ntnet_global.update_max_log_count(logcount) - if("toggle_function") - . = 1 - if(!GLOB.ntnet_global) - return 1 - GLOB.ntnet_global.toggle_function(text2num(href_list["id"])) - -/datum/computer_file/program/ntnetmonitor/ui_data(mob/user) - if(!GLOB.ntnet_global) - return - var/list/data = get_header_data() - - data["ntnetstatus"] = GLOB.ntnet_global.check_function() - data["ntnetrelays"] = GLOB.ntnet_global.relays.len - data["idsstatus"] = GLOB.ntnet_global.intrusion_detection_enabled - data["idsalarm"] = GLOB.ntnet_global.intrusion_detection_alarm - - data["config_softwaredownload"] = GLOB.ntnet_global.setting_softwaredownload - data["config_peertopeer"] = GLOB.ntnet_global.setting_peertopeer - data["config_communication"] = GLOB.ntnet_global.setting_communication - data["config_systemcontrol"] = GLOB.ntnet_global.setting_systemcontrol - - data["ntnetlogs"] = list() - - for(var/i in GLOB.ntnet_global.logs) - data["ntnetlogs"] += list(list("entry" = i)) - data["ntnetmaxlogs"] = GLOB.ntnet_global.setting_maxlogcount - - return data diff --git a/code/modules/modular_computers/hardware/CPU.dm b/code/modules/modular_computers/hardware/CPU.dm deleted file mode 100644 index 02e7d41d512..00000000000 --- a/code/modules/modular_computers/hardware/CPU.dm +++ /dev/null @@ -1,44 +0,0 @@ -// CPU that allows the computer to run programs. -// Better CPUs are obtainable via research and can run more programs on background. - -/obj/item/computer_hardware/processor_unit - name = "processor board" - desc = "A standard CPU board used in most computers. It can run up to three programs simultaneously." - icon_state = "cpuboard" - w_class = WEIGHT_CLASS_SMALL - power_usage = 50 - critical = 1 - malfunction_probability = 1 - origin_tech = "programming=3;engineering=2" - var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description. - device_type = MC_CPU - -/obj/item/computer_hardware/processor_unit/on_remove(obj/item/modular_computer/MC, mob/user) - MC.shutdown_computer() - -/obj/item/computer_hardware/processor_unit/small - name = "microprocessor" - desc = "A miniaturised CPU used in portable devices. It can run up to two programs simultaneously." - icon_state = "cpu" - w_class = WEIGHT_CLASS_TINY - power_usage = 25 - max_idle_programs = 1 - origin_tech = "programming=2;engineering=2" - -/obj/item/computer_hardware/processor_unit/photonic - name = "photonic processor board" - desc = "An advanced experimental CPU board that uses photonic core instead of regular circuitry. It can run up to five programs simultaneously, but uses a lot of power." - icon_state = "cpuboard_super" - w_class = WEIGHT_CLASS_SMALL - power_usage = 250 - max_idle_programs = 4 - origin_tech = "programming=5;engineering=4" - -/obj/item/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_super" - w_class = WEIGHT_CLASS_TINY - power_usage = 75 - max_idle_programs = 2 - origin_tech = "programming=4;engineering=3" diff --git a/code/modules/modular_computers/hardware/_hardware.dm b/code/modules/modular_computers/hardware/_hardware.dm deleted file mode 100644 index 3e82455c53b..00000000000 --- a/code/modules/modular_computers/hardware/_hardware.dm +++ /dev/null @@ -1,105 +0,0 @@ -/obj/item/computer_hardware - name = "hardware" - desc = "Unknown Hardware." - icon = 'icons/obj/module.dmi' - icon_state = "std_mod" - - w_class = WEIGHT_CLASS_TINY // w_class limits which devices can contain this component. - // 1: PDAs/Tablets, 2: Laptops, 3-4: Consoles only - var/obj/item/modular_computer/holder = null - // Computer that holds this hardware, if any. - - max_integrity = 200 - - 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 = 0 // Prevent disabling for important component, like the CPU. - var/can_install = 1 // Prevents direct installation of removable media. - 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 - var/device_type - -/obj/item/computer_hardware/New(var/obj/L) - ..() - pixel_x = rand(-8, 8) - pixel_y = rand(-8, 8) - -/obj/item/computer_hardware/Destroy() - if(holder) - holder.uninstall_component(src) - return ..() - - -/obj/item/computer_hardware/attackby(obj/item/I, mob/living/user) - // Multitool. Runs diagnostics - if(istype(I, /obj/item/multitool)) - to_chat(user, "***** DIAGNOSTICS REPORT *****") - diagnostics(user) - to_chat(user, "******************************") - return 1 - - // Cable coil. Works as repair method, but will probably require multiple applications and more cable. - if(istype(I, /obj/item/stack/cable_coil)) - var/obj/item/stack/S = I - if(obj_integrity == max_integrity) - 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 [I].") - obj_integrity = min(obj_integrity + 10, max_integrity) - return 1 - - if(try_insert(I, user)) - return 1 - - return ..() - -// Called on multitool click, prints diagnostic information to the user. -/obj/item/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"]") - -// Handles damage checks -/obj/item/computer_hardware/proc/check_functionality() - if(!enabled) // Disabled. - return FALSE - - if(damage > damage_failure) // Too damaged to work at all. - return FALSE - - if(damage > damage_malfunction) // Still working. Well, sometimes... - if(prob(malfunction_probability)) - return FALSE - - return TRUE // Good to go. - -/obj/item/computer_hardware/examine(var/mob/user) - . = ..() - if(damage > damage_failure) - . += "It seems to be severely damaged!" - else if(damage > damage_malfunction) - . += "It seems to be damaged!" - else if(damage) - . += "It seems to be slightly damaged." - -// Component-side compatibility check. -/obj/item/computer_hardware/proc/can_install(obj/item/modular_computer/M, mob/living/user = null) - return can_install - -// Called when component is installed into PC. -/obj/item/computer_hardware/proc/on_install(obj/item/modular_computer/M, mob/living/user = null) - return - -// Called when component is removed from PC. -/obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/M, mob/living/user = null) - try_eject(forced = 1) - -// Called when someone tries to insert something in it - paper in printer, card in card reader, etc. -/obj/item/computer_hardware/proc/try_insert(obj/item/I, mob/living/user = null) - return FALSE - -// Called when someone tries to eject something from it - card from card reader, etc. -/obj/item/computer_hardware/proc/try_eject(slot=0, mob/living/user = null, forced = 0) - return FALSE diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm deleted file mode 100644 index 1b97ae5ede8..00000000000 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ /dev/null @@ -1,80 +0,0 @@ -/obj/item/computer_hardware/ai_slot - name = "intelliCard interface slot" - desc = "A module allowing this computer to interface with most common intelliCard modules. Necessary for some programs to run properly." - power_usage = 100 //W - icon_state = "card_mini" - w_class = WEIGHT_CLASS_SMALL - origin_tech = "programming=2" - device_type = MC_AI - - var/obj/item/aicard/stored_card = null - var/locked = FALSE - -/obj/item/computer_hardware/ai_slot/Destroy() - QDEL_NULL(stored_card) - return ..() - - -/obj/item/computer_hardware/ai_slot/examine(mob/user) - . = ..() - if(stored_card) - . += "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it" - -/obj/item/computer_hardware/ai_slot/on_install(obj/item/modular_computer/M, mob/living/user = null) - M.add_verb(device_type) - -/obj/item/computer_hardware/ai_slot/on_remove(obj/item/modular_computer/M, mob/living/user = null) - M.remove_verb(device_type) - try_eject(0, forced = 1) - -/obj/item/computer_hardware/ai_slot/try_insert(obj/item/I, mob/living/user = null) - if(!holder) - return FALSE - - if(!istype(I, /obj/item/aicard)) - return FALSE - - if(stored_card) - if(user) - to_chat(user, "You try to insert \the [I] into \the [src], but the slot is occupied.") - return FALSE - if(user && !user.unEquip(I)) - return FALSE - - I.forceMove(src) - stored_card = I - if(user) - to_chat(user, "You insert \the [I] into \the [src].") - - return TRUE - - -/obj/item/computer_hardware/ai_slot/try_eject(slot=0, mob/living/user = null, forced = 0) - if(!stored_card) - if(user) - to_chat(user, "There is no card in \the [src].") - return FALSE - - if(locked && !forced) - if(user) - to_chat(user, "Safeties prevent you from removing the card until reconstruction is complete...") - return FALSE - - if(stored_card) - stored_card.forceMove(get_turf(src)) - locked = FALSE - stored_card.verb_pickup() - stored_card = null - - if(user) - to_chat(user, "You remove the card from \the [src].") - return TRUE - return FALSE - -/obj/item/computer_hardware/ai_slot/attackby(obj/item/I, mob/living/user) - if(..()) - return - if(istype(I, /obj/item/screwdriver)) - to_chat(user, "You press down on the manual eject button with \the [I].") - try_eject(0, user, 1) - return diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm deleted file mode 100644 index 1a48110006a..00000000000 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ /dev/null @@ -1,108 +0,0 @@ -/obj/item/computer_hardware/battery - name = "power cell controller" - desc = "A charge controller for standard power cells, used in all kinds of modular computers." - icon_state = "cell_con" - critical = 1 - malfunction_probability = 1 - origin_tech = "powerstorage=1;engineering=1" - var/obj/item/stock_parts/cell/battery = null - device_type = MC_CELL - -/obj/item/computer_hardware/battery/get_cell() - return battery - -/obj/item/computer_hardware/battery/New(loc, battery_type = null) - if(battery_type) - battery = new battery_type(src) - ..() - -/obj/item/computer_hardware/battery/Destroy() - QDEL_NULL(battery) - return ..() - -/obj/item/computer_hardware/battery/on_remove(obj/item/modular_computer/M, mob/living/user = null) - try_eject(0, forced = 1) - -/obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null) - if(!holder) - return FALSE - - if(!istype(I, /obj/item/stock_parts/cell)) - return FALSE - - if(battery) - if(user) - to_chat(user, "You try to connect \the [I] to \the [src], but its connectors are occupied.") - return FALSE - - if(I.w_class > holder.max_hardware_size) - if(user) - to_chat(user, "This power cell is too large for \the [holder]!") - return FALSE - - if(user && !user.unEquip(I)) - return FALSE - - I.forceMove(src) - battery = I - if(user) - to_chat(user, "You connect \the [I] to \the [src].") - - return TRUE - - -/obj/item/computer_hardware/battery/try_eject(slot=0, mob/living/user = null, forced = 0) - if(!battery) - if(user) - to_chat(user, "There is no power cell connected to \the [src].") - return FALSE - else - battery.forceMove(get_turf(src)) - if(user) - to_chat(user, "You detach \the [battery] from \the [src].") - battery = null - - if(holder) - if(holder.enabled && !holder.use_power()) - holder.shutdown_computer() - - return TRUE - - -// Stock parts -/obj/item/stock_parts/cell/computer - name = "standard battery" - desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops." - icon = 'icons/obj/module.dmi' - icon_state = "cell_mini" - origin_tech = "powerstorage=2;engineering=1" - w_class = WEIGHT_CLASS_TINY - maxcharge = 750 - -/obj/item/stock_parts/cell/computer/advanced - name = "advanced battery" - desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices." - icon_state = "cell" - origin_tech = "powerstorage=2;engineering=2" - maxcharge = 1500 - -/obj/item/stock_parts/cell/computer/super - name = "super battery" - desc = "An advanced power cell, often used in high-end laptops." - icon_state = "cell" - origin_tech = "powerstorage=3;engineering=3" - maxcharge = 2000 - -/obj/item/stock_parts/cell/computer/micro - name = "micro battery" - desc = "A small power cell, commonly seen in most portable microcomputers." - icon_state = "cell_micro" - w_class = WEIGHT_CLASS_TINY - maxcharge = 500 - -/obj/item/stock_parts/cell/computer/nano - name = "nano battery" - desc = "A tiny power cell, commonly seen in low-end portable microcomputers." - icon_state = "cell_micro" - w_class = WEIGHT_CLASS_TINY - maxcharge = 300 diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm deleted file mode 100644 index fc1abc207a5..00000000000 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ /dev/null @@ -1,112 +0,0 @@ -/obj/item/computer_hardware/card_slot - name = "identification card authentication module" // \improper breaks the find_hardware_by_name proc - desc = "A module allowing this computer to read or write data on ID cards. Necessary for some programs to run properly." - power_usage = 10 //W - icon_state = "card_mini" - w_class = WEIGHT_CLASS_TINY - origin_tech = "programming=2" - device_type = MC_CARD - - var/obj/item/card/id/stored_card = null - var/obj/item/card/id/stored_card2 = null - -/obj/item/computer_hardware/card_slot/Destroy() - QDEL_NULL(stored_card) - QDEL_NULL(stored_card2) - return ..() - -/obj/item/computer_hardware/card_slot/GetAccess() - if(stored_card && stored_card2) // Best of both worlds - return (stored_card.GetAccess() | stored_card2.GetAccess()) - else if(stored_card) - return stored_card.GetAccess() - else if(stored_card2) - return stored_card2.GetAccess() - return ..() - -/obj/item/computer_hardware/card_slot/GetID() - if(stored_card) - return stored_card - else if(stored_card2) - return stored_card2 - return ..() - -/obj/item/computer_hardware/card_slot/on_install(obj/item/modular_computer/M, mob/living/user = null) - M.add_verb(device_type) - -/obj/item/computer_hardware/card_slot/on_remove(obj/item/modular_computer/M, mob/living/user = null) - M.remove_verb(device_type) - try_eject(0, forced = 1) - -/obj/item/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null) - if(!holder) - return FALSE - - if(!istype(I, /obj/item/card/id)) - return FALSE - - if(stored_card && stored_card2) - if(user) - to_chat(user, "You try to insert \the [I] into \the [src], but its slots are occupied.") - return FALSE - if(user && !user.unEquip(I)) - return FALSE - - I.forceMove(src) - - if(!stored_card) - stored_card = I - else - stored_card2 = I - - if(user) - to_chat(user, "You insert \the [I] into \the [src].") - - return TRUE - - -/obj/item/computer_hardware/card_slot/try_eject(slot = 0, mob/living/user = null, forced = 0) - if(!stored_card && !stored_card2) - if(user) - to_chat(user, "There are no cards in \the [src].") - return FALSE - - var/ejected = 0 - if(stored_card && (!slot || slot == 1)) - stored_card.forceMove(get_turf(src)) - stored_card.verb_pickup() - stored_card = null - ejected++ - - if(stored_card2 && (!slot || slot == 2)) - stored_card2.forceMove(get_turf(src)) - stored_card2.verb_pickup() - stored_card2 = null - ejected++ - - if(ejected) - if(holder) - if(holder.active_program) - holder.active_program.event_idremoved(0, slot) - - for(var/I in holder.idle_threads) - var/datum/computer_file/program/P = I - P.event_idremoved(1, slot) - - if(user) - to_chat(user, "You remove the card[ejected>1 ? "s" : ""] from \the [src].") - return TRUE - return FALSE - -/obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user) - if(..()) - return - if(istype(I, /obj/item/screwdriver)) - to_chat(user, "You press down on the manual eject button with \the [I].") - try_eject(0,user) - return - -/obj/item/computer_hardware/card_slot/examine(mob/user) - . = ..() - if(stored_card || stored_card2) - . += "There appears to be something loaded in the card slots." diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm deleted file mode 100644 index ce7fc997192..00000000000 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ /dev/null @@ -1,173 +0,0 @@ -/obj/item/computer_hardware/hard_drive - name = "hard disk drive" - desc = "A small HDD, for use in basic computers where power efficiency is desired." - power_usage = 25 - icon_state = "harddisk_mini" - critical = 1 - w_class = WEIGHT_CLASS_TINY - origin_tech = "programming=1;engineering=1" - device_type = MC_HDD - 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/computer_hardware/hard_drive/on_remove(obj/item/modular_computer/MC, mob/user) - MC.shutdown_computer() - -/obj/item/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. - -/obj/item/computer_hardware/hard_drive/examine(user) - . = ..() - . += "It has [max_capacity] GQ of storage capacity." - -/obj/item/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/computer_hardware/hard_drive/proc/store_file(var/datum/computer_file/F) - if(!F || !istype(F)) - return 0 - - if(!can_store_file(F)) - 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 remove file from the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. -/obj/item/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/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. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file. -/obj/item/computer_hardware/hard_drive/proc/can_store_file(var/datum/computer_file/F) - if(!F || !istype(F)) - return 0 - - if(F in stored_files) - 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 - - // 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 + F.size) > max_capacity) - return 0 - else - return 1 - - -// Tries to find the file by filename. Returns null on failure -/obj/item/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/computer_hardware/hard_drive/Destroy() - stored_files = null - return ..() - -/obj/item/computer_hardware/hard_drive/New() - install_default_programs() - ..() - - -/obj/item/computer_hardware/hard_drive/advanced - name = "advanced hard disk drive" - desc = "A hybrid HDD, for use in higher grade computers where balance between power efficiency and capacity is desired." - max_capacity = 256 - origin_tech = "programming=2;engineering=2" - power_usage = 50 // Hybrid, medium capacity and medium power storage - icon_state = "harddisk_mini" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/computer_hardware/hard_drive/super - name = "super hard disk drive" - desc = "A high capacity HDD, for use in cluster storage solutions where capacity is more important than power efficiency." - max_capacity = 512 - origin_tech = "programming=3;engineering=3" - power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. - icon_state = "harddisk_mini" - w_class = WEIGHT_CLASS_SMALL - -/obj/item/computer_hardware/hard_drive/cluster - name = "cluster hard disk drive" - desc = "A large storage cluster consisting of multiple HDDs for usage in dedicated storage systems." - power_usage = 500 - origin_tech = "programming=4;engineering=4" - max_capacity = 2048 - icon_state = "harddisk" - w_class = WEIGHT_CLASS_NORMAL - -// For tablets, etc. - highly power efficient. -/obj/item/computer_hardware/hard_drive/small - name = "solid state drive" - desc = "An efficient SSD for portable devices." - power_usage = 10 - origin_tech = "programming=2;engineering=2" - max_capacity = 64 - icon_state = "ssd_mini" - w_class = WEIGHT_CLASS_TINY - -/obj/item/computer_hardware/hard_drive/micro - name = "micro solid state drive" - desc = "A highly efficient SSD chip for portable devices." - power_usage = 2 - origin_tech = "programming=1;engineering=1" - max_capacity = 32 - icon_state = "ssd_micro" - w_class = WEIGHT_CLASS_TINY diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm deleted file mode 100644 index 3e5409b5d61..00000000000 --- a/code/modules/modular_computers/hardware/network_card.dm +++ /dev/null @@ -1,82 +0,0 @@ -GLOBAL_VAR_INIT(ntnet_card_uid, 1) - -/obj/item/computer_hardware/network_card - name = "network card" - desc = "A basic wireless network card for usage with standard NTNet frequencies." - power_usage = 50 - origin_tech = "programming=2;engineering=1" - icon_state = "radio_mini" - 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 - device_type = MC_NET - -/obj/item/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/computer_hardware/network_card/New(var/l) - ..(l) - identification_id = GLOB.ntnet_card_uid - GLOB.ntnet_card_uid++ - -// Returns a string identifier of this network card -/obj/item/computer_hardware/network_card/proc/get_network_tag() - return "[identification_string] (NID [identification_id])" - -// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection -/obj/item/computer_hardware/network_card/proc/get_signal(var/specific_action = 0) - if(!holder) // Hardware is not installed in anything. No signal. How did this even get called? - return 0 - - if(!check_functionality()) - return 0 - - if(ethernet) // Computer is connected via wired connection. - return 3 - - if(!GLOB.ntnet_global || !GLOB.ntnet_global.check_function(specific_action)) // NTNet is down and we are not connected via wired connection. No signal. - return 0 - - if(holder) - - var/turf/T = get_turf(holder) - if((T && istype(T)) && is_station_contact(T.z)) - // 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(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/computer_hardware/network_card/advanced - name = "advanced network card" - desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter is strong enough to connect even off-station." - long_range = 1 - origin_tech = "programming=4;engineering=2" - power_usage = 100 // Better range but higher power usage. - icon_state = "radio" - w_class = WEIGHT_CLASS_TINY - -/obj/item/computer_hardware/network_card/wired - name = "wired network card" - desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection." - ethernet = 1 - origin_tech = "programming=5;engineering=3" - power_usage = 100 // Better range but higher power usage. - icon_state = "net_wired" - w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/modular_computers/hardware/portable_disk.dm b/code/modules/modular_computers/hardware/portable_disk.dm deleted file mode 100644 index 93c9c1f412b..00000000000 --- a/code/modules/modular_computers/hardware/portable_disk.dm +++ /dev/null @@ -1,35 +0,0 @@ -/obj/item/computer_hardware/hard_drive/portable - name = "data disk" - desc = "Removable disk used to store data." - power_usage = 10 - icon_state = "datadisk6" - w_class = WEIGHT_CLASS_TINY - critical = 0 - max_capacity = 16 - origin_tech = "programming=1" - device_type = MC_SDD - -/obj/item/computer_hardware/hard_drive/portable/on_install(obj/item/modular_computer/M, mob/living/user = null) - M.add_verb(device_type) - -/obj/item/computer_hardware/hard_drive/portable/on_remove(obj/item/modular_computer/M, mob/living/user = null) - ..() - M.remove_verb(device_type) - -/obj/item/computer_hardware/hard_drive/portable/install_default_programs() - return // Empty by default - -/obj/item/computer_hardware/hard_drive/portable/advanced - name = "advanced data disk" - power_usage = 20 - icon_state = "datadisk5" - max_capacity = 64 - origin_tech = "programming=2" - -/obj/item/computer_hardware/hard_drive/portable/super - name = "super data disk" - desc = "Removable disk used to store large amounts of data." - power_usage = 40 - icon_state = "datadisk3" - max_capacity = 256 - origin_tech = "programming=4" diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm deleted file mode 100644 index 49c5d72a6f1..00000000000 --- a/code/modules/modular_computers/hardware/printer.dm +++ /dev/null @@ -1,70 +0,0 @@ -/obj/item/computer_hardware/printer - name = "printer" - desc = "Computer-integrated printer with paper recycling module." - power_usage = 100 - origin_tech = "programming=2;engineering=2" - icon_state = "printer" - w_class = WEIGHT_CLASS_NORMAL - device_type = MC_PRINT - var/stored_paper = 20 - var/max_paper = 30 - -/obj/item/computer_hardware/printer/diagnostics(mob/living/user) - ..() - to_chat(user, "Paper level: [stored_paper]/[max_paper]") - -/obj/item/computer_hardware/printer/examine(mob/user) - . = ..() - . += "Paper level: [stored_paper]/[max_paper]" - - -/obj/item/computer_hardware/printer/proc/print_text(var/text_to_print, var/paper_title = "") - if(!stored_paper) - return FALSE - if(!check_functionality()) - return FALSE - - var/obj/item/paper/P = new/obj/item/paper(holder.drop_location()) - - // 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() - P.populatefields() - P.updateinfolinks() - stored_paper-- - P = null - - playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) - - return TRUE - -/obj/item/computer_hardware/printer/try_insert(obj/item/I, mob/living/user = null) - if(istype(I, /obj/item/paper)) - if(stored_paper >= max_paper) - if(user) - to_chat(user, "You try to add \the [I] into [src], but its paper bin is full!") - return FALSE - - if(user && !user.unEquip(I)) - return FALSE - - if(user) - to_chat(user, "You insert \the [I] into [src]'s paper recycler.") - qdel(I) - stored_paper++ - return TRUE - return FALSE - -/obj/item/computer_hardware/printer/mini - name = "miniprinter" - desc = "A small printer with paper recycling module." - power_usage = 50 - icon_state = "printer_mini" - w_class = WEIGHT_CLASS_TINY - stored_paper = 5 - max_paper = 15 diff --git a/code/modules/modular_computers/hardware/recharger.dm b/code/modules/modular_computers/hardware/recharger.dm deleted file mode 100644 index 418a9736528..00000000000 --- a/code/modules/modular_computers/hardware/recharger.dm +++ /dev/null @@ -1,94 +0,0 @@ -/obj/item/computer_hardware/recharger - critical = 1 - enabled = 1 - var/charge_rate = 100 - device_type = MC_CHARGE - -/obj/item/computer_hardware/recharger/proc/use_power(amount, charging=0) - if(charging) - return 1 - return 0 - -/obj/item/computer_hardware/recharger/process() - ..() - var/obj/item/computer_hardware/battery/battery_module = holder.all_components[MC_CELL] - if(!holder || !battery_module || !battery_module.battery) - return - - var/obj/item/stock_parts/cell/cell = battery_module.battery - if(cell.charge >= cell.maxcharge) - return - - if(use_power(charge_rate, charging=1)) - holder.give_power(charge_rate * GLOB.CELLRATE) - - -/obj/item/computer_hardware/recharger/APC - name = "area power connector" - desc = "A device that wirelessly recharges connected device from nearby APC." - icon_state = "charger_APC" - w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs - origin_tech = "programming=2;engineering=2;powerstorage=3" - -/obj/item/computer_hardware/recharger/APC/use_power(amount, charging=0) - if(istype(holder.physical, /obj/machinery)) - var/obj/machinery/M = holder.physical - if(M.powered()) - M.use_power(amount) - return 1 - - else - var/area/A = get_area(src) - if(!istype(A)) - return 0 - - if(A.powered(EQUIP)) - A.use_power(amount, EQUIP) - return 1 - return 0 - -/obj/item/computer_hardware/recharger/wired - name = "wired power connector" - desc = "A power connector that recharges connected device from nearby power wire. Incompatible with portable computers." - icon_state = "charger_wire" - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=2;powerstorage=1" - -/obj/item/computer_hardware/recharger/wired/can_install(obj/item/modular_computer/M, mob/living/user = null) - if(istype(M.physical, /obj/machinery) && M.physical.anchored) - return ..() - if(user) - to_chat(user, "\The [src] is incompatible with portable computers!") - return 0 - -/obj/item/computer_hardware/recharger/wired/use_power(amount, charging=0) - if(istype(holder.physical, /obj/machinery) && holder.physical.anchored) - var/obj/machinery/M = holder.physical - var/turf/T = M.loc - if(!T || !istype(T)) - return 0 - - var/obj/structure/cable/C = T.get_cable_node() - if(!C || !C.powernet) - return 0 - - var/power_in_net = C.powernet.avail-C.powernet.load - - if(power_in_net && power_in_net > amount) - C.powernet.load += amount - return 1 - - return 0 - - - -// This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes. -/obj/item/computer_hardware/recharger/lambda - name = "lambda coil" - desc = "A very complex device that draws power from its own bluespace dimension." - icon_state = "charger_lambda" - w_class = WEIGHT_CLASS_TINY - charge_rate = 100000 - -/obj/item/computer_hardware/recharger/lambda/use_power(amount, charging=0) - return 1 diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm deleted file mode 100644 index aa69b85b1df..00000000000 --- a/code/modules/modular_computers/laptop_vendor.dm +++ /dev/null @@ -1,291 +0,0 @@ -// 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 = BELOW_OBJ_LAYER - 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_apc_recharger = 0 // 0: None, 1: Standard (LAPTOP ONLY) - var/dev_printer = 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 - QDEL_NULL(fabricated_laptop) - QDEL_NULL(fabricated_tablet) - dev_cpu = 1 - dev_battery = 1 - dev_disk = 1 - dev_netcard = 0 - dev_apc_recharger = 0 - dev_printer = 0 - dev_card = 0 - -// Recalculates the price and optionally even fabricates the device. -/obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = 0) - total_price = 0 - if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles - var/obj/item/computer_hardware/battery/battery_module = null - if(fabricate) - fabricated_laptop = new /obj/item/modular_computer/laptop/buildable(src) - fabricated_laptop.install_component(new /obj/item/computer_hardware/battery) - battery_module = fabricated_laptop.all_components[MC_CELL] - total_price = 99 - switch(dev_cpu) - if(1) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/processor_unit/small) - if(2) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/processor_unit) - total_price += 299 - switch(dev_battery) - if(1) // Basic(750C) - if(fabricate) - battery_module.try_insert(new /obj/item/stock_parts/cell/computer) - if(2) // Upgraded(1100C) - if(fabricate) - battery_module.try_insert(new /obj/item/stock_parts/cell/computer/advanced) - total_price += 199 - if(3) // Advanced(1500C) - if(fabricate) - battery_module.try_insert(new /obj/item/stock_parts/cell/computer/super) - total_price += 499 - switch(dev_disk) - if(1) // Basic(128GQ) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/hard_drive) - if(2) // Upgraded(256GQ) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/hard_drive/advanced) - total_price += 99 - if(3) // Advanced(512GQ) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/hard_drive/super) - total_price += 299 - switch(dev_netcard) - if(1) // Basic(Short-Range) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/network_card) - total_price += 99 - if(2) // Advanced (Long Range) - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/network_card/advanced) - total_price += 299 - if(dev_apc_recharger) - total_price += 399 - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/recharger/APC) - if(dev_printer) - total_price += 99 - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/printer/mini) - if(dev_card) - total_price += 199 - if(fabricate) - fabricated_laptop.install_component(new /obj/item/computer_hardware/card_slot) - - return total_price - else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. - var/obj/item/computer_hardware/battery/battery_module = null - if(fabricate) - fabricated_tablet = new(src) - fabricated_tablet.install_component(new /obj/item/computer_hardware/battery) - fabricated_tablet.install_component(new /obj/item/computer_hardware/processor_unit/small) - battery_module = fabricated_tablet.all_components[MC_CELL] - total_price = 199 - switch(dev_battery) - if(1) // Basic(300C) - if(fabricate) - battery_module.try_insert(new /obj/item/stock_parts/cell/computer/nano) - if(2) // Upgraded(500C) - if(fabricate) - battery_module.try_insert(new /obj/item/stock_parts/cell/computer/micro) - total_price += 199 - if(3) // Advanced(750C) - if(fabricate) - battery_module.try_insert(new /obj/item/stock_parts/cell/computer) - total_price += 499 - switch(dev_disk) - if(1) // Basic(32GQ) - if(fabricate) - fabricated_tablet.install_component(new /obj/item/computer_hardware/hard_drive/micro) - if(2) // Upgraded(64GQ) - if(fabricate) - fabricated_tablet.install_component(new /obj/item/computer_hardware/hard_drive/small) - total_price += 99 - if(3) // Advanced(128GQ) - if(fabricate) - fabricated_tablet.install_component(new /obj/item/computer_hardware/hard_drive) - total_price += 299 - switch(dev_netcard) - if(1) // Basic(Short-Range) - if(fabricate) - fabricated_tablet.install_component(new/obj/item/computer_hardware/network_card) - total_price += 99 - if(2) // Advanced (Long Range) - if(fabricate) - fabricated_tablet.install_component(new/obj/item/computer_hardware/network_card/advanced) - total_price += 299 - if(dev_printer) - total_price += 99 - if(fabricate) - fabricated_tablet.install_component(new/obj/item/computer_hardware/printer) - if(dev_card) - total_price += 199 - if(fabricate) - fabricated_tablet.install_component(new/obj/item/computer_hardware/card_slot) - return total_price - return 0 - - -/obj/machinery/lapvend/Topic(href, href_list) - if(..()) - return 1 - - switch(href_list["action"]) - if("pick_device") - if(state) // We've already picked a device type - return 0 - devtype = text2num(href_list["pick"]) - state = 1 - fabricate_and_recalc_price(0) - return 1 - if("clean_order") - reset_order() - return 1 - if((state != 1) && devtype) // Following IFs should only be usable when in the Select Loadout mode - return 0 - switch(href_list["action"]) - if("confirm_order") - state = 2 // Wait for ID swipe for payment processing - fabricate_and_recalc_price(0) - return 1 - if("hw_cpu") - dev_cpu = text2num(href_list["cpu"]) - fabricate_and_recalc_price(0) - return 1 - if("hw_battery") - dev_battery = text2num(href_list["battery"]) - fabricate_and_recalc_price(0) - return 1 - if("hw_disk") - dev_disk = text2num(href_list["disk"]) - fabricate_and_recalc_price(0) - return 1 - if("hw_netcard") - dev_netcard = text2num(href_list["netcard"]) - fabricate_and_recalc_price(0) - return 1 - if("hw_tesla") - dev_apc_recharger = text2num(href_list["tesla"]) - fabricate_and_recalc_price(0) - return 1 - if("hw_nanoprint") - dev_printer = text2num(href_list["print"]) - fabricate_and_recalc_price(0) - return 1 - if("hw_card") - dev_card = text2num(href_list["card"]) - fabricate_and_recalc_price(0) - return 1 - return 0 - -/obj/machinery/lapvend/attack_hand(mob/user) - ui_interact(user) - -/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "computer_fabricator.tmpl", "Personal Computer Vendor", 500, 700) - ui.set_auto_update(1) - ui.open() - -/obj/machinery/lapvend/ui_data(mob/user) - 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_apc_recharger - data["hw_nanoprint"] = dev_printer - data["hw_card"] = dev_card - data["hw_cpu"] = dev_cpu - if(state == 1 || state == 2) - data["totalprice"] = total_price - return data - -obj/machinery/lapvend/attackby(obj/item/I, mob/user) - var/obj/item/card/id/C - if(istype(I, /obj/item/card/id)) - C = I - if(istype(I, /obj/item/pda)) - var/obj/item/pda/PDA = I - if(PDA.id) - C = PDA.id - - if(C && istype(C) && state == 2) - if(process_payment(C, I)) - fabricate_and_recalc_price(1) - if((devtype == 1) && fabricated_laptop) - fabricated_laptop.forceMove(loc) - fabricated_laptop = null - else if((devtype == 2) && fabricated_tablet) - fabricated_tablet.update_icon() - fabricated_tablet.forceMove(loc) - fabricated_tablet = null - atom_say("Enjoy your new product!") - state = 3 - return 1 - return 0 - return ..() - - -// Simplified payment processing, returns 1 on success. -/obj/machinery/lapvend/proc/process_payment(obj/item/card/id/I, obj/item/ID_container) - visible_message("\The [usr] swipes \the [ID_container] through \the [src].") - var/datum/money_account/customer_account = get_card_account(I) - if(!customer_account || customer_account.suspended) - atom_say("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) - atom_say("Unable to access account: incorrect credentials.") - return 0 - - if(total_price > customer_account.money) - atom_say("Insufficient funds in account.") - return 0 - else - customer_account.charge(total_price, GLOB.vendor_account, - "Purchase of [(devtype == 1) ? "laptop computer" : "tablet microcomputer"].", - name, customer_account.owner_name, "Sale of [(devtype == 1) ? "laptop computer" : "tablet microcomputer"].", - customer_account.owner_name) - - return 1 diff --git a/code/modules/nano/modules/atmos_control.dm b/code/modules/nano/modules/atmos_control.dm index 2c74a1ce844..273b0bfc137 100644 --- a/code/modules/nano/modules/atmos_control.dm +++ b/code/modules/nano/modules/atmos_control.dm @@ -34,6 +34,11 @@ ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 900, 800, state = state) ui.add_template("mapContent", "atmos_control_map_content.tmpl") ui.add_template("mapHeader", "atmos_control_map_header.tmpl") + + // Send nanomaps + var/datum/asset/nanomaps = get_asset_datum(/datum/asset/simple/nanomaps) + nanomaps.send(user) + ui.set_show_map(1) ui.open() ui.set_auto_update(1) diff --git a/code/modules/nano/modules/ert_manager.dm b/code/modules/nano/modules/ert_manager.dm deleted file mode 100644 index 98a3e19d052..00000000000 --- a/code/modules/nano/modules/ert_manager.dm +++ /dev/null @@ -1,105 +0,0 @@ -/datum/nano_module/ert_manager - name = "ERT Manager" - var/ert_type = "Code Red" - var/commander_slots = 1 - var/security_slots = 3 - var/medical_slots = 3 - var/engineering_slots = 3 - var/janitor_slots = 0 - var/paranormal_slots = 0 - var/cyborg_slots = 0 - var/autoclose = 0 - - -/datum/nano_module/ert_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.admin_state) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(ui && autoclose) - ui.close() - return 0 - if(!ui) - ui = new(user, src, ui_key, "ert_config.tmpl", "ERT Panel", 600, 600, state = state) - ui.open() - ui.set_auto_update(1) - -/datum/nano_module/ert_manager/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["set_code"]) - ert_type = href_list["set_code"] - - if(href_list["set_com"]) - commander_slots = text2num(href_list["set_com"]) - - if(href_list["set_sec"]) - security_slots = text2num(href_list["set_sec"]) - - if(href_list["set_med"]) - medical_slots = text2num(href_list["set_med"]) - - if(href_list["set_eng"]) - engineering_slots = text2num(href_list["set_eng"]) - - if(href_list["set_jan"]) - janitor_slots = text2num(href_list["set_jan"]) - - if(href_list["set_par"]) - paranormal_slots = text2num(href_list["set_par"]) - - if(href_list["set_cyb"]) - cyborg_slots = text2num(href_list["set_cyb"]) - - if(href_list["dispatch_ert"]) - GLOB.ert_request_answered = TRUE - var/slots_list = list() - if(commander_slots > 0) - slots_list += "commander: [commander_slots]" - if(security_slots > 0) - slots_list += "security: [security_slots]" - if(medical_slots > 0) - slots_list += "medical: [medical_slots]" - if(engineering_slots > 0) - slots_list += "engineering: [engineering_slots]" - if(janitor_slots > 0) - slots_list += "janitor: [janitor_slots]" - if(paranormal_slots > 0) - slots_list += "paranormal: [paranormal_slots]" - if(cyborg_slots > 0) - slots_list += "cyborg: [cyborg_slots]" - var/slot_text = jointext(slots_list, ", ") - notify_ghosts("An ERT is being dispatched. Open positions: [slot_text]") - message_admins("[key_name_admin(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]", 1) - log_admin("[key_name(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]") - GLOB.event_announcement.Announce("Attention, [station_name()]. We are attempting to assemble an ERT. Standby.", "ERT Protocol Activated") - autoclose = 1 - ui_interact(usr) - trigger_armed_response_team(convert_ert_string(ert_type), commander_slots, security_slots, medical_slots, engineering_slots, janitor_slots, paranormal_slots, cyborg_slots) - return 0 - - ui_interact(usr) - - -/proc/convert_ert_string(thestring) - switch(thestring) - if("Code Amber") - return new /datum/response_team/amber - if("Code Red") - return new /datum/response_team/red - if("Code Gamma") - return new /datum/response_team/gamma - - -/datum/nano_module/ert_manager/ui_data() - var/data[0] - data["alert_level"] = get_security_level() - data["ert_type"] = ert_type - data["com"] = commander_slots - data["sec"] = security_slots - data["med"] = medical_slots - data["eng"] = engineering_slots - data["jan"] = janitor_slots - data["par"] = paranormal_slots - data["cyb"] = cyborg_slots - - return data - diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index a65610c7382..f495466d3f5 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -42,7 +42,7 @@ if(in_range(user, src) && toppaper) . += toppaper.examine(user) -obj/item/clipboard/proc/penPlacement(mob/user, obj/item/pen/P, placing) +/obj/item/clipboard/proc/penPlacement(mob/user, obj/item/pen/P, placing) if(placing) if(containedpen) to_chat(user, "There's already a pen in [src]!") diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index b1fe71db72e..d94e69133a7 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -314,7 +314,7 @@ /obj/item/paper/contract/infernal/magic/FulfillContract(mob/living/carbon/human/user = target.current, blood = 0) if(!istype(user) || !user.mind) return -1 - user.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) + user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/click/fireball/hellish(null)) user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) return ..() diff --git a/code/modules/paperwork/silicon_photography.dm b/code/modules/paperwork/silicon_photography.dm index eb8904cf3e8..17cfcacec62 100644 --- a/code/modules/paperwork/silicon_photography.dm +++ b/code/modules/paperwork/silicon_photography.dm @@ -150,7 +150,7 @@ // Explicitly only allow deletion from the local camera deletepicture(src) -obj/item/camera/siliconcam/proc/getsource() +/obj/item/camera/siliconcam/proc/getsource() if(istype(src.loc, /mob/living/silicon/ai)) return src diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index f214e705268..cd549759c1c 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -70,26 +70,22 @@ switch(href_list["op"]) if("control") active = locate(href_list["bot"]) - spawn(0) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) if("scanbots") // find all bots botlist = null - spawn(0) - post_signal(control_freq, "command", "bot_status", s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", s_filter = bot_filter) if("botlist") active = null if("stop", "go", "home") - spawn(0) - post_signal(control_freq, "command", href_list["op"], "active", active, s_filter = bot_filter) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) + post_signal(control_freq, "command", href_list["op"], "active", active, s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) if("summon") - spawn(0) - post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(hostpda), "useraccess", hostpda.GetAccess(), "user", usr, s_filter = bot_filter) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) + post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(hostpda), "useraccess", hostpda.GetAccess(), "user", usr, s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) /obj/item/integrated_radio/proc/add_to_radio(bot_filter) //Master filter control for bots. Must be placed in the bot's local New() to support map spawned bots. if(SSradio) @@ -123,38 +119,30 @@ ..() switch(href_list["op"]) if("start") - spawn(0) - post_signal(control_freq, "command", "start", "active", active, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "start", "active", active, s_filter = RADIO_MULEBOT) if("unload") - spawn(0) - post_signal(control_freq, "command", "unload", "active", active, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "unload", "active", active, s_filter = RADIO_MULEBOT) if("setdest") if(GLOB.deliverybeacons) var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in GLOB.deliverybeacontags if(dest) - spawn(0) - post_signal(control_freq, "command", "target", "active", active, "destination", dest, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "target", "active", active, "destination", dest, s_filter = RADIO_MULEBOT) if("retoff") - spawn(0) - post_signal(control_freq, "command", "autoret", "active", active, "value", 0, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "autoret", "active", active, "value", 0, s_filter = RADIO_MULEBOT) if("reton") - spawn(0) - post_signal(control_freq, "command", "autoret", "active", active, "value", 1, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "autoret", "active", active, "value", 1, s_filter = RADIO_MULEBOT) if("pickoff") - spawn(0) - post_signal(control_freq, "command", "autopick", "active", active, "value", 0, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "autopick", "active", active, "value", 0, s_filter = RADIO_MULEBOT) if("pickon") - spawn(0) - post_signal(control_freq, "command", "autopick", "active", active, "value", 1, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "autopick", "active", active, "value", 1, s_filter = RADIO_MULEBOT) - spawn(10) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_MULEBOT) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_MULEBOT) diff --git a/code/modules/pda/utilities.dm b/code/modules/pda/utilities.dm index 1dfb819c826..c527e1dd12d 100644 --- a/code/modules/pda/utilities.dm +++ b/code/modules/pda/utilities.dm @@ -10,6 +10,10 @@ name = fon ? "Disable Flashlight" : "Enable Flashlight" pda.update_shortcuts() pda.set_light(fon ? f_lum : 0) + if(fon) + pda.overlays += image('icons/obj/pda.dmi', "pda-light") + else + pda.overlays -= image('icons/obj/pda.dmi', "pda-light") /datum/data/pda/utility/honk name = "Honk Synthesizer" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 4b64266f2b7..c4d3fb6cb91 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -940,7 +940,7 @@ update() if("overload") if(usr.has_unlimited_silicon_privilege) - overload_lighting() + INVOKE_ASYNC(src, /obj/machinery/power/apc.proc/overload_lighting) if("hack") if(get_malf_status(usr)) malfhack(usr) @@ -1287,11 +1287,10 @@ return if(cell && cell.charge >= 20) cell.use(20) - spawn(0) - for(var/obj/machinery/light/L in area) - if(prob(chance)) - L.break_light_tube(0, 1) - stoplag() + for(var/obj/machinery/light/L in area) + if(prob(chance)) + L.break_light_tube(0, 1) + stoplag() /obj/machinery/power/apc/proc/null_charge() for(var/obj/machinery/light/L in area) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 992020e7090..40969d7e677 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -229,7 +229,7 @@ By design, d1 is the smallest direction and d2 is the highest if(current_size >= STAGE_FIVE) deconstruct() -obj/structure/cable/proc/cable_color(colorC) +/obj/structure/cable/proc/cable_color(colorC) if(!colorC) color = COLOR_RED else if(colorC == "rainbow") diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 3ad96050123..d1c7d3433fe 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -235,6 +235,7 @@ investigate_log("turned [active?"ON":"OFF"] by [usr ? usr.key : "outside forces"]","singulo") if(active) msg_admin_attack("PA Control Computer turned ON by [key_name_admin(usr)]", ATKLOG_FEW) + usr.create_log(MISC_LOG, "PA Control Computer turned ON", src) log_game("PA Control Computer turned ON by [key_name(usr)] in ([x],[y],[z])") use_log += text("\[[time_stamp()]\] [key_name(usr)] has turned on the PA Control Computer.") if(active) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index d99df1de7bb..7bb2f16b64a 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -254,13 +254,17 @@ // Solar Control Computer // +#define TRACKER_OFF 0 +#define TRACKER_TIMED 1 +#define TRACKER_AUTO 2 + /obj/machinery/power/solar_control name = "solar panel control" desc = "A controller for solar panel arrays." icon = 'icons/obj/computer.dmi' icon_state = "computer" - anchored = 1 - density = 1 + anchored = TRUE + density = TRUE use_power = IDLE_POWER_USE idle_power_usage = 250 max_integrity = 200 @@ -272,17 +276,17 @@ var/targetdir = 0 // target angle in manual tracking (since it updates every game minute) var/gen = 0 var/lastgen = 0 - var/track = 0 // 0= off 1=timed 2=auto (tracker) + var/track = TRACKER_OFF var/trackrate = 600 // 300-900 seconds var/nexttime = 0 // time for a panel to rotate of 1? in manual tracking - var/autostart = 0 // Automatically search for connected devices + var/autostart = FALSE // Automatically search for connected devices var/obj/machinery/power/tracker/connected_tracker = null var/list/connected_panels = list() // Used for mapping in solar array which automatically starts itself (telecomms, for example) /obj/machinery/power/solar_control/autostart - track = 2 // Auto tracking mode - autostart = 1 // Automatically start + track = TRACKER_AUTO + autostart = TRUE // Automatically search for connected devices /obj/machinery/power/solar_control/Initialize() SSsun.solars |= src @@ -294,7 +298,7 @@ set_panels(cdir) if(autostart) search_for_connected() - if(connected_tracker && track == 2) + if(connected_tracker && track == TRACKER_AUTO) connected_tracker.set_angle(SSsun.angle) set_panels(cdir) @@ -334,15 +338,9 @@ if(stat & (NOPOWER | BROKEN)) return - switch(track) - if(1) - if(trackrate) //we're manual tracking. If we set a rotation speed... - cdir = targetdir //...the current direction is the targetted one (and rotates panels to it) - if(2) // auto-tracking - if(connected_tracker) - connected_tracker.set_angle(SSsun.angle) - - set_panels(cdir) + if(track == TRACKER_AUTO && connected_tracker) // auto-tracking + connected_tracker.set_angle(SSsun.angle) + set_panels(cdir) updateDialog() /obj/machinery/power/solar_control/update_icon() @@ -359,44 +357,73 @@ overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir)) /obj/machinery/power/solar_control/attack_ai(mob/user as mob) - src.add_hiddenprint(user) - ui_interact(user) + add_hiddenprint(user) + tgui_interact(user) /obj/machinery/power/solar_control/attack_ghost(mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/power/solar_control/attack_hand(mob/user) if(..(user)) - return 1 - + return TRUE if(stat & BROKEN) return + tgui_interact(user) - ui_interact(user) - -/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/power/solar_control/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "solar_control.tmpl", name, 490, 420) + ui = new(user, src, ui_key, "SolarControl", name, 490, 300) ui.open() - ui.set_auto_update(1) - -/obj/machinery/power/solar_control/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] - - data["generated"] = round(lastgen) - data["angle"] = cdir - data["direction"] = angle2text(cdir) - - data["tracking_state"] = track - data["tracking_rate"] = trackrate - data["rotating_way"] = (trackrate<0 ? "CCW" : "CW") +/obj/machinery/power/solar_control/tgui_data(mob/user) + var/list/data = list() + data["generated"] = round(lastgen) //generated power by all connected panels + data["generated_ratio"] = data["generated"] / round(max(connected_panels.len, 1) * SOLARGENRATE) //power generation ratio. Used for the power bar + data["direction"] = angle2text(cdir) //current orientation of the panels + data["cdir"] = cdir //current orientation of the of the panels in degrees + data["tracking_state"] = track //tracker status: TRACKER_OFF, TRACKER_TIMED, TRACKER_AUTO + data["tracking_rate"] = trackrate //rotation speed of tracker in degrees/h + data["rotating_direction"] = (trackrate < 0 ? "Counter clockwise" : "Clockwise") //direction of tracker data["connected_panels"] = connected_panels.len - data["connected_tracker"] = (connected_tracker ? 1 : 0) - + data["connected_tracker"] = (connected_tracker ? TRUE : FALSE) return data +/obj/machinery/power/solar_control/tgui_act(action, params) + if(..()) + return + . = TRUE + + switch(action) + if("cdir") //change panel orientation + var/newAngle = text2num(params["cdir"]) + if(!isnull(newAngle)) //0 is ok + cdir = clamp(newAngle, 0, 359) + targetdir = cdir + set_panels(cdir) + if("tdir") //change tracker rotation + var/newTrackrate = text2num(params["tdir"]) + if(!newTrackrate) + newTrackrate = 1 + trackrate = clamp(newTrackrate, -7200, 7200) + nexttime = world.time + 36000 / abs(trackrate) + if("track") //change tracker status + track = text2num(params["track"]) + if(track == TRACKER_AUTO) + if(connected_tracker) + connected_tracker.set_angle(SSsun.angle) + set_panels(cdir) + else if(track == TRACKER_TIMED) + targetdir = cdir + if(trackrate) + nexttime = world.time + 36000 / abs(trackrate) + set_panels(targetdir) + if("refresh") + search_for_connected() + if(connected_tracker && track == TRACKER_AUTO) + connected_tracker.set_angle(SSsun.angle) + set_panels(cdir) + /obj/machinery/power/solar_control/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) playsound(src.loc, I.usesound, 50, 1) @@ -450,50 +477,16 @@ if(stat & (NOPOWER | BROKEN)) return - if(connected_tracker) //NOTE : handled here so that we don't add trackers to the processing list - if(connected_tracker.powernet != powernet) - connected_tracker.unset_control() + if(connected_tracker && connected_tracker.powernet != powernet) //NOTE : handled here so that we don't add trackers to the processing list + connected_tracker.unset_control() - if(track==1 && trackrate) //manual tracking and set a rotation speed - if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1?... - targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it - nexttime += 36000/abs(trackrate) //reset the counter for the next 1? - -/obj/machinery/power/solar_control/Topic(href, href_list) - if(..()) - return - - if(href_list["rate_control"]) - if(href_list["cdir"]) - src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360) - src.targetdir = src.cdir - if(track == 2) //manual update, so losing auto-tracking - track = 0 - spawn(1) - set_panels(cdir) - if(href_list["tdir"]) - src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"])) - if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) - - if(href_list["track"]) - track = text2num(href_list["track"]) - if(track == 2) - if(connected_tracker) - connected_tracker.set_angle(SSsun.angle) - set_panels(cdir) - else if(track == 1) //begin manual tracking - src.targetdir = src.cdir - if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) - set_panels(targetdir) - - if(href_list["search_connected"]) - search_for_connected() - if(connected_tracker && track == 2) - connected_tracker.set_angle(SSsun.angle) + //manual tracking and set a rotation speed + if(track == TRACKER_TIMED && trackrate && nexttime <= world.time) //every time we need to increase/decrease the angle by 1?... + targetdir = (targetdir + trackrate / abs(trackrate) + 360) % 360 //... do it + nexttime += 36000 / abs(trackrate) //reset the counter for the next 1? + cdir = targetdir set_panels(cdir) - return - //rotates the panel to the passed angle /obj/machinery/power/solar_control/proc/set_panels(var/cdir) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index e6165103234..fd526d0e12a 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -97,6 +97,7 @@ var/ammo_type = /obj/item/ammo_casing var/max_ammo = 7 var/multiple_sprites = 0 + var/icon_prefix // boxes with multiple sprites use this as their base var/caliber var/multiload = 1 var/list/initial_mats //For calculating refund values. @@ -192,11 +193,12 @@ update_icon() /obj/item/ammo_box/update_icon() + var/icon_base = initial(icon_prefix) ? initial(icon_prefix) : initial(icon_state) switch(multiple_sprites) if(1) - icon_state = "[initial(icon_state)]-[stored_ammo.len]" + icon_state = "[icon_base]-[stored_ammo.len]" if(2) - icon_state = "[initial(icon_state)]-[stored_ammo.len ? "[max_ammo]" : "0"]" + icon_state = "[icon_base]-[stored_ammo.len ? "[max_ammo]" : "0"]" desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!" /obj/item/ammo_box/proc/update_mat_value() diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 4484be63c83..53004b768db 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -1,10 +1,11 @@ /obj/item/ammo_box/a357 name = "speed loader (.357)" desc = "Designed to quickly reload revolvers." - icon_state = "357" ammo_type = /obj/item/ammo_casing/a357 max_ammo = 7 - multiple_sprites = 1 + icon_state = "357-7" // DEFAULT icon, composed of prefix + "-" + max_ammo for multiple_sprites == 1 boxes + multiple_sprites = 1 // see: /obj/item/ammo_box/update_icon() + icon_prefix = "357" // icon prefix, used in above formula to generate dynamic icons /obj/item/ammo_box/c38 name = "speed loader (.38)" @@ -12,7 +13,9 @@ icon_state = "38" ammo_type = /obj/item/ammo_casing/c38 max_ammo = 6 + icon_state = "38-6" // see previous entry for explanation of these vars multiple_sprites = 1 + icon_prefix = "38" /obj/item/ammo_box/c9mm name = "ammo box (9mm)" diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm index 3c25bc30f93..bb800214020 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -87,7 +87,7 @@ damage = 7 armour_penetration = 0 -obj/item/projectile/bullet/saw/incen/Move() +/obj/item/projectile/bullet/saw/incen/Move() ..() var/turf/location = get_turf(src) if(location) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index c33c649ae77..2a7fd2e602d 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -287,7 +287,7 @@ Range() sleep(max(1, speed)) -obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = list(0, 0, 0, 0, 0, -1, 1, -2, 2)) +/obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = list(0, 0, 0, 0, 0, -1, 1, -2, 2)) if(starting) var/new_x = starting.x + pick(position_modifiers) var/new_y = starting.y + pick(position_modifiers) @@ -306,7 +306,7 @@ obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = lis xo = new_x - curloc.x Angle = null // Will be calculated in fire() -obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile with a projectile is hit by it. +/obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile with a projectile is hit by it. ..() if(isliving(AM) && AM.density && !checkpass(PASSMOB)) Bump(AM, 1) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 2323aa06cf4..d6140d28f4e 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -31,16 +31,17 @@ M.AdjustDrowsy(10) A.volume += 5 //Because we can -/obj/item/projectile/bullet/weakbullet2 //detective revolver instastuns, but multiple shots are better for keeping punks down +/obj/item/projectile/bullet/weakbullet2 //detective revolver name = "rubber bullet" damage = 5 - weaken = 3 - stamina = 60 + stamina = 35 icon_state = "bullet-r" /obj/item/projectile/bullet/weakbullet2/invisible //finger gun bullets name = "invisible bullet" damage = 0 + weaken = 3 + stamina = 60 icon_state = null hitsound_wall = null diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 7f0ed2c91dc..c5ef03040b4 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -144,56 +144,69 @@ return STATUS_UPDATE_NONE /datum/reagent/proc/addiction_act_stage2(mob/living/M) - if(prob(8)) - M.emote("shiver") - if(prob(8)) - M.emote("sneeze") - if(prob(4)) - to_chat(M, "You feel a dull headache.") + if(minor_addiction) + if(prob(4)) + to_chat(M, "You briefly think about getting some more [name].") + else + if(prob(8)) + M.emote("shiver") + if(prob(8)) + M.emote("sneeze") + if(prob(4)) + to_chat(M, "You feel a dull headache.") return STATUS_UPDATE_NONE /datum/reagent/proc/addiction_act_stage3(mob/living/M) - if(prob(8)) - M.emote("twitch_s") - if(prob(8)) - M.emote("shiver") - if(prob(4)) - to_chat(M, "Your head hurts.") - if(prob(4)) - to_chat(M, "You begin craving [name]!") + if(minor_addiction) + if(prob(4)) + to_chat(M, "You could really go for some [name] right now.") + else + if(prob(8)) + M.emote("twitch_s") + if(prob(8)) + M.emote("shiver") + if(prob(4)) + to_chat(M, "Your head hurts.") + if(prob(4)) + to_chat(M, "You begin craving [name]!") return STATUS_UPDATE_NONE /datum/reagent/proc/addiction_act_stage4(mob/living/M) - if(prob(8)) - M.emote("twitch") - if(prob(4)) - to_chat(M, "You have a pounding headache.") - if(prob(4)) - to_chat(M, "You have the strong urge for some [name]!") - else if(prob(4)) - to_chat(M, "You REALLY crave some [name]!") + if(minor_addiction) + if(prob(8)) + to_chat(M, "You could really go for some [name] right now.") + else + if(prob(8)) + M.emote("twitch") + if(prob(4)) + to_chat(M, "You have a pounding headache.") + if(prob(4)) + to_chat(M, "You have the strong urge for some [name]!") + else if(prob(4)) + to_chat(M, "You REALLY crave some [name]!") return STATUS_UPDATE_NONE /datum/reagent/proc/addiction_act_stage5(mob/living/M) var/update_flags = STATUS_UPDATE_NONE if(minor_addiction) - if(prob(6)) - M.AdjustSlowed(3) - to_chat(M, "You feel [pick("tired", "exhausted", "sluggish")].") + if(prob(8)) + to_chat(M, "You can't stop thinking about [name]...") + if(prob(4)) + M.emote(pick("twitch")) else if(prob(6)) to_chat(M, "Your stomach lurches painfully!") M.visible_message("[M] gags and retches!") update_flags |= M.Stun(rand(2,4), FALSE) update_flags |= M.Weaken(rand(2,4), FALSE) - if(prob(8)) - M.emote(pick("twitch", "twitch_s", "shiver")) - if(prob(4)) - to_chat(M, "Your head is killing you!") - if(prob(5)) - to_chat(M, "You feel like you can't live without [name]!") - else if(prob(5)) - to_chat(M, "You would DIE for some [name] right now!") + if(prob(8)) + M.emote(pick("twitch", "twitch_s", "shiver")) + if(prob(4)) + to_chat(M, "Your head is killing you!") + if(prob(5)) + to_chat(M, "You feel like you can't live without [name]!") + else if(prob(5)) + to_chat(M, "You would DIE for some [name] right now!") return update_flags /datum/reagent/proc/fakedeath(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index e90789f9d8b..9797951f290 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -849,7 +849,7 @@ /datum/reagent/medicine/stimulants name = "Stimulants" id = "stimulants" - description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and stun." + description = "An illegal compound that dramatically enhances the body's performance and healing capabilities." color = "#C8A5DC" harmless = FALSE can_synth = FALSE @@ -886,7 +886,7 @@ /datum/reagent/medicine/stimulative_agent name = "Stimulative Agent" id = "stimulative_agent" - description = "An illegal compound that dramatically enhances the body's performance and healing capabilities." + description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and be less effective for healing stamina." color = "#C8A5DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index f9a6f974dcf..2b65054f21f 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -603,7 +603,7 @@ name = "Left 4 Zed" id = "left4zednutriment" description = "Unstable nutriment that makes plants mutate more often than usual." - color = "#1A1E4D" // RBG: 26, 30, 77 + color = "#2A1680" // RBG: 42, 128, 22 tox_prob = 25 taste_description = "evolution" diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index b015b75be2a..914fabbc752 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -1054,7 +1054,7 @@ id = "atrazine" description = "A herbicidal compound used for destroying unwanted plants." reagent_state = LIQUID - color = "#17002D" + color = "#773E73" //RGB: 47 24 45 lethality = 2 //Atrazine, however, is definitely toxic diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index abdf0305934..4be84e21d2c 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -163,8 +163,7 @@ /datum/chemical_reaction/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume) var/location = get_turf(holder.my_atom) do_sparks(2, 1, location) - spawn(rand(5, 15)) - blackpowder_detonate(holder, created_volume) + addtimer(CALLBACK(null, .proc/blackpowder_detonate, holder, created_volume), rand(5, 15)) /proc/blackpowder_detonate(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) @@ -175,8 +174,7 @@ explosion(T, ex_severe, ex_heavy,ex_light, ex_flash, 1) // If this black powder is in a decal, remove the decal, because it just exploded if(istype(holder.my_atom, /obj/effect/decal/cleanable/dirt/blackpowder)) - spawn(0) - qdel(holder.my_atom) + qdel(holder.my_atom) /datum/chemical_reaction/flash_powder name = "Flash powder" diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index 1525ed42bd3..5da09309057 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -146,7 +146,8 @@ /obj/item/reagent_containers/food/snacks/meat/slab, /obj/item/reagent_containers/food/snacks/grown, /obj/item/reagent_containers/food/snacks/grown/mushroom, - /obj/item/reagent_containers/food/snacks/deepfryholder + /obj/item/reagent_containers/food/snacks/deepfryholder, + /obj/item/reagent_containers/food/snacks/monstermeat ) blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 01a5e6823a5..f5bc4a3274a 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -39,7 +39,7 @@ reagents.add_reagent("blood", disease_amount, data) add_initial_reagents() -obj/item/reagent_containers/proc/add_initial_reagents() +/obj/item/reagent_containers/proc/add_initial_reagents() if(list_reagents) reagents.add_reagent_list(list_reagents) @@ -50,16 +50,25 @@ obj/item/reagent_containers/proc/add_initial_reagents() if(!QDELETED(src)) ..() + +/obj/item/reagent_containers/proc/add_lid() + if(has_lid) + container_type ^= REFILLABLE | DRAINABLE + update_icon() + +/obj/item/reagent_containers/proc/remove_lid() + if(has_lid) + container_type |= REFILLABLE | DRAINABLE + update_icon() + /obj/item/reagent_containers/attack_self(mob/user) if(has_lid) if(is_open_container()) to_chat(usr, "You put the lid on [src].") - container_type ^= REFILLABLE | DRAINABLE + add_lid() else to_chat(usr, "You take the lid off [src].") - container_type |= REFILLABLE | DRAINABLE - update_icon() - return + remove_lid() /obj/item/reagent_containers/attack(mob/M, mob/user, def_zone) if(user.a_intent == INTENT_HARM) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index f6980c03620..831a3ddc44f 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -23,13 +23,12 @@ /obj/item/reagent_containers/food/pill/attack(mob/living/carbon/M, mob/user, def_zone) if(!istype(M)) - return 0 + return FALSE bitesize = reagents.total_volume if(M.eat(src, user)) - spawn(0) - qdel(src) - return 1 - return 0 + qdel(src) + return TRUE + return FALSE /obj/item/reagent_containers/food/pill/afterattack(obj/target, mob/user, proximity) if(!proximity) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 8826efa5eb8..5e20dbf6f35 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -44,7 +44,7 @@ return var/contents_log = reagents.reagent_list.Join(", ") - spray(A) + INVOKE_ASYNC(src, .proc/spray, A) playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6) user.changeNext_move(CLICK_CD_RANGE*2) @@ -57,24 +57,24 @@ var/attack_log_type = ATKLOG_MOST if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube")) attack_log_type = ATKLOG_FEW - msg_admin_attack("[key_name_admin(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type) - log_game("[key_name(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K") + + add_attack_logs(user, A, "Used a potentially harmful spray bottle. Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type) return -/obj/item/reagent_containers/spray/proc/spray(var/atom/A) +/obj/item/reagent_containers/spray/proc/spray(atom/A) var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src)) D.create_reagents(amount_per_transfer_from_this) reagents.trans_to(D, amount_per_transfer_from_this, 1/spray_currentrange) D.icon += mix_color_from_reagents(D.reagents.reagent_list) - spawn(0) - for(var/i=0, iJMP)", ATKLOG_FEW) log_game("[key_name(user)] rigged [src.name] with [I.name] for explosion at [COORD(loc)]") - add_attack_logs(user, src, "rigged fuel tank") + add_attack_logs(user, src, "rigged fuel tank with [I.name] for explosion", ATKLOG_FEW) investigate_log("[key_name(user)] rigged [src.name] with [I.name] for explosion at [COORD(loc)]", INVESTIGATE_BOMB) lastrigger = "[key_name(user)]" @@ -159,7 +156,7 @@ else return ..() -obj/structure/reagent_dispensers/fueltank/welder_act(mob/user, obj/item/I) +/obj/structure/reagent_dispensers/fueltank/welder_act(mob/user, obj/item/I) . = TRUE if(!reagents.has_reagent("fuel")) to_chat(user, "[src] is out of fuel!") diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index eda48794d86..309cdb7eef1 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -15,7 +15,6 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). var/list/categories = list( "AI Modules", "Computer Boards", - "Computer Parts", "Engineering Machinery", "Exosuit Modules", "Hydroponics Machinery", diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index e813597c4d8..a014a6be34b 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -872,22 +872,6 @@ build_path = /obj/item/storage/conveyor category = list("initial", "Construction") -/datum/design/laptop - name = "Laptop Frame" - id = "laptop" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 1000) - build_path = /obj/item/modular_computer/laptop/buildable - category = list("initial", "Miscellaneous") - -/datum/design/tablet - name = "Tablet Frame" - id = "tablet" - build_type = AUTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) - build_path = /obj/item/modular_computer/tablet - category = list("initial", "Miscellaneous") - /datum/design/mousetrap name = "Mousetrap" id = "mousetrap" diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index b70771cb8d3..f01fc5303a9 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -88,7 +88,7 @@ id = "weed_killer" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 50) - build_path = /obj/item/reagent_containers/glass/bottle/killer/weedkiller + build_path = /obj/item/reagent_containers/glass/bottle/nutrient/killer/weedkiller category = list("initial","Botany Chemicals") /datum/design/pest_spray @@ -96,12 +96,12 @@ id = "pest_spray" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 50) - build_path = /obj/item/reagent_containers/glass/bottle/killer/pestkiller + build_path = /obj/item/reagent_containers/glass/bottle/nutrient/killer/pestkiller category = list("initial","Botany Chemicals") /datum/design/botany_bottle - name = "Empty Bottle" - id = "botany_bottle" + name = "Empty Jug" + id = "botany_jug" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 5) build_path = /obj/item/reagent_containers/glass/bottle/nutrient/empty diff --git a/code/modules/research/designs/computer_part_designs.dm b/code/modules/research/designs/computer_part_designs.dm deleted file mode 100644 index 438a679f97a..00000000000 --- a/code/modules/research/designs/computer_part_designs.dm +++ /dev/null @@ -1,251 +0,0 @@ -//////////////////////////////////////// -///////////Computer Parts/////////////// -//////////////////////////////////////// - -/datum/design/disk/normal - name = "hard disk drive" - id = "hdd_basic" - req_tech = list("programming" = 1, "engineering" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 400, MAT_GLASS = 100) - build_path = /obj/item/computer_hardware/hard_drive - category = list("Computer Parts") - -/datum/design/disk/advanced - name = "advanced hard disk drive" - id = "hdd_advanced" - req_tech = list("programming" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 800, MAT_GLASS = 200) - build_path = /obj/item/computer_hardware/hard_drive/advanced - category = list("Computer Parts") - -/datum/design/disk/super - name = "super hard disk drive" - id = "hdd_super" - req_tech = list("programming" = 3, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1600, MAT_GLASS = 400) - build_path = /obj/item/computer_hardware/hard_drive/super - category = list("Computer Parts") - -/datum/design/disk/cluster - name = "cluster hard disk drive" - id = "hdd_cluster" - req_tech = list("programming" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3200, MAT_GLASS = 800) - build_path = /obj/item/computer_hardware/hard_drive/cluster - category = list("Computer Parts") - -/datum/design/disk/small - name = "solid state drive" - id = "ssd_small" - req_tech = list("programming" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 800, MAT_GLASS = 200) - build_path = /obj/item/computer_hardware/hard_drive/small - category = list("Computer Parts") - -/datum/design/disk/micro - name = "micro solid state drive" - id = "ssd_micro" - req_tech = list("programming" = 1, "engineering" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 400, MAT_GLASS = 100) - build_path = /obj/item/computer_hardware/hard_drive/micro - category = list("Computer Parts") - - -// Network cards -/datum/design/netcard/basic - name = "network card" - id = "netcard_basic" - req_tech = list("programming" = 2, "engineering" = 1) - build_type = IMPRINTER - materials = list(MAT_METAL = 250, MAT_GLASS = 100) - build_path = /obj/item/computer_hardware/network_card - category = list("Computer Parts") - -/datum/design/netcard/advanced - name = "advanced network card" - id = "netcard_advanced" - req_tech = list("programming" = 4, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_METAL = 500, MAT_GLASS = 200) - build_path = /obj/item/computer_hardware/network_card/advanced - category = list("Computer Parts") - -/datum/design/netcard/wired - name = "wired network card" - id = "netcard_wired" - req_tech = list("programming" = 5, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_METAL = 2500, MAT_GLASS = 400) - build_path = /obj/item/computer_hardware/network_card/wired - category = list("Computer Parts") - - -// Data disks -/datum/design/portabledrive/basic - name = "data disk" - id = "portadrive_basic" - req_tech = list("programming" = 1) - build_type = IMPRINTER - materials = list(MAT_GLASS = 800) - build_path = /obj/item/computer_hardware/hard_drive/portable - category = list("Computer Parts") - -/datum/design/portabledrive/advanced - name = "advanced data disk" - id = "portadrive_advanced" - req_tech = list("programming" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1600) - build_path = /obj/item/computer_hardware/hard_drive/portable/advanced - category = list("Computer Parts") - -/datum/design/portabledrive/super - name = "super data disk" - id = "portadrive_super" - req_tech = list("programming" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS = 3200) - build_path = /obj/item/computer_hardware/hard_drive/portable/super - category = list("Computer Parts") - - -// Card slot -/datum/design/cardslot - name = "ID card slot" - id = "cardslot" - req_tech = list("programming" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600) - build_path = /obj/item/computer_hardware/card_slot - category = list("Computer Parts") - -// Intellicard slot -/datum/design/aislot - name = "Intellicard slot" - id = "aislot" - req_tech = list("programming" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600) - build_path = /obj/item/computer_hardware/ai_slot - category = list("Computer Parts") - -// Mini printer -/datum/design/miniprinter - name = "miniprinter" - id = "miniprinter" - req_tech = list("programming" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600) - build_path = /obj/item/computer_hardware/printer/mini - category = list("Computer Parts") - - -// APC Link -/datum/design/APClink - name = "area power connector" - id = "APClink" - req_tech = list("programming" = 2, "powerstorage" = 3, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000) - build_path = /obj/item/computer_hardware/recharger/APC - category = list("Computer Parts") - - -// Batteries -/datum/design/battery/controller - name = "power cell controller" - id = "bat_control" - req_tech = list("powerstorage" = 1, "engineering" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 400) - build_path = /obj/item/computer_hardware/battery - category = list("Computer Parts") - -/datum/design/battery/normal - name = "battery module" - id = "bat_normal" - req_tech = list("powerstorage" = 1, "engineering" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 400) - build_path = /obj/item/stock_parts/cell/computer - category = list("Computer Parts") - -/datum/design/battery/advanced - name = "advanced battery module" - id = "bat_advanced" - req_tech = list("powerstorage" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 800) - build_path = /obj/item/stock_parts/cell/computer/advanced - category = list("Computer Parts") - -/datum/design/battery/super - name = "super battery module" - id = "bat_super" - req_tech = list("powerstorage" = 3, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1600) - build_path = /obj/item/stock_parts/cell/computer/super - category = list("Computer Parts") - -/datum/design/battery/nano - name = "nano battery module" - id = "bat_nano" - req_tech = list("powerstorage" = 1, "engineering" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 200) - build_path = /obj/item/stock_parts/cell/computer/nano - category = list("Computer Parts") - -/datum/design/battery/micro - name = "micro battery module" - id = "bat_micro" - req_tech = list("powerstorage" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 400) - build_path = /obj/item/stock_parts/cell/computer/micro - category = list("Computer Parts") - - -// Processor unit -/datum/design/cpu - name = "processor board" - id = "cpu_normal" - req_tech = list("programming" = 3, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 1600) - build_path = /obj/item/computer_hardware/processor_unit - category = list("Computer Parts") - -/datum/design/cpu/small - name = "microprocessor" - id = "cpu_small" - req_tech = list("programming" = 2, "engineering" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS = 800) - build_path = /obj/item/computer_hardware/processor_unit/small - category = list("Computer Parts") - -/datum/design/cpu/photonic - name = "photonic processor board" - id = "pcpu_normal" - req_tech = list("programming" = 5, "engineering" = 4) - build_type = IMPRINTER - materials = list(MAT_GLASS= 6400, MAT_GOLD = 2000) - build_path = /obj/item/computer_hardware/processor_unit/photonic - category = list("Computer Parts") - -/datum/design/cpu/photonic/small - name = "photonic microprocessor" - id = "pcpu_small" - req_tech = list("programming" = 4, "engineering" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS = 3200, MAT_GOLD = 1000) - build_path = /obj/item/computer_hardware/processor_unit/photonic/small - category = list("Computer Parts") diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 3900acf5093..5cd4c9bdc81 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -531,13 +531,3 @@ materials = list(MAT_GLASS=1000) build_path = /obj/item/circuitboard/plantgenes category = list("Hydroponics Machinery") - -/datum/design/ntnet_relay - name = "Machine Design (NTNet Relay Board)" - desc = "The circuit board for a wireless network relay." - id = "ntnet_relay" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 2) - build_type = IMPRINTER - materials = list(MAT_GLASS=1000) - build_path = /obj/item/circuitboard/machine/ntnet_relay - category = list("Subspace Telecomms") diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 75e64a43215..7bd5b3e9c93 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1094,7 +1094,7 @@ name = "Cyborg Upgrade (Safety Override)" id = "borg_syndicate_module" build_type = MECHFAB - req_tech = list("combat" = 4, "syndicate" = 2) + req_tech = list("combat" = 7, "programming" = 7) build_path = /obj/item/borg/upgrade/syndicate materials = list(MAT_METAL=10000,MAT_GLASS=15000,MAT_DIAMOND = 10000) construction_time = 120 diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 3fe0ef54c0c..009e4810d3e 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -335,7 +335,7 @@ GLOBAL_DATUM(blackbox, /obj/machinery/blackbox_recorder) return FALSE // don't fuck with the stupid blackbox shit -proc/feedback_set(var/variable,var/value) +/proc/feedback_set(var/variable,var/value) if(IsAdminAdvancedProcCall()) to_chat(usr, "Feedback edit blocked: Advanced ProcCall detected.") message_admins("[key_name(usr)] attempted to edit feedback data via advanced proc-call") @@ -351,7 +351,7 @@ proc/feedback_set(var/variable,var/value) FV.set_value(value) -proc/feedback_inc(var/variable,var/value) +/proc/feedback_inc(var/variable,var/value) if(IsAdminAdvancedProcCall()) to_chat(usr, "Feedback edit blocked: Advanced ProcCall detected.") message_admins("[key_name(usr)] attempted to edit feedback data via advanced proc-call") @@ -367,7 +367,7 @@ proc/feedback_inc(var/variable,var/value) FV.inc(value) -proc/feedback_dec(var/variable,var/value) +/proc/feedback_dec(var/variable,var/value) if(IsAdminAdvancedProcCall()) to_chat(usr, "Feedback edit blocked: Advanced ProcCall detected.") message_admins("[key_name(usr)] attempted to edit feedback data via advanced proc-call") @@ -383,7 +383,7 @@ proc/feedback_dec(var/variable,var/value) FV.dec(value) -proc/feedback_set_details(var/variable,var/details) +/proc/feedback_set_details(var/variable,var/details) if(IsAdminAdvancedProcCall()) to_chat(usr, "Feedback edit blocked: Advanced ProcCall detected.") message_admins("[key_name(usr)] attempted to edit feedback data via advanced proc-call") @@ -400,7 +400,7 @@ proc/feedback_set_details(var/variable,var/details) FV.set_details(details) -proc/feedback_add_details(var/variable,var/details) +/proc/feedback_add_details(var/variable,var/details) if(IsAdminAdvancedProcCall()) to_chat(usr, "Feedback edit blocked: Advanced ProcCall detected.") message_admins("[key_name(usr)] attempted to edit feedback data via advanced proc-call") diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 6f2e608ef4b..8e85c041708 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -17,7 +17,6 @@ Note: Must be placed west/left of and R&D console to function. var/list/categories = list( "Bluespace", - "Computer Parts", "Equipment", "Janitorial", "Medical", diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 84f15745df6..ce1580d13ce 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -68,6 +68,7 @@ eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) eyeobj.origin = src eyeobj.visible_icon = 1 + eyeobj.acceleration = FALSE eyeobj.icon = 'icons/obj/abductor.dmi' eyeobj.icon_state = "camera_target" diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index 68ed3cb7749..78022bb6d7c 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -33,8 +33,8 @@ GLOBAL_VAR_INIT(ert_request_answered, FALSE) to_chat(usr, "Central Command has already dispatched an emergency response team!") return - var/datum/nano_module/ert_manager/E = new() - E.ui_interact(usr) + var/datum/tgui_module/ert_manager/E = new() + E.tgui_interact(usr) /mob/dead/observer/proc/JoinResponseTeam() @@ -209,7 +209,7 @@ GLOBAL_VAR_INIT(ert_request_answered, FALSE) var/paranormal_outfit var/borg_path = /mob/living/silicon/robot/ert -/datum/response_team/proc/setSlots(com=1, sec=3, med=3, eng=3, jan=0, par=0, cyb=0) +/datum/response_team/proc/setSlots(com=1, sec=4, med=0, eng=0, jan=0, par=0, cyb=0) slots["Commander"] = com slots["Security"] = sec slots["Medic"] = med diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index f4ab9561bd5..96825ebdab7 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -36,7 +36,7 @@ rt_job = "Emergency Response Team Leader" rt_mob_job = "ERT Commander" - uniform = /obj/item/clothing/under/rank/centcom_officer + uniform = /obj/item/clothing/under/rank/centcom_officer/sensor back = /obj/item/storage/backpack/ert/commander id = /obj/item/card/id/ert/commander @@ -56,12 +56,12 @@ gloves = /obj/item/clothing/gloves/color/black suit = /obj/item/clothing/suit/armor/vest/ert/command glasses = /obj/item/clothing/glasses/sunglasses + mask = /obj/item/clothing/mask/gas/sechailer belt = /obj/item/gun/energy/gun backpack_contents = list( /obj/item/clothing/head/helmet/ert/command = 1, - /obj/item/clothing/mask/gas/sechailer = 1, /obj/item/restraints/handcuffs = 1, /obj/item/storage/lockbox/mindshield = 1, /obj/item/flashlight = 1 @@ -73,6 +73,7 @@ gloves = /obj/item/clothing/gloves/combat suit = /obj/item/clothing/suit/space/hardsuit/ert/commander glasses = /obj/item/clothing/glasses/sunglasses + mask = /obj/item/clothing/mask/gas/sechailer/swat cybernetic_implants = list( /obj/item/organ/internal/cyberimp/eyes/hud/security, /obj/item/organ/internal/cyberimp/chest/nutriment @@ -80,7 +81,6 @@ belt = /obj/item/gun/energy/gun/blueshield/pdw9 backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/gun/energy/ionrifle/carbine = 1, /obj/item/restraints/handcuffs = 1, /obj/item/clothing/shoes/magboots = 1, @@ -93,11 +93,11 @@ gloves = /obj/item/clothing/gloves/combat suit = /obj/item/clothing/suit/space/hardsuit/ert/commander/gamma glasses = /obj/item/clothing/glasses/night + mask = /obj/item/clothing/mask/gas/sechailer/swat suit_store = /obj/item/gun/energy/gun/blueshield/pdw9 belt = /obj/item/gun/projectile/automatic/pistol/enforcer/lethal backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/restraints/handcuffs = 1, /obj/item/storage/lockbox/mindshield = 1, /obj/item/gun/energy/ionrifle/carbine = 1, @@ -107,7 +107,7 @@ cybernetic_implants = list( /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/cyberimp/brain/anti_stun, + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, /obj/item/organ/internal/cyberimp/arm/flash ) @@ -117,7 +117,7 @@ name = "RT Security" rt_job = "Emergency Response Team Officer" rt_mob_job = "ERT Security" - uniform = /obj/item/clothing/under/rank/security + uniform = /obj/item/clothing/under/rank/security/sensor back = /obj/item/storage/backpack/ert/security belt = /obj/item/storage/belt/security/response_team pda = /obj/item/pda/heads/ert/security @@ -130,12 +130,12 @@ suit = /obj/item/clothing/suit/armor/vest/ert/security suit_store = /obj/item/gun/energy/gun/advtaser glasses = /obj/item/clothing/glasses/hud/security/sunglasses + mask = /obj/item/clothing/mask/gas/sechailer r_hand = /obj/item/gun/energy/laser backpack_contents = list( /obj/item/clothing/head/helmet/ert/security = 1, - /obj/item/clothing/mask/gas/sechailer = 1, /obj/item/storage/box/zipties = 1, /obj/item/storage/box/teargas = 1, /obj/item/flashlight/seclite = 1 @@ -149,6 +149,7 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/security suit_store = /obj/item/gun/energy/gun/blueshield/pdw9 glasses = /obj/item/clothing/glasses/sunglasses + mask = /obj/item/clothing/mask/gas/sechailer r_hand = /obj/item/gun/projectile/automatic/lasercarbine @@ -159,11 +160,9 @@ ) backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer = 1, /obj/item/clothing/shoes/magboots = 1, /obj/item/storage/box/handcuffs = 1, - /obj/item/storage/box/teargas = 1, - /obj/item/grenade/flashbang = 1, + /obj/item/grenade/flashbang = 2, /obj/item/ammo_box/magazine/laser = 2 ) @@ -175,13 +174,13 @@ belt = /obj/item/storage/belt/security/response_team_gamma suit_store = /obj/item/gun/energy/gun/nuclear glasses = /obj/item/clothing/glasses/night + mask = /obj/item/clothing/mask/gas/sechailer/swat l_pocket = /obj/item/restraints/legcuffs/bola/energy r_pocket = /obj/item/extinguisher/mini r_hand = /obj/item/gun/energy/immolator/multi backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/storage/box/handcuffs = 1, /obj/item/storage/box/flashbangs = 1, /obj/item/whetstone = 1, @@ -191,9 +190,9 @@ cybernetic_implants = list( /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/cyberimp/brain/anti_stun, + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, /obj/item/organ/internal/cyberimp/arm/telebaton, - /obj/item/organ/internal/cyberimp/chest/reviver + /obj/item/organ/internal/cyberimp/chest/reviver/hardened ) @@ -217,12 +216,12 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer suit_store = /obj/item/tank/emergency_oxygen/engi glasses = /obj/item/clothing/glasses/meson + mask = /obj/item/clothing/mask/gas l_pocket = /obj/item/gun/energy/gun/mini r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/mask/gas = 1, /obj/item/t_scanner = 1, /obj/item/stack/sheet/glass/fifty = 1, /obj/item/stack/sheet/metal/fifty = 1, @@ -237,6 +236,7 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma suit_store = /obj/item/tank/emergency_oxygen/engi glasses = /obj/item/clothing/glasses/meson + mask = /obj/item/clothing/mask/gas cybernetic_implants = list( /obj/item/organ/internal/cyberimp/eyes/shield, /obj/item/organ/internal/cyberimp/chest/nutriment @@ -245,7 +245,6 @@ r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/mask/gas = 1, /obj/item/rcd/preloaded = 1, /obj/item/rcd_ammo = 3, /obj/item/gun/energy/gun = 1 @@ -259,12 +258,12 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma suit_store = /obj/item/gun/energy/gun/blueshield/pdw9 glasses = /obj/item/clothing/glasses/meson/night + mask = /obj/item/clothing/mask/gas/sechailer/swat l_pocket = /obj/item/t_scanner/extended_range r_pocket = /obj/item/melee/classic_baton/telescopic backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/rcd/combat = 1, /obj/item/rcd_ammo/large = 3 ) @@ -272,7 +271,7 @@ cybernetic_implants = list( /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/cyberimp/brain/anti_stun, + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened, /obj/item/organ/internal/cyberimp/eyes/shield, /obj/item/organ/internal/cyberimp/arm/toolset ) @@ -353,6 +352,7 @@ gloves = /obj/item/clothing/gloves/combat suit = /obj/item/clothing/suit/space/hardsuit/ert/medical/gamma glasses = /obj/item/clothing/glasses/night + mask = /obj/item/clothing/mask/gas/sechailer/swat suit_store = /obj/item/gun/energy/gun/blueshield/pdw9 belt = /obj/item/defibrillator/compact/loaded @@ -361,7 +361,6 @@ r_pocket = /obj/item/reagent_containers/hypospray/autoinjector backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/bodyanalyzer/advanced = 1, /obj/item/extinguisher/mini = 1, /obj/item/roller = 1, @@ -375,7 +374,7 @@ /obj/item/organ/internal/cyberimp/arm/medibeam, /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/eyes/hud/medical, - /obj/item/organ/internal/cyberimp/brain/anti_stun + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened ) //////////////////// PARANORMAL /////////////////// @@ -390,11 +389,11 @@ shoes = /obj/item/clothing/shoes/combat l_ear = /obj/item/radio/headset/ert/alt glasses = /obj/item/clothing/glasses/hud/security/sunglasses + mask = /obj/item/clothing/mask/gas/sechailer/swat belt = /obj/item/storage/belt/security/response_team id = /obj/item/card/id/centcom pda = /obj/item/pda/centcom backpack_contents = list( - /obj/item/clothing/mask/gas/sechailer/swat = 1, /obj/item/storage/box/zipties = 1, /obj/item/flashlight/seclite = 1 ) @@ -435,7 +434,7 @@ cybernetic_implants = list( /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/eyes/hud/security, - /obj/item/organ/internal/cyberimp/brain/anti_stun + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened ) //////////////////// JANITORIAL /////////////////// @@ -444,7 +443,7 @@ name = "RT Janitor" rt_job = "Emergency Response Team Janitor" rt_mob_job = "ERT Janitor" - uniform = /obj/item/clothing/under/color/purple + uniform = /obj/item/clothing/under/color/purple/sensor back = /obj/item/storage/backpack/ert/janitor belt = /obj/item/storage/belt/janitor/full gloves = /obj/item/clothing/gloves/color/yellow @@ -500,5 +499,6 @@ ) cybernetic_implants = list( - /obj/item/organ/internal/cyberimp/arm/advmop + /obj/item/organ/internal/cyberimp/arm/advmop, + /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened ) diff --git a/code/modules/ruins/lavalandruin_code/animal_hospital.dm b/code/modules/ruins/lavalandruin_code/animal_hospital.dm index 1cf21d5a890..18ea13770a6 100644 --- a/code/modules/ruins/lavalandruin_code/animal_hospital.dm +++ b/code/modules/ruins/lavalandruin_code/animal_hospital.dm @@ -6,9 +6,10 @@ name = "broken rejuvenation pod" desc = "A small sleeper typically used to instantly restore minor wounds. This one seems broken, and its occupant is comatose." mob_name = "a translocated vet" - flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \ + description = "You are an intern working in an animal hospital that suddenly got transported to lavaland. Good luck." + flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \ everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; you see them right now. So where is \ - everyone? Where did they go? What happened to the hospital? And is that smoke you smell? You need to find someone else. Maybe they can tell you what happened." + everyone? Where did they go? What happened to the hospital? And is that smoke you smell? You need to find someone else. Maybe they can tell you what happened." assignedrole = "Translocated Vet" allow_species_pick = TRUE diff --git a/code/modules/ruins/lavalandruin_code/ash_walker_den.dm b/code/modules/ruins/lavalandruin_code/ash_walker_den.dm index 62b2343f10a..c173097fcad 100644 --- a/code/modules/ruins/lavalandruin_code/ash_walker_den.dm +++ b/code/modules/ruins/lavalandruin_code/ash_walker_den.dm @@ -67,9 +67,10 @@ anchored = FALSE move_resist = MOVE_FORCE_NORMAL density = FALSE - flavour_text = "You are an ash walker. Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. \ - You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest. \ -
You are free to attack miners and other outsiders. DO NOT leave Lavaland without admin permission! DO NOT attack the mining outpost without being provoked.
" + important_info = "Do not leave Lavaland without admin permission. Do not attack the mining outpost without being provoked." + description = "You are an ashwalker, a native inhabitant of Lavaland. Try to survive with nothing but spears and other tribal technology. Bring dead bodies back to your tendril to create more of your kind. You are free to attack miners and other outsiders." + flavour_text = "Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. \ + You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest." assignedrole = "Ash Walker" /obj/effect/mob_spawn/human/ash_walker/special(mob/living/carbon/human/new_spawn) diff --git a/code/modules/ruins/lavalandruin_code/hermit.dm b/code/modules/ruins/lavalandruin_code/hermit.dm index a28f30b9ed1..93056ee1d9a 100644 --- a/code/modules/ruins/lavalandruin_code/hermit.dm +++ b/code/modules/ruins/lavalandruin_code/hermit.dm @@ -10,7 +10,8 @@ random = TRUE allow_species_pick = TRUE mob_species = /datum/species/human - flavour_text = "You've been stranded in this godless prison of a planet for longer than you can remember. Each day you barely scrape by, and between the terrible \ + description = "You are a single survivor stranded on lavaland in a makeshift shelter. Try to survive with barely any equipment. For when miner is just too boring." + flavour_text = "You've been stranded in this godless prison of a planet for longer than you can remember. Each day you barely scrape by, and between the terrible \ conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \ the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... " assignedrole = "Hermit" @@ -22,28 +23,28 @@ if(1) flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \ only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \ - life and sent you to this hell are forever branded into your memory." + life and sent you to this hell are forever branded into your memory." outfit.uniform = /obj/item/clothing/under/assistantformal outfit.shoes = /obj/item/clothing/shoes/black outfit.back = /obj/item/storage/backpack if(2) flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \ heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \ - scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.
" + scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since." outfit.uniform = /obj/item/clothing/under/color/orange outfit.shoes = /obj/item/clothing/shoes/orange outfit.back = /obj/item/storage/backpack if(3) flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \ - to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.
" + to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there." outfit.uniform = /obj/item/clothing/under/rank/medical outfit.suit = /obj/item/clothing/suit/storage/labcoat outfit.back = /obj/item/storage/backpack/medic outfit.shoes = /obj/item/clothing/shoes/black if(4) - flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so kindly put it. It seems that they were right when you, on a tour \ + flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so kindly put it. It seems that they were right when you, on a tour \ at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \ - it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now." + it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now." outfit.uniform = /obj/item/clothing/under/color/grey/glorf outfit.shoes = /obj/item/clothing/shoes/black outfit.back = /obj/item/storage/backpack diff --git a/code/modules/ruins/lavalandruin_code/seed_vault.dm b/code/modules/ruins/lavalandruin_code/seed_vault.dm index 2c999a7ce29..1a5e863c52f 100644 --- a/code/modules/ruins/lavalandruin_code/seed_vault.dm +++ b/code/modules/ruins/lavalandruin_code/seed_vault.dm @@ -18,9 +18,10 @@ roundstart = FALSE death = FALSE mob_species = /datum/species/diona/pod - flavour_text = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \ + description = "You are a diona on Lavaland with access to a full botany setup. Perfect to mess around with plants in peace." + flavour_text = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \ seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \ - for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago." + for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago." assignedrole = "Lifebringer" /obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn) diff --git a/code/modules/ruins/lavalandruin_code/syndicate_base.dm b/code/modules/ruins/lavalandruin_code/syndicate_base.dm index d053e139f61..1e745e8d3ed 100644 --- a/code/modules/ruins/lavalandruin_code/syndicate_base.dm +++ b/code/modules/ruins/lavalandruin_code/syndicate_base.dm @@ -28,8 +28,10 @@ death = FALSE icon = 'icons/obj/cryogenic2.dmi' icon_state = "sleeper_s" - flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. The base is rigged with explosives, do not abandon it or let it fall into enemy hands! \ -
You are free to attack anyone not aligned with the Syndicate in the vicinity of your base. DO NOT work against Syndicate personnel (such as traitors or nuclear operatives). You may work with or against non-Syndicate antagonists on a case-by-case basis. DO NOT leave your base without admin permission." + important_info = "Do not work against Syndicate personnel (such as traitors or nuclear operatives). You may work with or against non-Syndicate antagonists on a case-by-case basis. Do not leave your base without admin permission." + description = "Experiment with deadly chems and viruses in peace or help any visiting Syndicate Agent." + flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. The base is rigged with explosives, do not abandon it or let it fall into enemy hands!\ + It's been made clear to you that the Syndicate will make you regret it if you disappoint them." outfit = /datum/outfit/lavaland_syndicate assignedrole = "Lavaland Syndicate" del_types = list() // Necessary to prevent del_types from removing radio! @@ -59,13 +61,13 @@ /obj/effect/mob_spawn/human/lavaland_syndicate/comms name = "Syndicate Comms Agent sleeper" mob_name = "Syndicate Comms Agent" - flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. Do not abandon the base. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands! \ -
You are free to attack anyone not aligned with the Syndicate in the vicinity of your base. DO NOT work against Syndicate personnel (such as traitors or nuclear operatives). You may work with or against non-Syndicate antagonists on a case-by-case basis. DO NOT leave your base without admin permission." + important_info = "Do not work against Syndicate personnel (such as traitors or nuclear operatives). You may work with or against non-Syndicate antagonists on a case-by-case basis. Do not leave your base without admin permission. Do not reveal the existence of yourself to NT." + description = "Monitor comms and cameras and try to assist any agents on station while keeping your existence a secret." + flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile." outfit = /datum/outfit/lavaland_syndicate/comms /obj/effect/mob_spawn/human/lavaland_syndicate/comms/space - flavour_text = "You are a syndicate agent, assigned to a small listening post station situated near your hated enemy's top secret research facility: Space Station 13. Monitor enemy activity as best you can, and try to keep a low profile. Do not abandon the base. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands! \ -
You are free to attack anyone not aligned with the Syndicate in the vicinity of your base. DO NOT work against Syndicate personnel (such as traitors or nuclear operatives). You may work with or against non-Syndicate antagonists on a case-by-case basis. DO NOT leave your base without admin permission." + flavour_text = "You are a syndicate agent, employed in a small listening outpost. You'd be bored to death if you couldn't listen in on those NT idiots mess up all the time." /obj/effect/mob_spawn/human/lavaland_syndicate/comms/space/Initialize(mapload) . = ..() diff --git a/code/modules/security_levels/keycard authentication.dm b/code/modules/security_levels/keycard authentication.dm index 87723701281..e51355e89bb 100644 --- a/code/modules/security_levels/keycard authentication.dm +++ b/code/modules/security_levels/keycard authentication.dm @@ -4,17 +4,17 @@ icon = 'icons/obj/monitors.dmi' icon_state = "auth_off" - var/active = 0 //This gets set to 1 on all devices except the one where the initial request was made. - var/event = "" - var/screen = 1 + var/active = FALSE // This gets set to TRUE on all devices except the one where the initial request was made. + var/event + var/swiping = FALSE // on swiping screen? var/list/ert_chosen = list() - var/confirmed = 0 //This variable is set by the device that confirms the request. - var/confirm_delay = 20 //(2 seconds) - var/busy = 0 //Busy when waiting for authentication or an event request has been sent from this device. + var/confirmed = FALSE // This variable is set by the device that confirms the request. + var/confirm_delay = 5 SECONDS // time allowed for a second person to confirm a swipe. + var/busy = FALSE // Busy when waiting for authentication or an event request has been sent from this device. var/obj/machinery/keycard_auth/event_source var/mob/event_triggered_by var/mob/event_confirmed_by - var/ert_reason = "Reason for ERT" + var/ert_reason anchored = 1 use_power = IDLE_POWER_USE @@ -35,16 +35,19 @@ return if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda)) if(check_access(W)) - if(active == 1) + if(active) //This is not the device that made the initial request. It is the device confirming the request. if(event_source) - event_source.confirmed = 1 + event_source.confirmed = TRUE event_source.event_confirmed_by = usr - else if(screen == 2) - if(event == "Emergency Response Team" && ert_reason == "Reason for ERT") - to_chat(user, "Supply a reason for calling the ERT first!") + SStgui.update_uis(event_source) + SStgui.update_uis(src) + else if(swiping) + if(event == "Emergency Response Team" && !ert_reason) + to_chat(user, "Supply a reason for calling the ERT first!") return event_triggered_by = usr + SStgui.update_uis(src) broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices else to_chat(user, "Access denied.") @@ -59,57 +62,58 @@ stat |= NOPOWER /obj/machinery/keycard_auth/attack_ghost(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/keycard_auth/attack_hand(mob/user as mob) +/obj/machinery/keycard_auth/attack_hand(mob/user) if(..()) - return 1 - ui_interact(user) + return TRUE + tgui_interact(user) -/obj/machinery/keycard_auth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(busy) - to_chat(user, "This device is busy.") - return - - user.set_machine(src) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/keycard_auth/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "keycard_auth.tmpl", "Keycard Authentication Device UI", 540, 320) + ui = new(user, src, ui_key, "KeycardAuth", name, 540, 300, master_ui, state) ui.open() -/obj/machinery/keycard_auth/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - var/data[0] - data["screen"] = screen - data["event"] = event - data["ertreason"] = ert_reason + +/obj/machinery/keycard_auth/tgui_data() + var/list/data = list() + data["redAvailable"] = GLOB.security_level == SEC_LEVEL_RED ? FALSE : TRUE + data["swiping"] = swiping + data["busy"] = busy + data["event"] = active && event_source && event_source.event ? event_source.event : event + data["ertreason"] = active && event_source && event_source.ert_reason ? event_source.ert_reason : ert_reason + data["isRemote"] = active ? TRUE : FALSE + data["hasSwiped"] = event_triggered_by ? TRUE : FALSE + data["hasConfirm"] = event_confirmed_by || (active && event_source && event_source.event_confirmed_by) ? TRUE : FALSE return data -/obj/machinery/keycard_auth/Topic(href, href_list) +/obj/machinery/keycard_auth/tgui_act(action, params) if(..()) - return 1 - - if(busy) - to_chat(usr, "This device is busy.") return + if(busy) + to_chat(usr, "This device is busy.") + return + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return + . = TRUE + switch(action) + if("ert") + ert_reason = stripped_input(usr, "Reason for ERT Call:", "", "") + if("reset") + reset() + if("triggerevent") + event = params["triggerevent"] + swiping = TRUE - if(href_list["triggerevent"]) - event = href_list["triggerevent"] - screen = 2 - if(href_list["reset"]) - reset() - if(href_list["ert"]) - ert_reason = stripped_input(usr, "Reason for ERT Call:", "", "") - - SSnanoui.update_uis(src) add_fingerprint(usr) - return /obj/machinery/keycard_auth/proc/reset() - active = 0 - event = "" - screen = 1 - confirmed = 0 + active = FALSE + event = null + swiping = FALSE + confirmed = FALSE event_source = null icon_state = "auth_off" event_triggered_by = null @@ -125,7 +129,7 @@ sleep(confirm_delay) if(confirmed) - confirmed = 0 + confirmed = FALSE trigger_event(event) log_game("[key_name(event_triggered_by)] triggered and [key_name(event_confirmed_by)] confirmed event [event]") message_admins("[key_name_admin(event_triggered_by)] triggered and [key_name_admin(event_confirmed_by)] confirmed event [event]", 1) @@ -135,16 +139,17 @@ if(stat & (BROKEN|NOPOWER)) return event_source = source - busy = 1 - active = 1 + busy = TRUE + active = TRUE + SStgui.update_uis(src) icon_state = "auth_on" sleep(confirm_delay) event_source = null icon_state = "auth_off" - active = 0 - busy = 0 + active = FALSE + busy = FALSE /obj/machinery/keycard_auth/proc/trigger_event() switch(event) @@ -178,7 +183,7 @@ if(fullmin_count) GLOB.ert_request_answered = TRUE ERT_Announce(ert_reason , event_triggered_by, 0) - ert_reason = "Reason for ERT" + ert_reason = null feedback_inc("alert_keycard_auth_ert",1) spawn(3000) if(!GLOB.ert_request_answered) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index aa0a21a165a..3fb173e7ac2 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -301,6 +301,7 @@ spawn(0) D.open() */ //Leaving this here incase someone decides to port -tg-'s escape shuttle stuff: + // This basically opens a big-ass row of blast doors when the shuttle arrives at centcom /obj/docking_port/mobile/pod name = "escape pod" diff --git a/code/modules/spacepods/construction.dm b/code/modules/spacepods/construction.dm index be2998fc0a3..d24758c3b19 100644 --- a/code/modules/spacepods/construction.dm +++ b/code/modules/spacepods/construction.dm @@ -222,7 +222,7 @@ // EOF ) - spawn_result(mob/user as mob) - ..() - feedback_inc("spacepod_created",1) - return +/datum/construction/reversible2/pod/spawn_result(mob/user as mob) + ..() + feedback_inc("spacepod_created",1) + return diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index 47f65ea2553..7f13651168b 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -13,7 +13,7 @@ /datum/station_goal/proc/send_report() GLOB.priority_announcement.Announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/AI/commandreport.ogg') - print_command_report(get_report(), "Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]") + print_command_report(get_report(), "Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", FALSE) on_report() /datum/station_goal/proc/on_report() diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 19ff7fa37d8..8e007f60f89 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -1,5 +1,3 @@ -#define STUN_SET_AMOUNT 2 - /obj/item/organ/internal/cyberimp name = "cybernetic implant" desc = "a state-of-the-art implant that improves a baseline's functionality" @@ -128,17 +126,27 @@ implant_color = "#FFFF00" slot = "brain_antistun" origin_tech = "materials=5;programming=4;biotech=5" + var/stun_max_amount = 2 + +/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened + name = "Hardened CNS Rebooter implant" + emp_proof = TRUE + +/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened/Initialize(mapload) + . = ..() + desc += " The implant has been hardened. It is invulnerable to EMPs." /obj/item/organ/internal/cyberimp/brain/anti_stun/on_life() ..() if(crit_fail) return - if(owner.stunned > STUN_SET_AMOUNT) - owner.SetStunned(STUN_SET_AMOUNT) - if(owner.weakened > STUN_SET_AMOUNT) - owner.SetWeakened(STUN_SET_AMOUNT) + if(owner.stunned > stun_max_amount) + owner.SetStunned(stun_max_amount) + if(owner.weakened > stun_max_amount) + owner.SetWeakened(stun_max_amount) /obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity) + ..() if(crit_fail || emp_proof) return crit_fail = TRUE @@ -147,6 +155,12 @@ /obj/item/organ/internal/cyberimp/brain/anti_stun/proc/reboot() crit_fail = FALSE +/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened + name = "Hardened CNS Rebooter implant" + desc = "A military-grade version of the standard implant, for NT's more elite forces." + origin_tech = "materials=6;programming=5;biotech=5" + emp_proof = TRUE + /obj/item/organ/internal/cyberimp/brain/clown_voice name = "Comical implant" desc = "Uh oh." diff --git a/code/modules/surgery/organs/pain.dm b/code/modules/surgery/organs/pain.dm index 91e4a2f6781..70f3ff43fa1 100644 --- a/code/modules/surgery/organs/pain.dm +++ b/code/modules/surgery/organs/pain.dm @@ -30,7 +30,7 @@ // message is the custom message to be displayed -mob/living/carbon/human/proc/custom_pain(message) +/mob/living/carbon/human/proc/custom_pain(message) if(stat >= UNCONSCIOUS) return @@ -49,7 +49,7 @@ mob/living/carbon/human/proc/custom_pain(message) to_chat(src, msg) next_pain_time = world.time + 100 -mob/living/carbon/human/proc/handle_pain() +/mob/living/carbon/human/proc/handle_pain() // not when sleeping if(stat >= UNCONSCIOUS) diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm index b61a7c429bc..b9afa20b7d2 100644 --- a/code/modules/surgery/organs/parasites.dm +++ b/code/modules/surgery/organs/parasites.dm @@ -54,8 +54,6 @@ var/eggs_hatched = 0 // num of hatch events completed var/awaymission_checked = FALSE var/awaymission_infection = FALSE // TRUE if infection occurred inside gateway - var/list/types_basic = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray) - var/list/types_adv = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green) /obj/item/organ/internal/body_egg/terror_eggs/on_life() @@ -104,12 +102,16 @@ var/infection_completed = FALSE var/obj/structure/spider/spiderling/terror_spiderling/S = new(get_turf(owner)) switch(eggs_hatched) - if(0) // First spiderling - S.grow_as = pick(types_basic) - if(1) // Second - S.grow_as = pick(types_adv) - if(2) // Last - S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/princess + if(0) // 1st spiderling + S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/gray + if(1) // 2nd + S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/red + if(2) // 3rd + S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/brown + if(3) // 4th + S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/green + if(4) // 5th + S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/green infection_completed = TRUE S.immediate_ventcrawl = TRUE eggs_hatched++ diff --git a/code/modules/tgui/modules/crew_monitor.dm b/code/modules/tgui/modules/crew_monitor.dm index f1da4ed89ba..a33a1d141f9 100644 --- a/code/modules/tgui/modules/crew_monitor.dm +++ b/code/modules/tgui/modules/crew_monitor.dm @@ -23,9 +23,12 @@ /datum/tgui_module/crew_monitor/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - // The 557 may seem random, but its the perfectsize for margins on the nanomap - ui = new(user, src, ui_key, "CrewMonitor", name, 1400, 557, master_ui, state) - ui.autoupdate = TRUE + ui = new(user, src, ui_key, "CrewMonitor", name, 800, 600, master_ui, state) + + // Send nanomaps + var/datum/asset/nanomaps = get_asset_datum(/datum/asset/simple/nanomaps) + nanomaps.send(user) + ui.open() diff --git a/code/modules/tgui/modules/ert_manager.dm b/code/modules/tgui/modules/ert_manager.dm new file mode 100644 index 00000000000..582d03f5a54 --- /dev/null +++ b/code/modules/tgui/modules/ert_manager.dm @@ -0,0 +1,100 @@ +/datum/tgui_module/ert_manager + name = "ERT Manager" + var/ert_type = "Red" + var/commander_slots = 1 // defaults for open slots + var/security_slots = 4 + var/medical_slots = 0 + var/engineering_slots = 0 + var/janitor_slots = 0 + var/paranormal_slots = 0 + var/cyborg_slots = 0 + +/datum/tgui_module/ert_manager/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_admin_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "ERTManager", name, 350, 430, master_ui, state) + ui.autoupdate = TRUE + ui.open() + +/datum/tgui_module/ert_manager/tgui_data(mob/user) + var/list/data = list() + data["str_security_level"] = capitalize(get_security_level()) + switch(GLOB.security_level) + if(SEC_LEVEL_GREEN) + data["security_level_color"] = "green" + if(SEC_LEVEL_BLUE) + data["security_level_color"] = "blue" + if(SEC_LEVEL_RED) + data["security_level_color"] = "red" + else + data["security_level_color"] = "purple" + data["ert_type"] = ert_type + data["com"] = commander_slots + data["sec"] = security_slots + data["med"] = medical_slots + data["eng"] = engineering_slots + data["jan"] = janitor_slots + data["par"] = paranormal_slots + data["cyb"] = cyborg_slots + data["total"] = commander_slots + security_slots + medical_slots + engineering_slots + janitor_slots + paranormal_slots + cyborg_slots + data["spawnpoints"] = GLOB.emergencyresponseteamspawn.len + return data + +/datum/tgui_module/ert_manager/tgui_act(action, params) + if(..()) + return + . = TRUE + switch(action) + if("ert_type") + ert_type = params["ert_type"] + if("toggle_com") + commander_slots = commander_slots ? 0 : 1 + if("set_sec") + security_slots = text2num(params["set_sec"]) + if("set_med") + medical_slots = text2num(params["set_med"]) + if("set_eng") + engineering_slots = text2num(params["set_eng"]) + if("set_jan") + janitor_slots = text2num(params["set_jan"]) + if("set_par") + paranormal_slots = text2num(params["set_par"]) + if("set_cyb") + cyborg_slots = text2num(params["set_cyb"]) + if("dispatch_ert") + var/datum/response_team/D + switch(ert_type) + if("Amber") + D = new /datum/response_team/amber + if("Red") + D = new /datum/response_team/red + if("Gamma") + D = new /datum/response_team/gamma + else + to_chat(usr, "Invalid ERT type.") + return + GLOB.ert_request_answered = TRUE + var/slots_list = list() + if(commander_slots > 0) + slots_list += "commander: [commander_slots]" + if(security_slots > 0) + slots_list += "security: [security_slots]" + if(medical_slots > 0) + slots_list += "medical: [medical_slots]" + if(engineering_slots > 0) + slots_list += "engineering: [engineering_slots]" + if(janitor_slots > 0) + slots_list += "janitor: [janitor_slots]" + if(paranormal_slots > 0) + slots_list += "paranormal: [paranormal_slots]" + if(cyborg_slots > 0) + slots_list += "cyborg: [cyborg_slots]" + var/slot_text = english_list(slots_list) + notify_ghosts("An ERT is being dispatched. Open positions: [slot_text]") + message_admins("[key_name_admin(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]", 1) + log_admin("[key_name(usr)] dispatched a [ert_type] ERT. Slots: [slot_text]") + GLOB.event_announcement.Announce("Attention, [station_name()]. We are attempting to assemble an ERT. Standby.", "ERT Protocol Activated") + trigger_armed_response_team(D, commander_slots, security_slots, medical_slots, engineering_slots, janitor_slots, paranormal_slots, cyborg_slots) + else + return FALSE + diff --git a/icons/_nanomaps/Cyberiad_nanomap_z1.png b/icons/_nanomaps/Cyberiad_nanomap_z1.png new file mode 100644 index 00000000000..fb87632863e Binary files /dev/null and b/icons/_nanomaps/Cyberiad_nanomap_z1.png differ diff --git a/icons/_nanomaps/Delta_nanomap_z1.png b/icons/_nanomaps/Delta_nanomap_z1.png new file mode 100644 index 00000000000..23a31d17241 Binary files /dev/null and b/icons/_nanomaps/Delta_nanomap_z1.png differ diff --git a/icons/_nanomaps/MetaStation_nanomap_z1.png b/icons/_nanomaps/MetaStation_nanomap_z1.png new file mode 100644 index 00000000000..77a34cd046a Binary files /dev/null and b/icons/_nanomaps/MetaStation_nanomap_z1.png differ diff --git a/icons/atmos/omni_devices.dmi b/icons/atmos/omni_devices.dmi deleted file mode 100644 index 3e7325b0556..00000000000 Binary files a/icons/atmos/omni_devices.dmi and /dev/null differ diff --git a/icons/atmos/vent_scrubber.dmi b/icons/atmos/vent_scrubber.dmi index c6b6d6ccfe4..628a17e8565 100644 Binary files a/icons/atmos/vent_scrubber.dmi and b/icons/atmos/vent_scrubber.dmi differ diff --git a/icons/goonstation/objects/pda_overlay.dmi b/icons/goonstation/objects/pda_overlay.dmi index 4c7cb24a7f4..74be20fc981 100644 Binary files a/icons/goonstation/objects/pda_overlay.dmi and b/icons/goonstation/objects/pda_overlay.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index e55b06fe8f1..d3253d3e1fb 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index f9c59529b28..f0579eae59b 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/corgi_head.dmi b/icons/mob/corgi_head.dmi index df2f3a66d84..7492b40833d 100644 Binary files a/icons/mob/corgi_head.dmi and b/icons/mob/corgi_head.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index 3892442c6ea..8257a4ffe01 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 1bd516110e5..ddc5f3cf05c 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_races/r_skeleton.dmi b/icons/mob/human_races/r_skeleton.dmi index a350c3f4c4d..6f98807254b 100644 Binary files a/icons/mob/human_races/r_skeleton.dmi and b/icons/mob/human_races/r_skeleton.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index 379c727930f..9fce742e0bf 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi index 2fc6aa9c4c1..772f8af73e4 100644 Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_lefthand.dmi b/icons/mob/inhands/equipment/belt_lefthand.dmi index 366493eebde..febcdb854b8 100644 Binary files a/icons/mob/inhands/equipment/belt_lefthand.dmi and b/icons/mob/inhands/equipment/belt_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/belt_righthand.dmi b/icons/mob/inhands/equipment/belt_righthand.dmi index 81b075f706e..d7b394cc09b 100644 Binary files a/icons/mob/inhands/equipment/belt_righthand.dmi and b/icons/mob/inhands/equipment/belt_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index b2f1bfa90c6..88cfce57ed9 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index a7772c3ebf4..44934af9bfc 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index dcbce35fb27..738fb1e0933 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/mob/screen_midnight.dmi b/icons/mob/screen_midnight.dmi index a5f9caa6a90..8d1f1648cf5 100644 Binary files a/icons/mob/screen_midnight.dmi and b/icons/mob/screen_midnight.dmi differ diff --git a/icons/mob/screen_ninja.dmi b/icons/mob/screen_ninja.dmi index 0f527241e0d..df30d63fe76 100644 Binary files a/icons/mob/screen_ninja.dmi and b/icons/mob/screen_ninja.dmi differ diff --git a/icons/mob/screen_operative.dmi b/icons/mob/screen_operative.dmi index 0bb1a0b9d44..4abe226fa84 100644 Binary files a/icons/mob/screen_operative.dmi and b/icons/mob/screen_operative.dmi differ diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi index 81453caddef..a9f2a25bd1a 100644 Binary files a/icons/mob/screen_plasmafire.dmi and b/icons/mob/screen_plasmafire.dmi differ diff --git a/icons/mob/screen_retro.dmi b/icons/mob/screen_retro.dmi index 1568e701222..0f2d9ed91e0 100644 Binary files a/icons/mob/screen_retro.dmi and b/icons/mob/screen_retro.dmi differ diff --git a/icons/mob/screen_slimecore.dmi b/icons/mob/screen_slimecore.dmi index 3b2392cb8fc..2cbc53e7ba1 100644 Binary files a/icons/mob/screen_slimecore.dmi and b/icons/mob/screen_slimecore.dmi differ diff --git a/icons/mob/screen_white.dmi b/icons/mob/screen_white.dmi index 361611cf4e0..ab65366bb52 100644 Binary files a/icons/mob/screen_white.dmi and b/icons/mob/screen_white.dmi differ diff --git a/icons/mob/species/drask/head.dmi b/icons/mob/species/drask/head.dmi index f0c888e9f68..ca15dea1cb4 100644 Binary files a/icons/mob/species/drask/head.dmi and b/icons/mob/species/drask/head.dmi differ diff --git a/icons/mob/species/drask/shoes.dmi b/icons/mob/species/drask/shoes.dmi index e51947fdd35..53664dd3d70 100644 Binary files a/icons/mob/species/drask/shoes.dmi and b/icons/mob/species/drask/shoes.dmi differ diff --git a/icons/mob/species/kidan/head.dmi b/icons/mob/species/kidan/head.dmi new file mode 100644 index 00000000000..83818995f69 Binary files /dev/null and b/icons/mob/species/kidan/head.dmi differ diff --git a/icons/mob/species/skrell/head.dmi b/icons/mob/species/skrell/head.dmi index ec5e8dd62e4..5ffe836ffc2 100644 Binary files a/icons/mob/species/skrell/head.dmi and b/icons/mob/species/skrell/head.dmi differ diff --git a/icons/mob/species/vox/shoes.dmi b/icons/mob/species/vox/shoes.dmi index 99eac81e3a9..f04249274b3 100644 Binary files a/icons/mob/species/vox/shoes.dmi and b/icons/mob/species/vox/shoes.dmi differ diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi index 0dbab70dd32..48f2080ea98 100644 Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index f007687d568..05d04330c38 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index 2521d36697d..000b6b7f1c3 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index c0501f9bb36..fb4063c1bf4 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index aae2d9df6fb..4c0b649f615 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 2b1c7edfa58..0cf67d92ef9 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index ff25b77ab45..ad31ac04998 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 303ae139574..ba64299a052 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi deleted file mode 100644 index fba8ad59431..00000000000 Binary files a/icons/obj/modular_console.dmi and /dev/null differ diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi deleted file mode 100644 index d04e68c2041..00000000000 Binary files a/icons/obj/modular_laptop.dmi and /dev/null differ diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi deleted file mode 100644 index a6e3223a8d0..00000000000 Binary files a/icons/obj/modular_tablet.dmi and /dev/null differ diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index b4956c33a9e..5cf13a408d5 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi index 51e9b66ee30..c36fbf01876 100644 Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index b39384b9b5b..5be90269399 100755 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/nano/images/Cyberiad_nanomap_z1.png b/nano/images/Cyberiad_nanomap_z1.png deleted file mode 100644 index 126f9021dac..00000000000 Binary files a/nano/images/Cyberiad_nanomap_z1.png and /dev/null differ diff --git a/nano/images/Delta_nanomap_z1.png b/nano/images/Delta_nanomap_z1.png deleted file mode 100644 index f0f4e31bca3..00000000000 Binary files a/nano/images/Delta_nanomap_z1.png and /dev/null differ diff --git a/nano/images/MetaStation_nanomap_z1.png b/nano/images/MetaStation_nanomap_z1.png deleted file mode 100644 index 280e28a2bc3..00000000000 Binary files a/nano/images/MetaStation_nanomap_z1.png and /dev/null differ diff --git a/nano/templates/ai_fixer.tmpl b/nano/templates/ai_fixer.tmpl deleted file mode 100644 index 4be6fee598d..00000000000 --- a/nano/templates/ai_fixer.tmpl +++ /dev/null @@ -1,58 +0,0 @@ - -{{if data.occupant}} -
-

Stored AI: {{:data.occupant}}

-

Information

-
- Integrity -
-
- {{:data.integrity}}% -
-
- Status -
-
- {{if data.stat == 2}} - Non-functional - {{else}} - Functional - {{/if}} -
-
- Wireless Activity -
-
- {{:helper.link('Enabled','check',{'wireless' : 0},data.wireless == 0 ? 'selected' : '')}} - {{:helper.link('Disabled','close',{'wireless' : 1},data.wireless == 1 ? 'selected' : '')}} -
-
- Subspace Transceiver -
-
- {{:helper.link('Enabled','check',{'radio' : 0},data.radio == 0 ? 'selected' : '')}} - {{:helper.link('Disabled','close',{'radio' : 1},data.radio == 1 ? 'selected' : '')}} -
-

Laws

- {{for data.laws}} - {{:value.number}}: {{:value.law}}
- {{empty}} - No laws detected! - {{/for}} - -

Actions

- {{if data.active}} - Reconstruction in progress, please wait. - {{:helper.displayBar(data.integrity, 0, 100, (data.integrity >= 75) ? 'good' : (data.integrity >= 25) ? 'average' : 'bad')}} - {{:helper.smoothRound(data.integrity)}}% - {{/if}} -
- {{:helper.link('Reconstruct', 'wrench', {'fix' : 1}, data.active || data.integrity >= 100 ? 'disabled' : '')}} -
-
-{{else}} -

No artificial intelligence detected.

-{{/if}} \ No newline at end of file diff --git a/nano/templates/aicard.tmpl b/nano/templates/aicard.tmpl deleted file mode 100644 index 8ebe6cff319..00000000000 --- a/nano/templates/aicard.tmpl +++ /dev/null @@ -1,98 +0,0 @@ - - - - - -{{if data.has_ai}} -
-
- Hardware Integrity: -
-
- {{:data.hardware_integrity}}% -
-
- - {{if data.has_laws}} - - - -
- Laws: -
- {{for data.laws}} - - {{/for}} -
IndexLaw
{{:value.index}}.{{:value.law}}
- {{else}} - No laws found. - {{/if}} - - {{if data.operational}} - - - - - - - - - - - {{if data.flushing}} - - {{else}} - - - - - {{/if}} -
Radio Subspace Transceiver{{:helper.link("Enabled", null, {'radio' : 0}, data.radio ? 'selected' : null)}}{{:helper.link("Disabled", null, {'radio' : 1}, data.radio ? null : 'redButton' )}}
Wireless Interface{{:helper.link("Enabled", null, {'wireless' : 0}, data.wireless ? 'selected' : null)}}{{:helper.link("Disabled", null, {'wireless' : 1}, data.wireless ? null : 'redButton' )}}
AI wipe in progress...
Wipe AI{{:helper.link("Wipe", 'exclamation-circle', {'wipe' : 1}, null, 'redButton')}}
- {{/if}} -{{else}} - Stored AI: No AI detected. -{{/if}} diff --git a/nano/templates/atmos_filter.tmpl b/nano/templates/atmos_filter.tmpl deleted file mode 100644 index e0715e243c5..00000000000 --- a/nano/templates/atmos_filter.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -
-
Power:
-
{{:helper.link(data.on ? 'On' : 'Off', data.on ? 'power-off' : 'times', {'power' : 1}, null, data.on ? 'selected' : null)}}
-
-
-
Output Pressure:
-
- {{:helper.link('Set', 'pencil', {'pressure' : 'input'})}} - {{:helper.link('Max', 'plus', {'pressure' : 'max'}, data.pressure == data.max_pressure ? 'disabled' : null)}} - {{:helper.smoothRound(data.pressure)}} kPa -
-
-
-
Filter:
-
- {{:helper.link('Nothing', null, {'filter' : -1}, data.filter_type == -1 ? 'selected' : null)}} - {{:helper.link('Plasma', null, {'filter' : 0}, data.filter_type == 0 ? 'selected' : null)}} - {{:helper.link('O2', null, {'filter' : 1}, data.filter_type == 1 ? 'selected' : null)}} - {{:helper.link('N2', null, {'filter' : 2}, data.filter_type == 2 ? 'selected' : null)}} - {{:helper.link('CO2', null, {'filter' : 3}, data.filter_type == 3 ? 'selected' : null)}} - {{:helper.link('N2O', null, {'filter' : 4}, data.filter_type == 4 ? 'selected' : null)}} -
-
- diff --git a/nano/templates/atmos_mixer.tmpl b/nano/templates/atmos_mixer.tmpl deleted file mode 100644 index 3bae7f993bd..00000000000 --- a/nano/templates/atmos_mixer.tmpl +++ /dev/null @@ -1,32 +0,0 @@ -
-
Power:
-
{{:helper.link(data.on ? 'On' : 'Off', data.on ? 'power-off' : 'times', {'power' : 1}, null, data.on ? 'selected' : null)}}
-
-
-
Output Pressure:
-
- {{:helper.link('Set', 'pencil', {'pressure' : 'input'})}} - {{:helper.link('Max', 'plus', {'pressure' : 'max'}, data.pressure == data.max_pressure ? 'disabled' : null)}} - {{:helper.smoothRound(data.pressure)}} kPa -
-
-
-
Node 1:
-
- {{:helper.link('', null, {'node1' : -0.1}, data.node1_concentration == 0 ? 'disabled' : null)}} - {{:helper.link('', null, {'node1' : -0.01}, data.node1_concentration == 0 ? 'disabled' : null)}} - {{:helper.link('', null, {'node1' : 0.01}, data.node1_concentration == 100 ? 'disabled' : null)}} - {{:helper.link('', null, {'node1' : 0.1}, data.node1_concentration == 100 ? 'disabled' : null)}} - {{:helper.smoothRound(data.node1_concentration)}}% -
-
-
-
Node 2:
-
- {{:helper.link('', null, {'node2' : -0.1}, data.node2_concentration == 0 ? 'disabled' : null)}} - {{:helper.link('', null, {'node2' : -0.01}, data.node2_concentration == 0 ? 'disabled' : null)}} - {{:helper.link('', null, {'node2' : 0.01}, data.node2_concentration == 100 ? 'disabled' : null)}} - {{:helper.link('', null, {'node2' : 0.1}, data.node2_concentration == 100 ? 'disabled' : null)}} - {{:helper.smoothRound(data.node2_concentration)}}% -
-
\ No newline at end of file diff --git a/nano/templates/atmos_pump.tmpl b/nano/templates/atmos_pump.tmpl deleted file mode 100644 index a27e5b710dd..00000000000 --- a/nano/templates/atmos_pump.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -
-
Power:
-
{{:helper.link(data.on ? 'On' : 'Off', data.on ? 'power-off' : 'times', {'power' : 1}, null, data.on ? 'selected' : null)}}
-
-{{if data.max_rate}} -
-
Transfer Rate:
-
- {{:helper.link('Set', 'pencil', {'rate' : 'input'})}} - {{:helper.link('Max', 'plus', {'rate' : 'max'}, data.rate == data.max_rate ? 'disabled' : null)}} - {{:helper.smoothRound(data.rate)}} L/s -
-
-{{else}} -
-
Output Pressure:
-
- {{:helper.link('Set', 'pencil', {'pressure' : 'input'})}} - {{:helper.link('Max', 'plus', {'pressure' : 'max'}, data.pressure == data.max_pressure ? 'disabled' : null)}} - {{:helper.smoothRound(data.pressure)}} kPa -
-
-{{/if}} - diff --git a/nano/templates/autolathe.tmpl b/nano/templates/autolathe.tmpl deleted file mode 100644 index d56ae4926c3..00000000000 --- a/nano/templates/autolathe.tmpl +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - -{{if data.screen == 2 || data.screen == 3}} -
- {{:helper.link('Main Menu', 'reply', {'menu' : 1})}} -
-{{/if}} - - - - -
-
- {{if data.screen == 1}} -

Autolathe Menu

-
- - - - - - - - - -
Total amount:{{:data.total_amount}} / {{:data.max_amount}} cm3
Metal amount:{{:data.metal_amount}} cm3
Glass amount:{{:data.glass_amount}} cm3
-
- - - -
- -
- - {{for data.categories}} - {{if (index & 1) == 0 && index != 0}} - - {{/if}} - - {{/for}} -
{{:helper.link(value, 'arrow-right', {'category': value})}}
- {{else data.screen == 2 || data.screen == 3}} - {{if data.screen == 2}} -

Viewing Category {{:data.selected_category}}:

- {{else data.screen == 3}} -

Search Results for '{{:data.search}}':

- {{/if}} -
- - - - - - - - - -
Total amount:{{:data.total_amount}} / {{:data.max_amount}} cm3
Metal amount:{{:data.metal_amount}} cm3
Glass amount:{{:data.glass_amount}} cm3
- - {{for data.designs}} - - - - - - - - {{/for}} -
{{:helper.link(value.name, 'print', {'make' : value.id, 'multiplier' : 1}, value.disabled)}}{{if value.max_multiplier > 10}} - {{:helper.link('x10', null, {'make' : value.id, 'multiplier' : 10}, value.disabled)}} - {{/if}}{{if value.max_multiplier > 25}} - {{:helper.link('x25', null, {'make' : value.id, 'multiplier' : 25}, value.disabled)}} - {{/if}}{{if value.max_multiplier}} - {{:helper.link('x' + value.max_multiplier, null, {'make' : value.id, 'multiplier' : value.max_multiplier}, value.disabled)}} - {{/if}} - {{for value.materials : material : i}} - {{if material.amount}} - | - {{if material.is_red}} - - {{/if}} - {{:material.amount}} {{:material.name}} - {{if material.is_red}} - - {{/if}} - {{/if}} - {{/for}} -
- {{/if}} -
-
-
-

Queue contains:

- {{if data.queue}} - {{if data.processing}} -
    {{:data.processing}}
- {{/if}} -
    - {{for data.queue}} -
  1. - {{if !value.can_build}} - - {{/if}} - {{:value.name}} {{:value.multiplier > 1 ? '(' + value.multiplier + ')' : ''}} - {{if !value.can_build}} - - {{/if}} -
    - {{if index + 1 > 1}} - {{:helper.link('', 'arrow-up', {'queue_move' : -1, 'index' : index + 1})}} - {{/if}} - {{if index + 1 < data.queue_len}} - {{:helper.link('', 'arrow-down', {'queue_move' : +1, 'index' : index + 1})}} - {{/if}} - {{:helper.link('Remove', 'times', {'remove_from_queue' : index + 1})}} -
    -
  2. - {{/for}} -
- {{:helper.link('Clear queue', 'trash', {'clear_queue' : 1})}} - {{else}} - {{if data.processing}} -
    {{:data.processing}}
- {{else}} -
    Nothing
- {{/if}} - {{/if}} -
-
\ No newline at end of file diff --git a/nano/templates/brig_timer.tmpl b/nano/templates/brig_timer.tmpl deleted file mode 100644 index 2cd1ab73a23..00000000000 --- a/nano/templates/brig_timer.tmpl +++ /dev/null @@ -1,91 +0,0 @@ - -
-
- Cell: -
-
- {{:data.cell_id}} -
-
-
-
- Occupant: -
-
- {{:data.occupant}} -
-
-
-
- Crimes: -
-
- {{:data.crimes}} -
-
-
-
- Brigged By: -
-
- {{:data.brigged_by}} -
-
-
-
- Time Brigged For: -
-
- {{:data.time_set}} -
-
-
-
- Time Left: -
-
- {{:data.time_left}} -
-
-{{if data.isAllowed}} -
-
- Actions: -
-
- {{:helper.link('Flash', 'flash', {'flash' : 1}, null, data.isAllowed ? '' : 'dsabled')}} - {{:helper.link('Release', null, {'release' : 1}, null, data.isAllowed ? '' : 'disabled')}} -
-
- {{if !data.timing}} -

Inmate Information

-
-
- Name: -
-
- {{:helper.link('Set', 'pencil', {'prisoner_name' : 'input'})}} {{:data.prisoner_name}} -
-
-
-
- Charge: -
-
- {{:helper.link('Set', 'pencil', {'prisoner_charge' : 'input'})}} {{:data.prisoner_charge}} -
-
-
-
- Time (in minutes): -
-
- {{:helper.link('Set', 'pencil', {'prisoner_time' : 'input'})}} {{:data.prisoner_time}} -
-
- {{:helper.link('Submit', null, {'set_timer' : 1}, null, data.isAllowed ? '' : 'disabled')}} - {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/card_prog.tmpl b/nano/templates/card_prog.tmpl deleted file mode 100644 index 7054f8bf4c2..00000000000 --- a/nano/templates/card_prog.tmpl +++ /dev/null @@ -1,309 +0,0 @@ -{{if data.printing}} -
The computer is currently busy.
-
-
Printing...
-
-

- Thank you for your patience! -

-{{else}} - {{:helper.link('Access Modification', 'home', {'action' : 'PRG_mode', 'mode_target' : 0}, !data.mode ? 'disabled' : null)}} - {{:helper.link('Job Management', 'gear', {'action' : 'PRG_mode', 'mode_target' : 1}, data.mode == 1 ? 'disabled' : null)}} - {{:helper.link('Crew Manifest', 'folder-open', {'action' : 'PRG_mode', 'mode_target' : 2}, data.mode == 2 ? 'disabled' : null)}} - {{:helper.link('Print', 'print', {'action' : 'PRG_print'}, data.printer && (data.mode == 2 || data.has_modify && !data.mode) ? null : 'disabled')}} - {{:helper.link('Records', 'file', {'action' : 'PRG_mode', 'mode_target' : 3}, (data.mode == 3) ? 'disabled' : null)}} - - {{if data.mode == 1}} -
-

Job Management

-
-
-
- Authorized Identity: -
-
- {{:helper.link(data.scan_name, 'eject', {'action' : 'PRG_scan'})}} -
-
- Cooldown: -
-
- {{if data.cooldown_mins > 0 || data.cooldown_mins == 0 && data.cooldown_secs > 0}} - Next change in: {{:data.cooldown_mins}}:{{:data.cooldown_secs}} - {{else}} - Ready - {{/if}} -
-
-
-
- {{for data.job_slots}} -
- {{:value.title}}: {{:value.current_positions}}/{{:value.total_positions}} - {{:helper.link('-', null, {'action' : 'PRG_make_job_unavailable', 'job' : value.title}, value.can_close == 1 && data.authenticated ? null : 'disabled')}} - {{:helper.link('+', null, {'action' : 'PRG_make_job_available', 'job' : value.title}, value.can_open == 1 && data.authenticated ? null : 'disabled')}} - {{:helper.link('Pri', null, {'action' : 'PRG_prioritize_job', 'job' : value.title}, value.can_prioritize > 0 && data.authenticated ? null : 'disabled')}} {{if value.can_prioritize == 2}}Priority Job {{/if}} -
- {{/for}} -
- {{else data.mode == 2}} -
-

Crew Manifest

-
-
- {{:data.manifest}} -
- {{else data.mode == 3}} -
-

Records

-
-
-
- Authorized Identity: -
-
- {{:helper.link(data.scan_name, 'eject', {'action' : 'PRG_scan'})}} -
-
-
- {{if data.authenticated}} - {{:data.id_change_html}} - {{if data.centcom_access}} - {{:helper.link('Delete Records By: ' + data.scan_owner, null, {'action' : 'PRG_wipe_my_logs'}, null, 'linkDanger')}} - {{/if}} - {{if !data.target_dept}} - {{:helper.link('Delete ALL Records', null, {'action' : 'PRG_wipe_all_logs'}, null, 'linkDanger')}} - {{/if}} - {{else}} - Please insert an authorized ID into the terminal to proceed.
- {{/if}} -
- {{else}} -
-

Access Modification

-
- - {{if !data.authenticated}} - Please insert the IDs into the terminal to proceed.
- {{/if}} - -
-
- Target Identity: -
-
- {{:helper.link(data.target_name, 'eject', {'action' : 'PRG_modify'})}} -
-
-
-
- Authorized Identity: -
-
- {{:helper.link(data.scan_name, 'eject', {'action' : 'PRG_scan'})}} -
-
-
- - {{if data.authenticated}} - - - {{if data.has_modify}} -
-

Details

-
- -
-
-
- - - Registered Name: -
-
- - -
-
-
- -
-
-
- - - Account Number: -
-
- - -
-
-
- -
-
- Terminations: -
-
- {{if data.target_rank == "Terminated"}} - {{:data.target_owner}} has already been terminated! - {{else}} - {{:helper.link('Terminate ' + data.target_owner, 'gear', {'action' : 'PRG_terminate'}, data.target_rank == "Terminated" ? 'disabled' : null, data.target_rank == "Terminated" ? 'disabled' : 'linkDanger')}} - {{/if}} -
-
- -
-

Assignment

-
- - -
- -
- - {{if data.centcom_access}} -
-

Central Command

-
-
- {{for data.all_centcom_access}} - {{:helper.link(value.desc, '', {'action' : 'PRG_access', 'access_target' : value.ref, 'allowed' : value.allowed}, null, value.allowed ? 'selected' : null)}} - {{/for}} -
-
Card Skin
- {{for data.all_centcom_skins}} - {{:helper.link(value.display_name, '', {'action' : 'PRG_skin', 'skin_target' : value.skin}, null,(data.current_skin == value.skin) ? 'selected' : null )}} - {{/for}} -
-
- {{else}} -
-

{{:data.station_name}}

-
-
- {{for data.regions}} -
-
{{:value.name}}
- {{for value.accesses :accessValue:accessKey}} -
- {{:helper.link(accessValue.desc, '', {'action' : 'PRG_access', 'access_target' : accessValue.ref, 'allowed' : accessValue.allowed}, null, accessValue.allowed ? 'selected' : null)}} -
- {{/for}} -
- {{/for}} -
-
Card Skin
- {{for data.card_skins}} - {{:helper.link(value.display_name, '', {'action' : 'PRG_skin', 'skin_target' : value.skin}, null,(data.current_skin == value.skin) ? 'selected' : null )}} - {{/for}} -
-
- {{/if}} - {{/if}} - {{/if}} - {{/if}} -{{/if}} diff --git a/nano/templates/comm_console.tmpl b/nano/templates/comm_console.tmpl deleted file mode 100644 index 2c36a011ac6..00000000000 --- a/nano/templates/comm_console.tmpl +++ /dev/null @@ -1,142 +0,0 @@ - - -{{if !data.authenticated}} -
Please swipe your ID card. {{:helper.link('Log In','unlock',{'login':1},null,'fixed')}}
-{{else}} - {{if !data.is_ai}} -
Please remember to {{:helper.link('Log Out','lock',{'logout':1},null,'fixed')}}
- {{/if}} - {{if data.lastCallLoc}} -
Most recent shuttle call/recall traced to: {{:data.lastCallLoc}}
- {{else}} -
Unable to trace most recent shuttle call/recall signal.
- {{/if}} -
-

Emergency Shuttle:

- {{if data.shuttle.eta}} -
ETA:
-
- {{>data.shuttle.eta}} -
- {{/if}} -
Options:
-
- {{if data.shuttle.callStatus == 1 && !data.is_ai}} - {{:helper.link('Cancel Shuttle','arrow-left',{'operation':'cancelshuttle'})}} - {{else data.shuttle.callStatus == 2}} - {{:helper.link('Call Shuttle','arrow-circle-down',{'operation':'callshuttle'})}} - {{/if}} -
-
- - {{if data.screen==1}} - -

Menu

-
- {{if data.authenticated==2}} -
- {{:helper.link('Make an Announcement','info',{'operation':'announce'})}} -
-
- {{if data.emagged}} - {{:helper.link('Message [UNKNOWN]','envelope',{'operation':'MessageSyndicate'})}} -
-
- {{:helper.link('Reset Relays','refresh',{'operation':'RestoreBackup'})}} - {{else}} - {{:helper.link('Message CentComm','envelope',{'operation':'MessageCentcomm'})}} - {{/if}} -
-
- {{:helper.link('Request Nuclear Authentication Codes','exclamation-triangle',{'operation':'nukerequest'})}} -
- {{/if}} -
- {{:helper.link('Change Alert Level','signal',{'operation':'changeseclevel'})}} -
-
- {{:helper.link('Change Status Displays','info',{'operation':'status'})}} -
-
- {{:helper.link('Message List','comment',{'operation':'messagelist'})}} -
-
- {{:helper.link('Restart Nano-Mob Hunter GO! Server','power-off',{'operation':'RestartNanoMob'})}} -
-
- {{else data.screen==2}} - -

Status Displays

- {{:helper.link('Back','home',{'operation':'main'})}} -

Presets

- {{for data.stat_display.presets}} -
-
{{:helper.link(value.label,'info',{'operation':'setstat','statdisp':value.name},null,(name==data.stat_display.type?'linkOn':''))}}
-
- {{/for}} -

Alerts

- {{for data.stat_display.alerts}} -
-
{{:helper.link(value.label,'exclamation-triangle',{'operation':'setstat','statdisp':'alert','alert':value.alert},null,(value.alert==data.stat_display.type?'linkOn':''))}}
-
- {{/for}} -

Messages

-
- {{if data.stat_display.type}} -
-
{{:helper.link('Line 1:','gear',{'operation':'setmsg1'})}}
-
{{>data.stat_display.line_1}}
-
-
-
{{:helper.link('Line 2:','gear',{'operation':'setmsg2'})}}
-
{{>data.stat_display.line_2}}
-
- {{/if}} -
- {{else data.screen==3}} - -

Messages

- {{if data.current_message}} - {{:helper.link('Messages','home',{'operation':'messagelist'})}} -

{{:data.current_message_title}}

-
- {{:data.current_message}} -
- {{else}} - {{:helper.link('Back','home',{'operation':'main'})}} - {{for data.messages}} -
- {{:value.title}}
- {{:helper.link('Open','envelope-o',{'operation':'messagelist','msgid':value.id})}} - {{:helper.link('Delete','close',{'operation':'delmessage','msgid':value.id})}} -
- {{/for}} - {{/if}} - {{else data.screen==4}} - -

Security Level

- {{:helper.link('Back','home',{'operation':'main'})}} -
-
-
Security Level:
-
{{>data.str_security_level}}
-
-
-
Presets:
-
- {{for data.levels}} - {{:helper.link(value.name,'comment',{'operation':'newalertlevel','level':value.id},null,(value.id==data.security_level?'linkOn':''))}} - {{/for}} -
-
-
- {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/comm_program.tmpl b/nano/templates/comm_program.tmpl deleted file mode 100644 index b1c64c6f4e3..00000000000 --- a/nano/templates/comm_program.tmpl +++ /dev/null @@ -1,129 +0,0 @@ -{{if !data.authenticated}} -
Please swipe your ID card. {{:helper.link('Log In', 'unlock', {'PRG_login' : 1}, null, 'fixed')}}
-{{else}} - {{if !data.is_ai}} -
Please remember to {{:helper.link('Log Out', 'lock', {'PRG_logout' : 1}, null, 'fixed')}}
- {{/if}} - {{if data.lastCallLoc}} -
Most recent shuttle call/recall traced to: {{:data.lastCallLoc}}
- {{else}} -
Unable to trace most recent shuttle call/recall signal.
- {{/if}} -
-

Emergency Shuttle:

- {{if data.shuttle.eta}} -
ETA:
-
- {{>data.shuttle.eta}} -
- {{/if}} -
Options:
-
- {{if data.shuttle.callStatus == 1 && !data.is_ai}} - {{:helper.link('Cancel Shuttle', 'arrow-left', {'PRG_operation' : 'cancelshuttle'})}} - {{else data.shuttle.callStatus == 2}} - {{:helper.link('Call Shuttle', 'arrow-circle-down', {'PRG_operation' : 'callshuttle'})}} - {{/if}} -
-
- - {{if data.screen==1}} - -

Menu

-
- {{if data.authenticated==2}} -
- {{:helper.link('Make an Announcement', 'info', {'PRG_operation' : 'announce'})}} -
-
- {{if data.emagged}} - {{:helper.link('Message [UNKNOWN]', 'envelope', {'PRG_operation' : 'MessageSyndicate'})}} - {{else}} - {{:helper.link('Message CentComm', 'envelope', {'PRG_operation' : 'MessageCentcomm'})}} - {{/if}} -
-
- {{:helper.link('Request Nuclear Authentication Codes', 'exclamation-triangle', {'PRG_operation' : 'nukerequest'})}} -
- {{/if}} -
- {{:helper.link('Change Alert Level', 'signal', {'PRG_operation' : 'changeseclevel'})}} -
-
- {{:helper.link('Change Status Displays', 'info', {'PRG_operation' : 'status'})}} -
-
- {{:helper.link('Message List', 'comment', {'PRG_operation' : 'messagelist'})}} -
-
- {{:helper.link('Restart Nano-Mob Hunter GO! Server', 'power-off', {'PRG_operation' : 'RestartNanoMob'})}} -
-
- {{else data.screen==2}} - -

Status Displays

- {{:helper.link('Back', 'home', {'PRG_operation' : 'main'})}} -

Presets

- {{for data.stat_display.presets}} -
-
{{:helper.link(value.label, 'info', {'PRG_operation' : 'setstat', 'statdisp' : value.name}, name == data.stat_display.type ? 'selected' : null)}}
-
- {{/for}} -

Alerts

- {{for data.stat_display.alerts}} -
-
{{:helper.link(value.label, 'exclamation-triangle', {'PRG_operation' : 'setstat', 'statdisp' : 'alert', 'alert' : value.alert}, value.alert == data.stat_display.type ? 'selected' : null)}}
-
- {{/for}} -

Messages

-
- {{if data.stat_display.type}} -
-
{{:helper.link('Line 1:', 'gear', {'PRG_operation':'setmsg1'})}}
-
{{>data.stat_display.line_1}}
-
-
-
{{:helper.link('Line 2:', 'gear', {'PRG_operation':'setmsg2'})}}
-
{{>data.stat_display.line_2}}
-
- {{/if}} -
- {{else data.screen==3}} - -

Messages

- {{if data.current_message}} - {{:helper.link('Messages', 'home', {'PRG_operation' : 'messagelist'})}} -

{{:data.current_message_title}}

-
- {{:data.current_message}} -
- {{else}} - {{:helper.link('Back', 'home', {'PRG_operation' : 'main'})}} - {{for data.messages}} -
- {{:value.title}}
- {{:helper.link('Open', 'envelope-o', {'PRG_operation' : 'messagelist', 'msgid' : value.id})}} - {{:helper.link('Delete', 'close', {'PRG_operation' : 'delmessage', 'msgid' : value.id})}} -
- {{/for}} - {{/if}} - {{else data.screen==4}} - -

Security Level

- {{:helper.link('Back', 'home', {'PRG_operation' : 'main'})}} -
-
-
Security Level:
-
{{>data.str_security_level}}
-
-
-
Presets:
-
- {{for data.levels}} - {{:helper.link(value.name, 'comment', {'PRG_operation' : 'newalertlevel', 'level' : value.id}, value.id == data.security_level ? 'selected' : null)}} - {{/for}} -
-
-
- {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/computer_fabricator.tmpl b/nano/templates/computer_fabricator.tmpl deleted file mode 100644 index 268f585a3da..00000000000 --- a/nano/templates/computer_fabricator.tmpl +++ /dev/null @@ -1,84 +0,0 @@ -{{:helper.link('Clear Order', 'circle', {'action' : 'clean_order'})}}

-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', 'laptop', {'action' : 'pick_device', 'pick' : 1})}} - {{:helper.link('Tablet', 'tablet', {'action' : 'pick_device', 'pick' : 2})}} -
-{{else data.state == 1}} -
-

Step 2: Personalise your device

- - - - - - - - - - {{if data.devtype != 2}} - - - {{/if}} - - - {{if data.devtype != 2}} - - - - - {{/if}} -
Current Price: - {{:data.totalprice}}C -
Battery: - {{:helper.link('Standard', 'bolt', {'action' : 'hw_battery', 'battery' : 1}, data.hw_battery == 1 ? "selected" : null)}} - {{:helper.link('Upgraded', 'bolt', {'action' : 'hw_battery', 'battery' : 2}, data.hw_battery == 2 ? "selected" : null)}} - {{:helper.link('Advanced', 'bolt', {'action' : 'hw_battery', 'battery' : 3}, data.hw_battery == 3 ? "selected" : null)}} -
Hard Drive: - {{:helper.link('Standard', 'hdd-o', {'action' : 'hw_disk', 'disk' : 1}, data.hw_disk == 1 ? "selected" : null)}} - {{:helper.link('Upgraded', 'hdd-o', {'action' : 'hw_disk', 'disk' : 2}, data.hw_disk == 2 ? "selected" : null)}} - {{:helper.link('Advanced', 'hdd-o', {'action' : 'hw_disk', 'disk' : 3}, data.hw_disk == 3 ? "selected" : null)}} -
Network Card: - {{:helper.link('None', 'times', {'action' : 'hw_netcard', 'netcard' : 0}, data.hw_netcard == 0 ? "selected" : null)}} - {{:helper.link('Standard', 'signal', {'action' : 'hw_netcard', 'netcard' : 1}, data.hw_netcard == 1 ? "selected" : null)}} - {{:helper.link('Advanced', 'signal', {'action' : 'hw_netcard', 'netcard' : 2}, data.hw_netcard == 2 ? "selected" : null)}} -
Nano Printer: - {{:helper.link('None', 'times', {'action' : 'hw_nanoprint', 'print' : 0}, data.hw_nanoprint == 0 ? "selected" : null)}} - {{:helper.link('Standard', 'print', {'action' : 'hw_nanoprint', 'print' : 1}, data.hw_nanoprint == 1 ? "selected" : null)}} -
Card Reader: - {{:helper.link('None', 'times', {'action' : 'hw_card', 'card' : 0}, data.hw_card == 0 ? "selected" : null)}} - {{:helper.link('Standard', 'credit-card', {'action' : 'hw_card', 'card' : 1}, data.hw_card == 1 ? "selected" : null)}} -
Processor Unit: - {{:helper.link('Standard', 'tasks', {'action' : 'hw_cpu', 'cpu' : 1}, data.hw_cpu == 1 ? "selected" : null)}} - {{:helper.link('Advanced', 'tasks', {'action' : 'hw_cpu', 'cpu' : 2}, data.hw_cpu == 2 ? "selected" : null)}} -
Tesla Relay: - {{:helper.link('None', 'times', {'action' : 'hw_tesla', 'tesla' : 0}, data.hw_tesla == 0 ? "selected" : null)}} - {{:helper.link('Standard', 'plug', {'action' : 'hw_tesla', 'tesla' : 1}, data.hw_tesla == 1 ? "selected" : null)}} -
- - - -
Confirm Order: - {{:helper.link('CONFIRM', 'check', {'action' : 'confirm_order'})}} -
- -
- 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.
- 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. This component is currently unavailable on tablet computers due to size restrictions.
- Nano Printer is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. 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}}C -{{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}} diff --git a/nano/templates/computer_main.tmpl b/nano/templates/computer_main.tmpl deleted file mode 100644 index 9aad3d58609..00000000000 --- a/nano/templates/computer_main.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -No program loaded. Please select program from list below. -
- - {{for data.programs}} -
{{:helper.link(value.desc, null, {'action' : 'PC_runprogram', 'name' : value.name})}} - {{:helper.link('', null, {'action' : 'PC_killprogram', 'name' : value.name}, value.running ? null : 'disabled')}} - {{/for}} -
-
\ No newline at end of file diff --git a/nano/templates/ert_config.tmpl b/nano/templates/ert_config.tmpl deleted file mode 100644 index c8ff0645b3b..00000000000 --- a/nano/templates/ert_config.tmpl +++ /dev/null @@ -1,75 +0,0 @@ -
- - - - - - -
Station Alert Level{{:data.alert_level}}
ERT Type - {{if data.ert_type == 'Code Amber'}} AMBER {{else}} {{:helper.link('Amber', null, {"set_code": 'Code Amber'})}} {{/if}} - {{if data.ert_type == 'Code Red'}} RED {{else}} {{:helper.link('Red', null, {"set_code": 'Code Red'})}} {{/if}} - {{if data.ert_type == 'Code Gamma'}} GAMMA {{else}} {{:helper.link('Gamma', null, {"set_code": 'Code Gamma'})}} {{/if}} -
-
-
-
- - - - - - - - - -
DepartmentSlotsChange Slots
Command{{if data.com == 0}}-{{else}}{{:helper.smoothRound(data.com)}}{{/if}} - {{:helper.link('0', null, {"set_com": 0})}} - {{:helper.link('1', null, {"set_com": 1})}}
Security{{if data.sec == 0}}-{{else}}{{:helper.smoothRound(data.sec)}}{{/if}} - {{:helper.link('0', null, {"set_sec": 0})}} - {{:helper.link('1', null, {"set_sec": 1})}} - {{:helper.link('2', null, {"set_sec": 2})}} - {{:helper.link('3', null, {"set_sec": 3})}} - {{:helper.link('4', null, {"set_sec": 4})}} - {{:helper.link('5', null, {"set_sec": 5})}} -
Medical{{if data.med == 0}}-{{else}}{{:helper.smoothRound(data.med)}}{{/if}} - {{:helper.link('0', null, {"set_med": 0})}} - {{:helper.link('1', null, {"set_med": 1})}} - {{:helper.link('2', null, {"set_med": 2})}} - {{:helper.link('3', null, {"set_med": 3})}} - {{:helper.link('4', null, {"set_med": 4})}} - {{:helper.link('5', null, {"set_med": 5})}} -
Engineering{{if data.eng == 0}}-{{else}}{{:helper.smoothRound(data.eng)}}{{/if}} - {{:helper.link('0', null, {"set_eng": 0})}} - {{:helper.link('1', null, {"set_eng": 1})}} - {{:helper.link('2', null, {"set_eng": 2})}} - {{:helper.link('3', null, {"set_eng": 3})}} - {{:helper.link('4', null, {"set_eng": 4})}} - {{:helper.link('5', null, {"set_eng": 5})}} -
Paranormal{{if data.par == 0}}-{{else}}{{:helper.smoothRound(data.par)}}{{/if}} - {{:helper.link('0', null, {"set_par": 0})}} - {{:helper.link('1', null, {"set_par": 1})}} - {{:helper.link('2', null, {"set_par": 2})}} - {{:helper.link('3', null, {"set_par": 3})}} - {{:helper.link('4', null, {"set_par": 4})}} - {{:helper.link('5', null, {"set_par": 5})}} -
Janitor{{if data.jan == 0}}-{{else}}{{:helper.smoothRound(data.jan)}}{{/if}} - {{:helper.link('0', null, {"set_jan": 0})}} - {{:helper.link('1', null, {"set_jan": 1})}} - {{:helper.link('2', null, {"set_jan": 2})}} - {{:helper.link('3', null, {"set_jan": 3})}} - {{:helper.link('4', null, {"set_jan": 4})}} - {{:helper.link('5', null, {"set_jan": 5})}} -
{{if data.ert_type == 'Code Gamma'}}GAMMA {{/if}}Cyborg{{if data.cyb == 0}}-{{else}}{{:helper.smoothRound(data.cyb)}}{{/if}} - {{:helper.link('0', null, {"set_cyb": 0})}} - {{:helper.link('1', null, {"set_cyb": 1})}} - {{:helper.link('2', null, {"set_cyb": 2})}} - {{:helper.link('3', null, {"set_cyb": 3})}} - {{:helper.link('4', null, {"set_cyb": 4})}} - {{:helper.link('5', null, {"set_cyb": 5})}} -
-
-
-
- {{:helper.link('Dispatch', null, {"dispatch_ert": 1})}} -
- diff --git a/nano/templates/file_manager.tmpl b/nano/templates/file_manager.tmpl deleted file mode 100644 index 51d40b84475..00000000000 --- a/nano/templates/file_manager.tmpl +++ /dev/null @@ -1,76 +0,0 @@ -{{if data.error}} -

An error has occurred 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, {'action' : 'PRG_closefile'})}} -{{else}} - {{if data.filename}} -

Viewing file {{:data.filename}}

-
- {{:helper.link('CLOSE', null, {'action' : 'PRG_closefile'})}} - {{:helper.link('EDIT', null, {'action' : 'PRG_edit'})}} - {{:helper.link('PRINT', null, {'action' : 'PRG_printfile'})}} -

- {{:data.filedata}} - {{else}} -

Available files (local):

-
- - - - - - - - {{for data.files}} - - - - - - - {{/for}} -
File nameFile typeFile size (GQ)Operations
{{:value.name}}.{{:value.type}}{{:value.size}}GQ - {{:helper.link('VIEW', 'eye', {'action' : 'PRG_openfile', 'name' : value.name})}} - {{:helper.link('DELETE', 'trash', {'action' : 'PRG_deletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{:helper.link('RENAME', 'pencil', {'action' : 'PRG_rename', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{:helper.link('CLONE', 'files-o', {'action' : 'PRG_clone', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{if !value.encrypted}} - {{:helper.link('ENCRYPT', null, {'action' : 'PRG_encrypt', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{else}} - {{:helper.link('DECRYPT', null, {'action' : 'PRG_decrypt', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{/if}} - {{if data.usbconnected}} - {{:helper.link('EXPORT', 'upload', {'action' : 'PRG_copytousb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{/if}} -
-
- {{if data.usbconnected}} -

Available files (portable device):

-
- - - - - - - - {{for data.usbfiles}} - - - - - - - {{/for}} -
File nameFile typeFile size (GQ)Operations
{{:value.name}}.{{:value.type}}{{:value.size}}GQ - {{:helper.link('DELETE', 'trash', {'action' : 'PRG_usbdeletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{if data.usbconnected}} - {{:helper.link('IMPORT', 'download', {'action' : 'PRG_copyfromusb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{/if}} -
-
- {{/if}} - {{:helper.link('NEW DATA FILE', 'file-text', {'action' : 'PRG_newtextfile'})}} - {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/firealarm.tmpl b/nano/templates/firealarm.tmpl deleted file mode 100644 index 5ddaa2977f4..00000000000 --- a/nano/templates/firealarm.tmpl +++ /dev/null @@ -1,69 +0,0 @@ - -
-
- Fire Alarm -
-
- {{:helper.link('Activated', 'lightbulb-o', {'alarm' : 1}, data.fire ? 'selected' : '')}} - {{:helper.link('Deactivated', 'lightbulb-o', {'reset' : 1}, data.fire ? '' : 'selected')}} -
-
- -
-
- Security Level -
-
- {{if data.sec_level == "green"}} - Green - {{else data.sec_level == "blue"}} - Blue - {{else data.sec_level == "red"}} - Red - {{else data.sec_level == "gamma"}} - Gamma - {{else data.sec_level == "epsilon"}} - Contracts terminated. - {{else data.sec_level == "delta"}} - Nuclear device primed. - {{else}} - ERR: Unable to ascertain security level. Please see an authorized NT fire alarm technician. - {{/if}} -
-
- -
-
- Timer System -
-
- {{:helper.link('Initiate', 'play', {'time': 1}, data.timing ? 'selected' : '')}} - {{:helper.link('Stop', 'pause', {'time': 0}, data.timing ? '' : 'selected')}} -
-
- -
-
- Time Modifiers -
-
- {{:helper.link('30', 'minus', {'tp': -30})}} - {{:helper.link('1', 'minus', {'tp': -1 })}} - {{:helper.link('1', 'plus', {'tp': +1 })}} - {{:helper.link('30', 'plus', {'tp': +30})}} -
-
- -{{if data.timing}} -
-
- Time Left -
-
- {{:data.time_left}} -
-
-{{/if}} \ No newline at end of file diff --git a/nano/templates/freezer.tmpl b/nano/templates/freezer.tmpl deleted file mode 100644 index 582598e05c5..00000000000 --- a/nano/templates/freezer.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -
-
- Status: -
-
- {{:helper.link('On', 'power-off', {'toggleStatus' : 1}, data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', {'toggleStatus' : 1}, data.on ? null : 'selected')}} -
-
- -
-
- Gas Pressure: -
-
- {{:helper.smoothRound(data.gasPressure)}} kPa -
-
- -

Gas Temperature

-
-
- Current: -
-
- {{:helper.displayBar(data.gasTemperature, data.minGasTemperature, data.maxGasTemperature, data.gasTemperatureClass)}} -
- {{:helper.smoothRound(data.gasTemperature)}} K ({{:helper.smoothRound(data.gasTemperatureCelsius)}} °C) -
-
-
- -
-
- Target: -
-
- {{:helper.displayBar(data.targetGasTemperature, data.minGasTemperature, data.maxGasTemperature)}} -
- {{:helper.link('Min', null, {'minimum' : 'yes'}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} - {{:helper.link('-', null, {'temp' : -100}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} - {{:helper.link('-', null, {'temp' : -10}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} - {{:helper.link('-', null, {'temp' : -1}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} -
{{:data.targetGasTemperature}} K ({{:data.targetGasTemperatureCelsius}} °C)
- {{:helper.link('+', null, {'temp' : 1}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} - {{:helper.link('+', null, {'temp' : 10}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} - {{:helper.link('+', null, {'temp' : 100}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} - {{:helper.link('Max', null, {'maximum' : 'yes'}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} -
-
-
- diff --git a/nano/templates/identification_computer.tmpl b/nano/templates/identification_computer.tmpl deleted file mode 100644 index 606af520168..00000000000 --- a/nano/templates/identification_computer.tmpl +++ /dev/null @@ -1,347 +0,0 @@ -{{if data.printing}} -
The computer is currently busy.
-
-
Printing...
-
-

- Thank you for your patience! -

-{{else}} - {{:helper.link('Access Modification', 'home', {'choice' : 'mode', 'mode_target' : 0}, !data.mode ? 'disabled' : null)}} - {{if !data.target_dept}}{{:helper.link('Job Management', 'gear', {'choice' : 'mode', 'mode_target' : 1}, data.mode == 1 ? 'disabled' : null)}}{{/if}} - {{:helper.link('Crew Manifest', 'folder-open', {'choice' : 'mode', 'mode_target' : 2}, data.mode == 2 ? 'disabled' : null)}} - {{if !data.target_dept}}{{:helper.link('Print', 'print', {'choice' : 'print'}, (data.mode == 2 || data.has_modify && !data.mode) ? null : 'disabled')}}{{/if}} - {{:helper.link('Records', 'file', {'choice' : 'mode', 'mode_target' : 3}, (data.mode == 3) ? 'disabled' : null)}} - - {{if data.mode == 1 && !data.target_dept}} -
-

Job Management

-
-
-
- Authorized Identity: -
-
- {{:helper.link(data.scan_name, 'eject', {'choice' : 'scan'})}} -
-
- Cooldown: -
-
- {{if data.cooldown_mins > 0 || data.cooldown_mins == 0 && data.cooldown_secs > 0}} - Next change in: {{:data.cooldown_mins}}:{{:data.cooldown_secs}} - {{else}} - Ready - {{/if}} -
-
-
-
- {{for data.job_slots}} -
- {{:value.title}}: {{:value.current_positions}}/{{:value.total_positions}} - {{:helper.link('-', null, {'choice' : 'make_job_unavailable', 'job' : value.title}, value.can_close == 1 && data.authenticated ? null : 'disabled')}} - {{:helper.link('+', null, {'choice' : 'make_job_available', 'job' : value.title}, value.can_open == 1 && data.authenticated ? null : 'disabled')}} - {{:helper.link('Pri', null, {'choice' : 'prioritize_job', 'job' : value.title}, value.can_prioritize > 0 && data.authenticated ? null : 'disabled')}} {{if value.can_prioritize == 2}}Priority Job {{/if}} -
- {{/for}} -
- {{else data.mode == 2}} -
-

Crew Manifest

-
-
- {{:data.manifest}} -
- {{else data.mode == 3}} -
-

Records

-
-
-
- Authorized Identity: -
-
- {{:helper.link(data.scan_name, 'eject', {'choice' : 'scan'})}} -
-
-
- {{if data.authenticated}} - {{:data.id_change_html}} - {{if data.centcom_access}} - {{:helper.link('Delete Records By: ' + data.scan_owner, null, {'choice' : 'wipe_my_logs'}, null, 'linkDanger')}} - {{/if}} - {{if !data.target_dept}} - {{:helper.link('Delete ALL Records', null, {'choice' : 'wipe_all_logs'}, null, 'linkDanger')}} - {{/if}} - {{else}} - Please insert an authorized ID into the terminal to proceed.
- {{/if}} -
- {{else}} -
-

Access Modification

-
- - {{if !data.authenticated}} - Please insert the IDs into the terminal to proceed.
- {{/if}} - -
-
- Target Identity: -
-
- {{:helper.link(data.target_name, 'eject', {'choice' : 'modify'})}} -
-
-
-
- Authorized Identity: -
-
- {{:helper.link(data.scan_name, 'eject', {'choice' : 'scan'})}} -
-
-
- - {{if data.authenticated}} - - - {{if data.has_modify}} - {{if !data.target_dept}} -
-

Details

-
- -
-
-
- - - Registered Name: -
-
- - -
-
-
- -
-
-
- - - Account Number: -
-
- - -
-
-
- {{/if}} - {{if data.target_rank != "Terminated"}} -
-
- Demotions: -
-
- {{if data.target_rank == "Demoted"}} - {{:data.target_owner}} has already been demoted! - {{else}} - {{:helper.link('Demote ' + data.target_owner, 'gear', {'choice' : 'demote'}, (data.target_rank == "Civilian" || data.target_rank == "Unassigned") ? 'disabled' : null, (data.target_rank == "Civilian" || data.target_rank == "Unassigned") ? 'disabled' : 'linkDanger')}} - {{/if}} -
-
- {{/if}} - {{if !data.target_dept}} -
-
- Terminations: -
-
- {{if data.target_rank == "Terminated"}} - {{:data.target_owner}} has already been terminated! - {{else}} - {{:helper.link('Terminate ' + data.target_owner, 'gear', {'choice' : 'terminate'}, data.target_rank == "Terminated" ? 'disabled' : null, data.target_rank == "Terminated" ? 'disabled' : 'linkDanger')}} - {{/if}} -
-
- -
-

Assignment

-
- - {{else}} - -
-

Assignment for {{:data.target_owner}}

-
- - {{/if}} - - -
- -
- - {{if data.centcom_access}} -
-

Central Command

-
-
- {{for data.all_centcom_access}} - {{:helper.link(value.desc, '', {'choice' : 'access', 'access_target' : value.ref, 'allowed' : value.allowed}, null, value.allowed ? 'selected' : null)}} - {{/for}} -
-
Card Skin
- {{for data.all_centcom_skins}} - {{:helper.link(value.display_name, '', {'choice' : 'skin', 'skin_target' : value.skin}, null,(data.current_skin == value.skin) ? 'selected' : null )}} - {{/for}} -
-
- {{else}} - {{if !data.target_dept}} -
-

{{:data.station_name}}

-
-
- {{for data.regions}} -
-
{{:value.name}}
- {{for value.accesses :accessValue:accessKey}} -
- {{:helper.link(accessValue.desc, '', {'choice' : 'access', 'access_target' : accessValue.ref, 'allowed' : accessValue.allowed}, null, accessValue.allowed ? 'selected' : null)}} -
- {{/for}} -
- {{/for}} -
-
Card Skin
- {{for data.card_skins}} - {{:helper.link(value.display_name, '', {'choice' : 'skin', 'skin_target' : value.skin}, null,(data.current_skin == value.skin) ? 'selected' : null )}} - {{/for}} -
-
- {{/if}} - {{/if}} - {{/if}} - {{/if}} - {{/if}} -{{/if}} diff --git a/nano/templates/keycard_auth.tmpl b/nano/templates/keycard_auth.tmpl deleted file mode 100644 index 96a3f44f60a..00000000000 --- a/nano/templates/keycard_auth.tmpl +++ /dev/null @@ -1,39 +0,0 @@ - - -
-

Keycard Authentication Device

- This device is used to trigger certain high security events. It requires the simultaneous swipe of two high-level ID cards. -
- {{if data.screen == 1}} -

Trigger Event

- {{:helper.link('Red Alert', 'exclamation-triangle', { 'triggerevent' : 'Red Alert' })}} - {{:helper.link('Emergency Response Team', 'exclamation-triangle', { 'triggerevent' : 'Emergency Response Team' })}} - {{:helper.link('Grant Emergency Maintenance Access', 'unlock', { 'triggerevent' : 'Grant Emergency Maintenance Access' })}} - {{:helper.link('Revoke Emergency Maintenance Access', 'lock', { 'triggerevent' : 'Revoke Emergency Maintenance Access' })}} - {{:helper.link('Activate Station-Wide Emergency Access', 'unlock', { 'triggerevent' : 'Activate Station-Wide Emergency Access' })}} - {{:helper.link('Deactivate Station-Wide Emergency Access', 'lock', { 'triggerevent' : 'Deactivate Station-Wide Emergency Access' })}} - {{else data.screen == 2}} - {{if data.event == 'Emergency Response Team'}} -
-
Reason for ERT Call:
-
- {{:helper.link(data.ertreason, 'exclamation-triangle', { 'ert' : 'callreason' })}} -
-
- {{/if}} -

Please swipe your card to authorize the following event:

-
{{:data.event}}
- {{:helper.link('Back', 'close', { 'reset' : 1 })}} - {{/if}} -
-
\ No newline at end of file diff --git a/nano/templates/laptop_configuration.tmpl b/nano/templates/laptop_configuration.tmpl deleted file mode 100644 index 95dd315b90e..00000000000 --- a/nano/templates/laptop_configuration.tmpl +++ /dev/null @@ -1,71 +0,0 @@ -Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device.
-
-

Power Supply

- {{if data.battery}} -
-
Battery Status
-
Active
-
-
-
Battery Rating
-
{{:data.battery.max}}
-
-
-
ETA
-
{{:data.eta.hours ? helper.smoothRound(data.eta.hours) + "h " : ""}}{{:data.eta.minutes ? helper.smoothRound(data.eta.minutes) + "m " : ""}}{{:helper.smoothRound(data.eta.seconds)}}s
-
-
-
Battery Charge
- {{:helper.displayBar(data.battery.charge, 0, data.battery.max, (data.battery.charge > data.battery.max/2) ? 'good' : (data.battery.charge > data.battery.max/4) ? 'average' : 'bad')}} -
- {{:helper.smoothRound(data.battery.charge, 1)}}/{{:data.battery.max}} -
-
- {{else}} -
-
Battery Status
-
Not Available
-
- {{/if}} - -
-
Power Usage
-
{{:data.power_usage}}W
-
-
- -
-

File System

-
-
Used Capacity
- {{:helper.displayBar(data.disk_used, 0, data.disk_size, (data.disk_used > data.disk_size*0.75) ? 'bad' : (data.disk_used > data.disk_size/2) ? 'average' : 'good')}} -
- {{:helper.smoothRound(data.disk_used, 1)}}/{{: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(value.enabled ? 'On' : 'Off', value.enabled ? 'power-off' : 'close', {'action' : 'PC_toggle_component', 'name' : value.name})}}
-
- {{/if}} -

- {{/for}} -
\ No newline at end of file diff --git a/nano/templates/ntnet_chat.tmpl b/nano/templates/ntnet_chat.tmpl deleted file mode 100644 index c3f2573f8e2..00000000000 --- a/nano/templates/ntnet_chat.tmpl +++ /dev/null @@ -1,58 +0,0 @@ -{{if data.adminmode}} -

ADMINISTRATIVE MODE

-{{/if}} - -{{if data.title}} -
-
Current channel:
-
{{:data.title}}
-
-
-
Operator access:
-
{{if data.is_operator}}Enabled{{else}}Disabled{{/if}}
-
-
-
Controls:
-
- -
{{:helper.link('Send message', 'comment-o', {'action' : 'PRG_speak'})}} -
{{:helper.link('Change nickname', 'pencil', {'action' : 'PRG_changename'})}} -
{{:helper.link('Toggle administration mode', 'lock', {'action' : 'PRG_toggleadmin'})}} -
{{:helper.link('Leave channel', 'sign-out', {'action' : 'PRG_leavechannel'})}} -
{{:helper.link('Save log to local drive', 'download', {'action' : 'PRG_savelog'})}} - {{if data.is_operator}} -
{{:helper.link('Rename channel', 'pencil', {'action' : 'PRG_renamechannel'})}} -
{{:helper.link('Set password', 'key', {'action' : 'PRG_setpassword'})}} -
{{:helper.link('Delete channel', 'trash', {'action' : 'PRG_deletechannel'})}} - {{/if}} -
-
-
- Chat Window -
-
-
- {{for data.messages}} - {{:value.msg}}
- {{/for}} -
-
-
- Connected Users
- {{for data.clients}} - {{:value.name}}
- {{/for}} -{{else}} - Controls: - -
{{:helper.link('Change nickname', 'pencil', {'action' : 'PRG_changename'})}} -
{{:helper.link('New Channel', 'plus', {'action' : 'PRG_newchannel'})}} -
{{:helper.link('Toggle administration mode', 'lock', {'action' : 'PRG_toggleadmin'})}} -
- Available channels: - - {{for data.all_channels}} -
{{:helper.link(value.chan, 'sign-in', {'action' : 'PRG_joinchannel', 'id' : value.id})}}
- {{/for}} -
-{{/if}} \ No newline at end of file diff --git a/nano/templates/ntnet_dos.tmpl b/nano/templates/ntnet_dos.tmpl deleted file mode 100644 index bff7bb3b9f0..00000000000 --- a/nano/templates/ntnet_dos.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{:helper.syndicateMode()}} -{{if data.error}} - ##SYSTEM ERROR: {{:data.error}}{{:helper.link('RESET', null, {'action' : 'PRG_reset'})}} -{{else data.target}} - ##DoS traffic generator active. Tx: {{:data.speed}}GQ/s
- {{for data.dos_strings}} - {{:value.nums}}
- {{/for}} - {{:helper.link('ABORT', 'ban', {'action' : 'PRG_reset'})}} -{{else}} - ##DoS traffic generator ready. Select target device.
-
-
Targeted device ID:
-
{{if data.focus}}{{:data.focus}}{{else}}None{{/if}}
-
-
- {{:helper.link('EXECUTE', 'play', {'action' : 'PRG_execute'})}}
-
- Detected devices on network:
- - {{for data.relays}} -
{{:helper.link(value.id, null, {'action' : 'PRG_target_relay', 'targid' : value.id})}} - {{/for}} -
-{{/if}} \ No newline at end of file diff --git a/nano/templates/ntnet_downloader.tmpl b/nano/templates/ntnet_downloader.tmpl deleted file mode 100644 index 35790bb3c7f..00000000000 --- a/nano/templates/ntnet_downloader.tmpl +++ /dev/null @@ -1,102 +0,0 @@ -Welcome to software download utility. Please select which software you wish to download.
-{{if data.error}} -

Download Error

-
-
Information
-
{{:data.error}}
-
-
-
Reset Program
-
{{:helper.link('RESET', 'times', {'action' : 'PRG_reseterror'})}}
-
-{{else}} - {{if data.downloadname}} -

Download Running

-
- Please wait... -
-
File name
-
{{:data.downloadname}}
-
-
-
File description
-
{{:data.downloaddesc}}
-
-
-
File size
-
{{:helper.smoothRound(data.downloadcompletion, 1)}}/{{:data.downloadsize}}GQ
-
-
-
Transfer Rate
-
{{:data.downloadspeed}} GQ/s
-
-
-
Download progress
- {{:helper.displayBar(data.downloadcompletion, 0, data.downloadsize, (data.downloadcompletion > data.downloadsize/2) ? 'good' : (data.downloadcompletion > data.downloadsize/4) ? 'average' : 'bad')}} -
- {{:helper.smoothRound(data.downloadcompletion, 1)}}/{{:data.downloadsize}}GQ -
-
-
- {{else}} -

Primary software repository

-
-
-
Hard drive
- {{:helper.displayBar(data.disk_used, 0, data.disk_size, (data.disk_used > data.disk_size/2) ? 'bad' : (data.disk_used > data.disk_size/4) ? 'average' : 'good')}} -
- {{:helper.smoothRound(data.disk_used, 1)}}/{{:data.disk_size}}GQ -
-
- {{for data.downloadable_programs}} -
-
-
File name
-
{{:value.filename}} ({{:value.size}} GQ)
-
-
-
Program name
-
{{:value.filedesc}}
-
-
-
Description
-
{{:value.fileinfo}}
-
-
-
Compatibility
-
{{:value.compatibility}}
-
-
-
File controls
-
{{:helper.link('DOWNLOAD', 'download', {'action' : 'PRG_downloadfile', 'filename' : value.filename}, value.status)}}
-
- {{/for}} -
- {{if data.hackedavailable}} -

UNKNOWN software repository

-
- Please note that Nanotrasen does not recommend download of software from non-official servers. - {{for data.hacked_programs}} -
-
-
File name
-
{{:value.filename}} ({{:value.size}} GQ)
-
-
-
Program name
-
{{:value.filedesc}}
-
-
-
Description
-
{{:value.fileinfo}}
-
-
-
File controls
-
{{:helper.link('DOWNLOAD', 'download', {'action' : 'PRG_downloadfile', 'filename' : value.filename})}}
-
- {{/for}} -
- {{/if}} - {{/if}} -{{/if}} -
NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559 diff --git a/nano/templates/ntnet_monitor.tmpl b/nano/templates/ntnet_monitor.tmpl deleted file mode 100644 index 319baa872f0..00000000000 --- a/nano/templates/ntnet_monitor.tmpl +++ /dev/null @@ -1,102 +0,0 @@ -

WIRELESS CONNECTIVITY

-
-
- Active NTNet Relays: -
-
- {{:data.ntnetrelays}} -
- {{if data.ntnetrelays}} -
-
- System status: -
-
- {{:data.ntnetstatus ? "ENABLED" : "DISABLED"}} -
-
-
-
- Control: -
-
- {{:helper.link('TOGGLE', null, {'action' : 'toggleWireless'})}} -
-
- Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again! - {{else}} -

Wireless coverage unavailable, no relays are connected.

- {{/if}} -
- -

FIREWALL CONFIGURATION

-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
PROTOCOLSTATUSCONTROL
Software Downloads
{{:data.config_softwaredownload ? 'ENABLED' : 'DISABLED'}}
{{:helper.link('TOGGLE', null, {'action' : 'toggle_function', 'id' : 1})}}
Peer to Peer Traffic
{{:data.config_peertopeer ? 'ENABLED' : 'DISABLED'}}
{{:helper.link('TOGGLE', null, {'action' : 'toggle_function', 'id' : 2})}}
Communication Systems
{{:data.config_communication ? 'ENABLED' : 'DISABLED'}}
{{:helper.link('TOGGLE', null, {'action' : 'toggle_function', 'id' : 3})}}
Remote System Control
{{:data.config_systemcontrol ? 'ENABLED' : 'DISABLED'}}
{{:helper.link('TOGGLE', null, {'action' : 'toggle_function', 'id' : 4})}}
-
- -

SECURITY SYSTEMS

-{{if data.idsalarm}} -
-
-
-

NETWORK INCURSION DETECTED

- An abnormal activity has been detected in the network. Please verify system logs for more information -
-
-
-{{/if}} -
-
Intrusion Detection System:
-
{{:data.idsstatus ? 'ENABLED' : 'DISABLED'}}
-
-
-
Maximal Log Count:
-
{{:data.ntnetmaxlogs}}
-
-
-
Controls:
-
- -
{{:helper.link('RESET IDS', null, {'action' : 'resetIDS'})}} -
{{:helper.link('TOGGLE IDS', null, {'action' : 'toggleIDS'})}} -
{{:helper.link('SET LOG LIMIT', null, {'action' : 'updatemaxlogs'})}} -
{{:helper.link('PURGE LOGS', null, {'action' : 'purgelogs'})}} -
-
-
-System Logs -
-
-
- {{for data.ntnetlogs}} - {{:value.entry}}
- {{/for}} -
-
-
\ No newline at end of file diff --git a/nano/templates/ntnet_relay.tmpl b/nano/templates/ntnet_relay.tmpl deleted file mode 100644 index 8625f94dd14..00000000000 --- a/nano/templates/ntnet_relay.tmpl +++ /dev/null @@ -1,19 +0,0 @@ -

Relay

-{{if data.dos_crashed}} -

NETWORK BUFFERS OVERLOADED

-

Overload Recovery Mode

- This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue. -

ADMINISTRATIVE OVERRIDE

- CAUTION - Data loss may occur - {{:helper.link('Purge buffered traffic', 'signal', {'action' : 'restart'})}} -{{else}} -
-
Relay status
-
{{:helper.link(data.enabled ? "ENABLED" : "DISABLED", 'power-off', {'action' : 'toggle'})}}
-
- -
-
Network buffer status
-
{{:data.dos_overload}}/{{:data.dos_capacity}} GQ
-
-{{/if}} \ No newline at end of file diff --git a/nano/templates/ntnet_transfer.tmpl b/nano/templates/ntnet_transfer.tmpl deleted file mode 100644 index 660838b94dc..00000000000 --- a/nano/templates/ntnet_transfer.tmpl +++ /dev/null @@ -1,77 +0,0 @@ -{{if data.error}} -
-

An error has occurred during operation...

- Additional information: {{:data.error}}
- {{:helper.link('Clear', null, {'action' : 'PRG_reset'})}} -
-{{else data.downloading}} -

Download in progress...

-
-
Downloaded file:
-
{{:data.download_name}}
-
-
-
Download progress:
-
{{:helper.smoothRound(data.download_progress)}}/{{:data.download_size}}GQ
-
-
-
Transfer speed:
-
{{:data.download_netspeed}}GQ/s
-
-
-
Controls:
-
{{:helper.link('Abort download', 'arrow-left', {'action' : 'PRG_reset'})}}
-
-{{else data.uploading}} -

Server enabled

-
-
Connected clients:
-
{{:data.upload_clients}}
-
-
-
Provided file:
-
{{:data.upload_filename}}
-
-
-
Server password:
-
{{if data.upload_haspassword}}ENABLED{{else}}DISABLED{{/if}}
-
-
-
Commands:
-
- {{:helper.link('Set password', 'key', {'action' : 'PRG_setpassword'})}} - {{:helper.link('Exit server', 'arrow-left', {'action' : 'PRG_reset'})}} -
-
-{{else data.upload_filelist}} -

File transfer server ready. Select file to upload:

- -
File nameFile sizeControls - {{for data.upload_filelist}} -
{{:value.filename}} - {{:value.size}}GQ - {{:helper.link('Select', 'upload', {'action' : 'PRG_uploadfile', 'id' : value.uid})}} - {{/for}} -
-
- {{:helper.link('Set password', 'key', {'action' : 'PRG_setpassword'})}} - {{:helper.link('Return', 'arrow-left', {'action' : 'PRG_reset'})}} -{{else}} -

Available files:

-
Server UIDFile NameFile SizePassword ProtectionOperations - {{for data.servers}} -
{{:value.uid}} - {{:value.filename}} - {{:value.size}}GQ - {{if value.haspassword}} - Enabled - {{else}} - Disabled - {{/if}} - - {{:helper.link('Download', 'download', {'action' : 'PRG_downloadfile', 'id' : value.uid})}} - {{/for}} -
-
- {{:helper.link('Send file', 'upload', {'action' : 'PRG_uploadmenu'})}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/nuclear_bomb.tmpl b/nano/templates/nuclear_bomb.tmpl deleted file mode 100644 index f2a12651af6..00000000000 --- a/nano/templates/nuclear_bomb.tmpl +++ /dev/null @@ -1,145 +0,0 @@ - -{{if data.is_syndicate}} - {{:helper.syndicateMode()}} -{{/if}} -
-
Authorization Disk:
-
- {{if data.auth}} - {{:helper.link('++++++++++', 'eject', {'auth' : 1})}} - {{else}} - {{:helper.link('----------', 'floppy-o', {'auth' : 1})}} - {{/if}} -
-
-
-
-
Status:
-
{{:data.authstatus}} - {{:data.safe}}
-
- -
-
Time Left:
-
{{:data.time}}
-
- -
- {{if data.auth && data.yescode}} -
-
- Timer -
-
- {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'selected' : '')}} - {{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}} -
-
-
-
- Set Time -
-
- {{:helper.link('--', '', {'time' : -10}, data.time <= 120 ? 'disabled' : '')}} - {{:helper.link('-', '', {'time' : -1}, data.time <= 120 ? 'disabled' : '')}} - - {{:helper.link('+', '', {'time' : 1})}} - {{:helper.link('++', '', {'time' : 10})}} -
-
- - {{else}} - -
-
- Timer -
-
- {{:helper.link('On', 'play', null, 'disabled')}} - {{:helper.link('Off', 'pause', null, 'disabled')}} -
-
-
-
- Set Time -
-
- {{:helper.link('--', '', null, 'disabled')}} - {{:helper.link('-', '', null, 'disabled')}} - - {{:helper.link('+', '', null, 'disabled')}} - {{:helper.link('++', '', null, 'disabled')}} -
-
- {{/if}} -
- -
- {{if data.auth && data.yescode}} -
-
- Safety -
-
- {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}} - {{:helper.link('Disengaged', 'exclamation-triangle', {'safety' : 0}, data.safety ? '' : 'selected')}} -
-
-
-
- Anchor -
-
- {{:helper.link('Engaged', 'lock', {'anchor' : 1}, data.anchored ? 'selected' : '')}} - {{:helper.link('Disengaged', 'unlock', {'anchor' : 0}, data.anchored ? '' : 'selected')}} -
-
- - {{else}} - -
-
- Safety -
-
- {{:helper.link('Engaged', 'info', null, 'disabled')}} - {{:helper.link('Disengaged', 'exclamation-triangle', null, 'disabled')}} -
-
-
-
- Anchor -
-
- {{:helper.link('Engaged', 'lock', null, 'disabled')}} - {{:helper.link('Disengaged', 'unlock', null, 'disabled')}} -
-
- {{/if}} -
-
-
-
- >{{if data.message}} {{:data.message}}{{/if}} -
-
-
- {{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}} -
-
- {{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}} -
-
- {{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}} -
-
- {{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}} -
-
-
\ No newline at end of file diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl deleted file mode 100644 index 8a3ffac0af7..00000000000 --- a/nano/templates/omni_filter.tmpl +++ /dev/null @@ -1,86 +0,0 @@ -
-
- {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} -
-
- {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
- - {{if data.config}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Input
- {{for data.ports}} -
- {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}} -
- {{/for}} -
-
-
Output
- {{for data.ports}} -
- {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
- {{/for}} -
-
-
Filter
- {{for data.ports}} -
- {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}} -
- {{/for}} -
-
- -
- Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
-
- {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
- - {{else}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Mode
- {{for data.ports}} -
- {{if value.input}} - Input - {{else value.output}} - Output - {{else value.f_type}} - {{:value.f_type}} - {{else}} - Disabled - {{/if}} -
- {{/for}} -
-
- -
- Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
- -
- Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
- {{/if}} -
\ No newline at end of file diff --git a/nano/templates/omni_mixer.tmpl b/nano/templates/omni_mixer.tmpl deleted file mode 100644 index 3d637687553..00000000000 --- a/nano/templates/omni_mixer.tmpl +++ /dev/null @@ -1,101 +0,0 @@ -
-
- {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} -
-
- {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
- - {{if data.config}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Input
- {{for data.ports}} -
- {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}} -
- {{/for}} -
-
-
Output
- {{for data.ports}} -
- {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
- {{/for}} -
-
-
Concentration
- {{for data.ports}} -
- {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}} -
- {{/for}} -
-
-
Lock
- {{for data.ports}} -
- {{:helper.link(' ', value.con_lock ? 'lock' : 'unlock', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}} -
- {{/for}} -
-
- -
- Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
-
- {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
- - {{else}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Mode
- {{for data.ports}} -
- {{if value.input}} - Input - {{else value.output}} - Output - {{else}} - Disabled - {{/if}} -
- {{/for}} -
-
-
Concentration
- {{for data.ports}} -
- {{if value.input}} - {{:helper.round(value.concentration*100)}} % - {{else}} - - - {{/if}} -
- {{/for}} -
-
- -
- Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
- - {{/if}} -
\ No newline at end of file diff --git a/nano/templates/portpump.tmpl b/nano/templates/portpump.tmpl deleted file mode 100644 index 91e37f38975..00000000000 --- a/nano/templates/portpump.tmpl +++ /dev/null @@ -1,84 +0,0 @@ -

Pump Status

-
-
- Tank Pressure: -
-
- {{:helper.smoothRound(data.tankPressure)}} kPa -
-
- -
-
- Port Status: -
-
- {{:data.portConnected ? 'Connected' : 'Disconnected'}} -
-
- -

Holding Tank Status

-{{if data.hasHoldingTank}} -
-
- Tank Label: -
-
-
{{:data.holdingTank.name}}
{{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} -
-
- -
-
- Tank Pressure: -
-
- {{:helper.smoothRound(data.holdingTank.tankPressure)}} kPa -
-
-{{else}} -
No holding tank inserted.
-
 
-{{/if}} - - -

Power Regulator Status

-
-
- Target Pressure: -
-
- {{:helper.displayBar(data.targetpressure, data.minpressure, data.maxpressure)}} -
- {{:helper.link('-', null, {'pressure_adj' : -1000}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -100}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -10}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -1}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} -
 {{:data.targetpressure}} kPa 
- {{:helper.link('+', null, {'pressure_adj' : 1}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 10}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 100}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 1000}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} -
-
-
- -
-
- Power Switch: -
-
- {{:helper.link('On', 'unlock', {'power' : 1}, data.on ? 'selected' : null)}}{{:helper.link('Off', 'lock', {'power' : 1}, data.on ? null : 'selected')}} -
-
- -
-
- Pump Direction: -
-
- {{:helper.link('Out', 'arrow-right', {'direction' : 1}, data.pump_dir ? 'selected' : null)}}{{:helper.link('In', 'arrow-left', {'direction' : 1}, data.pump_dir ? null : 'selected')}} -
-
- - diff --git a/nano/templates/revelation.tmpl b/nano/templates/revelation.tmpl deleted file mode 100644 index 5412c440caa..00000000000 --- a/nano/templates/revelation.tmpl +++ /dev/null @@ -1,23 +0,0 @@ -{{:helper.syndicateMode()}} -
-
- Payload status: -
-
- {{if data.armed}} - ARMED - {{else}} - DISARMED - {{/if}} -
-
- Controls: -
-
- -
{{:helper.link('OBFUSCATE PROGRAM NAME', 'eye-slash', {'action' : 'PRG_obfuscate'})}} -
{{:helper.link(data.armed ? 'DISARM' : 'ARM', data.armed ? 'crosshairs' : 'info', {'action' : 'PRG_arm'})}} - {{:helper.link('ACTIVATE', 'exclamation-triangle', {'action' : 'PRG_activate'}, data.armed ? null : 'disabled', data.armed ? 'redButton' : null)}} -
-
-
\ No newline at end of file diff --git a/nano/templates/smartfridge.tmpl b/nano/templates/smartfridge.tmpl deleted file mode 100644 index 3c59892486d..00000000000 --- a/nano/templates/smartfridge.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -
- {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} -
- -
-

Storage

- {{if data.secure}} - - {{:data.locked == -1 ? "Sec.re ACC_** //):securi_nt.diag=>##'or 1=1'%($..." : "Secure Access: Please have your identification ready."}} - - {{/if}} -
-
- {{if data.can_dry}} -
- Drying: -
-
- {{:helper.link('On', 'power-off', {'dryingOn' : 1}, data.drying ? 'selected' : null)}}{{:helper.link('Off', 'close', {'dryingOff' : 1}, data.drying ? null : 'selected')}} -
- {{/if}} -
-
- {{if data.contents}} - {{for data.contents}} -
- {{:value.display_name}} ({{:value.quantity}} available) -
Vend: 
{{:helper.link('x1', 'arrow-circle-down', { "vend" : value.vend, "amount" : 1 }, null, 'statusValue')}} - {{if value.quantity >= 5}} - {{:helper.link('x5', 'arrow-circle-down', { "vend" : value.vend, "amount" : 5 }, null, 'statusValue')}} - {{/if}} - {{if value.quantity >= 10}} - {{:helper.link('x10', 'arrow-circle-down', { "vend" : value.vend, "amount" : 10 }, null, 'statusValue')}} - {{/if}} - {{if value.quantity >= 25}} - {{:helper.link('x25', 'arrow-circle-down', { "vend" : value.vend, "amount" : 25 }, null, 'statusValue')}} - {{/if}} - {{if value.quantity > 1}} - {{:helper.link('All', 'arrow-circle-down', { "vend" : value.vend, "amount" : value.quantity }, null, 'statusValue')}} - {{/if}} -
- {{/for}} - {{else}} - No products loaded. - {{/if}} -
diff --git a/nano/templates/solar_control.tmpl b/nano/templates/solar_control.tmpl deleted file mode 100644 index f4fbf6ea739..00000000000 --- a/nano/templates/solar_control.tmpl +++ /dev/null @@ -1,96 +0,0 @@ - - -

Status

-
-
-
- Generated power: -
-
- {{:helper.smoothRound(data.generated)}} W -
-
- -
-
- Orientation: -
- -
- {{:helper.smoothRound(data.angle)}}° ({{:data.direction}})  -
- - {{:helper.link('15°', 'minus', {'rate_control' : '1', 'cdir' : '-15'})}} - {{:helper.link('1°', 'minus', {'rate_control' : '1', 'cdir' : '-1'})}} - {{:helper.link('1°', 'plus', {'rate_control' : '1', 'cdir' : '1'})}} - {{:helper.link('15°', 'plus', {'rate_control' : '1', 'cdir' : '15'})}} -
-
- -

Tracking

-
-
-
- Tracker status: -
- - {{:helper.link('Off', 'close', {'track' : '0'}, (data.tracking_state == 0) ? 'selected' : '')}} - {{:helper.link('Timed', 'clock-o', {'track' : '1'}, (data.tracking_state == 1) ? 'selected' : '')}} - {{if data.connected_tracker}} - {{:helper.link('Auto', 'signal', {'track' : '2'}, (data.tracking_state == 2) ? 'selected' : '')}} - {{else}} - {{:helper.link('Auto', 'signal', null, 'disabled')}} - {{/if}} -
- -
-
- Tracking rate: -
- -
- {{:helper.smoothRound(data.tracking_rate)}} deg/h ({{:data.rotating_way}}) -
-
- -
- {{:helper.link('180°', 'minus', {'rate_control' : '1', 'tdir' : '-180'})}} - {{:helper.link('30°', 'minus', {'rate_control' : '1', 'tdir' : '-30'})}} - {{:helper.link('1°', 'minus', {'rate_control' : '1', 'tdir' : '-1'})}} - {{:helper.link('1°', 'plus', {'rate_control' : '1', 'tdir' : '1'})}} - {{:helper.link('30°', 'plus', {'rate_control' : '1', 'tdir' : '30'})}} - {{:helper.link('180°', 'plus', {'rate_control' : '1', 'tdir' : '180'})}} -
-
- -

Connected Devices

-
-
-
- Solars panels: -
-
- {{:data.connected_panels}} connected -
-
- -
-
- Solar tracker: -
- -
- {{if data.connected_tracker}} - Found - {{else}} - Not Found - {{/if}} -
-
-
-
- {{:helper.link('Search for devices', 'refresh', {'search_connected' : '1'})}} -
diff --git a/nano/templates/spawners_menu.tmpl b/nano/templates/spawners_menu.tmpl deleted file mode 100644 index c12490bbb60..00000000000 --- a/nano/templates/spawners_menu.tmpl +++ /dev/null @@ -1,20 +0,0 @@ -
-

Mob Spawners

- - {{for data.spawners}} -
-
-

{{:value.name}}

-

{{:value.amount_left}} spawners left.

-
-
- {{:value.desc}} -
-
- {{:helper.link('Jump', null, {'action': 'jump', 'uid': value.uids}, null)}} - {{:helper.link('Spawn', null, {'action': 'spawn', 'uid': value.uids}, value.amount_left > 0 ? null : 'disabled')}} -
-
- {{/for}} -
-
diff --git a/nano/templates/supermatter_monitor.tmpl b/nano/templates/supermatter_monitor.tmpl deleted file mode 100644 index 3bc87984d79..00000000000 --- a/nano/templates/supermatter_monitor.tmpl +++ /dev/null @@ -1,111 +0,0 @@ -{{if data.active}} - {{:helper.link('Back to Menu', null, {'clear' : 1})}}
-
-
- Core Integrity: -
-
- {{:helper.displayBar(data.SM_integrity, 0, 100, (data.SM_integrity == 100) ? 'good' : (data.SM_integrity >= 50) ? 'average' : 'bad')}} {{:data.SM_integrity}}% -
-
- Relative EER: -
-
- {{if data.SM_power > 300}} - {{:data.SM_power}} MeV/cm3 - {{else data.SM_power > 150}} - {{:data.SM_power}} MeV/cm3 - {{else}} - {{:data.SM_power}} MeV/cm3 - {{/if}} -
-
- Temperature: -
-
- {{if data.SM_ambienttemp > 5000}} - {{:data.SM_ambienttemp}} K - {{else data.SM_ambienttemp > 4000}} - {{:data.SM_ambienttemp}} K - {{else}} - {{:data.SM_ambienttemp}} K - {{/if}} -
-
- Pressure: -
-
- {{if data.SM_ambientpressure > 10000}} - {{:data.SM_ambientpressure}} kPa - {{else data.SM_ambientpressure > 5000}} - {{:data.SM_ambientpressure}} kPa - {{else}} - {{:data.SM_ambientpressure}} kPa - {{/if}} -
-
-

-
- Gas Composition: -
-
-
-
- O2: -
-
- {{:data.SM_gas_O2}} % -
-
- CO2: -
-
- {{:data.SM_gas_CO2}} % -
-
- N2: -
-
- {{:data.SM_gas_N2}} % -
-
- PL: -
-
- {{:data.SM_gas_PL}} % -
-
- OTHER: -
-
- {{:data.SM_gas_OTHER}} % -
-
-
- -{{else}} - {{:helper.link('Refresh', null, {'refresh' : 1})}}
- {{for data.supermatters}} -
-
- Area: -
-
- {{:value.area_name}} -
-
- Integrity: -
-
- {{:value.integrity}} % -
-
- Options: -
-
- {{:helper.link('View Details', null, {'set' : value.uid})}} -
-
- {{/for}} -{{/if}} diff --git a/nano/templates/teleporter_console.tmpl b/nano/templates/teleporter_console.tmpl deleted file mode 100644 index 026917eb8ef..00000000000 --- a/nano/templates/teleporter_console.tmpl +++ /dev/null @@ -1,36 +0,0 @@ - -

Teleporter Status

-{{if !data.powerstation}} -
No power station linked.
-{{else !data.teleporterhub}} -
No hub linked.
-{{else}} -
-
-
Current Regime
-
{{:data.regime}}
-
-
-
Current Target
-
{{:data.target}}{{if data.target != "None"}}{{if data.regime == "Gate"}} Teleporter{{/if}}{{/if}}
-
-
-
Calibration
-
{{if data.calibrating}}In Progress{{else data.calibrated}}Optimal{{else data.accurate > 2}}Optimal{{else}}Sub-Optimal{{/if}}
-
-
-
-
{{:helper.link('Change regime', 'gear', {'regimeset': 1})}}
-
{{:helper.link('Set target', 'gear', {'settarget': 1})}}
-
-
-
{{:helper.link('Get target from memory', 'arrow-circle-down', {'lock': 1}, data.locked ? '' : 'disabled')}}
-
{{:helper.link('Eject GPS device', 'eject', {'eject': 1}, data.locked ? '' : 'disabled')}}
-
-
-
{{:helper.link('Calibrate hub', 'arrows-alt', {'calibrate': 1}, data.target == 'None' ? 'disabled' : '')}}
-
-{{/if}} \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 4a5c6350f91..51c6c3e8103 100644 --- a/paradise.dme +++ b/paradise.dme @@ -50,6 +50,7 @@ #include "code\__DEFINES\lighting.dm" #include "code\__DEFINES\logs.dm" #include "code\__DEFINES\machines.dm" +#include "code\__DEFINES\martial_arts.dm" #include "code\__DEFINES\math.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\mecha.dm" @@ -174,10 +175,6 @@ #include "code\ATMOSPHERICS\components\binary_devices\pump.dm" #include "code\ATMOSPHERICS\components\binary_devices\valve.dm" #include "code\ATMOSPHERICS\components\binary_devices\volume_pump.dm" -#include "code\ATMOSPHERICS\components\omni_devices\_omni_extras.dm" -#include "code\ATMOSPHERICS\components\omni_devices\filter.dm" -#include "code\ATMOSPHERICS\components\omni_devices\mixer.dm" -#include "code\ATMOSPHERICS\components\omni_devices\omni_base.dm" #include "code\ATMOSPHERICS\components\trinary_devices\filter.dm" #include "code\ATMOSPHERICS\components\trinary_devices\mixer.dm" #include "code\ATMOSPHERICS\components\trinary_devices\trinary_base.dm" @@ -218,6 +215,7 @@ #include "code\controllers\subsystem\assets.dm" #include "code\controllers\subsystem\atoms.dm" #include "code\controllers\subsystem\changelog.dm" +#include "code\controllers\subsystem\cleanup.dm" #include "code\controllers\subsystem\events.dm" #include "code\controllers\subsystem\fires.dm" #include "code\controllers\subsystem\garbage.dm" @@ -1666,7 +1664,28 @@ #include "code\modules\martial_arts\mimejutsu.dm" #include "code\modules\martial_arts\plasma_fist.dm" #include "code\modules\martial_arts\sleeping_carp.dm" -#include "code\modules\martial_arts\wrestleing.dm" +#include "code\modules\martial_arts\wrestling.dm" +#include "code\modules\martial_arts\combos\martial_combo.dm" +#include "code\modules\martial_arts\combos\adminfu\healing_palm.dm" +#include "code\modules\martial_arts\combos\cqc\consecutive.dm" +#include "code\modules\martial_arts\combos\cqc\kick.dm" +#include "code\modules\martial_arts\combos\cqc\pressure.dm" +#include "code\modules\martial_arts\combos\cqc\restrain.dm" +#include "code\modules\martial_arts\combos\cqc\slam.dm" +#include "code\modules\martial_arts\combos\krav_maga\leg_sweep.dm" +#include "code\modules\martial_arts\combos\krav_maga\lung_punch.dm" +#include "code\modules\martial_arts\combos\krav_maga\neck_chop.dm" +#include "code\modules\martial_arts\combos\mimejutsu\mimechucks.dm" +#include "code\modules\martial_arts\combos\mimejutsu\silent_palm.dm" +#include "code\modules\martial_arts\combos\mimejutsu\smokebomb.dm" +#include "code\modules\martial_arts\combos\plasma_fist\plasma_fist.dm" +#include "code\modules\martial_arts\combos\plasma_fist\throwback.dm" +#include "code\modules\martial_arts\combos\plasma_fist\tornado_sweep.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\back_kick.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\elbow_drop.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\head_kick.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\stomach_knee.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\wrist_wrench.dm" #include "code\modules\mining\abandonedcrates.dm" #include "code\modules\mining\fulton.dm" #include "code\modules\mining\machine_processing.dm" @@ -2060,50 +2079,6 @@ #include "code\modules\mob\new_player\sprite_accessories\vulpkanin\vulpkanin_head_markings.dm" #include "code\modules\mob\new_player\sprite_accessories\vulpkanin\vulpkanin_tail_markings.dm" #include "code\modules\mob\new_player\sprite_accessories\wryn\wryn_face.dm" -#include "code\modules\modular_computers\laptop_vendor.dm" -#include "code\modules\modular_computers\computers\item\computer.dm" -#include "code\modules\modular_computers\computers\item\computer_components.dm" -#include "code\modules\modular_computers\computers\item\computer_damage.dm" -#include "code\modules\modular_computers\computers\item\computer_power.dm" -#include "code\modules\modular_computers\computers\item\computer_ui.dm" -#include "code\modules\modular_computers\computers\item\laptop.dm" -#include "code\modules\modular_computers\computers\item\laptop_presets.dm" -#include "code\modules\modular_computers\computers\item\processor.dm" -#include "code\modules\modular_computers\computers\item\tablet.dm" -#include "code\modules\modular_computers\computers\item\tablet_presets.dm" -#include "code\modules\modular_computers\computers\machinery\console_presets.dm" -#include "code\modules\modular_computers\computers\machinery\modular_computer.dm" -#include "code\modules\modular_computers\computers\machinery\modular_console.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\program.dm" -#include "code\modules\modular_computers\file_system\program_events.dm" -#include "code\modules\modular_computers\file_system\programs\antagonist\dos.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\comms.dm" -#include "code\modules\modular_computers\file_system\programs\engineering\power_monitor.dm" -#include "code\modules\modular_computers\file_system\programs\engineering\sm_monitor.dm" -#include "code\modules\modular_computers\file_system\programs\generic\configurator.dm" -#include "code\modules\modular_computers\file_system\programs\generic\file_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\research\airestorer.dm" -#include "code\modules\modular_computers\file_system\programs\research\ntmonitor.dm" -#include "code\modules\modular_computers\hardware\_hardware.dm" -#include "code\modules\modular_computers\hardware\ai_slot.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\CPU.dm" -#include "code\modules\modular_computers\hardware\hard_drive.dm" -#include "code\modules\modular_computers\hardware\network_card.dm" -#include "code\modules\modular_computers\hardware\portable_disk.dm" -#include "code\modules\modular_computers\hardware\printer.dm" -#include "code\modules\modular_computers\hardware\recharger.dm" -#include "code\modules\modular_computers\NTNet\NTNet.dm" -#include "code\modules\modular_computers\NTNet\NTNet_relay.dm" -#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm" #include "code\modules\nano\nanoexternal.dm" #include "code\modules\nano\nanoui.dm" #include "code\modules\nano\subsystem.dm" @@ -2120,7 +2095,6 @@ #include "code\modules\nano\interaction\self.dm" #include "code\modules\nano\interaction\zlevel.dm" #include "code\modules\nano\modules\atmos_control.dm" -#include "code\modules\nano\modules\ert_manager.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" @@ -2325,7 +2299,6 @@ #include "code\modules\research\designs\biogenerator_designs.dm" #include "code\modules\research\designs\bluespace_designs.dm" #include "code\modules\research\designs\comp_board_designs.dm" -#include "code\modules\research\designs\computer_part_designs.dm" #include "code\modules\research\designs\equipment_designs.dm" #include "code\modules\research\designs\janitorial_designs.dm" #include "code\modules\research\designs\machine_designs.dm" @@ -2460,6 +2433,7 @@ #include "code\modules\tgui\tgui.dm" #include "code\modules\tgui\modules\_base.dm" #include "code\modules\tgui\modules\crew_monitor.dm" +#include "code\modules\tgui\modules\ert_manager.dm" #include "code\modules\tgui\states\admin.dm" #include "code\modules\tgui\states\always.dm" #include "code\modules\tgui\states\conscious.dm" diff --git a/sound/AI/apc_overload.ogg b/sound/AI/apc_overload.ogg deleted file mode 100644 index ef9357b9eb6..00000000000 Binary files a/sound/AI/apc_overload.ogg and /dev/null differ diff --git a/sound/AI/apc_short.ogg b/sound/AI/apc_short.ogg deleted file mode 100644 index 90afc50f6fb..00000000000 Binary files a/sound/AI/apc_short.ogg and /dev/null differ diff --git a/sound/weapons/jug_empty_impact.ogg b/sound/weapons/jug_empty_impact.ogg new file mode 100644 index 00000000000..d78c1c5e554 Binary files /dev/null and b/sound/weapons/jug_empty_impact.ogg differ diff --git a/sound/weapons/jug_filled_impact.ogg b/sound/weapons/jug_filled_impact.ogg new file mode 100644 index 00000000000..05e2d364373 Binary files /dev/null and b/sound/weapons/jug_filled_impact.ogg differ diff --git a/strings/tips.txt b/strings/tips.txt index 4218e01bbfe..d28943913d3 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -23,7 +23,6 @@ If you find yourself in a fistfight with another player, running away and callin Different weapons have different strengths. Some weapons, such as spears, floor tiles, and throwing stars, deal more damage when thrown compared to when attacked normally. Clicking on a tile on harm intent with a glass of water can make a slippery tile, allowing you to slow down your pursuers in a pinch. When dealing with security, you can often get your sentence negated entirely through cooperation and deception. -The P2P chat function found on tablet computers allows for a stealthy way to communicate with people. We were all new once, be patient and guide new players in the right direction. On most clothing items that go in the exosuit slot, you can put certain small items into your suit storage, such as a spraycan, your emergency oxygen tank, or a flashlight. Most job-related exosuit clothing can fit job-related items into it. For example, the atmospheric technician's hardsuit/winter coat can hold an RPD, and labcoats can hold most medicine. @@ -68,7 +67,7 @@ As a Medical Cyborg, you can partially perform surgery, as you cannot replace or As a Janitor Cyborg, you are the bane of all slaughter demons. Cleaning up blood stains will severely gimp them. As the Chief Engineer, you can rename areas or create entirely new ones using your station blueprints. As the Chief Engineer, your hardsuit is significantly better than everybody else's. It has the best features of both engineering and atmospherics hardsuits, boasting nigh-invulnerability to radiation and all atmospheric conditions. -As the Chief Engineer, the power flow control console in your office will show you APC infos and lets you control them remotely. +As the Chief Engineer, the power flow control console in your office will show you APC infos and lets you control them remotely. As an Engineer, you can electrify grilles by placing wire "nodes" beneath them: the big seemingly unconnected bulges from a half completed wiring job. The wire will be need to be connected to an active power source in order to function. As an Engineer, return to Engineering once in a while to check on the engine and SMES cells. It's always a good idea to make sure containment isn't compromised. As an Engineer, you can power the station solely with the solar arrays. They will provide just enough electricity to power the station, however their output is still much worse compared to the true engine. @@ -86,7 +85,7 @@ As the Head of Security, don't let the power go to your head. You may have high As the Warden, your duty is to be the watchdog of the brig and handler of prisoners when little is happening, and to hand out equipment and weapons to the security officers when a crisis strikes. As the Warden, keep a close eye on the armory at all times, as it is a favored strike point of nuclear operatives and cocky traitors. As the Warden, if a prisoner's crimes are heinous enough you can put them in permabrig or the gulag. Make sure to check on them once in a while! -As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals. +As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals. As a Security Officer, communicate and coordinate with your fellow officers using the security channel (:s) to avoid confusion. As a Security Officer, your sechuds or HUDsunglasses let you see crewmates' job assignments, their criminal status, and whether they have a mindshield or not. A flashing green border around their job icon means they are mindshielded. As a Security Officer, mindshield implants can only prevent someone from being turned into a cultist. It will not de-cult them if they have already been converted. @@ -98,7 +97,6 @@ As the IAA, try to negotiate with the Warden if sentences seem too high for the As the IAA, you can try to convince the Captain and Head of Security to hold trials for prisoners in the courtroom. As the Head of Personnel, you are not higher ranking than other heads of staff, even though you are expected to take the Captain's place first should he go missing. If the situation seems too rough for you, consider allowing another head to become temporary Captain. As the Head of Personnel, you are just as large a target as the Captain because of the potential power your ID and computer can hand out. -As the Head of Personnel, consider getting a laptop with an ID slot. It allows you to do your job even when out of your office. As the Mime, your invisible wall power blocks people as well as projectiles. You can use it in a pinch to delay your pursuer. As the Mime, your oath of silence is your source of power. Breaking it robs you of your powers and of your honor. As the Clown, if you lose your banana peel, you can still slip people with your PDA! Honk! @@ -178,7 +176,7 @@ As a Swarmer, you can teleport fellow swarmers away if you think they are in dan As a Ghost, you can double click on just about anything to follow it. Or just warp around! As a Devil, you gain power for every three souls you control, however you also become more obvious. As a Devil, as long as you control at least one other soul, you will automatically resurrect, as long as a banishment ritual is not performed. -At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. +At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. As a Security Officer, remember that correlation does not equal causation. Someone may have just been at the wrong place at the wrong time! As a Security Officer, remember that you can attach a sec-lite to your taser! As a Terror Spider, leave wrapping of corpses to green spiders unless absolutely necessary. They need it to lay eggs! diff --git a/tgui/packages/tgui/components/NanoMap.js b/tgui/packages/tgui/components/NanoMap.js index cca06ea4e9d..6c4d8c48b16 100644 --- a/tgui/packages/tgui/components/NanoMap.js +++ b/tgui/packages/tgui/components/NanoMap.js @@ -1,45 +1,179 @@ +import { Component } from 'inferno'; import { Box, Icon, Tooltip } from '.'; import { useBackend } from "../backend"; +import { LabeledList } from './LabeledList'; +import { Slider } from './Slider'; -export const NanoMap = (props, context) => { - const { config } = useBackend(context); - const { onClick } = props; - return ( - - - - ); +const pauseEvent = e => { + if (e.stopPropagation) { e.stopPropagation(); } + if (e.preventDefault) { e.preventDefault(); } + e.cancelBubble = true; + e.returnValue = false; + return false; }; -const NanoMapMarker = props => { +export class NanoMap extends Component { + constructor(props) { + super(props); + + // Auto center based on window size + const Xcenter = (window.innerWidth / 2) - 256; + const Ycenter = (window.innerHeight / 2) - 256; + + this.state = { + offsetX: 128, + offsetY: 48, + transform: 'none', + dragging: false, + originX: null, + originY: null, + zoom: 1, + }; + + // Dragging + this.handleDragStart = e => { + this.ref = e.target; + this.setState({ + dragging: false, + originX: e.screenX, + originY: e.screenY, + }); + document.addEventListener('mousemove', this.handleDragMove); + document.addEventListener('mouseup', this.handleDragEnd); + pauseEvent(e); + }; + + this.handleDragMove = e => { + this.setState(prevState => { + const state = { ...prevState }; + const newOffsetX = e.screenX - state.originX; + const newOffsetY = e.screenY - state.originY; + if (prevState.dragging) { + state.offsetX += newOffsetX; + state.offsetY += newOffsetY; + state.originX = e.screenX; + state.originY = e.screenY; + } else { + state.dragging = true; + } + return state; + }); + pauseEvent(e); + }; + + this.handleDragEnd = e => { + this.setState({ + dragging: false, + originX: null, + originY: null, + }); + document.removeEventListener('mousemove', this.handleDragMove); + document.removeEventListener('mouseup', this.handleDragEnd); + pauseEvent(e); + }; + + this.handleZoom = (_e, value) => { + this.setState(state => { + const newZoom = Math.min(Math.max(value, 1), 8); + let zoomDiff = (newZoom - state.zoom) * 1.5; + state.zoom = newZoom; + state.offsetX = state.offsetX - 262 * zoomDiff; + state.offsetY = state.offsetY - 256 * zoomDiff; + if (props.onZoom) { + props.onZoom(state.zoom); + } + return state; + }); + }; + + } + + render() { + const { config } = useBackend(this.context); + const { dragging, offsetX, offsetY, zoom = 1 } = this.state; + const { children } = this.props; + + const mapUrl = config.map + "_nanomap_z1.png"; + const mapSize = (510 * zoom) + 'px'; + const newStyle = { + width: mapSize, + height: mapSize, + "margin-top": offsetY + "px", + "margin-left": offsetX + "px", + "overflow": "hidden", + "position": "relative", + "background-image": "url(" + mapUrl + ")", + "background-size": "cover", + "background-repeat": "no-repeat", + "text-align": "center", + "cursor": dragging ? "move" : "auto", + }; + + return ( + + + + {children} + + + + + ); + } +} + +const NanoMapMarker = (props, context) => { const { x, y, + zoom = 1, icon, tooltip, color, } = props; + const rx = ((x * 2 * zoom) - zoom) - 3; + const ry = ((y * 2 * zoom) - zoom) - 3; return ( - - - - +
+ + + + +
); }; NanoMap.Marker = NanoMapMarker; + +const NanoMapZoomer = (props, context) => { + return ( + + + + v + "x"} + value={props.zoom} + onDrag={(e, v) => props.onZoom(e, v)} + /> + + + + ); +}; + +NanoMap.Zoomer = NanoMapZoomer; diff --git a/tgui/packages/tgui/constants.js b/tgui/packages/tgui/constants.js index 94f32cd2697..024278e39b3 100644 --- a/tgui/packages/tgui/constants.js +++ b/tgui/packages/tgui/constants.js @@ -104,6 +104,11 @@ export const RADIO_CHANNELS = [ freq: 1355, color: '#57b8f0', }, + { + name: 'Medical(I)', + freq: 1485, + color: '#57b8f0', + }, { name: 'Engineering', freq: 1357, @@ -114,6 +119,11 @@ export const RADIO_CHANNELS = [ freq: 1359, color: '#dd3535', }, + { + name: 'Security(I)', + freq: 1475, + color: '#dd3535', + }, { name: 'AI Private', freq: 1343, diff --git a/tgui/packages/tgui/interfaces/AICard.js b/tgui/packages/tgui/interfaces/AICard.js new file mode 100644 index 00000000000..8ffe9906e2c --- /dev/null +++ b/tgui/packages/tgui/interfaces/AICard.js @@ -0,0 +1,94 @@ +import { useBackend } from "../backend"; +import { Button, ProgressBar, LabeledList, Box, Section } from "../components"; +import { Window } from "../layouts"; + +export const AICard = (props, context) => { + const { act, data } = useBackend(context); + if (data.has_ai === 0) { + return ( + + +
+ +

No AI detected.

+
+
+
+
+ ); + } else { + + let integrityColor = null; // Handles changing color of the integrity bar + if (data.integrity >= 75) { integrityColor = 'green'; } + else if (data.integrity >= 25) { integrityColor = 'yellow'; } + else { integrityColor = 'red'; } + + return ( + + +
+ +

{data.name}

+
+ + + + + + + + +

{data.flushing === 1 ? "Wipe of AI in progress..." : ""}

+
+
+ +
+ {!!data.has_laws && ( + + {data.laws.map((value, key) => ( + + {value} + + ))} + + ) || ( // Else, no laws. + +

No laws detected.

+
+ )} +
+ +
+ + +
+
+
+ ); + } +}; diff --git a/tgui/packages/tgui/interfaces/AIFixer.js b/tgui/packages/tgui/interfaces/AIFixer.js new file mode 100644 index 00000000000..7a7d65101d5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AIFixer.js @@ -0,0 +1,110 @@ +import { useBackend } from "../backend"; +import { Button, ProgressBar, Box, LabeledList, Section } from "../components"; +import { Window } from "../layouts"; + +export const AIFixer = (props, context) => { + const { act, data } = useBackend(context); + if (data.occupant === null) { + return ( + + +
+ +

No artificial intelligence detected.

+
+
+
+
+ ); + } else { + + let workingAI = null; // If the AI is dead (stat = 2) or isn't existent + if (data.stat === 2 || data.stat === null) { + workingAI = false; + } else { + workingAI = true; + } + + let integrityColor = null; // Handles changing color of the integrity bar + if (data.integrity >= 75) { integrityColor = 'green'; } + else if (data.integrity >= 25) { integrityColor = 'yellow'; } + else { integrityColor = 'red'; } + + let integrityFull = null; // If integrity >= 100, prevents overchar + if (data.integrity >= 100) { integrityFull = true; } + else { integrityFull = false; } + + + return ( + + +
+ +

{data.occupant}

+
+
+ +
+ + + + + + {workingAI ? "Functional" : "Non-Functional"} + + +
+ +
+ {!!data.has_laws && ( + + {data.laws.map((value, key) => ( + + {value} + + ))} + + ) || ( // Else, no laws. + +

No laws detected.

+
+ )} +
+ +
+ + +
+
+
+ ); + } +}; diff --git a/tgui/packages/tgui/interfaces/AtmosFilter.js b/tgui/packages/tgui/interfaces/AtmosFilter.js new file mode 100644 index 00000000000..37b99bfed7f --- /dev/null +++ b/tgui/packages/tgui/interfaces/AtmosFilter.js @@ -0,0 +1,70 @@ +import { useBackend } from "../backend"; +import { Button, Section, NumberInput, LabeledList } from "../components"; +import { Window } from "../layouts"; + +export const AtmosFilter = (props, context) => { + const { act, data } = useBackend(context); + const { + on, + pressure, + max_pressure, + filter_type, + filter_type_list, + } = data; + + return ( + + +
+ + +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/AtmosMixer.js b/tgui/packages/tgui/interfaces/AtmosMixer.js new file mode 100644 index 00000000000..66621ed8f78 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AtmosMixer.js @@ -0,0 +1,109 @@ +import { useBackend } from "../backend"; +import { Button, Section, NumberInput, LabeledList, Flex } from "../components"; +import { Window } from "../layouts"; + +export const AtmosMixer = (props, context) => { + const { act, data } = useBackend(context); + const { + on, + pressure, + max_pressure, + node1_concentration, + node2_concentration, + } = data; + + return ( + + +
+ + +
+
+
+ ); +}; + +const NodeControls = (props, context) => { + const { act, data } = useBackend(context); + const { + node_name, + node_ref, + } = props; + + return ( + + + {recipe.max_multiplier >= 10 && ( + + )} + {recipe.max_multiplier >= 25 && ( + + )} + {recipe.max_multiplier > 25 && ( + + )} + + + {recipe.requirements && ( + Object + .keys(recipe.requirements) + .map(mat => toTitleCase(mat) + + ": " + recipe.requirements[mat]) + .join(", ") + ) || ( + + No resources required. + + )} + + + ))} + + +
+
+ + + {metalReadable} + + + {glassReadable} + + + {totalReadable} + + + {data.fill_percent}% Full + + +
+
+ + {busyname ? busyname : "Nothing"} + +
+
+ {buildQueueItems} +
+
+
+
+ + + + ); +}; + + diff --git a/tgui/packages/tgui/interfaces/BodyScanner.js b/tgui/packages/tgui/interfaces/BodyScanner.js index 48a4a08e20f..9e24c62900f 100644 --- a/tgui/packages/tgui/interfaces/BodyScanner.js +++ b/tgui/packages/tgui/interfaces/BodyScanner.js @@ -113,16 +113,16 @@ const BodyScannerMainOccupant = (props, context) => { title="Occupant" buttons={( - + )}> diff --git a/tgui/packages/tgui/interfaces/BrigTimer.js b/tgui/packages/tgui/interfaces/BrigTimer.js new file mode 100644 index 00000000000..5895b333c9c --- /dev/null +++ b/tgui/packages/tgui/interfaces/BrigTimer.js @@ -0,0 +1,123 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, Dropdown, Box, Section } from '../components'; +import { Window } from '../layouts'; + +export const BrigTimer = (props, context) => { + const { act, data } = useBackend(context); + data.nameText = data.occupant; + if (data.timing) { + if (data.prisoner_hasrec) { + data.nameText = ({data.occupant}); + } else { + data.nameText = ({data.occupant}); + } + } + let nameIcon = "pencil-alt"; + if (data.prisoner_name) { + if (!data.prisoner_hasrec) { + nameIcon = "exclamation-triangle"; + } + } + let nameOptions = []; + let i = 0; + for (i = 0; i < data.spns.length; i++) { + nameOptions.push(data.spns[i]); + } + return ( + + +
+ + + {data.cell_id} + + + {data.nameText} + + + {data.crimes} + + + {data.brigged_by} + + + {data.time_set} + + + {data.time_left} + + + +
+ {!data.timing && ( +
+ + +
+ )} +
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/CardComputer.js b/tgui/packages/tgui/interfaces/CardComputer.js new file mode 100644 index 00000000000..7e460fe1869 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CardComputer.js @@ -0,0 +1,549 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, Box, Section, Table, Tabs } from '../components'; +import { Window } from '../layouts'; +import { AccessList } from './common/AccessList'; + +export const CardComputer = (props, context) => { + const { act, data } = useBackend(context); + + + let menuBlock = ( + + act("mode", { mode: 0 })} > + Job Transfers + + {!data.target_dept && ( + act("mode", { mode: 2 })} > + Access Modification + + )} + act("mode", { mode: 1 })}> + Job Management + + act("mode", { mode: 3 })}> + Records + + act("mode", { mode: 4 })}> + Department + + + ); + + + let authBlock = ( +
+ + +
+ ); + + let bodyBlock; + + switch (data.mode) { + case 0: // job transfer + if (!data.authenticated || !data.scan_name) { + bodyBlock = ( +
+ Not logged in. +
+ ); + } else if (!data.modify_name) { + bodyBlock = ( +
+ No card to modify. +
+ ); + } else if (data.target_dept) { + bodyBlock = ( +
+ + {!!data.modify_lastlog && ( + + {data.modify_lastlog} + + )} + + {data.jobs_dept.map(v => ( +
+ ); + } else { + bodyBlock = ( + +
+ +
+
+ + + {data.jobs_top.map(v => ( +
+
+ {data.card_skins.map(v => ( +
+
+ ); + } + break; + case 1: // job slot management + if (!data.authenticated || !data.scan_name) { + bodyBlock = ( +
+ Not logged in. +
+ ); + } else { + bodyBlock = ( + +
+ Next Change Available: + {data.cooldown_time ? data.cooldown_time : "Now"} +
+
+ + + + + Title + Used Slots + Total Slots + Free Slots + Close Slot + Open Slot + Priority + + {data.job_slots.map(slotData => ( + + + {slotData.title} + + + {slotData.current_positions} + + + {slotData.total_positions} + + + {slotData.total_positions + > slotData.current_positions && ( + + {slotData.total_positions + - slotData.current_positions} + + ) || ( + + 0 + + )} + + +
+
+
+ ); + } + break; + case 2: // access change + if (!data.authenticated || !data.scan_name) { + bodyBlock = ( +
+ Not logged in. +
+ ); + } else if (!data.modify_name) { + bodyBlock = ( +
+ No card to modify. +
+ ); + } else { + bodyBlock = ( + act('set', { + access: ref, + })} + grantAll={() => act('grant_all')} + denyAll={() => act('clear_all')} + grantDep={ref => act('grant_region', { + region: ref, + })} + denyDep={ref => act('deny_region', { + region: ref, + })} /> + ); + } + break; + case 3: // records + if (!data.authenticated) { + bodyBlock = ( +
+ Not logged in. +
+ ); + } else if (!data.records.length) { + bodyBlock = ( +
+ No records. +
+ ); + } else { + bodyBlock = ( +
act('wipe_all_logs')} /> + }> + + + Crewman + Old Rank + New Rank + Authorized By + Time + Reason + {!!data.iscentcom && ( + + Deleted By + + )} + + {data.records.map(record => ( + + {record.transferee} + {record.oldvalue} + {record.newvalue} + {record.whodidit} + {record.timestamp} + {record.reason} + {!!data.iscentcom && ( + + {record.deletedby} + + )} + + ))} +
+ {!!data.iscentcom && ( + +
+ ); + } + break; + case 4: // department + if (!data.authenticated || !data.scan_name) { + bodyBlock = ( +
+ Not logged in. +
+ ); + } else { + bodyBlock = ( +
+ + + Name + Rank + Sec Status + Actions + + {data.people_dept.map(record => ( + + {record.name} + {record.title} + {record.crimstat} + +
+
+ ); + } + break; + default: + bodyBlock = ( +
+ ERROR: Unknown Mode. +
+ ); + } + + return ( + + + {menuBlock} + {authBlock} + {bodyBlock} + + + ); + +}; diff --git a/tgui/packages/tgui/interfaces/CommunicationsComputer.js b/tgui/packages/tgui/interfaces/CommunicationsComputer.js new file mode 100644 index 00000000000..7e4cc98d438 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CommunicationsComputer.js @@ -0,0 +1,317 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, Box, Section } from '../components'; +import { Window } from '../layouts'; + +export const CommunicationsComputer = (props, context) => { + const { act, data } = useBackend(context); + + let authReadable; + if (!data.authenticated) { + authReadable = "Not Logged In"; + } else if (data.is_ai) { + authReadable = "AI"; + } else if (data.authenticated === 1) { + authReadable = "Command"; + } else if (data.authenticated === 2) { + authReadable = "Captain"; + } else { + authReadable = "ERROR: Report This Bug!"; + } + let reportText = "View (" + data.messages.length + ")"; + let authBlock = ( + +
+ + {data.is_ai && ( + + AI + + ) || ( + +
+ {!!data.esc_section && ( +
+ + {!!data.esc_status && ( + + {data.esc_status} + + )} + {!!data.esc_callable && ( + +
+ )} +
+ ); + let announceText = "Make Priority Announcement"; + if (data.msg_cooldown > 0) { + announceText += " (" + data.msg_cooldown + "s)"; + } + let ccMessageText = data.emagged ? "Message [UNKNOWN]" : "Message CentComm"; + let nukeRequestText = "Request Authentication Codes"; + if (data.cc_cooldown > 0) { + ccMessageText += " (" + data.cc_cooldown + "s)"; + nukeRequestText += " (" + data.cc_cooldown + "s)"; + } + let alertLevelText = data.str_security_level; + let alertLevelButtons = data.levels.map(slevel => { + return ( + + }> + + + Tank Label: + + + {holding_tank.name} + + + + + Tank Pressure: + + + + {holding_tank.tank_pressure} kPa + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/Radio.js b/tgui/packages/tgui/interfaces/Radio.js index b264254c0d7..957055b5c31 100644 --- a/tgui/packages/tgui/interfaces/Radio.js +++ b/tgui/packages/tgui/interfaces/Radio.js @@ -27,13 +27,17 @@ export const Radio = (props, context) => { rc = RADIO_CHANNELS[i]; colorMap[rc["name"]] = rc["color"]; } - const channels = map((value, key) => ({ + const schannels = map((value, key) => ({ name: key, status: !!value, - }))(data.channels); + }))(data.schannels); + const ichannels = map((value, key) => ({ + name: key, + freq: value, + }))(data.ichannels); return ( - - + +
@@ -99,27 +103,38 @@ export const Radio = (props, context) => { onClick={() => act('loudspeaker')} /> )} - - {channels.length === 0 && ( - - No encryption keys installed. - - )} - {channels.map(channel => ( - -
diff --git a/tgui/packages/tgui/interfaces/Smartfridge.js b/tgui/packages/tgui/interfaces/Smartfridge.js new file mode 100644 index 00000000000..fbd044d0179 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Smartfridge.js @@ -0,0 +1,75 @@ +import { useBackend } from '../backend'; +import { Box, Section, Button, NumberInput, Flex, NoticeBox } from '../components'; +import { Window } from '../layouts'; + +export const Smartfridge = (props, context) => { + const { act, data } = useBackend(context); + const { + secure, // secure fridge notice + can_dry, // dry section + drying, // drying rack on/off. + contents, + } = data; + return ( + + + {!!secure && ( +
+ + Secure Access: Please have your identification ready. + +
+ )} + {!!can_dry && ( +
+
+ )} +
+ {!contents && ( + No products loaded. + )} + {!!contents && contents.map(item => { + return ( + + + {item.display_name} + + + ({item.quantity} in stock) + + +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/SolarControl.js b/tgui/packages/tgui/interfaces/SolarControl.js new file mode 100644 index 00000000000..39687492cff --- /dev/null +++ b/tgui/packages/tgui/interfaces/SolarControl.js @@ -0,0 +1,142 @@ +import { useBackend } from '../backend'; +import { Box, Button, Grid, LabeledList, NumberInput, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; + +export const SolarControl = (props, context) => { + const { act, data } = useBackend(context); + const TRACKER_OFF = 0; + const TRACKER_TIMED = 1; + const TRACKER_AUTO = 2; + const { + generated, + generated_ratio, + tracking_state, + tracking_rate, + connected_panels, + connected_tracker, + cdir, + direction, + rotating_direction, + } = data; + return ( + + +
act('refresh')} /> + )}> + + + + + {connected_tracker ? 'OK' : 'N/A'} + + 0 ? 'good' : 'bad'}> + {connected_panels} + + + + + + + + {generated + ' W'} + + + + {cdir}° ({direction}) + + + {(tracking_state === TRACKER_AUTO + && Automated + )} + {(tracking_state === TRACKER_TIMED + && {tracking_rate}°/h ({rotating_direction}) + )} + {(tracking_state === TRACKER_OFF + && Tracker offline + )} + + + + +
+
+ + + {tracking_state !== TRACKER_AUTO + && act('cdir', { cdir })} + />} + {(tracking_state === TRACKER_AUTO + && Automated + )} + + +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/SpawnersMenu.js b/tgui/packages/tgui/interfaces/SpawnersMenu.js new file mode 100644 index 00000000000..63e9d9fa5ba --- /dev/null +++ b/tgui/packages/tgui/interfaces/SpawnersMenu.js @@ -0,0 +1,66 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Section } from '../components'; +import { Window } from '../layouts'; + +export const SpawnersMenu = (props, context) => { + const { act, data } = useBackend(context); + const spawners = data.spawners || []; + return ( + + +
+ {spawners.map(spawner => ( +
+
+ ))} +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/Teleporter.js b/tgui/packages/tgui/interfaces/Teleporter.js new file mode 100644 index 00000000000..8bdff77017a --- /dev/null +++ b/tgui/packages/tgui/interfaces/Teleporter.js @@ -0,0 +1,167 @@ +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, Section, Grid, Dropdown, Flex } from '../components'; +import { Window } from '../layouts'; +import { GridColumn } from '../components/Grid'; + +export const Teleporter = (props, context) => { + const { act, data } = useBackend(context); + let targetsTeleport = data.targetsTeleport ? data.targetsTeleport : {}; + const REGIME_TELEPORT = 0; + const REGIME_GATE = 1; + const REGIME_GPS = 2; + const { + calibrated, + calibrating, + powerstation, + regime, + teleporterhub, + target, + locked, + } = data; + return ( + + + {(!powerstation || !teleporterhub) + && ( +
+ {teleporterhub} + {!powerstation + && ( + Powerstation not linked + )} + {powerstation && !teleporterhub + && ( + Teleporter hub not linked + )} +
+ )} + {(powerstation && teleporterhub) + && ( +
+ + + + + + + + {/* The duplication of the dropdowns is due to the + updates of selected not affecting the state + of the dropdown */} + {regime === REGIME_TELEPORT && ( + act('settarget', + { + x: targetsTeleport[val]["x"], + y: targetsTeleport[val]["y"], + z: targetsTeleport[val]["z"], + })} /> + )} + {regime === REGIME_GATE && ( + act('settarget', + { + x: targetsTeleport[val]["x"], + y: targetsTeleport[val]["y"], + z: targetsTeleport[val]["z"], + })} /> + )} + {regime === REGIME_GPS && ( + + {target} + + )} + + + {target !== 'None' + && ( + + + {calibrating + && ( + + In Progress + + ) || (calibrated + && ( + + Optimal + + ) || ( + + Sub-Optimal + + ))} + + + +
+ )} + {!!(locked && powerstation && teleporterhub && regime === REGIME_GPS) + && ( +
+ +
+ )} +
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/common/ComplexModal.js b/tgui/packages/tgui/interfaces/common/ComplexModal.js index b5420443b2e..0bc6804752c 100644 --- a/tgui/packages/tgui/interfaces/common/ComplexModal.js +++ b/tgui/packages/tgui/interfaces/common/ComplexModal.js @@ -187,7 +187,8 @@ export const ComplexModal = (props, context) => { maxWidth={props.maxWidth || (window.innerWidth / 2 + "px")} maxHeight={props.maxHeight || (window.innerHeight / 2 + "px")} onEnter={modalOnEnter} - mx="auto"> + mx="auto" + overflowY="auto"> {text} diff --git a/tgui/packages/tgui/public/tgui.bundle.css b/tgui/packages/tgui/public/tgui.bundle.css index aeae1dbae77..5bf98af8530 100644 --- a/tgui/packages/tgui/public/tgui.bundle.css +++ b/tgui/packages/tgui/public/tgui.bundle.css @@ -1 +1 @@ -body,html{box-sizing:border-box;height:100%;margin:0;font-size:12px}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4,h5,h6{display:block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}td,th{vertical-align:baseline;text-align:left}.candystripe:nth-child(odd){background-color:rgba(0,0,0,.25)}.color-black{color:#0d0d0d!important}.color-white{color:#fff!important}.color-red{color:#d33!important}.color-orange{color:#f37827!important}.color-yellow{color:#fbd814!important}.color-olive{color:#c0d919!important}.color-green{color:#22be47!important}.color-teal{color:#00c5bd!important}.color-blue{color:#238cdc!important}.color-violet{color:#6c3fcc!important}.color-purple{color:#a93bcd!important}.color-pink{color:#e2439c!important}.color-brown{color:#af6d43!important}.color-grey{color:#7d7d7d!important}.color-good{color:#62b62a!important}.color-average{color:#f1951d!important}.color-bad{color:#d33!important}.color-label{color:#8496ab!important}.color-bg-black{background-color:#000!important}.color-bg-white{background-color:#d9d9d9!important}.color-bg-red{background-color:#bd2020!important}.color-bg-orange{background-color:#d95e0c!important}.color-bg-yellow{background-color:#d9b804!important}.color-bg-olive{background-color:#9aad14!important}.color-bg-green{background-color:#1b9638!important}.color-bg-teal{background-color:#009a93!important}.color-bg-blue{background-color:#1c71b1!important}.color-bg-violet{background-color:#552dab!important}.color-bg-purple{background-color:#8b2baa!important}.color-bg-pink{background-color:#cf2082!important}.color-bg-brown{background-color:#8c5836!important}.color-bg-grey{background-color:#646464!important}.color-bg-good{background-color:#4d9121!important}.color-bg-average{background-color:#cd7a0d!important}.color-bg-bad{background-color:#bd2020!important}.color-bg-label{background-color:#657a94!important}.debug-layout,.debug-layout :not(g):not(path){color:hsla(0,0%,100%,.9)!important;background:transparent!important;outline:1px solid hsla(0,0%,100%,.5)!important;box-shadow:none!important;filter:none!important}.debug-layout:hover,.debug-layout :not(g):not(path):hover{outline-color:hsla(0,0%,100%,.8)!important}.display-none{display:none}.display-block{display:block}.display-inline{display:inline}.display-inline-block{display:inline-block}.m-0{margin:0}.mx-0{margin-left:0;margin-right:0}.my-0{margin-top:0;margin-bottom:0}.ml-0{margin-left:0}.mt-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.m-1{margin:6px}.mx-1{margin-left:6px;margin-right:6px}.my-1{margin-top:6px;margin-bottom:6px}.ml-1{margin-left:6px}.mt-1{margin-top:6px}.mr-1{margin-right:6px}.mb-1{margin-bottom:6px}.m-2{margin:12px}.mx-2{margin-left:12px;margin-right:12px}.my-2{margin-top:12px;margin-bottom:12px}.ml-2{margin-left:12px}.mt-2{margin-top:12px}.mr-2{margin-right:12px}.mb-2{margin-bottom:12px}.outline-dotted{outline-style:dotted!important;outline-width:2px!important}.outline-dashed{outline-style:dashed!important;outline-width:2px!important}.outline-solid{outline-style:solid!important;outline-width:2px!important}.outline-double{outline-style:double!important;outline-width:2px!important}.outline-groove{outline-style:groove!important;outline-width:2px!important}.outline-ridge{outline-style:ridge!important;outline-width:2px!important}.outline-inset{outline-style:inset!important;outline-width:2px!important}.outline-outset{outline-style:outset!important;outline-width:2px!important}.outline-color-black{outline-color:#0d0d0d!important}.outline-color-white{outline-color:#fff!important}.outline-color-red{outline-color:#d33!important}.outline-color-orange{outline-color:#f37827!important}.outline-color-yellow{outline-color:#fbd814!important}.outline-color-olive{outline-color:#c0d919!important}.outline-color-green{outline-color:#22be47!important}.outline-color-teal{outline-color:#00c5bd!important}.outline-color-blue{outline-color:#238cdc!important}.outline-color-violet{outline-color:#6c3fcc!important}.outline-color-purple{outline-color:#a93bcd!important}.outline-color-pink{outline-color:#e2439c!important}.outline-color-brown{outline-color:#af6d43!important}.outline-color-grey{outline-color:#7d7d7d!important}.outline-color-good{outline-color:#62b62a!important}.outline-color-average{outline-color:#f1951d!important}.outline-color-bad{outline-color:#d33!important}.outline-color-label{outline-color:#8496ab!important}.position-relative{position:relative}.position-absolute{position:absolute}.position-fixed{position:fixed}.position-sticky{position:sticky}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-baseline{text-align:baseline}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-pre{white-space:pre}.text-bold{font-weight:700}.text-italic{font-style:italic}.text-underline{text-decoration:underline}.BlockQuote{color:#8496ab;border-left:2px solid #8496ab;padding-left:6px;margin-bottom:6px}.BlockQuote:last-child{margin-bottom:0}.Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.Button:last-child{margin-right:0}.Button .fa,.Button .far,.Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.Button--hasContent .fa,.Button--hasContent .far,.Button--hasContent .fas{margin-right:3px}.Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.Button--fluid{display:block;margin-left:0;margin-right:0}.Button--color--black{transition:color 50ms,background-color 50ms;background-color:#000;color:#fff}.Button--color--black:hover{transition:color 0ms,background-color 0ms}.Button--color--black:focus{transition:color .1s,background-color .1s}.Button--color--black:focus,.Button--color--black:hover{background-color:#0a0a0a;color:#fff}.Button--color--white{transition:color 50ms,background-color 50ms;background-color:#d9d9d9;color:#000}.Button--color--white:hover{transition:color 0ms,background-color 0ms}.Button--color--white:focus{transition:color .1s,background-color .1s}.Button--color--white:focus,.Button--color--white:hover{background-color:#f3f3f3;color:#000}.Button--color--red{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--red:hover{transition:color 0ms,background-color 0ms}.Button--color--red:focus{transition:color .1s,background-color .1s}.Button--color--red:focus,.Button--color--red:hover{background-color:#d52b2b;color:#fff}.Button--color--orange{transition:color 50ms,background-color 50ms;background-color:#d95e0c;color:#fff}.Button--color--orange:hover{transition:color 0ms,background-color 0ms}.Button--color--orange:focus{transition:color .1s,background-color .1s}.Button--color--orange:focus,.Button--color--orange:hover{background-color:#ed6f1d;color:#fff}.Button--color--yellow{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--yellow:hover{transition:color 0ms,background-color 0ms}.Button--color--yellow:focus{transition:color .1s,background-color .1s}.Button--color--yellow:focus,.Button--color--yellow:hover{background-color:#f3d00e;color:#000}.Button--color--olive{transition:color 50ms,background-color 50ms;background-color:#9aad14;color:#fff}.Button--color--olive:hover{transition:color 0ms,background-color 0ms}.Button--color--olive:focus{transition:color .1s,background-color .1s}.Button--color--olive:focus,.Button--color--olive:hover{background-color:#afc41f;color:#fff}.Button--color--green{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--color--green:hover{transition:color 0ms,background-color 0ms}.Button--color--green:focus{transition:color .1s,background-color .1s}.Button--color--green:focus,.Button--color--green:hover{background-color:#27ab46;color:#fff}.Button--color--teal{transition:color 50ms,background-color 50ms;background-color:#009a93;color:#fff}.Button--color--teal:hover{transition:color 0ms,background-color 0ms}.Button--color--teal:focus{transition:color .1s,background-color .1s}.Button--color--teal:focus,.Button--color--teal:hover{background-color:#0aafa8;color:#fff}.Button--color--blue{transition:color 50ms,background-color 50ms;background-color:#1c71b1;color:#fff}.Button--color--blue:hover{transition:color 0ms,background-color 0ms}.Button--color--blue:focus{transition:color .1s,background-color .1s}.Button--color--blue:focus,.Button--color--blue:hover{background-color:#2883c8;color:#fff}.Button--color--violet{transition:color 50ms,background-color 50ms;background-color:#552dab;color:#fff}.Button--color--violet:hover{transition:color 0ms,background-color 0ms}.Button--color--violet:focus{transition:color .1s,background-color .1s}.Button--color--violet:focus,.Button--color--violet:hover{background-color:#653ac1;color:#fff}.Button--color--purple{transition:color 50ms,background-color 50ms;background-color:#8b2baa;color:#fff}.Button--color--purple:hover{transition:color 0ms,background-color 0ms}.Button--color--purple:focus{transition:color .1s,background-color .1s}.Button--color--purple:focus,.Button--color--purple:hover{background-color:#9e38c1;color:#fff}.Button--color--pink{transition:color 50ms,background-color 50ms;background-color:#cf2082;color:#fff}.Button--color--pink:hover{transition:color 0ms,background-color 0ms}.Button--color--pink:focus{transition:color .1s,background-color .1s}.Button--color--pink:focus,.Button--color--pink:hover{background-color:#dd3794;color:#fff}.Button--color--brown{transition:color 50ms,background-color 50ms;background-color:#8c5836;color:#fff}.Button--color--brown:hover{transition:color 0ms,background-color 0ms}.Button--color--brown:focus{transition:color .1s,background-color .1s}.Button--color--brown:focus,.Button--color--brown:hover{background-color:#a06844;color:#fff}.Button--color--grey{transition:color 50ms,background-color 50ms;background-color:#646464;color:#fff}.Button--color--grey:hover{transition:color 0ms,background-color 0ms}.Button--color--grey:focus{transition:color .1s,background-color .1s}.Button--color--grey:focus,.Button--color--grey:hover{background-color:#757575;color:#fff}.Button--color--good{transition:color 50ms,background-color 50ms;background-color:#4d9121;color:#fff}.Button--color--good:hover{transition:color 0ms,background-color 0ms}.Button--color--good:focus{transition:color .1s,background-color .1s}.Button--color--good:focus,.Button--color--good:hover{background-color:#5da52d;color:#fff}.Button--color--average{transition:color 50ms,background-color 50ms;background-color:#cd7a0d;color:#fff}.Button--color--average:hover{transition:color 0ms,background-color 0ms}.Button--color--average:focus{transition:color .1s,background-color .1s}.Button--color--average:focus,.Button--color--average:hover{background-color:#e68d18;color:#fff}.Button--color--bad{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--bad:hover{transition:color 0ms,background-color 0ms}.Button--color--bad:focus{transition:color .1s,background-color .1s}.Button--color--bad:focus,.Button--color--bad:hover{background-color:#d52b2b;color:#fff}.Button--color--label{transition:color 50ms,background-color 50ms;background-color:#657a94;color:#fff}.Button--color--label:hover{transition:color 0ms,background-color 0ms}.Button--color--label:focus{transition:color .1s,background-color .1s}.Button--color--label:focus,.Button--color--label:hover{background-color:#7b8da4;color:#fff}.Button--color--default{transition:color 50ms,background-color 50ms;background-color:#3e6189;color:#fff}.Button--color--default:hover{transition:color 0ms,background-color 0ms}.Button--color--default:focus{transition:color .1s,background-color .1s}.Button--color--default:focus,.Button--color--default:hover{background-color:#4c729d;color:#fff}.Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--caution:hover{transition:color 0ms,background-color 0ms}.Button--color--caution:focus{transition:color .1s,background-color .1s}.Button--color--caution:focus,.Button--color--caution:hover{background-color:#f3d00e;color:#000}.Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--danger:hover{transition:color 0ms,background-color 0ms}.Button--color--danger:focus{transition:color .1s,background-color .1s}.Button--color--danger:focus,.Button--color--danger:hover{background-color:#d52b2b;color:#fff}.Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#252525;color:#fff;background-color:rgba(37,37,37,0);color:hsla(0,0%,100%,.5)}.Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.Button--color--transparent:focus{transition:color .1s,background-color .1s}.Button--color--transparent:focus,.Button--color--transparent:hover{background-color:#323232;color:#fff}.Button--disabled{background-color:#999!important}.Button--selected{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--selected:hover{transition:color 0ms,background-color 0ms}.Button--selected:focus{transition:color .1s,background-color .1s}.Button--selected:focus,.Button--selected:hover{background-color:#27ab46;color:#fff}.Collapsible{margin-bottom:.5rem}.Collapsible:last-child{margin-bottom:0}.ColorBox{display:inline-block;width:12px;height:12px;line-height:12px;text-align:center}.Dimmer{display:flex;justify-content:center;align-items:center;position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.75);z-index:1}.Divider--horizontal{margin:6px 0}.Divider--horizontal:not(.Divider--hidden){border-top:2px solid hsla(0,0%,100%,.1)}.Divider--vertical{height:100%;margin:0 6px}.Divider--vertical:not(.Divider--hidden){border-left:2px solid hsla(0,0%,100%,.1)}.Dropdown{position:relative}.Dropdown__control{position:relative;display:inline-block;font-family:Verdana,sans-serif;font-size:12px;width:100px;line-height:17px;user-select:none}.Dropdown__arrow-button{float:right;padding-left:6px;border-left:1px solid #000;border-left:1px solid rgba(0,0,0,.25)}.Dropdown__menu{overflow-y:auto;overflow-y:scroll}.Dropdown__menu,.Dropdown__menu-noscroll{position:absolute;z-index:5;width:100px;max-height:200px;border-radius:0 0 2px 2px;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menu-noscroll{overflow-y:auto}.Dropdown__menuentry{padding:2px 4px;font-family:Verdana,sans-serif;font-size:12px;line-height:17px;transition:background-color .1s}.Dropdown__menuentry:hover{background-color:#444;transition:background-color 0ms}.Dropdown__over{top:auto;bottom:100%}.FatalError{display:block!important;position:absolute;top:0;left:0;right:0;bottom:0;padding:12px;font-size:12px;font-family:Consolas,monospace;color:#fff;background-color:#00d;z-index:1000;overflow:hidden;text-align:center}.FatalError__logo{display:inline-block;text-align:left;font-size:10px;line-height:8px;position:relative;margin-top:12px;top:0;left:0;animation:FatalError__rainbow 2s linear infinite alternate,FatalError__shadow 4s linear infinite alternate,FatalError__tfmX 3s infinite alternate,FatalError__tfmY 4s infinite alternate;white-space:pre-wrap;word-break:break-all}.FatalError__header{margin-top:12px}.FatalError__stack{text-align:left;white-space:pre-wrap;word-break:break-all;margin-top:24px;margin-bottom:24px}.FatalError__footer{margin-bottom:24px}@keyframes FatalError__rainbow{0%{color:#ff0}50%{color:#0ff}to{color:#f0f}}@keyframes FatalError__shadow{0%{left:-2px;text-shadow:4px 0 #f0f}50%{left:0;text-shadow:0 0 #0ff}to{left:2px;text-shadow:-4px 0 #ff0}}@keyframes FatalError__tfmX{0%{left:15px}to{left:-15px}}@keyframes FatalError__tfmY{to{top:-15px}}.Flex{display:-ms-flexbox;display:flex}.Flex--inline{display:inline-flex}.Flex--ie8{display:table!important}.Flex--ie8--column{display:block!important}.Flex--ie8--column>.Flex__item{display:block!important;margin-left:6px;margin-right:6px}.Flex__item--ie8{display:table-cell!important}.Flex--spacing--1{margin:0 -3px}.Flex--spacing--1>.Flex__item{margin:0 3px}.Flex--spacingPrecise--1{margin:-1px}.Flex--spacingPrecise--1>.Flex__item{margin:1px}.Flex--spacing--2{margin:0 -6px}.Flex--spacing--2>.Flex__item{margin:0 6px}.Flex--spacingPrecise--2{margin:-2px}.Flex--spacingPrecise--2>.Flex__item{margin:2px}.Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto -.2em;cursor:n-resize}.Knob:after{content:".";color:transparent;line-height:2.5em}.Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(180deg,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,0));border-radius:50%;box-shadow:0 .05em .5em 0 rgba(0,0,0,.5)}.Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:hsla(0,0%,100%,.9)}.Knob__popupValue,.Knob__popupValue--right{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;background-color:#000;transform:translateX(50%);white-space:nowrap}.Knob__popupValue--right{top:.25rem;right:-50%}.Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.Knob__ringTrackPivot{transform:rotate(135deg)}.Knob__ringTrack{fill:transparent;stroke:hsla(0,0%,100%,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.Knob__ringFillPivot{transform:rotate(135deg)}.Knob--bipolar .Knob__ringFillPivot{transform:rotate(270deg)}.Knob__ringFill{fill:transparent;stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms}.Knob--color--black .Knob__ringFill{stroke:#0d0d0d}.Knob--color--white .Knob__ringFill{stroke:#fff}.Knob--color--red .Knob__ringFill{stroke:#d33}.Knob--color--orange .Knob__ringFill{stroke:#f37827}.Knob--color--yellow .Knob__ringFill{stroke:#fbd814}.Knob--color--olive .Knob__ringFill{stroke:#c0d919}.Knob--color--green .Knob__ringFill{stroke:#22be47}.Knob--color--teal .Knob__ringFill{stroke:#00c5bd}.Knob--color--blue .Knob__ringFill{stroke:#238cdc}.Knob--color--violet .Knob__ringFill{stroke:#6c3fcc}.Knob--color--purple .Knob__ringFill{stroke:#a93bcd}.Knob--color--pink .Knob__ringFill{stroke:#e2439c}.Knob--color--brown .Knob__ringFill{stroke:#af6d43}.Knob--color--grey .Knob__ringFill{stroke:#7d7d7d}.Knob--color--good .Knob__ringFill{stroke:#62b62a}.Knob--color--average .Knob__ringFill{stroke:#f1951d}.Knob--color--bad .Knob__ringFill{stroke:#d33}.Knob--color--label .Knob__ringFill{stroke:#8496ab}.LabeledList{display:table;width:100%;width:calc(100% + 12px);border-collapse:collapse;border-spacing:0;margin:-3px -6px 0;padding:0}.LabeledList__row{display:table-row}.LabeledList__row:last-child .LabeledList__cell{padding-bottom:0}.LabeledList__cell{display:table-cell;margin:0;padding:3px 6px;border:0;text-align:left;vertical-align:baseline}.LabeledList__label{width:1%;white-space:nowrap;min-width:60px}.LabeledList__buttons{width:.1%;white-space:nowrap;text-align:right;padding-top:1px;padding-bottom:0}.LabeledList__breakContents{word-break:break-all;word-wrap:break-word}.Modal{background-color:#252525;max-width:calc(100% - 1rem);padding:1rem}.NanoMap__contentOffset{position:absolute;top:0;bottom:0;left:524px;right:0;background-color:rgba(0,0,0,.33);overflow-y:scroll}.NanoMap__container{position:absolute;z-index:1}.NanoMap__marker{z-index:10}.NoticeBox{padding:4px 6px;margin-bottom:6px;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent 10px,rgba(0,0,0,.1) 0,rgba(0,0,0,.1) 20px)}.NoticeBox--color--black{color:#fff;background-color:#000}.NoticeBox--color--white{color:#000;background-color:#b3b3b3}.NoticeBox--color--red{color:#fff;background-color:#701f1f}.NoticeBox--color--orange{color:#fff;background-color:#854114}.NoticeBox--color--yellow{color:#000;background-color:#83710d}.NoticeBox--color--olive{color:#000;background-color:#576015}.NoticeBox--color--green{color:#fff;background-color:#174e24}.NoticeBox--color--teal{color:#fff;background-color:#064845}.NoticeBox--color--blue{color:#fff;background-color:#1b4565}.NoticeBox--color--violet{color:#fff;background-color:#3b2864}.NoticeBox--color--purple{color:#fff;background-color:#542663}.NoticeBox--color--pink{color:#fff;background-color:#802257}.NoticeBox--color--brown{color:#fff;background-color:#4c3729}.NoticeBox--color--grey{color:#fff;background-color:#3e3e3e}.NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.NoticeBox--color--average{color:#fff;background-color:#7b4e13}.NoticeBox--color--bad{color:#fff;background-color:#701f1f}.NoticeBox--color--label{color:#fff;background-color:#53565a}.NoticeBox--type--info{color:#fff;background-color:#235982}.NoticeBox--type--success{color:#fff;background-color:#1e662f}.NoticeBox--type--warning{color:#fff;background-color:#a95219}.NoticeBox--type--danger{color:#fff;background-color:#8f2828}.Input{position:relative;display:inline-block;width:120px;border:1px solid #88bfff;border:1px solid rgba(136,191,255,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.NumberInput{position:relative;display:inline-block;border:1px solid #88bfff;border:1px solid rgba(136,191,255,.75);border-radius:2px;color:#88bfff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.NumberInput--fluid{display:block}.NumberInput__content{margin-left:6px}.NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #88bfff;background-color:#88bfff}.NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:transparent;transition:border-color .5s}.ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.ProgressBar__fill--animated{transition:background-color .5s,width .5s}.ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.ProgressBar--color--default{border:1px solid #3e6189}.ProgressBar--color--default .ProgressBar__fill{background-color:#3e6189}.ProgressBar--color--black{border:1px solid #000!important}.ProgressBar--color--black .ProgressBar__fill{background-color:#000}.ProgressBar--color--white{border:1px solid #d9d9d9!important}.ProgressBar--color--white .ProgressBar__fill{background-color:#d9d9d9}.ProgressBar--color--red{border:1px solid #bd2020!important}.ProgressBar--color--red .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--orange{border:1px solid #d95e0c!important}.ProgressBar--color--orange .ProgressBar__fill{background-color:#d95e0c}.ProgressBar--color--yellow{border:1px solid #d9b804!important}.ProgressBar--color--yellow .ProgressBar__fill{background-color:#d9b804}.ProgressBar--color--olive{border:1px solid #9aad14!important}.ProgressBar--color--olive .ProgressBar__fill{background-color:#9aad14}.ProgressBar--color--green{border:1px solid #1b9638!important}.ProgressBar--color--green .ProgressBar__fill{background-color:#1b9638}.ProgressBar--color--teal{border:1px solid #009a93!important}.ProgressBar--color--teal .ProgressBar__fill{background-color:#009a93}.ProgressBar--color--blue{border:1px solid #1c71b1!important}.ProgressBar--color--blue .ProgressBar__fill{background-color:#1c71b1}.ProgressBar--color--violet{border:1px solid #552dab!important}.ProgressBar--color--violet .ProgressBar__fill{background-color:#552dab}.ProgressBar--color--purple{border:1px solid #8b2baa!important}.ProgressBar--color--purple .ProgressBar__fill{background-color:#8b2baa}.ProgressBar--color--pink{border:1px solid #cf2082!important}.ProgressBar--color--pink .ProgressBar__fill{background-color:#cf2082}.ProgressBar--color--brown{border:1px solid #8c5836!important}.ProgressBar--color--brown .ProgressBar__fill{background-color:#8c5836}.ProgressBar--color--grey{border:1px solid #646464!important}.ProgressBar--color--grey .ProgressBar__fill{background-color:#646464}.ProgressBar--color--good{border:1px solid #4d9121!important}.ProgressBar--color--good .ProgressBar__fill{background-color:#4d9121}.ProgressBar--color--average{border:1px solid #cd7a0d!important}.ProgressBar--color--average .ProgressBar__fill{background-color:#cd7a0d}.ProgressBar--color--bad{border:1px solid #bd2020!important}.ProgressBar--color--bad .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--label{border:1px solid #657a94!important}.ProgressBar--color--label .ProgressBar__fill{background-color:#657a94}.Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#1c1c1c;scrollbar-face-color:#3b3b3b;scrollbar-3dlight-color:#252525;scrollbar-highlight-color:#252525;scrollbar-track-color:#1c1c1c;scrollbar-arrow-color:#929292;scrollbar-shadow-color:#3b3b3b}.Section:last-child{margin-bottom:0}.Section--flex{display:flex;flex-flow:column}.Section--flex .Section__content{overflow:auto;flex:1}.Section__title{padding:6px;border-bottom:2px solid #4972a1}.Section__titleText{font-size:14px;font-weight:700}.Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.Section__content{padding:8px 6px}.Section__content--noTopPadding{padding-top:0}.Section__content--stretchContents{height:100%}.Section--level--1 .Section__titleText{font-size:14px}.Section--level--2 .Section__titleText{font-size:13px}.Section--level--3 .Section__titleText{font-size:12px}.Section--level--2,.Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.Slider{cursor:e-resize}.Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none!important}.Slider__cursor{position:absolute;top:0;right:-1px;bottom:0;width:0;border-left:2px solid #fff}.Slider__pointer{position:absolute;right:-5px;bottom:-4px;width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #fff}.Slider__popupValue{position:absolute;right:0;top:-22px;padding:2px 4px;background-color:#000;transform:translateX(50%);white-space:nowrap}.Table{display:table;width:100%;border-collapse:collapse;border-spacing:0;margin:0}.Table--collapsing{width:auto}.Table__row{display:table-row}.Table__cell{display:table-cell;padding:0 3px}.Table__cell:first-child{padding-left:0}.Table__cell:last-child{padding-right:0}.Table__cell--header,.Table__row--header .Table__cell{font-weight:700;padding-bottom:6px}.Table__cell--collapsing{width:1%;white-space:nowrap}.Tabs--horizontal{border-bottom:2px solid hsla(0,0%,100%,.1);margin-bottom:6px}.Tabs--horizontal .Tabs__tab--altSelection:after{content:"";position:absolute;bottom:0;right:0;left:0;height:2px;width:100%;background-color:#fff;border-radius:2px}.Tabs--vertical{margin-right:9px}.Tabs--vertical .Tabs__tabBox{border-right:2px solid hsla(0,0%,100%,.1);vertical-align:top}.Tabs--vertical .Tabs__tab{display:block!important;margin-right:0!important;margin-bottom:0;padding:1px 9px 0 6px;border-bottom:2px solid hsla(0,0%,100%,.1)}.Tabs--vertical .Tabs__tab:last-child{border-bottom:0}.Tabs--vertical .Tabs__tab--altSelection:after{content:"";position:absolute;top:0;bottom:0;right:0;height:100%;width:3px;background-color:#fff;border-radius:2px}.Tooltip{position:absolute;top:0;left:0;right:0;bottom:0;font-style:normal;font-weight:400}.Tooltip:after{position:absolute;display:block;white-space:nowrap;z-index:2;padding:6px 10px;transform:translateX(-50%);pointer-events:none;visibility:hidden;opacity:0;text-align:left;content:attr(data-tooltip);transition:all .15s;background-color:#000;box-shadow:1px 1px 15px -1px rgba(0,0,0,.5);border-radius:2px}.Tooltip:hover:after{transition:all 70ms;pointer-events:none;visibility:visible;opacity:1}.Tooltip--long:after{width:250px;white-space:normal}.Tooltip--top:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}.Tooltip--top:hover:after{transform:translateX(-50%) translateY(-8px)}.Tooltip--top-left:after{bottom:100%;right:50%;transform:translateX(12px) translateY(-8px)}.Tooltip--top-left:hover:after{transform:translateX(12px) translateY(8px)}.Tooltip--top-right:after{bottom:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.Tooltip--top-right:hover:after{transform:translateX(-12px) translateY(8px)}.Tooltip--bottom:after{top:100%;left:50%;transform:translateX(-50%) translateY(-8px)}.Tooltip--bottom:hover:after{transform:translateX(-50%) translateY(8px)}.Tooltip--bottom-left:after{top:100%;right:50%;transform:translateX(12px) translateY(-8px)}.Tooltip--bottom-left:hover:after{transform:translateX(12px) translateY(8px)}.Tooltip--bottom-right:after{top:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.Tooltip--bottom-right:hover:after{transform:translateX(-12px) translateY(8px)}.Tooltip--left:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}.Tooltip--left:hover:after,.Tooltip--right:after{transform:translateX(-8px) translateY(-50%)}.Tooltip--right:after{top:50%;left:100%}.Tooltip--right:hover:after{transform:translateX(8px) translateY(-50%)}.CameraConsole__left{position:absolute;top:0;bottom:0;left:0;width:220px}.CameraConsole__right{position:absolute;top:0;bottom:0;left:220px;right:0;background-color:rgba(0,0,0,.33)}.CameraConsole__toolbar{left:0;margin:3px 12px 0}.CameraConsole__toolbar,.CameraConsole__toolbarRight{position:absolute;top:0;right:0;height:24px;line-height:24px}.CameraConsole__toolbarRight{margin:4px 6px 0}.CameraConsole__map{position:absolute;top:26px;bottom:0;left:0;right:0;margin:6px;text-align:center}.CameraConsole__map .NoticeBox{margin-top:calc(50% - 24px)}.NuclearBomb__displayBox{background-color:#002003;border:4px inset #e8e4c9;color:#03e017;font-size:24px;font-family:monospace;padding:6px}.NuclearBomb__Button--keypad{background-color:#e8e4c9;border-color:#e8e4c9}.NuclearBomb__Button--keypad:hover{background-color:#f7f6ee!important;border-color:#f7f6ee!important}.NuclearBomb__Button--1{background-color:#d3cfb7!important;border-color:#d3cfb7!important;color:#a9a692!important}.NuclearBomb__Button--E{background-color:#d9b804!important;border-color:#d9b804!important}.NuclearBomb__Button--E:hover{background-color:#f3d00e!important;border-color:#f3d00e!important}.NuclearBomb__Button--C{background-color:#bd2020!important;border-color:#bd2020!important}.NuclearBomb__Button--C:hover{background-color:#d52b2b!important;border-color:#d52b2b!important}.NuclearBomb__NTIcon{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDQyNSAyMDAiIG9wYWNpdHk9Ii4zMyI+PHBhdGggZD0iTTE3OC4wMDQuMDM5SDEwNi44YTYuNzYxIDYuMDI2IDAgMDAtNi43NjEgNi4wMjV2MTg3Ljg3MmE2Ljc2MSA2LjAyNiAwIDAwNi43NjEgNi4wMjVoNTMuMTA3YTYuNzYxIDYuMDI2IDAgMDA2Ljc2Mi02LjAyNVY5Mi4zOTJsNzIuMjE2IDEwNC43YTYuNzYxIDYuMDI2IDAgMDA1Ljc2IDIuODdIMzE4LjJhNi43NjEgNi4wMjYgMCAwMDYuNzYxLTYuMDI2VjYuMDY0QTYuNzYxIDYuMDI2IDAgMDAzMTguMi4wNGgtNTQuNzE3YTYuNzYxIDYuMDI2IDAgMDAtNi43NiA2LjAyNXYxMDIuNjJMMTgzLjc2MyAyLjkwOWE2Ljc2MSA2LjAyNiAwIDAwLTUuNzYtMi44N3pNNC44NDUgMjIuMTA5QTEzLjQxMiAxMi41MDIgMCAwMTEzLjQ3OC4wMzloNjYuMTE4QTUuMzY1IDUgMCAwMTg0Ljk2IDUuMDR2NzkuODh6TTQyMC4xNTUgMTc3Ljg5MWExMy40MTIgMTIuNTAyIDAgMDEtOC42MzMgMjIuMDdoLTY2LjExOGE1LjM2NSA1IDAgMDEtNS4zNjUtNS4wMDF2LTc5Ljg4eiIvPjwvc3ZnPg==);background-size:70%;background-position:50%;background-repeat:no-repeat}.Roulette{font-family:Palatino}.Roulette__board{display:table;width:100%;border-collapse:collapse;border:2px solid #fff;margin:0}.Roulette__board-row{padding:0;margin:0}.Roulette__board-cell{display:table-cell;padding:0;margin:0;border:2px solid #fff;font-family:Palatino}.Roulette__board-cell:first-child{padding-left:0}.Roulette__board-cell:last-child{padding-right:0}.Roulette__board-extrabutton{text-align:center;font-size:20px;font-weight:700;height:28px;border:none!important;margin:0!important;padding-top:4px!important;color:#fff!important}.Roulette__lowertable{margin-top:8px;margin-left:80px;margin-right:80px;border-collapse:collapse;border:2px solid #fff;border-spacing:0}.Roulette__lowertable--cell{border:2px solid #fff;padding:0;margin:0}.Roulette__lowertable--betscell{vertical-align:top}.Roulette__lowertable--spinresult{text-align:center;font-size:100px;font-weight:700;vertical-align:middle}.Roulette__lowertable--spinresult-black{background-color:#000}.Roulette__lowertable--spinresult-red{background-color:#db2828}.Roulette__lowertable--spinresult-green{background-color:#20b142}.Roulette__lowertable--spinbutton{margin:0!important;border:none!important;font-size:50px;line-height:60px!important;text-align:center;font-weight:700}.Roulette__lowertable--header{width:1%;text-align:center;font-size:20px;font-weight:700}.Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#1c1c1c;scrollbar-face-color:#3b3b3b;scrollbar-3dlight-color:#252525;scrollbar-highlight-color:#252525;scrollbar-track-color:#1c1c1c;scrollbar-arrow-color:#929292;scrollbar-shadow-color:#3b3b3b}.Layout__content--flexRow{display:flex;flex-flow:row}.Layout__content--flexColumn{display:flex;flex-flow:column}.Layout__content--scrollable{overflow-y:auto}.Layout__content--noMargin{margin:0}.NtosHeader__left{position:absolute;left:12px}.NtosHeader__right{position:absolute;right:12px}.NtosHeader__icon{margin-top:-9px;margin-bottom:-6px;vertical-align:middle}.NtosWindow__header{position:absolute;top:0;left:0;right:0;height:28px;line-height:27px;background-color:rgba(0,0,0,.5);font-family:Consolas,monospace;font-size:14px;user-select:none;-ms-user-select:none}.NtosWindow__content .Layout__content{margin-top:28px;font-family:Consolas,monospace;font-size:14px}.TitleBar{background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#363636;transition:color .25s,background-color .25s}.TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.TitleBar__minimize{position:absolute;top:6px;right:46px}.TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.Window{bottom:0;right:0;color:#fff;background-color:#252525;background-image:linear-gradient(180deg,#2a2a2a 0,#202020)}.Window,.Window__titleBar{position:fixed;top:0;left:0}.Window__titleBar{z-index:1;width:100%;height:32px}.Window__rest{top:32px}.Window__dimmer,.Window__rest{position:fixed;bottom:0;left:0;right:0}.Window__dimmer{top:0;background-color:rgba(62,62,62,.25);pointer-events:none}.Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#131313;color:hsla(0,0%,100%,.8)}.Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.Layout__content{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDQyNSAyMDAiIG9wYWNpdHk9Ii4zMyI+PHBhdGggZD0iTTE3OC4wMDQuMDM5SDEwNi44YTYuNzYxIDYuMDI2IDAgMDAtNi43NjEgNi4wMjV2MTg3Ljg3MmE2Ljc2MSA2LjAyNiAwIDAwNi43NjEgNi4wMjVoNTMuMTA3YTYuNzYxIDYuMDI2IDAgMDA2Ljc2Mi02LjAyNVY5Mi4zOTJsNzIuMjE2IDEwNC43YTYuNzYxIDYuMDI2IDAgMDA1Ljc2IDIuODdIMzE4LjJhNi43NjEgNi4wMjYgMCAwMDYuNzYxLTYuMDI2VjYuMDY0QTYuNzYxIDYuMDI2IDAgMDAzMTguMi4wNGgtNTQuNzE3YTYuNzYxIDYuMDI2IDAgMDAtNi43NiA2LjAyNXYxMDIuNjJMMTgzLjc2MyAyLjkwOWE2Ljc2MSA2LjAyNiAwIDAwLTUuNzYtMi44N3pNNC44NDUgMjIuMTA5QTEzLjQxMiAxMi41MDIgMCAwMTEzLjQ3OC4wMzloNjYuMTE4QTUuMzY1IDUgMCAwMTg0Ljk2IDUuMDR2NzkuODh6TTQyMC4xNTUgMTc3Ljg5MWExMy40MTIgMTIuNTAyIDAgMDEtOC42MzMgMjIuMDdoLTY2LjExOGE1LjM2NSA1IDAgMDEtNS4zNjUtNS4wMDF2LTc5Ljg4eiIvPjwvc3ZnPg==);background-size:70%;background-position:50%;background-repeat:no-repeat}.theme-cardtable .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:0;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-cardtable .Button:last-child{margin-right:0}.theme-cardtable .Button .fa,.theme-cardtable .Button .far,.theme-cardtable .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-cardtable .Button--hasContent .fa,.theme-cardtable .Button--hasContent .far,.theme-cardtable .Button--hasContent .fas{margin-right:3px}.theme-cardtable .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-cardtable .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-cardtable .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#117039;color:#fff}.theme-cardtable .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--default:focus,.theme-cardtable .Button--color--default:hover{background-color:#1c8247;color:#fff}.theme-cardtable .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-cardtable .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--caution:focus,.theme-cardtable .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-cardtable .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-cardtable .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--danger:focus,.theme-cardtable .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-cardtable .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#117039;color:#fff;background-color:rgba(17,112,57,0);color:hsla(0,0%,100%,.5)}.theme-cardtable .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--transparent:focus,.theme-cardtable .Button--color--transparent:hover{background-color:#1c8247;color:#fff}.theme-cardtable .Button--disabled{background-color:#363636!important}.theme-cardtable .Button--selected{transition:color 50ms,background-color 50ms;background-color:#9d0808;color:#fff}.theme-cardtable .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--selected:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--selected:focus,.theme-cardtable .Button--selected:hover{background-color:#b31212;color:#fff}.theme-cardtable .Input{position:relative;display:inline-block;width:120px;border:1px solid #88bfff;border:1px solid rgba(136,191,255,.75);border-radius:0;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-cardtable .Input--fluid{display:block;width:auto}.theme-cardtable .Input__baseline{display:inline-block;color:transparent}.theme-cardtable .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-cardtable .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-cardtable .NumberInput{position:relative;display:inline-block;border:1px solid #fff;border:1px solid hsla(0,0%,100%,.75);border-radius:0;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.theme-cardtable .NumberInput--fluid{display:block}.theme-cardtable .NumberInput__content{margin-left:6px}.theme-cardtable .NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.theme-cardtable .NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #fff;background-color:#fff}.theme-cardtable .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.theme-cardtable .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-cardtable .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-cardtable .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-cardtable .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-cardtable .ProgressBar--color--default{border:1px solid #000}.theme-cardtable .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-cardtable .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#0d542b;scrollbar-face-color:#16914a;scrollbar-3dlight-color:#117039;scrollbar-highlight-color:#117039;scrollbar-track-color:#0d542b;scrollbar-arrow-color:#5ae695;scrollbar-shadow-color:#16914a}.theme-cardtable .Section:last-child{margin-bottom:0}.theme-cardtable .Section--flex{display:flex;flex-flow:column}.theme-cardtable .Section--flex .Section__content{overflow:auto;flex:1}.theme-cardtable .Section__title{padding:6px;border-bottom:2px solid #000}.theme-cardtable .Section__titleText{font-size:14px;font-weight:700}.theme-cardtable .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-cardtable .Section__content{padding:8px 6px}.theme-cardtable .Section__content--noTopPadding{padding-top:0}.theme-cardtable .Section__content--stretchContents{height:100%}.theme-cardtable .Section--level--1 .Section__titleText{font-size:14px}.theme-cardtable .Section--level--2 .Section__titleText{font-size:13px}.theme-cardtable .Section--level--3 .Section__titleText{font-size:12px}.theme-cardtable .Section--level--2,.theme-cardtable .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-cardtable .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#0d542b;scrollbar-face-color:#16914a;scrollbar-3dlight-color:#117039;scrollbar-highlight-color:#117039;scrollbar-track-color:#0d542b;scrollbar-arrow-color:#5ae695;scrollbar-shadow-color:#16914a}.theme-cardtable .Layout__content--flexRow{display:flex;flex-flow:row}.theme-cardtable .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-cardtable .Layout__content--scrollable{overflow-y:auto}.theme-cardtable .Layout__content--noMargin{margin:0}.theme-cardtable .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#117039;background-image:linear-gradient(180deg,#117039 0,#117039)}.theme-cardtable .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-cardtable .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-cardtable .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(39,148,85,.25);pointer-events:none}.theme-cardtable .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#09381d;color:hsla(0,0%,100%,.8)}.theme-cardtable .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-cardtable .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-cardtable .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-cardtable .TitleBar{background-color:#381608;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-cardtable .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#381608;transition:color .25s,background-color .25s}.theme-cardtable .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-cardtable .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-cardtable .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-cardtable .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-cardtable .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-cardtable .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-cardtable .Button{border:2px solid #fff}.theme-hackerman .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-hackerman .Button:last-child{margin-right:0}.theme-hackerman .Button .fa,.theme-hackerman .Button .far,.theme-hackerman .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-hackerman .Button--hasContent .fa,.theme-hackerman .Button--hasContent .far,.theme-hackerman .Button--hasContent .fas{margin-right:3px}.theme-hackerman .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-hackerman .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-hackerman .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#0f0;color:#000}.theme-hackerman .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--default:focus,.theme-hackerman .Button--color--default:hover{background-color:#26ff26;color:#000}.theme-hackerman .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.theme-hackerman .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--caution:focus,.theme-hackerman .Button--color--caution:hover{background-color:#f3d00e;color:#000}.theme-hackerman .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.theme-hackerman .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--danger:focus,.theme-hackerman .Button--color--danger:hover{background-color:#d52b2b;color:#fff}.theme-hackerman .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#121b12;color:#fff;background-color:rgba(18,27,18,0);color:hsla(0,0%,100%,.5)}.theme-hackerman .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--transparent:focus,.theme-hackerman .Button--color--transparent:hover{background-color:#1d271d;color:#fff}.theme-hackerman .Button--disabled{background-color:#4a6a4a!important}.theme-hackerman .Button--selected{transition:color 50ms,background-color 50ms;background-color:#0f0;color:#000}.theme-hackerman .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--selected:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--selected:focus,.theme-hackerman .Button--selected:hover{background-color:#26ff26;color:#000}.theme-hackerman .Input{position:relative;display:inline-block;width:120px;border:1px solid #0f0;border:1px solid rgba(0,255,0,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-hackerman .Input--fluid{display:block;width:auto}.theme-hackerman .Input__baseline{display:inline-block;color:transparent}.theme-hackerman .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-hackerman .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-hackerman .Modal{background-color:#121b12;max-width:calc(100% - 1rem);padding:1rem}.theme-hackerman .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Section:last-child{margin-bottom:0}.theme-hackerman .Section--flex{display:flex;flex-flow:column}.theme-hackerman .Section--flex .Section__content{overflow:auto;flex:1}.theme-hackerman .Section__title{padding:6px;border-bottom:2px solid #0f0}.theme-hackerman .Section__titleText{font-size:14px;font-weight:700}.theme-hackerman .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-hackerman .Section__content{padding:8px 6px}.theme-hackerman .Section__content--noTopPadding{padding-top:0}.theme-hackerman .Section__content--stretchContents{height:100%}.theme-hackerman .Section--level--1 .Section__titleText{font-size:14px}.theme-hackerman .Section--level--2 .Section__titleText{font-size:13px}.theme-hackerman .Section--level--3 .Section__titleText{font-size:12px}.theme-hackerman .Section--level--2,.theme-hackerman .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-hackerman .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Layout__content--flexRow{display:flex;flex-flow:row}.theme-hackerman .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-hackerman .Layout__content--scrollable{overflow-y:auto}.theme-hackerman .Layout__content--noMargin{margin:0}.theme-hackerman .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#121b12;background-image:linear-gradient(180deg,#121b12 0,#121b12)}.theme-hackerman .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-hackerman .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-hackerman .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(40,50,40,.25);pointer-events:none}.theme-hackerman .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#090e09;color:hsla(0,0%,100%,.8)}.theme-hackerman .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-hackerman .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-hackerman .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-hackerman .TitleBar{background-color:#223d22;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-hackerman .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#223d22;transition:color .25s,background-color .25s}.theme-hackerman .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-hackerman .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-hackerman .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-hackerman .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-hackerman .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-hackerman .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-hackerman .Layout__content{background-image:none}.theme-hackerman .Button{font-family:monospace;border:2px outset #0a0;outline:1px solid #007a00}.theme-hackerman .candystripe:nth-child(odd){background-color:rgba(0,100,0,.5)}.theme-malfunction .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-malfunction .Button:last-child{margin-right:0}.theme-malfunction .Button .fa,.theme-malfunction .Button .far,.theme-malfunction .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-malfunction .Button--hasContent .fa,.theme-malfunction .Button--hasContent .far,.theme-malfunction .Button--hasContent .fas{margin-right:3px}.theme-malfunction .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-malfunction .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-malfunction .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#910101;color:#fff}.theme-malfunction .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--default:focus,.theme-malfunction .Button--color--default:hover{background-color:#a60b0b;color:#fff}.theme-malfunction .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-malfunction .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--caution:focus,.theme-malfunction .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-malfunction .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-malfunction .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--danger:focus,.theme-malfunction .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-malfunction .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#1b3443;color:#fff;background-color:rgba(27,52,67,0);color:hsla(0,0%,100%,.5)}.theme-malfunction .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--transparent:focus,.theme-malfunction .Button--color--transparent:hover{background-color:#274252;color:#fff}.theme-malfunction .Button--disabled{background-color:#363636!important}.theme-malfunction .Button--selected{transition:color 50ms,background-color 50ms;background-color:#1e5881;color:#fff}.theme-malfunction .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--selected:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--selected:focus,.theme-malfunction .Button--selected:hover{background-color:#2a6894;color:#fff}.theme-malfunction .NoticeBox{padding:4px 6px;margin-bottom:6px;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#1a3f57;background-image:repeating-linear-gradient(-45deg,transparent,transparent 10px,rgba(0,0,0,.1) 0,rgba(0,0,0,.1) 20px)}.theme-malfunction .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-malfunction .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-malfunction .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-malfunction .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-malfunction .Input{position:relative;display:inline-block;width:120px;border:1px solid #910101;border:1px solid rgba(145,1,1,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-malfunction .Input--fluid{display:block;width:auto}.theme-malfunction .Input__baseline{display:inline-block;color:transparent}.theme-malfunction .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-malfunction .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-malfunction .NumberInput{position:relative;display:inline-block;border:1px solid #910101;border:1px solid rgba(145,1,1,.75);border-radius:2px;color:#910101;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.theme-malfunction .NumberInput--fluid{display:block}.theme-malfunction .NumberInput__content{margin-left:6px}.theme-malfunction .NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.theme-malfunction .NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #910101;background-color:#910101}.theme-malfunction .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.theme-malfunction .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-malfunction .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-malfunction .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-malfunction .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-malfunction .ProgressBar--color--default{border:1px solid #7b0101}.theme-malfunction .ProgressBar--color--default .ProgressBar__fill{background-color:#7b0101}.theme-malfunction .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#142732;scrollbar-face-color:#274b61;scrollbar-3dlight-color:#1b3443;scrollbar-highlight-color:#1b3443;scrollbar-track-color:#142732;scrollbar-arrow-color:#6ba2c3;scrollbar-shadow-color:#274b61}.theme-malfunction .Section:last-child{margin-bottom:0}.theme-malfunction .Section--flex{display:flex;flex-flow:column}.theme-malfunction .Section--flex .Section__content{overflow:auto;flex:1}.theme-malfunction .Section__title{padding:6px;border-bottom:2px solid #910101}.theme-malfunction .Section__titleText{font-size:14px;font-weight:700}.theme-malfunction .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-malfunction .Section__content{padding:8px 6px}.theme-malfunction .Section__content--noTopPadding{padding-top:0}.theme-malfunction .Section__content--stretchContents{height:100%}.theme-malfunction .Section--level--1 .Section__titleText{font-size:14px}.theme-malfunction .Section--level--2 .Section__titleText{font-size:13px}.theme-malfunction .Section--level--3 .Section__titleText{font-size:12px}.theme-malfunction .Section--level--2,.theme-malfunction .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-malfunction .Tooltip{position:absolute;top:0;left:0;right:0;bottom:0;font-style:normal;font-weight:400}.theme-malfunction .Tooltip:after{position:absolute;display:block;white-space:nowrap;z-index:2;padding:6px 10px;transform:translateX(-50%);pointer-events:none;visibility:hidden;opacity:0;text-align:left;content:attr(data-tooltip);transition:all .15s;background-color:#235577;box-shadow:1px 1px 15px -1px rgba(0,0,0,.5);border-radius:2px}.theme-malfunction .Tooltip:hover:after{transition:all 70ms;pointer-events:none;visibility:visible;opacity:1}.theme-malfunction .Tooltip--long:after{width:250px;white-space:normal}.theme-malfunction .Tooltip--top:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}.theme-malfunction .Tooltip--top:hover:after{transform:translateX(-50%) translateY(-8px)}.theme-malfunction .Tooltip--top-left:after{bottom:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-malfunction .Tooltip--top-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-malfunction .Tooltip--top-right:after{bottom:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-malfunction .Tooltip--top-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-malfunction .Tooltip--bottom:after{top:100%;left:50%;transform:translateX(-50%) translateY(-8px)}.theme-malfunction .Tooltip--bottom:hover:after{transform:translateX(-50%) translateY(8px)}.theme-malfunction .Tooltip--bottom-left:after{top:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-malfunction .Tooltip--bottom-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-malfunction .Tooltip--bottom-right:after{top:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-malfunction .Tooltip--bottom-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-malfunction .Tooltip--left:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}.theme-malfunction .Tooltip--left:hover:after,.theme-malfunction .Tooltip--right:after{transform:translateX(-8px) translateY(-50%)}.theme-malfunction .Tooltip--right:after{top:50%;left:100%}.theme-malfunction .Tooltip--right:hover:after{transform:translateX(8px) translateY(-50%)}.theme-malfunction .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#142732;scrollbar-face-color:#274b61;scrollbar-3dlight-color:#1b3443;scrollbar-highlight-color:#1b3443;scrollbar-track-color:#142732;scrollbar-arrow-color:#6ba2c3;scrollbar-shadow-color:#274b61}.theme-malfunction .Layout__content--flexRow{display:flex;flex-flow:row}.theme-malfunction .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-malfunction .Layout__content--scrollable{overflow-y:auto}.theme-malfunction .Layout__content--noMargin{margin:0}.theme-malfunction .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1b3443;background-image:linear-gradient(180deg,#244559 0,#12232d)}.theme-malfunction .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-malfunction .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-malfunction .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(50,79,96,.25);pointer-events:none}.theme-malfunction .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#0e1a22;color:hsla(0,0%,100%,.8)}.theme-malfunction .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-malfunction .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-malfunction .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-malfunction .TitleBar{background-color:#1a3f57;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-malfunction .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#1a3f57;transition:color .25s,background-color .25s}.theme-malfunction .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-malfunction .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-malfunction .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-malfunction .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-malfunction .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-malfunction .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-malfunction .Layout__content{background-image:none}.theme-ntos .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-ntos .Button:last-child{margin-right:0}.theme-ntos .Button .fa,.theme-ntos .Button .far,.theme-ntos .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-ntos .Button--hasContent .fa,.theme-ntos .Button--hasContent .far,.theme-ntos .Button--hasContent .fas{margin-right:3px}.theme-ntos .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-ntos .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-ntos .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#384e68;color:#fff}.theme-ntos .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--default:focus,.theme-ntos .Button--color--default:hover{background-color:#465e7a;color:#fff}.theme-ntos .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.theme-ntos .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--caution:focus,.theme-ntos .Button--color--caution:hover{background-color:#f3d00e;color:#000}.theme-ntos .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.theme-ntos .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--danger:focus,.theme-ntos .Button--color--danger:hover{background-color:#d52b2b;color:#fff}.theme-ntos .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#1f2b39;color:#fff;background-color:rgba(31,43,57,0);color:rgba(227,240,255,.75)}.theme-ntos .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--transparent:focus,.theme-ntos .Button--color--transparent:hover{background-color:#2b3847;color:#fff}.theme-ntos .Button--disabled{background-color:#999!important}.theme-ntos .Button--selected{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.theme-ntos .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--selected:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--selected:focus,.theme-ntos .Button--selected:hover{background-color:#27ab46;color:#fff}.theme-ntos .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-ntos .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-ntos .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-ntos .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-ntos .ProgressBar--color--default{border:1px solid #384e68}.theme-ntos .ProgressBar--color--default .ProgressBar__fill{background-color:#384e68}.theme-ntos .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#17202b;scrollbar-face-color:#2e3f55;scrollbar-3dlight-color:#1f2b39;scrollbar-highlight-color:#1f2b39;scrollbar-track-color:#17202b;scrollbar-arrow-color:#7693b5;scrollbar-shadow-color:#2e3f55}.theme-ntos .Section:last-child{margin-bottom:0}.theme-ntos .Section--flex{display:flex;flex-flow:column}.theme-ntos .Section--flex .Section__content{overflow:auto;flex:1}.theme-ntos .Section__title{padding:6px;border-bottom:2px solid #4972a1}.theme-ntos .Section__titleText{font-size:14px;font-weight:700}.theme-ntos .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-ntos .Section__content{padding:8px 6px}.theme-ntos .Section__content--noTopPadding{padding-top:0}.theme-ntos .Section__content--stretchContents{height:100%}.theme-ntos .Section--level--1 .Section__titleText{font-size:14px}.theme-ntos .Section--level--2 .Section__titleText{font-size:13px}.theme-ntos .Section--level--3 .Section__titleText{font-size:12px}.theme-ntos .Section--level--2,.theme-ntos .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-ntos .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#17202b;scrollbar-face-color:#2e3f55;scrollbar-3dlight-color:#1f2b39;scrollbar-highlight-color:#1f2b39;scrollbar-track-color:#17202b;scrollbar-arrow-color:#7693b5;scrollbar-shadow-color:#2e3f55}.theme-ntos .Layout__content--flexRow{display:flex;flex-flow:row}.theme-ntos .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-ntos .Layout__content--scrollable{overflow-y:auto}.theme-ntos .Layout__content--noMargin{margin:0}.theme-ntos .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1f2b39;background-image:linear-gradient(180deg,#223040 0,#1b2633)}.theme-ntos .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-ntos .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-ntos .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(55,69,85,.25);pointer-events:none}.theme-ntos .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#0f151d;color:hsla(0,0%,100%,.8)}.theme-ntos .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-ntos .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-ntos .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-ntos .TitleBar{background-color:#2a3b4e;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-ntos .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#2a3b4e;transition:color .25s,background-color .25s}.theme-ntos .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-ntos .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-ntos .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-ntos .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-ntos .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-ntos .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-retro .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:0;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-retro .Button:last-child{margin-right:0}.theme-retro .Button .fa,.theme-retro .Button .far,.theme-retro .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-retro .Button--hasContent .fa,.theme-retro .Button--hasContent .far,.theme-retro .Button--hasContent .fas{margin-right:3px}.theme-retro .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-retro .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-retro .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#e8e4c9;color:#000}.theme-retro .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--default:focus,.theme-retro .Button--color--default:hover{background-color:#f7f6ee;color:#000}.theme-retro .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-retro .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--caution:focus,.theme-retro .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-retro .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-retro .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--danger:focus,.theme-retro .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-retro .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#e8e4c9;color:#000;background-color:rgba(232,228,201,0);color:hsla(0,0%,100%,.5)}.theme-retro .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--transparent:focus,.theme-retro .Button--color--transparent:hover{background-color:#f7f6ee;color:#000}.theme-retro .Button--disabled{background-color:#363636!important}.theme-retro .Button--selected{transition:color 50ms,background-color 50ms;background-color:#9d0808;color:#fff}.theme-retro .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--selected:focus{transition:color .1s,background-color .1s}.theme-retro .Button--selected:focus,.theme-retro .Button--selected:hover{background-color:#b31212;color:#fff}.theme-retro .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-retro .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-retro .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-retro .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-retro .ProgressBar--color--default{border:1px solid #000}.theme-retro .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-retro .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-retro .Section:last-child{margin-bottom:0}.theme-retro .Section--flex{display:flex;flex-flow:column}.theme-retro .Section--flex .Section__content{overflow:auto;flex:1}.theme-retro .Section__title{padding:6px;border-bottom:2px solid #000}.theme-retro .Section__titleText{font-size:14px;font-weight:700}.theme-retro .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-retro .Section__content{padding:8px 6px}.theme-retro .Section__content--noTopPadding{padding-top:0}.theme-retro .Section__content--stretchContents{height:100%}.theme-retro .Section--level--1 .Section__titleText{font-size:14px}.theme-retro .Section--level--2 .Section__titleText{font-size:13px}.theme-retro .Section--level--3 .Section__titleText{font-size:12px}.theme-retro .Section--level--2,.theme-retro .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-retro .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-retro .Layout__content--flexRow{display:flex;flex-flow:row}.theme-retro .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-retro .Layout__content--scrollable{overflow-y:auto}.theme-retro .Layout__content--noMargin{margin:0}.theme-retro .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#e8e4c9;background-image:linear-gradient(180deg,#e8e4c9 0,#e8e4c9)}.theme-retro .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-retro .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-retro .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(251,250,246,.25);pointer-events:none}.theme-retro .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#988d41;color:hsla(0,0%,100%,.8)}.theme-retro .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-retro .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-retro .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-retro .TitleBar{background-color:#585337;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-retro .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#585337;transition:color .25s,background-color .25s}.theme-retro .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-retro .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-retro .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-retro .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-retro .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-retro .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-retro .Button{font-family:monospace;color:#161613;border:8px outset #e8e4c9;outline:3px solid #161613}.theme-retro .Layout__content{background-image:none}.theme-syndicate .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-syndicate .Button:last-child{margin-right:0}.theme-syndicate .Button .fa,.theme-syndicate .Button .far,.theme-syndicate .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-syndicate .Button--hasContent .fa,.theme-syndicate .Button--hasContent .far,.theme-syndicate .Button--hasContent .fas{margin-right:3px}.theme-syndicate .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-syndicate .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-syndicate .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#397439;color:#fff}.theme-syndicate .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--default:focus,.theme-syndicate .Button--color--default:hover{background-color:#478647;color:#fff}.theme-syndicate .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-syndicate .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--caution:focus,.theme-syndicate .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-syndicate .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-syndicate .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--danger:focus,.theme-syndicate .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-syndicate .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#550202;color:#fff;background-color:rgba(85,2,2,0);color:hsla(0,0%,100%,.5)}.theme-syndicate .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--transparent:focus,.theme-syndicate .Button--color--transparent:hover{background-color:#650c0c;color:#fff}.theme-syndicate .Button--disabled{background-color:#363636!important}.theme-syndicate .Button--selected{transition:color 50ms,background-color 50ms;background-color:#9d0808;color:#fff}.theme-syndicate .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--selected:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--selected:focus,.theme-syndicate .Button--selected:hover{background-color:#b31212;color:#fff}.theme-syndicate .NoticeBox{padding:4px 6px;margin-bottom:6px;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#910101;background-image:repeating-linear-gradient(-45deg,transparent,transparent 10px,rgba(0,0,0,.1) 0,rgba(0,0,0,.1) 20px)}.theme-syndicate .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-syndicate .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-syndicate .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-syndicate .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-syndicate .Input{position:relative;display:inline-block;width:120px;border:1px solid #87ce87;border:1px solid rgba(135,206,135,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-syndicate .Input--fluid{display:block;width:auto}.theme-syndicate .Input__baseline{display:inline-block;color:transparent}.theme-syndicate .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-syndicate .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-syndicate .NumberInput{position:relative;display:inline-block;border:1px solid #87ce87;border:1px solid rgba(135,206,135,.75);border-radius:2px;color:#87ce87;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.theme-syndicate .NumberInput--fluid{display:block}.theme-syndicate .NumberInput__content{margin-left:6px}.theme-syndicate .NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.theme-syndicate .NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #87ce87;background-color:#87ce87}.theme-syndicate .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.theme-syndicate .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-syndicate .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-syndicate .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-syndicate .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-syndicate .ProgressBar--color--default{border:1px solid #306330}.theme-syndicate .ProgressBar--color--default .ProgressBar__fill{background-color:#306330}.theme-syndicate .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#400202;scrollbar-face-color:#7e0303;scrollbar-3dlight-color:#550202;scrollbar-highlight-color:#550202;scrollbar-track-color:#400202;scrollbar-arrow-color:#fa3030;scrollbar-shadow-color:#7e0303}.theme-syndicate .Section:last-child{margin-bottom:0}.theme-syndicate .Section--flex{display:flex;flex-flow:column}.theme-syndicate .Section--flex .Section__content{overflow:auto;flex:1}.theme-syndicate .Section__title{padding:6px;border-bottom:2px solid #397439}.theme-syndicate .Section__titleText{font-size:14px;font-weight:700}.theme-syndicate .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-syndicate .Section__content{padding:8px 6px}.theme-syndicate .Section__content--noTopPadding{padding-top:0}.theme-syndicate .Section__content--stretchContents{height:100%}.theme-syndicate .Section--level--1 .Section__titleText{font-size:14px}.theme-syndicate .Section--level--2 .Section__titleText{font-size:13px}.theme-syndicate .Section--level--3 .Section__titleText{font-size:12px}.theme-syndicate .Section--level--2,.theme-syndicate .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-syndicate .Tooltip{position:absolute;top:0;left:0;right:0;bottom:0;font-style:normal;font-weight:400}.theme-syndicate .Tooltip:after{position:absolute;display:block;white-space:nowrap;z-index:2;padding:6px 10px;transform:translateX(-50%);pointer-events:none;visibility:hidden;opacity:0;text-align:left;content:attr(data-tooltip);transition:all .15s;background-color:#4a0202;box-shadow:1px 1px 15px -1px rgba(0,0,0,.5);border-radius:2px}.theme-syndicate .Tooltip:hover:after{transition:all 70ms;pointer-events:none;visibility:visible;opacity:1}.theme-syndicate .Tooltip--long:after{width:250px;white-space:normal}.theme-syndicate .Tooltip--top:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}.theme-syndicate .Tooltip--top:hover:after{transform:translateX(-50%) translateY(-8px)}.theme-syndicate .Tooltip--top-left:after{bottom:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-syndicate .Tooltip--top-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-syndicate .Tooltip--top-right:after{bottom:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-syndicate .Tooltip--top-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-syndicate .Tooltip--bottom:after{top:100%;left:50%;transform:translateX(-50%) translateY(-8px)}.theme-syndicate .Tooltip--bottom:hover:after{transform:translateX(-50%) translateY(8px)}.theme-syndicate .Tooltip--bottom-left:after{top:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-syndicate .Tooltip--bottom-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-syndicate .Tooltip--bottom-right:after{top:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-syndicate .Tooltip--bottom-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-syndicate .Tooltip--left:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}.theme-syndicate .Tooltip--left:hover:after,.theme-syndicate .Tooltip--right:after{transform:translateX(-8px) translateY(-50%)}.theme-syndicate .Tooltip--right:after{top:50%;left:100%}.theme-syndicate .Tooltip--right:hover:after{transform:translateX(8px) translateY(-50%)}.theme-syndicate .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#400202;scrollbar-face-color:#7e0303;scrollbar-3dlight-color:#550202;scrollbar-highlight-color:#550202;scrollbar-track-color:#400202;scrollbar-arrow-color:#fa3030;scrollbar-shadow-color:#7e0303}.theme-syndicate .Layout__content--flexRow{display:flex;flex-flow:row}.theme-syndicate .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-syndicate .Layout__content--scrollable{overflow-y:auto}.theme-syndicate .Layout__content--noMargin{margin:0}.theme-syndicate .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#550202;background-image:linear-gradient(180deg,#730303 0,#370101)}.theme-syndicate .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-syndicate .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-syndicate .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(117,22,22,.25);pointer-events:none}.theme-syndicate .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#2b0101;color:hsla(0,0%,100%,.8)}.theme-syndicate .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-syndicate .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-syndicate .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-syndicate .TitleBar{background-color:#910101;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-syndicate .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#910101;transition:color .25s,background-color .25s}.theme-syndicate .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-syndicate .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-syndicate .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-syndicate .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-syndicate .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-syndicate .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-syndicate .Layout__content{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDIwMCAyODkuNzQyIiBvcGFjaXR5PSIuMzMiPjxwYXRoIGQ9Ik05My41MzggMGMtMTguMTEzIDAtMzQuMjIgMy4xMTItNDguMzI0IDkuMzM0LTEzLjk2NSA2LjIyMi0yNC42MTIgMTUuMDcyLTMxLjk0IDI2LjU0N0M2LjA4NCA0Ny4yMiAyLjk3MiA2MC42MzEgMi45NzIgNzYuMTE2YzAgMTAuNjQ3IDIuNzI1IDIwLjQ2NSA4LjE3NSAyOS40NTMgNS42MTYgOC45ODcgMTQuMDM5IDE3LjM1MiAyNS4yNyAyNS4wOTQgMTEuMjMgNy42MDYgMjYuNTA3IDE1LjQxOSA0NS44MyAyMy40MzggMTkuOTg0IDguMjk2IDM0Ljg0OSAxNS41NTUgNDQuNTkzIDIxLjc3NiA5Ljc0NCA2LjIyMyAxNi43NjEgMTIuODU5IDIxLjA1NSAxOS45MSA0LjI5NSA3LjA1MiA2LjQ0MiAxNS43NjQgNi40NDIgMjYuMTM0IDAgMTYuMTc4LTUuMjAyIDI4LjQ4My0xNS42MDYgMzYuOTE3LTEwLjI0IDguNDM1LTI1LjAyMiAxMi42NTMtNDQuMzQ1IDEyLjY1My0xNC4wMzkgMC0yNS41MTYtMS42Ni0zNC40MzQtNC45NzgtOC45MTgtMy40NTctMTYuMTg2LTguNzExLTIxLjgtMTUuNzYzLTUuNjE2LTcuMDUyLTEwLjA3Ni0xNi42NjEtMTMuMzc5LTI4LjgyOUgwdjU2LjgyN2MzMy44NTcgNy4zMjggNjMuNzQ5IDEwLjk5NCA4OS42NzggMTAuOTk0IDE2LjAyIDAgMzAuNzItMS4zODMgNDQuMDk4LTQuMTQ4IDEzLjU0Mi0yLjkwNCAyNS4xMDQtNy40NjcgMzQuNjgzLTEzLjY5IDkuNzQ0LTYuMzU5IDE3LjM0LTE0LjUxOSAyMi43OS0yNC40NzQgNS40NS0xMC4wOTMgOC4xNzUtMjIuNCA4LjE3NS0zNi45MTcgMC0xMi45OTctMy4zMDItMjQuMzM1LTkuOTA4LTM0LjAxNC02LjQ0LTkuODE4LTE1LjUyNS0xOC41MjctMjcuMjUxLTI2LjEzMi0xMS41NjEtNy42MDQtMjcuOTExLTE1LjgzMS00OS4wNTEtMjQuNjgtMTcuNTA2LTcuMTktMzAuNzItMTMuNjktMzkuNjM4LTE5LjQ5N1M1NC45NjkgOTMuNzU2IDQ5LjQ3OSA4Ny4zMTZjLTUuNDI2LTYuMzY2LTkuNjU4LTE1LjA3LTkuNjU4LTI0Ljg4NyAwLTkuMjY0IDIuMDc1LTE3LjIxNCA2LjIyMy0yMy44NUM1Ny4xNDIgMjQuMTggODcuMzMxIDM2Ljc4MiA5MS4xMiA2Mi45MjVjNC44NCA2Ljc3NSA4Ljg1IDE2LjI0NyAxMi4wMyAyOC40MTVoMjAuNTMydi01NmMtNC40NzktNS45MjQtOS45NTUtMTAuNjMxLTE1LjkwOS0xNC4zNzMgMS42NC40NzkgMy4xOSAxLjAyMyA0LjYzOSAxLjY0IDYuNDk4IDIuNjI2IDEyLjE2OCA3LjMyNyAxNy4wMDcgMTQuMTAzIDQuODQgNi43NzUgOC44NSAxNi4yNDYgMTIuMDMgMjguNDE0IDAgMCA4LjQ4LS4xMjkgOC40OS0uMDAyLjQxNyA2LjQxNS0xLjc1NCA5LjQ1My00LjEyNCAxMi41NjEtMi40MTcgMy4xNy01LjE0NSA2Ljc5LTQuMDAzIDEzLjAwMyAxLjUwOCA4LjIwMyAxMC4xODQgMTAuNTk3IDE0LjYyMiA5LjMxMi0zLjMxOC0uNS01LjMxOC0xLjc1LTUuMzE4LTEuNzVzMS44NzYuOTk5IDUuNjUtMS4zNmMtMy4yNzYuOTU2LTEwLjcwNC0uNzk3LTExLjgtNi43NjMtLjk1OC01LjIwOC45NDYtNy4yOTUgMy40LTEwLjUxNCAyLjQ1NS0zLjIyIDUuMjg1LTYuOTU5IDQuNjg1LTE0LjQ4OWwuMDAzLjAwMmg4LjkyN3YtNTZjLTE1LjA3Mi0zLjg3MS0yNy42NTMtNi4zNi0zNy43NDctNy40NjVDMTE0LjI3OS41NTIgMTA0LjA0NiAwIDkzLjUzNyAwem03MC4zMjEgMTcuMzA5bC4yMzggNDAuMzA1YzEuMzE4IDEuMjI2IDIuNDQgMi4yNzggMy4zNDEgMy4xMDYgNC44NCA2Ljc3NSA4Ljg1IDE2LjI0NiAxMi4wMyAyOC40MTRIMjAwdi01NmMtNi42NzctNC41OTQtMTkuODM2LTEwLjQ3My0zNi4xNC0xNS44MjV6bS0yOC4xMiA1LjYwNWw4LjU2NSAxNy43MTdjLTExLjk3LTYuNDY3LTEzLjg0Ny05LjcxNy04LjU2NS0xNy43MTd6bTIyLjc5NyAwYzIuNzcxIDggMS43ODcgMTEuMjUtNC40OTQgMTcuNzE3bDQuNDk0LTE3LjcxN3ptMTUuMjIyIDI0LjAwOWw4LjU2NSAxNy43MTZjLTExLjk3LTYuNDY2LTEzLjg0Ny05LjcxNy04LjU2NS0xNy43MTZ6bTIyLjc5NyAwYzIuNzcxIDggMS43ODcgMTEuMjUtNC40OTQgMTcuNzE2bDQuNDk0LTE3LjcxNnpNOTcuNDQgNDkuMTNsOC41NjUgMTcuNzE2Yy0xMS45Ny02LjQ2Ny0xMy44NDctOS43MTctOC41NjUtMTcuNzE2em0yMi43OTUgMGMyLjc3MiA3Ljk5OSAxLjc4OCAxMS4yNS00LjQ5MyAxNy43MTZsNC40OTMtMTcuNzE2eiIvPjwvc3ZnPg==)} \ No newline at end of file +body,html{box-sizing:border-box;height:100%;margin:0;font-size:12px}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4,h5,h6{display:block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}td,th{vertical-align:baseline;text-align:left}.candystripe:nth-child(odd){background-color:rgba(0,0,0,.25)}.color-black{color:#0d0d0d!important}.color-white{color:#fff!important}.color-red{color:#d33!important}.color-orange{color:#f37827!important}.color-yellow{color:#fbd814!important}.color-olive{color:#c0d919!important}.color-green{color:#22be47!important}.color-teal{color:#00c5bd!important}.color-blue{color:#238cdc!important}.color-violet{color:#6c3fcc!important}.color-purple{color:#a93bcd!important}.color-pink{color:#e2439c!important}.color-brown{color:#af6d43!important}.color-grey{color:#7d7d7d!important}.color-good{color:#62b62a!important}.color-average{color:#f1951d!important}.color-bad{color:#d33!important}.color-label{color:#8496ab!important}.color-bg-black{background-color:#000!important}.color-bg-white{background-color:#d9d9d9!important}.color-bg-red{background-color:#bd2020!important}.color-bg-orange{background-color:#d95e0c!important}.color-bg-yellow{background-color:#d9b804!important}.color-bg-olive{background-color:#9aad14!important}.color-bg-green{background-color:#1b9638!important}.color-bg-teal{background-color:#009a93!important}.color-bg-blue{background-color:#1c71b1!important}.color-bg-violet{background-color:#552dab!important}.color-bg-purple{background-color:#8b2baa!important}.color-bg-pink{background-color:#cf2082!important}.color-bg-brown{background-color:#8c5836!important}.color-bg-grey{background-color:#646464!important}.color-bg-good{background-color:#4d9121!important}.color-bg-average{background-color:#cd7a0d!important}.color-bg-bad{background-color:#bd2020!important}.color-bg-label{background-color:#657a94!important}.debug-layout,.debug-layout :not(g):not(path){color:hsla(0,0%,100%,.9)!important;background:transparent!important;outline:1px solid hsla(0,0%,100%,.5)!important;box-shadow:none!important;filter:none!important}.debug-layout:hover,.debug-layout :not(g):not(path):hover{outline-color:hsla(0,0%,100%,.8)!important}.display-none{display:none}.display-block{display:block}.display-inline{display:inline}.display-inline-block{display:inline-block}.m-0{margin:0}.mx-0{margin-left:0;margin-right:0}.my-0{margin-top:0;margin-bottom:0}.ml-0{margin-left:0}.mt-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.m-1{margin:6px}.mx-1{margin-left:6px;margin-right:6px}.my-1{margin-top:6px;margin-bottom:6px}.ml-1{margin-left:6px}.mt-1{margin-top:6px}.mr-1{margin-right:6px}.mb-1{margin-bottom:6px}.m-2{margin:12px}.mx-2{margin-left:12px;margin-right:12px}.my-2{margin-top:12px;margin-bottom:12px}.ml-2{margin-left:12px}.mt-2{margin-top:12px}.mr-2{margin-right:12px}.mb-2{margin-bottom:12px}.outline-dotted{outline-style:dotted!important;outline-width:2px!important}.outline-dashed{outline-style:dashed!important;outline-width:2px!important}.outline-solid{outline-style:solid!important;outline-width:2px!important}.outline-double{outline-style:double!important;outline-width:2px!important}.outline-groove{outline-style:groove!important;outline-width:2px!important}.outline-ridge{outline-style:ridge!important;outline-width:2px!important}.outline-inset{outline-style:inset!important;outline-width:2px!important}.outline-outset{outline-style:outset!important;outline-width:2px!important}.outline-color-black{outline-color:#0d0d0d!important}.outline-color-white{outline-color:#fff!important}.outline-color-red{outline-color:#d33!important}.outline-color-orange{outline-color:#f37827!important}.outline-color-yellow{outline-color:#fbd814!important}.outline-color-olive{outline-color:#c0d919!important}.outline-color-green{outline-color:#22be47!important}.outline-color-teal{outline-color:#00c5bd!important}.outline-color-blue{outline-color:#238cdc!important}.outline-color-violet{outline-color:#6c3fcc!important}.outline-color-purple{outline-color:#a93bcd!important}.outline-color-pink{outline-color:#e2439c!important}.outline-color-brown{outline-color:#af6d43!important}.outline-color-grey{outline-color:#7d7d7d!important}.outline-color-good{outline-color:#62b62a!important}.outline-color-average{outline-color:#f1951d!important}.outline-color-bad{outline-color:#d33!important}.outline-color-label{outline-color:#8496ab!important}.position-relative{position:relative}.position-absolute{position:absolute}.position-fixed{position:fixed}.position-sticky{position:sticky}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-baseline{text-align:baseline}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-pre{white-space:pre}.text-bold{font-weight:700}.text-italic{font-style:italic}.text-underline{text-decoration:underline}.BlockQuote{color:#8496ab;border-left:2px solid #8496ab;padding-left:6px;margin-bottom:6px}.BlockQuote:last-child{margin-bottom:0}.Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.Button:last-child{margin-right:0}.Button .fa,.Button .far,.Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.Button--hasContent .fa,.Button--hasContent .far,.Button--hasContent .fas{margin-right:3px}.Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.Button--fluid{display:block;margin-left:0;margin-right:0}.Button--color--black{transition:color 50ms,background-color 50ms;background-color:#000;color:#fff}.Button--color--black:hover{transition:color 0ms,background-color 0ms}.Button--color--black:focus{transition:color .1s,background-color .1s}.Button--color--black:focus,.Button--color--black:hover{background-color:#0a0a0a;color:#fff}.Button--color--white{transition:color 50ms,background-color 50ms;background-color:#d9d9d9;color:#000}.Button--color--white:hover{transition:color 0ms,background-color 0ms}.Button--color--white:focus{transition:color .1s,background-color .1s}.Button--color--white:focus,.Button--color--white:hover{background-color:#f3f3f3;color:#000}.Button--color--red{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--red:hover{transition:color 0ms,background-color 0ms}.Button--color--red:focus{transition:color .1s,background-color .1s}.Button--color--red:focus,.Button--color--red:hover{background-color:#d52b2b;color:#fff}.Button--color--orange{transition:color 50ms,background-color 50ms;background-color:#d95e0c;color:#fff}.Button--color--orange:hover{transition:color 0ms,background-color 0ms}.Button--color--orange:focus{transition:color .1s,background-color .1s}.Button--color--orange:focus,.Button--color--orange:hover{background-color:#ed6f1d;color:#fff}.Button--color--yellow{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--yellow:hover{transition:color 0ms,background-color 0ms}.Button--color--yellow:focus{transition:color .1s,background-color .1s}.Button--color--yellow:focus,.Button--color--yellow:hover{background-color:#f3d00e;color:#000}.Button--color--olive{transition:color 50ms,background-color 50ms;background-color:#9aad14;color:#fff}.Button--color--olive:hover{transition:color 0ms,background-color 0ms}.Button--color--olive:focus{transition:color .1s,background-color .1s}.Button--color--olive:focus,.Button--color--olive:hover{background-color:#afc41f;color:#fff}.Button--color--green{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--color--green:hover{transition:color 0ms,background-color 0ms}.Button--color--green:focus{transition:color .1s,background-color .1s}.Button--color--green:focus,.Button--color--green:hover{background-color:#27ab46;color:#fff}.Button--color--teal{transition:color 50ms,background-color 50ms;background-color:#009a93;color:#fff}.Button--color--teal:hover{transition:color 0ms,background-color 0ms}.Button--color--teal:focus{transition:color .1s,background-color .1s}.Button--color--teal:focus,.Button--color--teal:hover{background-color:#0aafa8;color:#fff}.Button--color--blue{transition:color 50ms,background-color 50ms;background-color:#1c71b1;color:#fff}.Button--color--blue:hover{transition:color 0ms,background-color 0ms}.Button--color--blue:focus{transition:color .1s,background-color .1s}.Button--color--blue:focus,.Button--color--blue:hover{background-color:#2883c8;color:#fff}.Button--color--violet{transition:color 50ms,background-color 50ms;background-color:#552dab;color:#fff}.Button--color--violet:hover{transition:color 0ms,background-color 0ms}.Button--color--violet:focus{transition:color .1s,background-color .1s}.Button--color--violet:focus,.Button--color--violet:hover{background-color:#653ac1;color:#fff}.Button--color--purple{transition:color 50ms,background-color 50ms;background-color:#8b2baa;color:#fff}.Button--color--purple:hover{transition:color 0ms,background-color 0ms}.Button--color--purple:focus{transition:color .1s,background-color .1s}.Button--color--purple:focus,.Button--color--purple:hover{background-color:#9e38c1;color:#fff}.Button--color--pink{transition:color 50ms,background-color 50ms;background-color:#cf2082;color:#fff}.Button--color--pink:hover{transition:color 0ms,background-color 0ms}.Button--color--pink:focus{transition:color .1s,background-color .1s}.Button--color--pink:focus,.Button--color--pink:hover{background-color:#dd3794;color:#fff}.Button--color--brown{transition:color 50ms,background-color 50ms;background-color:#8c5836;color:#fff}.Button--color--brown:hover{transition:color 0ms,background-color 0ms}.Button--color--brown:focus{transition:color .1s,background-color .1s}.Button--color--brown:focus,.Button--color--brown:hover{background-color:#a06844;color:#fff}.Button--color--grey{transition:color 50ms,background-color 50ms;background-color:#646464;color:#fff}.Button--color--grey:hover{transition:color 0ms,background-color 0ms}.Button--color--grey:focus{transition:color .1s,background-color .1s}.Button--color--grey:focus,.Button--color--grey:hover{background-color:#757575;color:#fff}.Button--color--good{transition:color 50ms,background-color 50ms;background-color:#4d9121;color:#fff}.Button--color--good:hover{transition:color 0ms,background-color 0ms}.Button--color--good:focus{transition:color .1s,background-color .1s}.Button--color--good:focus,.Button--color--good:hover{background-color:#5da52d;color:#fff}.Button--color--average{transition:color 50ms,background-color 50ms;background-color:#cd7a0d;color:#fff}.Button--color--average:hover{transition:color 0ms,background-color 0ms}.Button--color--average:focus{transition:color .1s,background-color .1s}.Button--color--average:focus,.Button--color--average:hover{background-color:#e68d18;color:#fff}.Button--color--bad{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--bad:hover{transition:color 0ms,background-color 0ms}.Button--color--bad:focus{transition:color .1s,background-color .1s}.Button--color--bad:focus,.Button--color--bad:hover{background-color:#d52b2b;color:#fff}.Button--color--label{transition:color 50ms,background-color 50ms;background-color:#657a94;color:#fff}.Button--color--label:hover{transition:color 0ms,background-color 0ms}.Button--color--label:focus{transition:color .1s,background-color .1s}.Button--color--label:focus,.Button--color--label:hover{background-color:#7b8da4;color:#fff}.Button--color--default{transition:color 50ms,background-color 50ms;background-color:#3e6189;color:#fff}.Button--color--default:hover{transition:color 0ms,background-color 0ms}.Button--color--default:focus{transition:color .1s,background-color .1s}.Button--color--default:focus,.Button--color--default:hover{background-color:#4c729d;color:#fff}.Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--caution:hover{transition:color 0ms,background-color 0ms}.Button--color--caution:focus{transition:color .1s,background-color .1s}.Button--color--caution:focus,.Button--color--caution:hover{background-color:#f3d00e;color:#000}.Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--danger:hover{transition:color 0ms,background-color 0ms}.Button--color--danger:focus{transition:color .1s,background-color .1s}.Button--color--danger:focus,.Button--color--danger:hover{background-color:#d52b2b;color:#fff}.Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#252525;color:#fff;background-color:rgba(37,37,37,0);color:hsla(0,0%,100%,.5)}.Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.Button--color--transparent:focus{transition:color .1s,background-color .1s}.Button--color--transparent:focus,.Button--color--transparent:hover{background-color:#323232;color:#fff}.Button--disabled{background-color:#999!important}.Button--selected{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--selected:hover{transition:color 0ms,background-color 0ms}.Button--selected:focus{transition:color .1s,background-color .1s}.Button--selected:focus,.Button--selected:hover{background-color:#27ab46;color:#fff}.Collapsible{margin-bottom:.5rem}.Collapsible:last-child{margin-bottom:0}.ColorBox{display:inline-block;width:12px;height:12px;line-height:12px;text-align:center}.Dimmer{display:flex;justify-content:center;align-items:center;position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.75);z-index:1}.Divider--horizontal{margin:6px 0}.Divider--horizontal:not(.Divider--hidden){border-top:2px solid hsla(0,0%,100%,.1)}.Divider--vertical{height:100%;margin:0 6px}.Divider--vertical:not(.Divider--hidden){border-left:2px solid hsla(0,0%,100%,.1)}.Dropdown{position:relative}.Dropdown__control{position:relative;display:inline-block;font-family:Verdana,sans-serif;font-size:12px;width:100px;line-height:17px;user-select:none}.Dropdown__arrow-button{float:right;padding-left:6px;border-left:1px solid #000;border-left:1px solid rgba(0,0,0,.25)}.Dropdown__menu{overflow-y:auto;overflow-y:scroll}.Dropdown__menu,.Dropdown__menu-noscroll{position:absolute;z-index:5;width:100px;max-height:200px;border-radius:0 0 2px 2px;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menu-noscroll{overflow-y:auto}.Dropdown__menuentry{padding:2px 4px;font-family:Verdana,sans-serif;font-size:12px;line-height:17px;transition:background-color .1s}.Dropdown__menuentry:hover{background-color:#444;transition:background-color 0ms}.Dropdown__over{top:auto;bottom:100%}.FatalError{display:block!important;position:absolute;top:0;left:0;right:0;bottom:0;padding:12px;font-size:12px;font-family:Consolas,monospace;color:#fff;background-color:#00d;z-index:1000;overflow:hidden;text-align:center}.FatalError__logo{display:inline-block;text-align:left;font-size:10px;line-height:8px;position:relative;margin-top:12px;top:0;left:0;animation:FatalError__rainbow 2s linear infinite alternate,FatalError__shadow 4s linear infinite alternate,FatalError__tfmX 3s infinite alternate,FatalError__tfmY 4s infinite alternate;white-space:pre-wrap;word-break:break-all}.FatalError__header{margin-top:12px}.FatalError__stack{text-align:left;white-space:pre-wrap;word-break:break-all;margin-top:24px;margin-bottom:24px}.FatalError__footer{margin-bottom:24px}@keyframes FatalError__rainbow{0%{color:#ff0}50%{color:#0ff}to{color:#f0f}}@keyframes FatalError__shadow{0%{left:-2px;text-shadow:4px 0 #f0f}50%{left:0;text-shadow:0 0 #0ff}to{left:2px;text-shadow:-4px 0 #ff0}}@keyframes FatalError__tfmX{0%{left:15px}to{left:-15px}}@keyframes FatalError__tfmY{to{top:-15px}}.Flex{display:-ms-flexbox;display:flex}.Flex--inline{display:inline-flex}.Flex--ie8{display:table!important}.Flex--ie8--column{display:block!important}.Flex--ie8--column>.Flex__item{display:block!important;margin-left:6px;margin-right:6px}.Flex__item--ie8{display:table-cell!important}.Flex--spacing--1{margin:0 -3px}.Flex--spacing--1>.Flex__item{margin:0 3px}.Flex--spacingPrecise--1{margin:-1px}.Flex--spacingPrecise--1>.Flex__item{margin:1px}.Flex--spacing--2{margin:0 -6px}.Flex--spacing--2>.Flex__item{margin:0 6px}.Flex--spacingPrecise--2{margin:-2px}.Flex--spacingPrecise--2>.Flex__item{margin:2px}.Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto -.2em;cursor:n-resize}.Knob:after{content:".";color:transparent;line-height:2.5em}.Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(180deg,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,0));border-radius:50%;box-shadow:0 .05em .5em 0 rgba(0,0,0,.5)}.Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:hsla(0,0%,100%,.9)}.Knob__popupValue,.Knob__popupValue--right{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;background-color:#000;transform:translateX(50%);white-space:nowrap}.Knob__popupValue--right{top:.25rem;right:-50%}.Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.Knob__ringTrackPivot{transform:rotate(135deg)}.Knob__ringTrack{fill:transparent;stroke:hsla(0,0%,100%,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.Knob__ringFillPivot{transform:rotate(135deg)}.Knob--bipolar .Knob__ringFillPivot{transform:rotate(270deg)}.Knob__ringFill{fill:transparent;stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms}.Knob--color--black .Knob__ringFill{stroke:#0d0d0d}.Knob--color--white .Knob__ringFill{stroke:#fff}.Knob--color--red .Knob__ringFill{stroke:#d33}.Knob--color--orange .Knob__ringFill{stroke:#f37827}.Knob--color--yellow .Knob__ringFill{stroke:#fbd814}.Knob--color--olive .Knob__ringFill{stroke:#c0d919}.Knob--color--green .Knob__ringFill{stroke:#22be47}.Knob--color--teal .Knob__ringFill{stroke:#00c5bd}.Knob--color--blue .Knob__ringFill{stroke:#238cdc}.Knob--color--violet .Knob__ringFill{stroke:#6c3fcc}.Knob--color--purple .Knob__ringFill{stroke:#a93bcd}.Knob--color--pink .Knob__ringFill{stroke:#e2439c}.Knob--color--brown .Knob__ringFill{stroke:#af6d43}.Knob--color--grey .Knob__ringFill{stroke:#7d7d7d}.Knob--color--good .Knob__ringFill{stroke:#62b62a}.Knob--color--average .Knob__ringFill{stroke:#f1951d}.Knob--color--bad .Knob__ringFill{stroke:#d33}.Knob--color--label .Knob__ringFill{stroke:#8496ab}.LabeledList{display:table;width:100%;width:calc(100% + 12px);border-collapse:collapse;border-spacing:0;margin:-3px -6px 0;padding:0}.LabeledList__row{display:table-row}.LabeledList__row:last-child .LabeledList__cell{padding-bottom:0}.LabeledList__cell{display:table-cell;margin:0;padding:3px 6px;border:0;text-align:left;vertical-align:baseline}.LabeledList__label{width:1%;white-space:nowrap;min-width:60px}.LabeledList__buttons{width:.1%;white-space:nowrap;text-align:right;padding-top:1px;padding-bottom:0}.LabeledList__breakContents{word-break:break-all;word-wrap:break-word}.Modal{background-color:#252525;max-width:calc(100% - 1rem);padding:1rem;scrollbar-base-color:#1c1c1c;scrollbar-face-color:#3b3b3b;scrollbar-3dlight-color:#252525;scrollbar-highlight-color:#252525;scrollbar-track-color:#1c1c1c;scrollbar-arrow-color:#929292;scrollbar-shadow-color:#3b3b3b}.NanoMap__container{overflow:hiddden;width:100%;z-index:1}.NanoMap__marker{z-index:10;padding:0;margin:0}.NanoMap__zoomer{z-index:20;background-color:rgba(0,0,0,.33);position:absolute;top:30px;left:0;padding:.5rem;width:20%}.NoticeBox{padding:4px 6px;margin-bottom:6px;box-shadow:none;font-weight:700;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,transparent,transparent 10px,rgba(0,0,0,.1) 0,rgba(0,0,0,.1) 20px)}.NoticeBox--color--black{color:#fff;background-color:#000}.NoticeBox--color--white{color:#000;background-color:#b3b3b3}.NoticeBox--color--red{color:#fff;background-color:#701f1f}.NoticeBox--color--orange{color:#fff;background-color:#854114}.NoticeBox--color--yellow{color:#000;background-color:#83710d}.NoticeBox--color--olive{color:#000;background-color:#576015}.NoticeBox--color--green{color:#fff;background-color:#174e24}.NoticeBox--color--teal{color:#fff;background-color:#064845}.NoticeBox--color--blue{color:#fff;background-color:#1b4565}.NoticeBox--color--violet{color:#fff;background-color:#3b2864}.NoticeBox--color--purple{color:#fff;background-color:#542663}.NoticeBox--color--pink{color:#fff;background-color:#802257}.NoticeBox--color--brown{color:#fff;background-color:#4c3729}.NoticeBox--color--grey{color:#fff;background-color:#3e3e3e}.NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.NoticeBox--color--average{color:#fff;background-color:#7b4e13}.NoticeBox--color--bad{color:#fff;background-color:#701f1f}.NoticeBox--color--label{color:#fff;background-color:#53565a}.NoticeBox--type--info{color:#fff;background-color:#235982}.NoticeBox--type--success{color:#fff;background-color:#1e662f}.NoticeBox--type--warning{color:#fff;background-color:#a95219}.NoticeBox--type--danger{color:#fff;background-color:#8f2828}.Input{position:relative;display:inline-block;width:120px;border:1px solid #88bfff;border:1px solid rgba(136,191,255,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.NumberInput{position:relative;display:inline-block;border:1px solid #88bfff;border:1px solid rgba(136,191,255,.75);border-radius:2px;color:#88bfff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.NumberInput--fluid{display:block}.NumberInput__content{margin-left:6px}.NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #88bfff;background-color:#88bfff}.NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:transparent;transition:border-color .5s}.ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.ProgressBar__fill--animated{transition:background-color .5s,width .5s}.ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.ProgressBar--color--default{border:1px solid #3e6189}.ProgressBar--color--default .ProgressBar__fill{background-color:#3e6189}.ProgressBar--color--black{border:1px solid #000!important}.ProgressBar--color--black .ProgressBar__fill{background-color:#000}.ProgressBar--color--white{border:1px solid #d9d9d9!important}.ProgressBar--color--white .ProgressBar__fill{background-color:#d9d9d9}.ProgressBar--color--red{border:1px solid #bd2020!important}.ProgressBar--color--red .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--orange{border:1px solid #d95e0c!important}.ProgressBar--color--orange .ProgressBar__fill{background-color:#d95e0c}.ProgressBar--color--yellow{border:1px solid #d9b804!important}.ProgressBar--color--yellow .ProgressBar__fill{background-color:#d9b804}.ProgressBar--color--olive{border:1px solid #9aad14!important}.ProgressBar--color--olive .ProgressBar__fill{background-color:#9aad14}.ProgressBar--color--green{border:1px solid #1b9638!important}.ProgressBar--color--green .ProgressBar__fill{background-color:#1b9638}.ProgressBar--color--teal{border:1px solid #009a93!important}.ProgressBar--color--teal .ProgressBar__fill{background-color:#009a93}.ProgressBar--color--blue{border:1px solid #1c71b1!important}.ProgressBar--color--blue .ProgressBar__fill{background-color:#1c71b1}.ProgressBar--color--violet{border:1px solid #552dab!important}.ProgressBar--color--violet .ProgressBar__fill{background-color:#552dab}.ProgressBar--color--purple{border:1px solid #8b2baa!important}.ProgressBar--color--purple .ProgressBar__fill{background-color:#8b2baa}.ProgressBar--color--pink{border:1px solid #cf2082!important}.ProgressBar--color--pink .ProgressBar__fill{background-color:#cf2082}.ProgressBar--color--brown{border:1px solid #8c5836!important}.ProgressBar--color--brown .ProgressBar__fill{background-color:#8c5836}.ProgressBar--color--grey{border:1px solid #646464!important}.ProgressBar--color--grey .ProgressBar__fill{background-color:#646464}.ProgressBar--color--good{border:1px solid #4d9121!important}.ProgressBar--color--good .ProgressBar__fill{background-color:#4d9121}.ProgressBar--color--average{border:1px solid #cd7a0d!important}.ProgressBar--color--average .ProgressBar__fill{background-color:#cd7a0d}.ProgressBar--color--bad{border:1px solid #bd2020!important}.ProgressBar--color--bad .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--label{border:1px solid #657a94!important}.ProgressBar--color--label .ProgressBar__fill{background-color:#657a94}.Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#1c1c1c;scrollbar-face-color:#3b3b3b;scrollbar-3dlight-color:#252525;scrollbar-highlight-color:#252525;scrollbar-track-color:#1c1c1c;scrollbar-arrow-color:#929292;scrollbar-shadow-color:#3b3b3b}.Section:last-child{margin-bottom:0}.Section--flex{display:flex;flex-flow:column}.Section--flex .Section__content{overflow:auto;flex:1}.Section__title{padding:6px;border-bottom:2px solid #4972a1}.Section__titleText{font-size:14px;font-weight:700}.Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.Section__content{padding:8px 6px}.Section__content--noTopPadding{padding-top:0}.Section__content--stretchContents{height:100%}.Section--level--1 .Section__titleText{font-size:14px}.Section--level--2 .Section__titleText{font-size:13px}.Section--level--3 .Section__titleText{font-size:12px}.Section--level--2,.Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.Slider{cursor:e-resize}.Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none!important}.Slider__cursor{position:absolute;top:0;right:-1px;bottom:0;width:0;border-left:2px solid #fff}.Slider__pointer{position:absolute;right:-5px;bottom:-4px;width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #fff}.Slider__popupValue{position:absolute;right:0;top:-22px;padding:2px 4px;background-color:#000;transform:translateX(50%);white-space:nowrap}.Table{display:table;width:100%;border-collapse:collapse;border-spacing:0;margin:0}.Table--collapsing{width:auto}.Table__row{display:table-row}.Table__cell{display:table-cell;padding:0 3px}.Table__cell:first-child{padding-left:0}.Table__cell:last-child{padding-right:0}.Table__cell--header,.Table__row--header .Table__cell{font-weight:700;padding-bottom:6px}.Table__cell--collapsing{width:1%;white-space:nowrap}.Tabs--horizontal{border-bottom:2px solid hsla(0,0%,100%,.1);margin-bottom:6px}.Tabs--horizontal .Tabs__tab--altSelection:after{content:"";position:absolute;bottom:0;right:0;left:0;height:2px;width:100%;background-color:#fff;border-radius:2px}.Tabs--vertical{margin-right:9px}.Tabs--vertical .Tabs__tabBox{border-right:2px solid hsla(0,0%,100%,.1);vertical-align:top}.Tabs--vertical .Tabs__tab{display:block!important;margin-right:0!important;margin-bottom:0;padding:1px 9px 0 6px;border-bottom:2px solid hsla(0,0%,100%,.1)}.Tabs--vertical .Tabs__tab:last-child{border-bottom:0}.Tabs--vertical .Tabs__tab--altSelection:after{content:"";position:absolute;top:0;bottom:0;right:0;height:100%;width:3px;background-color:#fff;border-radius:2px}.Tooltip{position:absolute;top:0;left:0;right:0;bottom:0;font-style:normal;font-weight:400}.Tooltip:after{position:absolute;display:block;white-space:nowrap;z-index:2;padding:6px 10px;transform:translateX(-50%);pointer-events:none;visibility:hidden;opacity:0;text-align:left;content:attr(data-tooltip);transition:all .15s;background-color:#000;box-shadow:1px 1px 15px -1px rgba(0,0,0,.5);border-radius:2px}.Tooltip:hover:after{transition:all 70ms;pointer-events:none;visibility:visible;opacity:1}.Tooltip--long:after{width:250px;white-space:normal}.Tooltip--top:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}.Tooltip--top:hover:after{transform:translateX(-50%) translateY(-8px)}.Tooltip--top-left:after{bottom:100%;right:50%;transform:translateX(12px) translateY(-8px)}.Tooltip--top-left:hover:after{transform:translateX(12px) translateY(8px)}.Tooltip--top-right:after{bottom:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.Tooltip--top-right:hover:after{transform:translateX(-12px) translateY(8px)}.Tooltip--bottom:after{top:100%;left:50%;transform:translateX(-50%) translateY(-8px)}.Tooltip--bottom:hover:after{transform:translateX(-50%) translateY(8px)}.Tooltip--bottom-left:after{top:100%;right:50%;transform:translateX(12px) translateY(-8px)}.Tooltip--bottom-left:hover:after{transform:translateX(12px) translateY(8px)}.Tooltip--bottom-right:after{top:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.Tooltip--bottom-right:hover:after{transform:translateX(-12px) translateY(8px)}.Tooltip--left:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}.Tooltip--left:hover:after,.Tooltip--right:after{transform:translateX(-8px) translateY(-50%)}.Tooltip--right:after{top:50%;left:100%}.Tooltip--right:hover:after{transform:translateX(8px) translateY(-50%)}.CameraConsole__left{position:absolute;top:0;bottom:0;left:0;width:220px}.CameraConsole__right{position:absolute;top:0;bottom:0;left:220px;right:0;background-color:rgba(0,0,0,.33)}.CameraConsole__toolbar{left:0;margin:3px 12px 0}.CameraConsole__toolbar,.CameraConsole__toolbarRight{position:absolute;top:0;right:0;height:24px;line-height:24px}.CameraConsole__toolbarRight{margin:4px 6px 0}.CameraConsole__map{position:absolute;top:26px;bottom:0;left:0;right:0;margin:6px;text-align:center}.CameraConsole__map .NoticeBox{margin-top:calc(50% - 24px)}.NuclearBomb__displayBox{background-color:#002003;border:4px inset #e8e4c9;color:#03e017;font-size:24px;font-family:monospace;padding:6px}.NuclearBomb__Button--keypad{background-color:#e8e4c9;border-color:#e8e4c9}.NuclearBomb__Button--keypad:hover{background-color:#f7f6ee!important;border-color:#f7f6ee!important}.NuclearBomb__Button--1{background-color:#d3cfb7!important;border-color:#d3cfb7!important;color:#a9a692!important}.NuclearBomb__Button--E{background-color:#d9b804!important;border-color:#d9b804!important}.NuclearBomb__Button--E:hover{background-color:#f3d00e!important;border-color:#f3d00e!important}.NuclearBomb__Button--C{background-color:#bd2020!important;border-color:#bd2020!important}.NuclearBomb__Button--C:hover{background-color:#d52b2b!important;border-color:#d52b2b!important}.NuclearBomb__NTIcon{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDQyNSAyMDAiIG9wYWNpdHk9Ii4zMyI+PHBhdGggZD0iTTE3OC4wMDQuMDM5SDEwNi44YTYuNzYxIDYuMDI2IDAgMDAtNi43NjEgNi4wMjV2MTg3Ljg3MmE2Ljc2MSA2LjAyNiAwIDAwNi43NjEgNi4wMjVoNTMuMTA3YTYuNzYxIDYuMDI2IDAgMDA2Ljc2Mi02LjAyNVY5Mi4zOTJsNzIuMjE2IDEwNC43YTYuNzYxIDYuMDI2IDAgMDA1Ljc2IDIuODdIMzE4LjJhNi43NjEgNi4wMjYgMCAwMDYuNzYxLTYuMDI2VjYuMDY0QTYuNzYxIDYuMDI2IDAgMDAzMTguMi4wNGgtNTQuNzE3YTYuNzYxIDYuMDI2IDAgMDAtNi43NiA2LjAyNXYxMDIuNjJMMTgzLjc2MyAyLjkwOWE2Ljc2MSA2LjAyNiAwIDAwLTUuNzYtMi44N3pNNC44NDUgMjIuMTA5QTEzLjQxMiAxMi41MDIgMCAwMTEzLjQ3OC4wMzloNjYuMTE4QTUuMzY1IDUgMCAwMTg0Ljk2IDUuMDR2NzkuODh6TTQyMC4xNTUgMTc3Ljg5MWExMy40MTIgMTIuNTAyIDAgMDEtOC42MzMgMjIuMDdoLTY2LjExOGE1LjM2NSA1IDAgMDEtNS4zNjUtNS4wMDF2LTc5Ljg4eiIvPjwvc3ZnPg==);background-size:70%;background-position:50%;background-repeat:no-repeat}.Roulette{font-family:Palatino}.Roulette__board{display:table;width:100%;border-collapse:collapse;border:2px solid #fff;margin:0}.Roulette__board-row{padding:0;margin:0}.Roulette__board-cell{display:table-cell;padding:0;margin:0;border:2px solid #fff;font-family:Palatino}.Roulette__board-cell:first-child{padding-left:0}.Roulette__board-cell:last-child{padding-right:0}.Roulette__board-extrabutton{text-align:center;font-size:20px;font-weight:700;height:28px;border:none!important;margin:0!important;padding-top:4px!important;color:#fff!important}.Roulette__lowertable{margin-top:8px;margin-left:80px;margin-right:80px;border-collapse:collapse;border:2px solid #fff;border-spacing:0}.Roulette__lowertable--cell{border:2px solid #fff;padding:0;margin:0}.Roulette__lowertable--betscell{vertical-align:top}.Roulette__lowertable--spinresult{text-align:center;font-size:100px;font-weight:700;vertical-align:middle}.Roulette__lowertable--spinresult-black{background-color:#000}.Roulette__lowertable--spinresult-red{background-color:#db2828}.Roulette__lowertable--spinresult-green{background-color:#20b142}.Roulette__lowertable--spinbutton{margin:0!important;border:none!important;font-size:50px;line-height:60px!important;text-align:center;font-weight:700}.Roulette__lowertable--header{width:1%;text-align:center;font-size:20px;font-weight:700}.Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#1c1c1c;scrollbar-face-color:#3b3b3b;scrollbar-3dlight-color:#252525;scrollbar-highlight-color:#252525;scrollbar-track-color:#1c1c1c;scrollbar-arrow-color:#929292;scrollbar-shadow-color:#3b3b3b}.Layout__content--flexRow{display:flex;flex-flow:row}.Layout__content--flexColumn{display:flex;flex-flow:column}.Layout__content--scrollable{overflow-y:auto}.Layout__content--noMargin{margin:0}.NtosHeader__left{position:absolute;left:12px}.NtosHeader__right{position:absolute;right:12px}.NtosHeader__icon{margin-top:-9px;margin-bottom:-6px;vertical-align:middle}.NtosWindow__header{position:absolute;top:0;left:0;right:0;height:28px;line-height:27px;background-color:rgba(0,0,0,.5);font-family:Consolas,monospace;font-size:14px;user-select:none;-ms-user-select:none}.NtosWindow__content .Layout__content{margin-top:28px;font-family:Consolas,monospace;font-size:14px}.TitleBar{background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#363636;transition:color .25s,background-color .25s}.TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.TitleBar__minimize{position:absolute;top:6px;right:46px}.TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.Window{bottom:0;right:0;color:#fff;background-color:#252525;background-image:linear-gradient(180deg,#2a2a2a 0,#202020)}.Window,.Window__titleBar{position:fixed;top:0;left:0}.Window__titleBar{z-index:1;width:100%;height:32px}.Window__rest{top:32px}.Window__dimmer,.Window__rest{position:fixed;bottom:0;left:0;right:0}.Window__dimmer{top:0;background-color:rgba(62,62,62,.25);pointer-events:none}.Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#131313;color:hsla(0,0%,100%,.8)}.Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.Layout__content{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDQyNSAyMDAiIG9wYWNpdHk9Ii4zMyI+PHBhdGggZD0iTTE3OC4wMDQuMDM5SDEwNi44YTYuNzYxIDYuMDI2IDAgMDAtNi43NjEgNi4wMjV2MTg3Ljg3MmE2Ljc2MSA2LjAyNiAwIDAwNi43NjEgNi4wMjVoNTMuMTA3YTYuNzYxIDYuMDI2IDAgMDA2Ljc2Mi02LjAyNVY5Mi4zOTJsNzIuMjE2IDEwNC43YTYuNzYxIDYuMDI2IDAgMDA1Ljc2IDIuODdIMzE4LjJhNi43NjEgNi4wMjYgMCAwMDYuNzYxLTYuMDI2VjYuMDY0QTYuNzYxIDYuMDI2IDAgMDAzMTguMi4wNGgtNTQuNzE3YTYuNzYxIDYuMDI2IDAgMDAtNi43NiA2LjAyNXYxMDIuNjJMMTgzLjc2MyAyLjkwOWE2Ljc2MSA2LjAyNiAwIDAwLTUuNzYtMi44N3pNNC44NDUgMjIuMTA5QTEzLjQxMiAxMi41MDIgMCAwMTEzLjQ3OC4wMzloNjYuMTE4QTUuMzY1IDUgMCAwMTg0Ljk2IDUuMDR2NzkuODh6TTQyMC4xNTUgMTc3Ljg5MWExMy40MTIgMTIuNTAyIDAgMDEtOC42MzMgMjIuMDdoLTY2LjExOGE1LjM2NSA1IDAgMDEtNS4zNjUtNS4wMDF2LTc5Ljg4eiIvPjwvc3ZnPg==);background-size:70%;background-position:50%;background-repeat:no-repeat}.theme-cardtable .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:0;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-cardtable .Button:last-child{margin-right:0}.theme-cardtable .Button .fa,.theme-cardtable .Button .far,.theme-cardtable .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-cardtable .Button--hasContent .fa,.theme-cardtable .Button--hasContent .far,.theme-cardtable .Button--hasContent .fas{margin-right:3px}.theme-cardtable .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-cardtable .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-cardtable .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#117039;color:#fff}.theme-cardtable .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--default:focus,.theme-cardtable .Button--color--default:hover{background-color:#1c8247;color:#fff}.theme-cardtable .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-cardtable .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--caution:focus,.theme-cardtable .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-cardtable .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-cardtable .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--danger:focus,.theme-cardtable .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-cardtable .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#117039;color:#fff;background-color:rgba(17,112,57,0);color:hsla(0,0%,100%,.5)}.theme-cardtable .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--color--transparent:focus,.theme-cardtable .Button--color--transparent:hover{background-color:#1c8247;color:#fff}.theme-cardtable .Button--disabled{background-color:#363636!important}.theme-cardtable .Button--selected{transition:color 50ms,background-color 50ms;background-color:#9d0808;color:#fff}.theme-cardtable .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-cardtable .Button--selected:focus{transition:color .1s,background-color .1s}.theme-cardtable .Button--selected:focus,.theme-cardtable .Button--selected:hover{background-color:#b31212;color:#fff}.theme-cardtable .Input{position:relative;display:inline-block;width:120px;border:1px solid #88bfff;border:1px solid rgba(136,191,255,.75);border-radius:0;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-cardtable .Input--fluid{display:block;width:auto}.theme-cardtable .Input__baseline{display:inline-block;color:transparent}.theme-cardtable .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-cardtable .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-cardtable .NumberInput{position:relative;display:inline-block;border:1px solid #fff;border:1px solid hsla(0,0%,100%,.75);border-radius:0;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.theme-cardtable .NumberInput--fluid{display:block}.theme-cardtable .NumberInput__content{margin-left:6px}.theme-cardtable .NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.theme-cardtable .NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #fff;background-color:#fff}.theme-cardtable .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.theme-cardtable .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-cardtable .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-cardtable .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-cardtable .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-cardtable .ProgressBar--color--default{border:1px solid #000}.theme-cardtable .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-cardtable .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#0d542b;scrollbar-face-color:#16914a;scrollbar-3dlight-color:#117039;scrollbar-highlight-color:#117039;scrollbar-track-color:#0d542b;scrollbar-arrow-color:#5ae695;scrollbar-shadow-color:#16914a}.theme-cardtable .Section:last-child{margin-bottom:0}.theme-cardtable .Section--flex{display:flex;flex-flow:column}.theme-cardtable .Section--flex .Section__content{overflow:auto;flex:1}.theme-cardtable .Section__title{padding:6px;border-bottom:2px solid #000}.theme-cardtable .Section__titleText{font-size:14px;font-weight:700}.theme-cardtable .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-cardtable .Section__content{padding:8px 6px}.theme-cardtable .Section__content--noTopPadding{padding-top:0}.theme-cardtable .Section__content--stretchContents{height:100%}.theme-cardtable .Section--level--1 .Section__titleText{font-size:14px}.theme-cardtable .Section--level--2 .Section__titleText{font-size:13px}.theme-cardtable .Section--level--3 .Section__titleText{font-size:12px}.theme-cardtable .Section--level--2,.theme-cardtable .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-cardtable .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#0d542b;scrollbar-face-color:#16914a;scrollbar-3dlight-color:#117039;scrollbar-highlight-color:#117039;scrollbar-track-color:#0d542b;scrollbar-arrow-color:#5ae695;scrollbar-shadow-color:#16914a}.theme-cardtable .Layout__content--flexRow{display:flex;flex-flow:row}.theme-cardtable .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-cardtable .Layout__content--scrollable{overflow-y:auto}.theme-cardtable .Layout__content--noMargin{margin:0}.theme-cardtable .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#117039;background-image:linear-gradient(180deg,#117039 0,#117039)}.theme-cardtable .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-cardtable .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-cardtable .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(39,148,85,.25);pointer-events:none}.theme-cardtable .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#09381d;color:hsla(0,0%,100%,.8)}.theme-cardtable .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-cardtable .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-cardtable .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-cardtable .TitleBar{background-color:#381608;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-cardtable .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#381608;transition:color .25s,background-color .25s}.theme-cardtable .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-cardtable .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-cardtable .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-cardtable .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-cardtable .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-cardtable .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-cardtable .Button{border:2px solid #fff}.theme-hackerman .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-hackerman .Button:last-child{margin-right:0}.theme-hackerman .Button .fa,.theme-hackerman .Button .far,.theme-hackerman .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-hackerman .Button--hasContent .fa,.theme-hackerman .Button--hasContent .far,.theme-hackerman .Button--hasContent .fas{margin-right:3px}.theme-hackerman .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-hackerman .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-hackerman .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#0f0;color:#000}.theme-hackerman .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--default:focus,.theme-hackerman .Button--color--default:hover{background-color:#26ff26;color:#000}.theme-hackerman .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.theme-hackerman .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--caution:focus,.theme-hackerman .Button--color--caution:hover{background-color:#f3d00e;color:#000}.theme-hackerman .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.theme-hackerman .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--danger:focus,.theme-hackerman .Button--color--danger:hover{background-color:#d52b2b;color:#fff}.theme-hackerman .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#121b12;color:#fff;background-color:rgba(18,27,18,0);color:hsla(0,0%,100%,.5)}.theme-hackerman .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--color--transparent:focus,.theme-hackerman .Button--color--transparent:hover{background-color:#1d271d;color:#fff}.theme-hackerman .Button--disabled{background-color:#4a6a4a!important}.theme-hackerman .Button--selected{transition:color 50ms,background-color 50ms;background-color:#0f0;color:#000}.theme-hackerman .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-hackerman .Button--selected:focus{transition:color .1s,background-color .1s}.theme-hackerman .Button--selected:focus,.theme-hackerman .Button--selected:hover{background-color:#26ff26;color:#000}.theme-hackerman .Input{position:relative;display:inline-block;width:120px;border:1px solid #0f0;border:1px solid rgba(0,255,0,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-hackerman .Input--fluid{display:block;width:auto}.theme-hackerman .Input__baseline{display:inline-block;color:transparent}.theme-hackerman .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-hackerman .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-hackerman .Modal{background-color:#121b12;max-width:calc(100% - 1rem);padding:1rem}.theme-hackerman .Modal,.theme-hackerman .Section{scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box}.theme-hackerman .Section:last-child{margin-bottom:0}.theme-hackerman .Section--flex{display:flex;flex-flow:column}.theme-hackerman .Section--flex .Section__content{overflow:auto;flex:1}.theme-hackerman .Section__title{padding:6px;border-bottom:2px solid #0f0}.theme-hackerman .Section__titleText{font-size:14px;font-weight:700}.theme-hackerman .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-hackerman .Section__content{padding:8px 6px}.theme-hackerman .Section__content--noTopPadding{padding-top:0}.theme-hackerman .Section__content--stretchContents{height:100%}.theme-hackerman .Section--level--1 .Section__titleText{font-size:14px}.theme-hackerman .Section--level--2 .Section__titleText{font-size:13px}.theme-hackerman .Section--level--3 .Section__titleText{font-size:12px}.theme-hackerman .Section--level--2,.theme-hackerman .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-hackerman .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#0e140e;scrollbar-face-color:#253725;scrollbar-3dlight-color:#121b12;scrollbar-highlight-color:#121b12;scrollbar-track-color:#0e140e;scrollbar-arrow-color:#74a274;scrollbar-shadow-color:#253725}.theme-hackerman .Layout__content--flexRow{display:flex;flex-flow:row}.theme-hackerman .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-hackerman .Layout__content--scrollable{overflow-y:auto}.theme-hackerman .Layout__content--noMargin{margin:0}.theme-hackerman .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#121b12;background-image:linear-gradient(180deg,#121b12 0,#121b12)}.theme-hackerman .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-hackerman .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-hackerman .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(40,50,40,.25);pointer-events:none}.theme-hackerman .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#090e09;color:hsla(0,0%,100%,.8)}.theme-hackerman .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-hackerman .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-hackerman .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-hackerman .TitleBar{background-color:#223d22;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-hackerman .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#223d22;transition:color .25s,background-color .25s}.theme-hackerman .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-hackerman .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-hackerman .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-hackerman .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-hackerman .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-hackerman .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-hackerman .Layout__content{background-image:none}.theme-hackerman .Button{font-family:monospace;border:2px outset #0a0;outline:1px solid #007a00}.theme-hackerman .candystripe:nth-child(odd){background-color:rgba(0,100,0,.5)}.theme-malfunction .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-malfunction .Button:last-child{margin-right:0}.theme-malfunction .Button .fa,.theme-malfunction .Button .far,.theme-malfunction .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-malfunction .Button--hasContent .fa,.theme-malfunction .Button--hasContent .far,.theme-malfunction .Button--hasContent .fas{margin-right:3px}.theme-malfunction .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-malfunction .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-malfunction .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#910101;color:#fff}.theme-malfunction .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--default:focus,.theme-malfunction .Button--color--default:hover{background-color:#a60b0b;color:#fff}.theme-malfunction .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-malfunction .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--caution:focus,.theme-malfunction .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-malfunction .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-malfunction .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--danger:focus,.theme-malfunction .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-malfunction .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#1b3443;color:#fff;background-color:rgba(27,52,67,0);color:hsla(0,0%,100%,.5)}.theme-malfunction .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--color--transparent:focus,.theme-malfunction .Button--color--transparent:hover{background-color:#274252;color:#fff}.theme-malfunction .Button--disabled{background-color:#363636!important}.theme-malfunction .Button--selected{transition:color 50ms,background-color 50ms;background-color:#1e5881;color:#fff}.theme-malfunction .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-malfunction .Button--selected:focus{transition:color .1s,background-color .1s}.theme-malfunction .Button--selected:focus,.theme-malfunction .Button--selected:hover{background-color:#2a6894;color:#fff}.theme-malfunction .NoticeBox{padding:4px 6px;margin-bottom:6px;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#1a3f57;background-image:repeating-linear-gradient(-45deg,transparent,transparent 10px,rgba(0,0,0,.1) 0,rgba(0,0,0,.1) 20px)}.theme-malfunction .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-malfunction .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-malfunction .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-malfunction .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-malfunction .Input{position:relative;display:inline-block;width:120px;border:1px solid #910101;border:1px solid rgba(145,1,1,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-malfunction .Input--fluid{display:block;width:auto}.theme-malfunction .Input__baseline{display:inline-block;color:transparent}.theme-malfunction .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-malfunction .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-malfunction .NumberInput{position:relative;display:inline-block;border:1px solid #910101;border:1px solid rgba(145,1,1,.75);border-radius:2px;color:#910101;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.theme-malfunction .NumberInput--fluid{display:block}.theme-malfunction .NumberInput__content{margin-left:6px}.theme-malfunction .NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.theme-malfunction .NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #910101;background-color:#910101}.theme-malfunction .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.theme-malfunction .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-malfunction .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-malfunction .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-malfunction .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-malfunction .ProgressBar--color--default{border:1px solid #7b0101}.theme-malfunction .ProgressBar--color--default .ProgressBar__fill{background-color:#7b0101}.theme-malfunction .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#142732;scrollbar-face-color:#274b61;scrollbar-3dlight-color:#1b3443;scrollbar-highlight-color:#1b3443;scrollbar-track-color:#142732;scrollbar-arrow-color:#6ba2c3;scrollbar-shadow-color:#274b61}.theme-malfunction .Section:last-child{margin-bottom:0}.theme-malfunction .Section--flex{display:flex;flex-flow:column}.theme-malfunction .Section--flex .Section__content{overflow:auto;flex:1}.theme-malfunction .Section__title{padding:6px;border-bottom:2px solid #910101}.theme-malfunction .Section__titleText{font-size:14px;font-weight:700}.theme-malfunction .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-malfunction .Section__content{padding:8px 6px}.theme-malfunction .Section__content--noTopPadding{padding-top:0}.theme-malfunction .Section__content--stretchContents{height:100%}.theme-malfunction .Section--level--1 .Section__titleText{font-size:14px}.theme-malfunction .Section--level--2 .Section__titleText{font-size:13px}.theme-malfunction .Section--level--3 .Section__titleText{font-size:12px}.theme-malfunction .Section--level--2,.theme-malfunction .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-malfunction .Tooltip{position:absolute;top:0;left:0;right:0;bottom:0;font-style:normal;font-weight:400}.theme-malfunction .Tooltip:after{position:absolute;display:block;white-space:nowrap;z-index:2;padding:6px 10px;transform:translateX(-50%);pointer-events:none;visibility:hidden;opacity:0;text-align:left;content:attr(data-tooltip);transition:all .15s;background-color:#235577;box-shadow:1px 1px 15px -1px rgba(0,0,0,.5);border-radius:2px}.theme-malfunction .Tooltip:hover:after{transition:all 70ms;pointer-events:none;visibility:visible;opacity:1}.theme-malfunction .Tooltip--long:after{width:250px;white-space:normal}.theme-malfunction .Tooltip--top:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}.theme-malfunction .Tooltip--top:hover:after{transform:translateX(-50%) translateY(-8px)}.theme-malfunction .Tooltip--top-left:after{bottom:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-malfunction .Tooltip--top-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-malfunction .Tooltip--top-right:after{bottom:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-malfunction .Tooltip--top-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-malfunction .Tooltip--bottom:after{top:100%;left:50%;transform:translateX(-50%) translateY(-8px)}.theme-malfunction .Tooltip--bottom:hover:after{transform:translateX(-50%) translateY(8px)}.theme-malfunction .Tooltip--bottom-left:after{top:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-malfunction .Tooltip--bottom-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-malfunction .Tooltip--bottom-right:after{top:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-malfunction .Tooltip--bottom-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-malfunction .Tooltip--left:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}.theme-malfunction .Tooltip--left:hover:after,.theme-malfunction .Tooltip--right:after{transform:translateX(-8px) translateY(-50%)}.theme-malfunction .Tooltip--right:after{top:50%;left:100%}.theme-malfunction .Tooltip--right:hover:after{transform:translateX(8px) translateY(-50%)}.theme-malfunction .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#142732;scrollbar-face-color:#274b61;scrollbar-3dlight-color:#1b3443;scrollbar-highlight-color:#1b3443;scrollbar-track-color:#142732;scrollbar-arrow-color:#6ba2c3;scrollbar-shadow-color:#274b61}.theme-malfunction .Layout__content--flexRow{display:flex;flex-flow:row}.theme-malfunction .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-malfunction .Layout__content--scrollable{overflow-y:auto}.theme-malfunction .Layout__content--noMargin{margin:0}.theme-malfunction .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1b3443;background-image:linear-gradient(180deg,#244559 0,#12232d)}.theme-malfunction .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-malfunction .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-malfunction .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(50,79,96,.25);pointer-events:none}.theme-malfunction .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#0e1a22;color:hsla(0,0%,100%,.8)}.theme-malfunction .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-malfunction .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-malfunction .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-malfunction .TitleBar{background-color:#1a3f57;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-malfunction .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#1a3f57;transition:color .25s,background-color .25s}.theme-malfunction .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-malfunction .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-malfunction .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-malfunction .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-malfunction .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-malfunction .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-malfunction .Layout__content{background-image:none}.theme-ntos .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-ntos .Button:last-child{margin-right:0}.theme-ntos .Button .fa,.theme-ntos .Button .far,.theme-ntos .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-ntos .Button--hasContent .fa,.theme-ntos .Button--hasContent .far,.theme-ntos .Button--hasContent .fas{margin-right:3px}.theme-ntos .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-ntos .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-ntos .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#384e68;color:#fff}.theme-ntos .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--default:focus,.theme-ntos .Button--color--default:hover{background-color:#465e7a;color:#fff}.theme-ntos .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.theme-ntos .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--caution:focus,.theme-ntos .Button--color--caution:hover{background-color:#f3d00e;color:#000}.theme-ntos .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.theme-ntos .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--danger:focus,.theme-ntos .Button--color--danger:hover{background-color:#d52b2b;color:#fff}.theme-ntos .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#1f2b39;color:#fff;background-color:rgba(31,43,57,0);color:rgba(227,240,255,.75)}.theme-ntos .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--color--transparent:focus,.theme-ntos .Button--color--transparent:hover{background-color:#2b3847;color:#fff}.theme-ntos .Button--disabled{background-color:#999!important}.theme-ntos .Button--selected{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.theme-ntos .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-ntos .Button--selected:focus{transition:color .1s,background-color .1s}.theme-ntos .Button--selected:focus,.theme-ntos .Button--selected:hover{background-color:#27ab46;color:#fff}.theme-ntos .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-ntos .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-ntos .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-ntos .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-ntos .ProgressBar--color--default{border:1px solid #384e68}.theme-ntos .ProgressBar--color--default .ProgressBar__fill{background-color:#384e68}.theme-ntos .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#17202b;scrollbar-face-color:#2e3f55;scrollbar-3dlight-color:#1f2b39;scrollbar-highlight-color:#1f2b39;scrollbar-track-color:#17202b;scrollbar-arrow-color:#7693b5;scrollbar-shadow-color:#2e3f55}.theme-ntos .Section:last-child{margin-bottom:0}.theme-ntos .Section--flex{display:flex;flex-flow:column}.theme-ntos .Section--flex .Section__content{overflow:auto;flex:1}.theme-ntos .Section__title{padding:6px;border-bottom:2px solid #4972a1}.theme-ntos .Section__titleText{font-size:14px;font-weight:700}.theme-ntos .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-ntos .Section__content{padding:8px 6px}.theme-ntos .Section__content--noTopPadding{padding-top:0}.theme-ntos .Section__content--stretchContents{height:100%}.theme-ntos .Section--level--1 .Section__titleText{font-size:14px}.theme-ntos .Section--level--2 .Section__titleText{font-size:13px}.theme-ntos .Section--level--3 .Section__titleText{font-size:12px}.theme-ntos .Section--level--2,.theme-ntos .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-ntos .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#17202b;scrollbar-face-color:#2e3f55;scrollbar-3dlight-color:#1f2b39;scrollbar-highlight-color:#1f2b39;scrollbar-track-color:#17202b;scrollbar-arrow-color:#7693b5;scrollbar-shadow-color:#2e3f55}.theme-ntos .Layout__content--flexRow{display:flex;flex-flow:row}.theme-ntos .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-ntos .Layout__content--scrollable{overflow-y:auto}.theme-ntos .Layout__content--noMargin{margin:0}.theme-ntos .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#1f2b39;background-image:linear-gradient(180deg,#223040 0,#1b2633)}.theme-ntos .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-ntos .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-ntos .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(55,69,85,.25);pointer-events:none}.theme-ntos .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#0f151d;color:hsla(0,0%,100%,.8)}.theme-ntos .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-ntos .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-ntos .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-ntos .TitleBar{background-color:#2a3b4e;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-ntos .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#2a3b4e;transition:color .25s,background-color .25s}.theme-ntos .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-ntos .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-ntos .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-ntos .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-ntos .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-ntos .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-retro .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:0;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-retro .Button:last-child{margin-right:0}.theme-retro .Button .fa,.theme-retro .Button .far,.theme-retro .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-retro .Button--hasContent .fa,.theme-retro .Button--hasContent .far,.theme-retro .Button--hasContent .fas{margin-right:3px}.theme-retro .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-retro .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-retro .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#e8e4c9;color:#000}.theme-retro .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--default:focus,.theme-retro .Button--color--default:hover{background-color:#f7f6ee;color:#000}.theme-retro .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-retro .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--caution:focus,.theme-retro .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-retro .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-retro .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--danger:focus,.theme-retro .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-retro .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#e8e4c9;color:#000;background-color:rgba(232,228,201,0);color:hsla(0,0%,100%,.5)}.theme-retro .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-retro .Button--color--transparent:focus,.theme-retro .Button--color--transparent:hover{background-color:#f7f6ee;color:#000}.theme-retro .Button--disabled{background-color:#363636!important}.theme-retro .Button--selected{transition:color 50ms,background-color 50ms;background-color:#9d0808;color:#fff}.theme-retro .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-retro .Button--selected:focus{transition:color .1s,background-color .1s}.theme-retro .Button--selected:focus,.theme-retro .Button--selected:hover{background-color:#b31212;color:#fff}.theme-retro .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:0;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-retro .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-retro .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-retro .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-retro .ProgressBar--color--default{border:1px solid #000}.theme-retro .ProgressBar--color--default .ProgressBar__fill{background-color:#000}.theme-retro .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-retro .Section:last-child{margin-bottom:0}.theme-retro .Section--flex{display:flex;flex-flow:column}.theme-retro .Section--flex .Section__content{overflow:auto;flex:1}.theme-retro .Section__title{padding:6px;border-bottom:2px solid #000}.theme-retro .Section__titleText{font-size:14px;font-weight:700}.theme-retro .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-retro .Section__content{padding:8px 6px}.theme-retro .Section__content--noTopPadding{padding-top:0}.theme-retro .Section__content--stretchContents{height:100%}.theme-retro .Section--level--1 .Section__titleText{font-size:14px}.theme-retro .Section--level--2 .Section__titleText{font-size:13px}.theme-retro .Section--level--3 .Section__titleText{font-size:12px}.theme-retro .Section--level--2,.theme-retro .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-retro .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#c8be7d;scrollbar-face-color:#eae7ce;scrollbar-3dlight-color:#e8e4c9;scrollbar-highlight-color:#e8e4c9;scrollbar-track-color:#c8be7d;scrollbar-arrow-color:#f4f2e4;scrollbar-shadow-color:#eae7ce}.theme-retro .Layout__content--flexRow{display:flex;flex-flow:row}.theme-retro .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-retro .Layout__content--scrollable{overflow-y:auto}.theme-retro .Layout__content--noMargin{margin:0}.theme-retro .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#e8e4c9;background-image:linear-gradient(180deg,#e8e4c9 0,#e8e4c9)}.theme-retro .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-retro .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-retro .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(251,250,246,.25);pointer-events:none}.theme-retro .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#988d41;color:hsla(0,0%,100%,.8)}.theme-retro .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-retro .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-retro .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-retro .TitleBar{background-color:#585337;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-retro .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#585337;transition:color .25s,background-color .25s}.theme-retro .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-retro .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-retro .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-retro .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-retro .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-retro .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-retro .Button{font-family:monospace;color:#161613;border:8px outset #e8e4c9;outline:3px solid #161613}.theme-retro .Layout__content{background-image:none}.theme-syndicate .Button{position:relative;display:inline-block;line-height:20px;padding:0 6px;margin-right:2px;white-space:nowrap;outline:0;border-radius:2px;margin-bottom:2px;user-select:none;-ms-user-select:none}.theme-syndicate .Button:last-child{margin-right:0}.theme-syndicate .Button .fa,.theme-syndicate .Button .far,.theme-syndicate .Button .fas{margin-left:-3px;margin-right:-3px;min-width:16px;text-align:center}.theme-syndicate .Button--hasContent .fa,.theme-syndicate .Button--hasContent .far,.theme-syndicate .Button--hasContent .fas{margin-right:3px}.theme-syndicate .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-syndicate .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-syndicate .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#397439;color:#fff}.theme-syndicate .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--default:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--default:focus,.theme-syndicate .Button--color--default:hover{background-color:#478647;color:#fff}.theme-syndicate .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-syndicate .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--caution:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--caution:focus,.theme-syndicate .Button--color--caution:hover{background-color:#d67313;color:#fff}.theme-syndicate .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-syndicate .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--danger:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--danger:focus,.theme-syndicate .Button--color--danger:hover{background-color:#afb30a;color:#fff}.theme-syndicate .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#550202;color:#fff;background-color:rgba(85,2,2,0);color:hsla(0,0%,100%,.5)}.theme-syndicate .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--color--transparent:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--color--transparent:focus,.theme-syndicate .Button--color--transparent:hover{background-color:#650c0c;color:#fff}.theme-syndicate .Button--disabled{background-color:#363636!important}.theme-syndicate .Button--selected{transition:color 50ms,background-color 50ms;background-color:#9d0808;color:#fff}.theme-syndicate .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-syndicate .Button--selected:focus{transition:color .1s,background-color .1s}.theme-syndicate .Button--selected:focus,.theme-syndicate .Button--selected:hover{background-color:#b31212;color:#fff}.theme-syndicate .NoticeBox{padding:4px 6px;margin-bottom:6px;box-shadow:none;font-weight:700;font-style:italic;color:#fff;background-color:#910101;background-image:repeating-linear-gradient(-45deg,transparent,transparent 10px,rgba(0,0,0,.1) 0,rgba(0,0,0,.1) 20px)}.theme-syndicate .NoticeBox--type--info{color:#fff;background-color:#235982}.theme-syndicate .NoticeBox--type--success{color:#fff;background-color:#1e662f}.theme-syndicate .NoticeBox--type--warning{color:#fff;background-color:#a95219}.theme-syndicate .NoticeBox--type--danger{color:#fff;background-color:#8f2828}.theme-syndicate .Input{position:relative;display:inline-block;width:120px;border:1px solid #87ce87;border:1px solid rgba(135,206,135,.75);border-radius:2px;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;overflow:visible}.theme-syndicate .Input--fluid{display:block;width:auto}.theme-syndicate .Input__baseline{display:inline-block;color:transparent}.theme-syndicate .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.theme-syndicate .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:hsla(0,0%,100%,.45)}.theme-syndicate .NumberInput{position:relative;display:inline-block;border:1px solid #87ce87;border:1px solid rgba(135,206,135,.75);border-radius:2px;color:#87ce87;background-color:#000;background-color:rgba(0,0,0,.75);padding:0 4px;margin-right:2px;line-height:17px;text-align:right;overflow:visible;cursor:n-resize}.theme-syndicate .NumberInput--fluid{display:block}.theme-syndicate .NumberInput__content{margin-left:6px}.theme-syndicate .NumberInput__barContainer{position:absolute;top:2px;bottom:2px;left:2px}.theme-syndicate .NumberInput__bar{position:absolute;bottom:0;left:0;width:3px;box-sizing:border-box;border-bottom:1px solid #87ce87;background-color:#87ce87}.theme-syndicate .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:12px;line-height:17px;height:17px;margin:0;padding:0 6px;font-family:Verdana,sans-serif;background-color:#000;color:#fff;text-align:right}.theme-syndicate .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 6px;border-radius:2px;background-color:rgba(0,0,0,.5);transition:border-color .5s}.theme-syndicate .ProgressBar__fill{position:absolute;top:0;left:0;bottom:0}.theme-syndicate .ProgressBar__fill--animated{transition:background-color .5s,width .5s}.theme-syndicate .ProgressBar__content{position:relative;line-height:17px;width:100%;text-align:right}.theme-syndicate .ProgressBar--color--default{border:1px solid #306330}.theme-syndicate .ProgressBar--color--default .ProgressBar__fill{background-color:#306330}.theme-syndicate .Section{position:relative;margin-bottom:6px;background-color:#1a1a1a;background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5);box-sizing:border-box;scrollbar-base-color:#400202;scrollbar-face-color:#7e0303;scrollbar-3dlight-color:#550202;scrollbar-highlight-color:#550202;scrollbar-track-color:#400202;scrollbar-arrow-color:#fa3030;scrollbar-shadow-color:#7e0303}.theme-syndicate .Section:last-child{margin-bottom:0}.theme-syndicate .Section--flex{display:flex;flex-flow:column}.theme-syndicate .Section--flex .Section__content{overflow:auto;flex:1}.theme-syndicate .Section__title{padding:6px;border-bottom:2px solid #397439}.theme-syndicate .Section__titleText{font-size:14px;font-weight:700}.theme-syndicate .Section__buttons{position:absolute;display:inline-block;right:6px;margin-top:-1px}.theme-syndicate .Section__content{padding:8px 6px}.theme-syndicate .Section__content--noTopPadding{padding-top:0}.theme-syndicate .Section__content--stretchContents{height:100%}.theme-syndicate .Section--level--1 .Section__titleText{font-size:14px}.theme-syndicate .Section--level--2 .Section__titleText{font-size:13px}.theme-syndicate .Section--level--3 .Section__titleText{font-size:12px}.theme-syndicate .Section--level--2,.theme-syndicate .Section--level--3{background-color:transparent;box-shadow:none;margin-left:-6px;margin-right:-6px}.theme-syndicate .Tooltip{position:absolute;top:0;left:0;right:0;bottom:0;font-style:normal;font-weight:400}.theme-syndicate .Tooltip:after{position:absolute;display:block;white-space:nowrap;z-index:2;padding:6px 10px;transform:translateX(-50%);pointer-events:none;visibility:hidden;opacity:0;text-align:left;content:attr(data-tooltip);transition:all .15s;background-color:#4a0202;box-shadow:1px 1px 15px -1px rgba(0,0,0,.5);border-radius:2px}.theme-syndicate .Tooltip:hover:after{transition:all 70ms;pointer-events:none;visibility:visible;opacity:1}.theme-syndicate .Tooltip--long:after{width:250px;white-space:normal}.theme-syndicate .Tooltip--top:after{bottom:100%;left:50%;transform:translateX(-50%) translateY(8px)}.theme-syndicate .Tooltip--top:hover:after{transform:translateX(-50%) translateY(-8px)}.theme-syndicate .Tooltip--top-left:after{bottom:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-syndicate .Tooltip--top-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-syndicate .Tooltip--top-right:after{bottom:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-syndicate .Tooltip--top-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-syndicate .Tooltip--bottom:after{top:100%;left:50%;transform:translateX(-50%) translateY(-8px)}.theme-syndicate .Tooltip--bottom:hover:after{transform:translateX(-50%) translateY(8px)}.theme-syndicate .Tooltip--bottom-left:after{top:100%;right:50%;transform:translateX(12px) translateY(-8px)}.theme-syndicate .Tooltip--bottom-left:hover:after{transform:translateX(12px) translateY(8px)}.theme-syndicate .Tooltip--bottom-right:after{top:100%;left:50%;transform:translateX(-12px) translateY(-8px)}.theme-syndicate .Tooltip--bottom-right:hover:after{transform:translateX(-12px) translateY(8px)}.theme-syndicate .Tooltip--left:after{top:50%;right:100%;transform:translateX(8px) translateY(-50%)}.theme-syndicate .Tooltip--left:hover:after,.theme-syndicate .Tooltip--right:after{transform:translateX(-8px) translateY(-50%)}.theme-syndicate .Tooltip--right:after{top:50%;left:100%}.theme-syndicate .Tooltip--right:hover:after{transform:translateX(8px) translateY(-50%)}.theme-syndicate .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;margin:6px;scrollbar-base-color:#400202;scrollbar-face-color:#7e0303;scrollbar-3dlight-color:#550202;scrollbar-highlight-color:#550202;scrollbar-track-color:#400202;scrollbar-arrow-color:#fa3030;scrollbar-shadow-color:#7e0303}.theme-syndicate .Layout__content--flexRow{display:flex;flex-flow:row}.theme-syndicate .Layout__content--flexColumn{display:flex;flex-flow:column}.theme-syndicate .Layout__content--scrollable{overflow-y:auto}.theme-syndicate .Layout__content--noMargin{margin:0}.theme-syndicate .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#550202;background-image:linear-gradient(180deg,#730303 0,#370101)}.theme-syndicate .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px}.theme-syndicate .Window__rest{position:fixed;top:32px;bottom:0;left:0;right:0}.theme-syndicate .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(117,22,22,.25);pointer-events:none}.theme-syndicate .Window__toast{position:fixed;bottom:0;left:0;right:0;font-size:12px;height:40px;line-height:39px;padding:0 12px;background-color:#2b0101;color:hsla(0,0%,100%,.8)}.theme-syndicate .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;height:20px;cursor:se-resize}.theme-syndicate .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;cursor:s-resize}.theme-syndicate .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;cursor:e-resize}.theme-syndicate .TitleBar{background-color:#910101;border-bottom:1px solid #161616;box-shadow:0 2px 2px rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-syndicate .TitleBar__clickable{color:hsla(0,0%,100%,.5);background-color:#910101;transition:color .25s,background-color .25s}.theme-syndicate .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-syndicate .TitleBar__title{position:absolute;top:0;left:46px;color:hsla(0,0%,100%,.75);font-size:14px;line-height:31px;white-space:nowrap}.theme-syndicate .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px}.theme-syndicate .TitleBar__statusIcon{position:absolute;top:0;left:12px;transition:color .5s;font-size:20px;line-height:32px!important}.theme-syndicate .TitleBar__minimize{position:absolute;top:6px;right:46px}.theme-syndicate .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;height:32px;font-size:20px;line-height:31px;text-align:center}.theme-syndicate .Layout__content{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDIwMCAyODkuNzQyIiBvcGFjaXR5PSIuMzMiPjxwYXRoIGQ9Ik05My41MzggMGMtMTguMTEzIDAtMzQuMjIgMy4xMTItNDguMzI0IDkuMzM0LTEzLjk2NSA2LjIyMi0yNC42MTIgMTUuMDcyLTMxLjk0IDI2LjU0N0M2LjA4NCA0Ny4yMiAyLjk3MiA2MC42MzEgMi45NzIgNzYuMTE2YzAgMTAuNjQ3IDIuNzI1IDIwLjQ2NSA4LjE3NSAyOS40NTMgNS42MTYgOC45ODcgMTQuMDM5IDE3LjM1MiAyNS4yNyAyNS4wOTQgMTEuMjMgNy42MDYgMjYuNTA3IDE1LjQxOSA0NS44MyAyMy40MzggMTkuOTg0IDguMjk2IDM0Ljg0OSAxNS41NTUgNDQuNTkzIDIxLjc3NiA5Ljc0NCA2LjIyMyAxNi43NjEgMTIuODU5IDIxLjA1NSAxOS45MSA0LjI5NSA3LjA1MiA2LjQ0MiAxNS43NjQgNi40NDIgMjYuMTM0IDAgMTYuMTc4LTUuMjAyIDI4LjQ4My0xNS42MDYgMzYuOTE3LTEwLjI0IDguNDM1LTI1LjAyMiAxMi42NTMtNDQuMzQ1IDEyLjY1My0xNC4wMzkgMC0yNS41MTYtMS42Ni0zNC40MzQtNC45NzgtOC45MTgtMy40NTctMTYuMTg2LTguNzExLTIxLjgtMTUuNzYzLTUuNjE2LTcuMDUyLTEwLjA3Ni0xNi42NjEtMTMuMzc5LTI4LjgyOUgwdjU2LjgyN2MzMy44NTcgNy4zMjggNjMuNzQ5IDEwLjk5NCA4OS42NzggMTAuOTk0IDE2LjAyIDAgMzAuNzItMS4zODMgNDQuMDk4LTQuMTQ4IDEzLjU0Mi0yLjkwNCAyNS4xMDQtNy40NjcgMzQuNjgzLTEzLjY5IDkuNzQ0LTYuMzU5IDE3LjM0LTE0LjUxOSAyMi43OS0yNC40NzQgNS40NS0xMC4wOTMgOC4xNzUtMjIuNCA4LjE3NS0zNi45MTcgMC0xMi45OTctMy4zMDItMjQuMzM1LTkuOTA4LTM0LjAxNC02LjQ0LTkuODE4LTE1LjUyNS0xOC41MjctMjcuMjUxLTI2LjEzMi0xMS41NjEtNy42MDQtMjcuOTExLTE1LjgzMS00OS4wNTEtMjQuNjgtMTcuNTA2LTcuMTktMzAuNzItMTMuNjktMzkuNjM4LTE5LjQ5N1M1NC45NjkgOTMuNzU2IDQ5LjQ3OSA4Ny4zMTZjLTUuNDI2LTYuMzY2LTkuNjU4LTE1LjA3LTkuNjU4LTI0Ljg4NyAwLTkuMjY0IDIuMDc1LTE3LjIxNCA2LjIyMy0yMy44NUM1Ny4xNDIgMjQuMTggODcuMzMxIDM2Ljc4MiA5MS4xMiA2Mi45MjVjNC44NCA2Ljc3NSA4Ljg1IDE2LjI0NyAxMi4wMyAyOC40MTVoMjAuNTMydi01NmMtNC40NzktNS45MjQtOS45NTUtMTAuNjMxLTE1LjkwOS0xNC4zNzMgMS42NC40NzkgMy4xOSAxLjAyMyA0LjYzOSAxLjY0IDYuNDk4IDIuNjI2IDEyLjE2OCA3LjMyNyAxNy4wMDcgMTQuMTAzIDQuODQgNi43NzUgOC44NSAxNi4yNDYgMTIuMDMgMjguNDE0IDAgMCA4LjQ4LS4xMjkgOC40OS0uMDAyLjQxNyA2LjQxNS0xLjc1NCA5LjQ1My00LjEyNCAxMi41NjEtMi40MTcgMy4xNy01LjE0NSA2Ljc5LTQuMDAzIDEzLjAwMyAxLjUwOCA4LjIwMyAxMC4xODQgMTAuNTk3IDE0LjYyMiA5LjMxMi0zLjMxOC0uNS01LjMxOC0xLjc1LTUuMzE4LTEuNzVzMS44NzYuOTk5IDUuNjUtMS4zNmMtMy4yNzYuOTU2LTEwLjcwNC0uNzk3LTExLjgtNi43NjMtLjk1OC01LjIwOC45NDYtNy4yOTUgMy40LTEwLjUxNCAyLjQ1NS0zLjIyIDUuMjg1LTYuOTU5IDQuNjg1LTE0LjQ4OWwuMDAzLjAwMmg4LjkyN3YtNTZjLTE1LjA3Mi0zLjg3MS0yNy42NTMtNi4zNi0zNy43NDctNy40NjVDMTE0LjI3OS41NTIgMTA0LjA0NiAwIDkzLjUzNyAwem03MC4zMjEgMTcuMzA5bC4yMzggNDAuMzA1YzEuMzE4IDEuMjI2IDIuNDQgMi4yNzggMy4zNDEgMy4xMDYgNC44NCA2Ljc3NSA4Ljg1IDE2LjI0NiAxMi4wMyAyOC40MTRIMjAwdi01NmMtNi42NzctNC41OTQtMTkuODM2LTEwLjQ3My0zNi4xNC0xNS44MjV6bS0yOC4xMiA1LjYwNWw4LjU2NSAxNy43MTdjLTExLjk3LTYuNDY3LTEzLjg0Ny05LjcxNy04LjU2NS0xNy43MTd6bTIyLjc5NyAwYzIuNzcxIDggMS43ODcgMTEuMjUtNC40OTQgMTcuNzE3bDQuNDk0LTE3LjcxN3ptMTUuMjIyIDI0LjAwOWw4LjU2NSAxNy43MTZjLTExLjk3LTYuNDY2LTEzLjg0Ny05LjcxNy04LjU2NS0xNy43MTZ6bTIyLjc5NyAwYzIuNzcxIDggMS43ODcgMTEuMjUtNC40OTQgMTcuNzE2bDQuNDk0LTE3LjcxNnpNOTcuNDQgNDkuMTNsOC41NjUgMTcuNzE2Yy0xMS45Ny02LjQ2Ny0xMy44NDctOS43MTctOC41NjUtMTcuNzE2em0yMi43OTUgMGMyLjc3MiA3Ljk5OSAxLjc4OCAxMS4yNS00LjQ5MyAxNy43MTZsNC40OTMtMTcuNzE2eiIvPjwvc3ZnPg==)} \ No newline at end of file diff --git a/tgui/packages/tgui/public/tgui.bundle.js b/tgui/packages/tgui/public/tgui.bundle.js index d7e9e057c3e..babceccfd1c 100644 --- a/tgui/packages/tgui/public/tgui.bundle.js +++ b/tgui/packages/tgui/public/tgui.bundle.js @@ -1,5 +1,5 @@ -!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=173)}([function(e,t,n){"use strict";var o=n(5),r=n(19).f,i=n(29),a=n(22),c=n(89),l=n(127),u=n(60);e.exports=function(e,t){var n,s,d,f,p,m=e.target,h=e.global,g=e.stat;if(n=h?o:g?o[m]||c(m,{}):(o[m]||{}).prototype)for(s in t){if(f=t[s],d=e.noTargetGet?(p=r(n,s))&&p.value:n[s],!u(h?s:m+(g?".":"#")+s,e.forced)&&d!==undefined){if(typeof f==typeof d)continue;l(f,d)}(e.sham||d&&d.sham)&&i(f,"sham",!0),a(n,s,f,e)}}},function(e,t,n){"use strict";t.__esModule=!0;var o=n(388);Object.keys(o).forEach((function(e){"default"!==e&&"__esModule"!==e&&(t[e]=o[e])}))},function(e,t,n){"use strict";e.exports=function(e){try{return!!e()}catch(t){return!0}}},function(e,t,n){"use strict";t.__esModule=!0,t.useSharedState=t.useLocalState=t.useBackend=t.backendReducer=t.backendSetSharedState=t.backendUpdate=void 0;var o=n(68),r=n(24);t.backendUpdate=function(e){return{type:"backend/update",payload:e}};var i=function(e,t){return{type:"backend/setSharedState",payload:{key:e,nextState:t}}};t.backendSetSharedState=i;t.backendReducer=function(e,t){var n=t.type,r=t.payload;if("backend/update"===n){var i=Object.assign({},e.config,{},r.config),a=Object.assign({},e.data,{},r.static_data,{},r.data),c=Object.assign({},e.shared);if(r.shared)for(var l=0,u=Object.keys(r.shared);l0?r(o(e),9007199254740991):0}},function(e,t,n){"use strict";t.__esModule=!0,t.isFalsy=t.pureComponentHooks=t.shallowDiffers=t.normalizeChildren=t.classes=void 0;t.classes=function(e){for(var t="",n=0;n0&&(t.style=l),t};t.computeBoxProps=g;var v=function(e){var t=e.textColor||e.color,n=e.backgroundColor;return(0,o.classes)([u(t)&&"color-"+t,u(n)&&"color-bg-"+n])};t.computeBoxClassName=v;var b=function(e){var t=e.as,n=void 0===t?"div":t,o=e.className,a=e.children,c=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["as","className","children"]);if("function"==typeof a)return a(g(e));var l="string"==typeof o?o+" "+v(c):v(c),u=g(c);return(0,r.createVNode)(i.VNodeFlags.HtmlElement,n,l,a,i.ChildFlags.UnknownChildren,u)};t.Box=b,b.defaultHooks=o.pureComponentHooks},function(e,t,n){"use strict";var o={}.hasOwnProperty;e.exports=function(e,t){return o.call(e,t)}},function(e,t,n){"use strict";var o=n(47),r=n(56),i=n(15),a=n(11),c=n(62),l=[].push,u=function(e){var t=1==e,n=2==e,u=3==e,s=4==e,d=6==e,f=5==e||d;return function(p,m,h,g){for(var v,b,C=i(p),N=r(C),y=o(m,h,3),V=a(N.length),x=0,w=g||c,k=t?w(p,V):n?w(p,0):undefined;V>x;x++)if((f||x in N)&&(b=y(v=N[x],x,C),e))if(t)k[x]=b;else if(b)switch(e){case 3:return!0;case 5:return v;case 6:return x;case 2:l.call(k,v)}else if(s)return!1;return d?-1:u||s?s:k}};e.exports={forEach:u(0),map:u(1),filter:u(2),some:u(3),every:u(4),find:u(5),findIndex:u(6)}},function(e,t,n){"use strict";var o=n(8),r=n(70),i=n(45),a=n(25),c=n(33),l=n(17),u=n(124),s=Object.getOwnPropertyDescriptor;t.f=o?s:function(e,t){if(e=a(e),t=c(t,!0),u)try{return s(e,t)}catch(n){}if(l(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t,n){"use strict";t.__esModule=!0,t.keyOfMatchingRange=t.inRange=t.toFixed=t.round=t.scale=t.clamp01=t.clamp=void 0;t.clamp=function(e,t,n){return en?n:e};t.clamp01=function(e){return e<0?0:e>1?1:e};t.scale=function(e,t,n){return(e-t)/(n-t)};t.round=function(e,t){return!e||isNaN(e)?e:(t|=0,i=(e*=n=Math.pow(10,t))>0|-(e<0),r=Math.abs(e%1)>=.4999999999854481,o=Math.floor(e),r&&(e=o+(i>0)),(r?e:Math.round(e))/n);var n,o,r,i};t.toFixed=function(e,t){return void 0===t&&(t=0),Number(e).toFixed(Math.max(t,0))};var o=function(e,t){return t&&e>=t[0]&&e<=t[1]};t.inRange=o;t.keyOfMatchingRange=function(e,t){for(var n=0,r=Object.keys(t);n"+a+""}},function(e,t,n){"use strict";var o=n(2);e.exports=function(e){return o((function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}))}},function(e,t,n){"use strict";var o=n(8),r=n(14),i=n(45);e.exports=o?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";var o=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:o)(e)}},function(e,t,n){"use strict";e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},function(e,t,n){"use strict";var o={}.toString;e.exports=function(e){return o.call(e).slice(8,-1)}},function(e,t,n){"use strict";var o=n(7);e.exports=function(e,t){if(!o(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!o(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},function(e,t,n){"use strict";var o,r,i,a=n(126),c=n(5),l=n(7),u=n(29),s=n(17),d=n(71),f=n(58),p=c.WeakMap;if(a){var m=new p,h=m.get,g=m.has,v=m.set;o=function(e,t){return v.call(m,e,t),t},r=function(e){return h.call(m,e)||{}},i=function(e){return g.call(m,e)}}else{var b=d("state");f[b]=!0,o=function(e,t){return u(e,b,t),t},r=function(e){return s(e,b)?e[b]:{}},i=function(e){return s(e,b)}}e.exports={set:o,get:r,has:i,enforce:function(e){return i(e)?r(e):o(e,{})},getterFor:function(e){return function(t){var n;if(!l(t)||(n=r(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){"use strict";var o=n(17),r=n(15),i=n(71),a=n(102),c=i("IE_PROTO"),l=Object.prototype;e.exports=a?Object.getPrototypeOf:function(e){return e=r(e),o(e,c)?e[c]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?l:null}},function(e,t,n){"use strict";var o=n(128),r=n(5),i=function(e){return"function"==typeof e?e:undefined};e.exports=function(e,t){return arguments.length<2?i(o[e])||i(r[e]):o[e]&&o[e][t]||r[e]&&r[e][t]}},function(e,t,n){"use strict";e.exports=!1},function(e,t,n){"use strict";var o=n(2);e.exports=function(e,t){var n=[][e];return!!n&&o((function(){n.call(null,t||function(){throw 1},1)}))}},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(8),a=n(115),c=n(10),l=n(76),u=n(53),s=n(45),d=n(29),f=n(11),p=n(142),m=n(157),h=n(33),g=n(17),v=n(73),b=n(7),C=n(41),N=n(49),y=n(46).f,V=n(158),x=n(18).forEach,w=n(52),k=n(14),_=n(19),L=n(34),S=n(78),B=L.get,E=L.set,I=k.f,T=_.f,A=Math.round,O=r.RangeError,M=l.ArrayBuffer,P=l.DataView,j=c.NATIVE_ARRAY_BUFFER_VIEWS,D=c.TYPED_ARRAY_TAG,F=c.TypedArray,R=c.TypedArrayPrototype,z=c.aTypedArrayConstructor,W=c.isTypedArray,U=function(e,t){for(var n=0,o=t.length,r=new(z(e))(o);o>n;)r[n]=t[n++];return r},K=function(e,t){I(e,t,{get:function(){return B(this)[t]}})},H=function(e){var t;return e instanceof M||"ArrayBuffer"==(t=v(e))||"SharedArrayBuffer"==t},Y=function(e,t){return W(e)&&"symbol"!=typeof t&&t in e&&String(+t)==String(t)},$=function(e,t){return Y(e,t=h(t,!0))?s(2,e[t]):T(e,t)},q=function(e,t,n){return!(Y(e,t=h(t,!0))&&b(n)&&g(n,"value"))||g(n,"get")||g(n,"set")||n.configurable||g(n,"writable")&&!n.writable||g(n,"enumerable")&&!n.enumerable?I(e,t,n):(e[t]=n.value,e)};i?(j||(_.f=$,k.f=q,K(R,"buffer"),K(R,"byteOffset"),K(R,"byteLength"),K(R,"length")),o({target:"Object",stat:!0,forced:!j},{getOwnPropertyDescriptor:$,defineProperty:q}),e.exports=function(e,t,n){var i=e.match(/\d+$/)[0]/8,c=e+(n?"Clamped":"")+"Array",l="get"+e,s="set"+e,h=r[c],g=h,v=g&&g.prototype,k={},_=function(e,t){I(e,t,{get:function(){return function(e,t){var n=B(e);return n.view[l](t*i+n.byteOffset,!0)}(this,t)},set:function(e){return function(e,t,o){var r=B(e);n&&(o=(o=A(o))<0?0:o>255?255:255&o),r.view[s](t*i+r.byteOffset,o,!0)}(this,t,e)},enumerable:!0})};j?a&&(g=t((function(e,t,n,o){return u(e,g,c),S(b(t)?H(t)?o!==undefined?new h(t,m(n,i),o):n!==undefined?new h(t,m(n,i)):new h(t):W(t)?U(g,t):V.call(g,t):new h(p(t)),e,g)})),N&&N(g,F),x(y(h),(function(e){e in g||d(g,e,h[e])})),g.prototype=v):(g=t((function(e,t,n,o){u(e,g,c);var r,a,l,s=0,d=0;if(b(t)){if(!H(t))return W(t)?U(g,t):V.call(g,t);r=t,d=m(n,i);var h=t.byteLength;if(o===undefined){if(h%i)throw O("Wrong length");if((a=h-d)<0)throw O("Wrong length")}else if((a=f(o)*i)+d>h)throw O("Wrong length");l=a/i}else l=p(t),r=new M(a=l*i);for(E(e,{buffer:r,byteOffset:d,byteLength:a,length:l,view:new P(r)});s"+e+"<\/script>"},m=function(){try{o=document.domain&&new ActiveXObject("htmlfile")}catch(r){}var e,t;m=o?function(e){e.write(p("")),e.close();var t=e.parentWindow.Object;return e=null,t}(o):((t=u("iframe")).style.display="none",l.appendChild(t),t.src=String("javascript:"),(e=t.contentWindow.document).open(),e.write(p("document.F=Object")),e.close(),e.F);for(var n=a.length;n--;)delete m.prototype[a[n]];return m()};c[d]=!0,e.exports=Object.create||function(e,t){var n;return null!==e?(f.prototype=r(e),n=new f,f.prototype=null,n[d]=e):n=m(),t===undefined?n:i(n,t)}},function(e,t,n){"use strict";var o=n(14).f,r=n(17),i=n(13)("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,i)&&o(e,i,{configurable:!0,value:t})}},function(e,t,n){"use strict";var o=n(13),r=n(41),i=n(14),a=o("unscopables"),c=Array.prototype;c[a]==undefined&&i.f(c,a,{configurable:!0,value:r(null)}),e.exports=function(e){c[a][e]=!0}},function(e,t,n){"use strict";var o=n(9),r=n(31),i=n(13)("species");e.exports=function(e,t){var n,a=o(e).constructor;return a===undefined||(n=o(a)[i])==undefined?t:r(n)}},function(e,t,n){"use strict";e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){"use strict";var o=n(129),r=n(93).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return o(e,r)}},function(e,t,n){"use strict";var o=n(31);e.exports=function(e,t,n){if(o(e),t===undefined)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,o){return e.call(t,n,o)};case 3:return function(n,o,r){return e.call(t,n,o,r)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){"use strict";var o=n(33),r=n(14),i=n(45);e.exports=function(e,t,n){var a=o(t);a in e?r.f(e,a,i(0,n)):e[a]=n}},function(e,t,n){"use strict";var o=n(9),r=n(140);e.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var e,t=!1,n={};try{(e=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set).call(n,[]),t=n instanceof Array}catch(i){}return function(n,i){return o(n),r(i),t?e.call(n,i):n.__proto__=i,n}}():undefined)},function(e,t,n){"use strict";var o=n(58),r=n(7),i=n(17),a=n(14).f,c=n(57),l=n(66),u=c("meta"),s=0,d=Object.isExtensible||function(){return!0},f=function(e){a(e,u,{value:{objectID:"O"+ ++s,weakData:{}}})},p=e.exports={REQUIRED:!1,fastKey:function(e,t){if(!r(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,u)){if(!d(e))return"F";if(!t)return"E";f(e)}return e[u].objectID},getWeakData:function(e,t){if(!i(e,u)){if(!d(e))return!0;if(!t)return!1;f(e)}return e[u].weakData},onFreeze:function(e){return l&&p.REQUIRED&&d(e)&&!i(e,u)&&f(e),e}};o[u]=!0},function(e,t,n){"use strict";var o=n(32);e.exports=Array.isArray||function(e){return"Array"==o(e)}},function(e,t,n){"use strict";var o=n(36),r=n(14),i=n(13),a=n(8),c=i("species");e.exports=function(e){var t=o(e),n=r.f;a&&t&&!t[c]&&n(t,c,{configurable:!0,get:function(){return this}})}},function(e,t,n){"use strict";e.exports=function(e,t,n){if(!(e instanceof t))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return e}},function(e,t,n){"use strict";var o=n(21),r="["+n(80)+"]",i=RegExp("^"+r+r+"*"),a=RegExp(r+r+"*$"),c=function(e){return function(t){var n=String(o(t));return 1&e&&(n=n.replace(i,"")),2&e&&(n=n.replace(a,"")),n}};e.exports={start:c(1),end:c(2),trim:c(3)}},function(e,t,n){"use strict";t.__esModule=!0,t.logger=t.createLogger=void 0;n(160);var o=n(24),r=0,i=1,a=2,c=3,l=4,u=function(e,t){for(var n=arguments.length,r=new Array(n>2?n-2:0),i=2;i=a){var c=[t].concat(r).map((function(e){return"string"==typeof e?e:e instanceof Error?e.stack||String(e):JSON.stringify(e)})).filter((function(e){return e})).join(" ")+"\nUser Agent: "+navigator.userAgent;(0,o.callByond)("",{src:window.__ref__,action:"tgui:log",log:c})}},s=function(e){return{debug:function(){for(var t=arguments.length,n=new Array(t),o=0;os;)if((c=l[s++])!=c)return!0}else for(;u>s;s++)if((e||s in l)&&l[s]===n)return e||s||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},function(e,t,n){"use strict";var o=n(2),r=/#|\.prototype\./,i=function(e,t){var n=c[a(e)];return n==u||n!=l&&("function"==typeof t?o(t):!!t)},a=i.normalize=function(e){return String(e).replace(r,".").toLowerCase()},c=i.data={},l=i.NATIVE="N",u=i.POLYFILL="P";e.exports=i},function(e,t,n){"use strict";var o=n(129),r=n(93);e.exports=Object.keys||function(e){return o(e,r)}},function(e,t,n){"use strict";var o=n(7),r=n(51),i=n(13)("species");e.exports=function(e,t){var n;return r(e)&&("function"!=typeof(n=e.constructor)||n!==Array&&!r(n.prototype)?o(n)&&null===(n=n[i])&&(n=undefined):n=undefined),new(n===undefined?Array:n)(0===t?0:t)}},function(e,t,n){"use strict";var o=n(2),r=n(13),i=n(96),a=r("species");e.exports=function(e){return i>=51||!o((function(){var t=[];return(t.constructor={})[a]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},function(e,t,n){"use strict";e.exports={}},function(e,t,n){"use strict";var o=n(22);e.exports=function(e,t,n){for(var r in t)o(e,r,t[r],n);return e}},function(e,t,n){"use strict";var o=n(2);e.exports=!o((function(){return Object.isExtensible(Object.preventExtensions({}))}))},function(e,t,n){"use strict";var o=n(9),r=n(98),i=n(11),a=n(47),c=n(99),l=n(137),u=function(e,t){this.stopped=e,this.result=t};(e.exports=function(e,t,n,s,d){var f,p,m,h,g,v,b,C=a(t,n,s?2:1);if(d)f=e;else{if("function"!=typeof(p=c(e)))throw TypeError("Target is not iterable");if(r(p)){for(m=0,h=i(e.length);h>m;m++)if((g=s?C(o(b=e[m])[0],b[1]):C(e[m]))&&g instanceof u)return g;return new u(!1)}f=p.call(e)}for(v=f.next;!(b=v.call(f)).done;)if("object"==typeof(g=l(f,C,b.value,s))&&g&&g instanceof u)return g;return new u(!1)}).stop=function(e){return new u(!0,e)}},function(e,t,n){"use strict";t.__esModule=!0,t.getGasColor=t.getGasLabel=t.RADIO_CHANNELS=t.CSS_COLORS=t.COLORS=t.UI_CLOSE=t.UI_DISABLED=t.UI_UPDATE=t.UI_INTERACTIVE=void 0;t.UI_INTERACTIVE=2;t.UI_UPDATE=1;t.UI_DISABLED=0;t.UI_CLOSE=-1;t.COLORS={department:{captain:"#c06616",security:"#e74c3c",medbay:"#3498db",science:"#9b59b6",engineering:"#f1c40f",cargo:"#f39c12",centcom:"#00c100",other:"#c38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}};t.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"];t.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}];var o=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"}];t.getGasLabel=function(e,t){var n=String(e).toLowerCase(),r=o.find((function(e){return e.id===n||e.name.toLowerCase()===n}));return r&&r.label||t||e};t.getGasColor=function(e){var t=String(e).toLowerCase(),n=o.find((function(e){return e.id===t||e.name.toLowerCase()===t}));return n&&n.color}},function(e,t,n){"use strict";t.__esModule=!0,t.zipWith=t.zip=t.uniqBy=t.reduce=t.sortBy=t.map=t.filter=t.toKeyedArray=t.toArray=void 0;t.toArray=function(e){if(Array.isArray(e))return e;if("object"==typeof e){var t=Object.prototype.hasOwnProperty,n=[];for(var o in e)t.call(e,o)&&n.push(e[o]);return n}return[]};t.toKeyedArray=function(e,t){return void 0===t&&(t="key"),o((function(e,n){var o;return Object.assign(((o={})[t]=n,o),e)}))(e)};t.filter=function(e){return function(t){if(null===t&&t===undefined)return t;if(Array.isArray(t)){for(var n=[],o=0;oc)return 1}return 0};t.sortBy=function(){for(var e=arguments.length,t=new Array(e),n=0;n=0:d>f;f+=p)f in s&&(l=n(l,s[f],f,u));return l}};e.exports={left:c(!1),right:c(!0)}},function(e,t,n){"use strict";var o=n(5),r=n(8),i=n(103),a=n(29),c=n(65),l=n(2),u=n(53),s=n(30),d=n(11),f=n(142),p=n(220),m=n(35),h=n(49),g=n(46).f,v=n(14).f,b=n(97),C=n(42),N=n(34),y=N.get,V=N.set,x=o.ArrayBuffer,w=x,k=o.DataView,_=k&&k.prototype,L=Object.prototype,S=o.RangeError,B=p.pack,E=p.unpack,I=function(e){return[255&e]},T=function(e){return[255&e,e>>8&255]},A=function(e){return[255&e,e>>8&255,e>>16&255,e>>24&255]},O=function(e){return e[3]<<24|e[2]<<16|e[1]<<8|e[0]},M=function(e){return B(e,23,4)},P=function(e){return B(e,52,8)},j=function(e,t){v(e.prototype,t,{get:function(){return y(this)[t]}})},D=function(e,t,n,o){var r=f(n),i=y(e);if(r+t>i.byteLength)throw S("Wrong index");var a=y(i.buffer).bytes,c=r+i.byteOffset,l=a.slice(c,c+t);return o?l:l.reverse()},F=function(e,t,n,o,r,i){var a=f(n),c=y(e);if(a+t>c.byteLength)throw S("Wrong index");for(var l=y(c.buffer).bytes,u=a+c.byteOffset,s=o(+r),d=0;dU;)(R=W[U++])in w||a(w,R,x[R]);z.constructor=w}h&&m(_)!==L&&h(_,L);var K=new k(new w(2)),H=_.setInt8;K.setInt8(0,2147483648),K.setInt8(1,2147483649),!K.getInt8(0)&&K.getInt8(1)||c(_,{setInt8:function(e,t){H.call(this,e,t<<24>>24)},setUint8:function(e,t){H.call(this,e,t<<24>>24)}},{unsafe:!0})}else w=function(e){u(this,w,"ArrayBuffer");var t=f(e);V(this,{bytes:b.call(new Array(t),0),byteLength:t}),r||(this.byteLength=t)},k=function(e,t,n){u(this,k,"DataView"),u(e,w,"DataView");var o=y(e).byteLength,i=s(t);if(i<0||i>o)throw S("Wrong offset");if(i+(n=n===undefined?o-i:d(n))>o)throw S("Wrong length");V(this,{buffer:e,byteLength:n,byteOffset:i}),r||(this.buffer=e,this.byteLength=n,this.byteOffset=i)},r&&(j(w,"byteLength"),j(k,"buffer"),j(k,"byteLength"),j(k,"byteOffset")),c(k.prototype,{getInt8:function(e){return D(this,1,e)[0]<<24>>24},getUint8:function(e){return D(this,1,e)[0]},getInt16:function(e){var t=D(this,2,e,arguments.length>1?arguments[1]:undefined);return(t[1]<<8|t[0])<<16>>16},getUint16:function(e){var t=D(this,2,e,arguments.length>1?arguments[1]:undefined);return t[1]<<8|t[0]},getInt32:function(e){return O(D(this,4,e,arguments.length>1?arguments[1]:undefined))},getUint32:function(e){return O(D(this,4,e,arguments.length>1?arguments[1]:undefined))>>>0},getFloat32:function(e){return E(D(this,4,e,arguments.length>1?arguments[1]:undefined),23)},getFloat64:function(e){return E(D(this,8,e,arguments.length>1?arguments[1]:undefined),52)},setInt8:function(e,t){F(this,1,e,I,t)},setUint8:function(e,t){F(this,1,e,I,t)},setInt16:function(e,t){F(this,2,e,T,t,arguments.length>2?arguments[2]:undefined)},setUint16:function(e,t){F(this,2,e,T,t,arguments.length>2?arguments[2]:undefined)},setInt32:function(e,t){F(this,4,e,A,t,arguments.length>2?arguments[2]:undefined)},setUint32:function(e,t){F(this,4,e,A,t,arguments.length>2?arguments[2]:undefined)},setFloat32:function(e,t){F(this,4,e,M,t,arguments.length>2?arguments[2]:undefined)},setFloat64:function(e,t){F(this,8,e,P,t,arguments.length>2?arguments[2]:undefined)}});C(w,"ArrayBuffer"),C(k,"DataView"),e.exports={ArrayBuffer:w,DataView:k}},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(60),a=n(22),c=n(50),l=n(67),u=n(53),s=n(7),d=n(2),f=n(74),p=n(42),m=n(78);e.exports=function(e,t,n){var h=-1!==e.indexOf("Map"),g=-1!==e.indexOf("Weak"),v=h?"set":"add",b=r[e],C=b&&b.prototype,N=b,y={},V=function(e){var t=C[e];a(C,e,"add"==e?function(e){return t.call(this,0===e?0:e),this}:"delete"==e?function(e){return!(g&&!s(e))&&t.call(this,0===e?0:e)}:"get"==e?function(e){return g&&!s(e)?undefined:t.call(this,0===e?0:e)}:"has"==e?function(e){return!(g&&!s(e))&&t.call(this,0===e?0:e)}:function(e,n){return t.call(this,0===e?0:e,n),this})};if(i(e,"function"!=typeof b||!(g||C.forEach&&!d((function(){(new b).entries().next()})))))N=n.getConstructor(t,e,h,v),c.REQUIRED=!0;else if(i(e,!0)){var x=new N,w=x[v](g?{}:-0,1)!=x,k=d((function(){x.has(1)})),_=f((function(e){new b(e)})),L=!g&&d((function(){for(var e=new b,t=5;t--;)e[v](t,t);return!e.has(-0)}));_||((N=t((function(t,n){u(t,N,e);var o=m(new b,t,N);return n!=undefined&&l(n,o[v],o,h),o}))).prototype=C,C.constructor=N),(k||L)&&(V("delete"),V("has"),h&&V("get")),(L||w)&&V(v),g&&C.clear&&delete C.clear}return y[e]=N,o({global:!0,forced:N!=b},y),p(N,e),g||n.setStrong(N,e,h),N}},function(e,t,n){"use strict";var o=n(7),r=n(49);e.exports=function(e,t,n){var i,a;return r&&"function"==typeof(i=t.constructor)&&i!==n&&o(a=i.prototype)&&a!==n.prototype&&r(e,a),e}},function(e,t,n){"use strict";var o=Math.expm1,r=Math.exp;e.exports=!o||o(10)>22025.465794806718||o(10)<22025.465794806718||-2e-17!=o(-2e-17)?function(e){return 0==(e=+e)?e:e>-1e-6&&e<1e-6?e+e*e/2:r(e)-1}:o},function(e,t,n){"use strict";e.exports="\t\n\x0B\f\r \xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff"},function(e,t,n){"use strict";var o=n(37),r=n(5),i=n(2);e.exports=o||!i((function(){var e=Math.random();__defineSetter__.call(null,e,(function(){})),delete r[e]}))},function(e,t,n){"use strict";var o=n(9);e.exports=function(){var e=o(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.dotAll&&(t+="s"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t}},function(e,t,n){"use strict";var o,r,i=n(82),a=n(109),c=RegExp.prototype.exec,l=String.prototype.replace,u=c,s=(o=/a/,r=/b*/g,c.call(o,"a"),c.call(r,"a"),0!==o.lastIndex||0!==r.lastIndex),d=a.UNSUPPORTED_Y||a.BROKEN_CARET,f=/()??/.exec("")[1]!==undefined;(s||f||d)&&(u=function(e){var t,n,o,r,a=this,u=d&&a.sticky,p=i.call(a),m=a.source,h=0,g=e;return u&&(-1===(p=p.replace("y","")).indexOf("g")&&(p+="g"),g=String(e).slice(a.lastIndex),a.lastIndex>0&&(!a.multiline||a.multiline&&"\n"!==e[a.lastIndex-1])&&(m="(?: "+m+")",g=" "+g,h++),n=new RegExp("^(?:"+m+")",p)),f&&(n=new RegExp("^"+m+"$(?!\\s)",p)),s&&(t=a.lastIndex),o=c.call(u?n:a,g),u?o?(o.input=o.input.slice(h),o[0]=o[0].slice(h),o.index=a.lastIndex,a.lastIndex+=o[0].length):a.lastIndex=0:s&&o&&(a.lastIndex=a.global?o.index+o[0].length:t),f&&o&&o.length>1&&l.call(o[0],n,(function(){for(r=1;r")})),s="$0"==="a".replace(/./,"$0"),d=i("replace"),f=!!/./[d]&&""===/./[d]("a","$0"),p=!r((function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var n="ab".split(e);return 2!==n.length||"a"!==n[0]||"b"!==n[1]}));e.exports=function(e,t,n,d){var m=i(e),h=!r((function(){var t={};return t[m]=function(){return 7},7!=""[e](t)})),g=h&&!r((function(){var t=!1,n=/a/;return"split"===e&&((n={}).constructor={},n.constructor[l]=function(){return n},n.flags="",n[m]=/./[m]),n.exec=function(){return t=!0,null},n[m](""),!t}));if(!h||!g||"replace"===e&&(!u||!s||f)||"split"===e&&!p){var v=/./[m],b=n(m,""[e],(function(e,t,n,o,r){return t.exec===a?h&&!r?{done:!0,value:v.call(t,n,o)}:{done:!0,value:e.call(n,t,o)}:{done:!1}}),{REPLACE_KEEPS_$0:s,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:f}),C=b[0],N=b[1];o(String.prototype,e,C),o(RegExp.prototype,m,2==t?function(e,t){return N.call(e,this,t)}:function(e){return N.call(e,this)})}d&&c(RegExp.prototype[m],"sham",!0)}},function(e,t,n){"use strict";var o=n(32),r=n(83);e.exports=function(e,t){var n=e.exec;if("function"==typeof n){var i=n.call(e,t);if("object"!=typeof i)throw TypeError("RegExp exec method returned something other than an Object or null");return i}if("RegExp"!==o(e))throw TypeError("RegExp#exec called on incompatible receiver");return r.call(e,t)}},function(e,t,n){"use strict";t.__esModule=!0,t.TableCell=t.TableRow=t.Table=void 0;var o=n(1),r=n(12),i=n(16);function a(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var c=function(e){var t=e.className,n=e.collapsing,c=e.children,l=a(e,["className","collapsing","children"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"table",(0,r.classes)(["Table",n&&"Table--collapsing",t,(0,i.computeBoxClassName)(l)]),(0,o.createVNode)(1,"tbody",null,c,0),2,Object.assign({},(0,i.computeBoxProps)(l))))};t.Table=c,c.defaultHooks=r.pureComponentHooks;var l=function(e){var t=e.className,n=e.header,c=a(e,["className","header"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"tr",(0,r.classes)(["Table__row",n&&"Table__row--header",t,(0,i.computeBoxClassName)(e)]),null,1,Object.assign({},(0,i.computeBoxProps)(c))))};t.TableRow=l,l.defaultHooks=r.pureComponentHooks;var u=function(e){var t=e.className,n=e.collapsing,c=e.header,l=a(e,["className","collapsing","header"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"td",(0,r.classes)(["Table__cell",n&&"Table__cell--collapsing",c&&"Table__cell--header",t,(0,i.computeBoxClassName)(e)]),null,1,Object.assign({},(0,i.computeBoxProps)(l))))};t.TableCell=u,u.defaultHooks=r.pureComponentHooks,c.Row=l,c.Cell=u},function(e,t,n){"use strict";t.__esModule=!0,t.ComplexModal=t.modalRegisterBodyOverride=t.modalOpen=void 0;var o=n(1),r=n(3),i=n(4),a={};t.modalOpen=function(e,t,n){var o=(0,r.useBackend)(e),i=o.act,a=o.data,c=Object.assign(a.modal?a.modal.args:{},n||{});i("modal_open",{id:t,arguments:JSON.stringify(c)})};t.modalRegisterBodyOverride=function(e,t){a[e]=t};var c=function(e,t,n,o){var i=(0,r.useBackend)(e),a=i.act,c=i.data;if(c.modal){var l=Object.assign(c.modal.args||{},o||{});a("modal_answer",{id:t,answer:n,arguments:JSON.stringify(l)})}},l=function(e,t){(0,(0,r.useBackend)(e).act)("modal_close",{id:t})};t.ComplexModal=function(e,t){var n=(0,r.useBackend)(t).data;if(n.modal){var u,s,d=n.modal,f=d.id,p=d.text,m=d.type,h=(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}});if(a[f])s=a[f](n.modal,t);else if("input"===m){var g=n.modal.value;u=function(e){return c(t,f,g)},s=(0,o.createComponentVNode)(2,i.Input,{value:n.modal.value,placeholder:"ENTER to submit",width:"100%",my:"0.5rem",autofocus:!0,onChange:function(e,t){g=t}}),h=(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"check",content:"Confirm",color:"good",float:"right",m:"0",onClick:function(){return c(t,f,g)}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]})}else if("choice"===m){var v="object"==typeof n.modal.choices?Object.values(n.modal.choices):n.modal.choices;s=(0,o.createComponentVNode)(2,i.Dropdown,{options:v,selected:n.modal.value,width:"100%",my:"0.5rem",onSelected:function(e){return c(t,f,e)}})}else"bento"===m?s=(0,o.createComponentVNode)(2,i.Flex,{spacingPrecise:"1",wrap:"wrap",my:"0.5rem",maxHeight:"1%",children:n.modal.choices.map((function(e,r){return(0,o.createComponentVNode)(2,i.Flex.Item,{flex:"1 1 auto",children:(0,o.createComponentVNode)(2,i.Button,{selected:r+1===parseInt(n.modal.value,10),onClick:function(){return c(t,f,r+1)},children:(0,o.createVNode)(1,"img",null,null,1,{src:e})})},r)}))}):"boolean"===m&&(h=(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:n.modal.no_text,color:"bad",float:"left",mb:"0",onClick:function(){return c(t,f,0)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"check",content:n.modal.yes_text,color:"good",float:"right",m:"0",onClick:function(){return c(t,f,1)}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]}));return(0,o.createComponentVNode)(2,i.Modal,{maxWidth:e.maxWidth||window.innerWidth/2+"px",maxHeight:e.maxHeight||window.innerHeight/2+"px",onEnter:u,mx:"auto",children:[(0,o.createComponentVNode)(2,i.Box,{display:"inline",children:p}),s,h]})}}},function(e,t,n){"use strict";var o=n(5),r=n(7),i=o.document,a=r(i)&&r(i.createElement);e.exports=function(e){return a?i.createElement(e):{}}},function(e,t,n){"use strict";var o=n(5),r=n(29);e.exports=function(e,t){try{r(o,e,t)}catch(n){o[e]=t}return t}},function(e,t,n){"use strict";var o=n(125),r=Function.toString;"function"!=typeof o.inspectSource&&(o.inspectSource=function(e){return r.call(e)}),e.exports=o.inspectSource},function(e,t,n){"use strict";var o=n(37),r=n(125);(e.exports=function(e,t){return r[e]||(r[e]=t!==undefined?t:{})})("versions",[]).push({version:"3.6.5",mode:o?"pure":"global",copyright:"\xa9 2020 Denis Pushkarev (zloirock.ru)"})},function(e,t,n){"use strict";var o=n(36),r=n(46),i=n(94),a=n(9);e.exports=o("Reflect","ownKeys")||function(e){var t=r.f(a(e)),n=i.f;return n?t.concat(n(e)):t}},function(e,t,n){"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t,n){"use strict";t.f=Object.getOwnPropertySymbols},function(e,t,n){"use strict";var o=n(2);e.exports=!!Object.getOwnPropertySymbols&&!o((function(){return!String(Symbol())}))},function(e,t,n){"use strict";var o,r,i=n(5),a=n(72),c=i.process,l=c&&c.versions,u=l&&l.v8;u?r=(o=u.split("."))[0]+o[1]:a&&(!(o=a.match(/Edge\/(\d+)/))||o[1]>=74)&&(o=a.match(/Chrome\/(\d+)/))&&(r=o[1]),e.exports=r&&+r},function(e,t,n){"use strict";var o=n(15),r=n(40),i=n(11);e.exports=function(e){for(var t=o(this),n=i(t.length),a=arguments.length,c=r(a>1?arguments[1]:undefined,n),l=a>2?arguments[2]:undefined,u=l===undefined?n:r(l,n);u>c;)t[c++]=e;return t}},function(e,t,n){"use strict";var o=n(13),r=n(64),i=o("iterator"),a=Array.prototype;e.exports=function(e){return e!==undefined&&(r.Array===e||a[i]===e)}},function(e,t,n){"use strict";var o=n(73),r=n(64),i=n(13)("iterator");e.exports=function(e){if(e!=undefined)return e[i]||e["@@iterator"]||r[o(e)]}},function(e,t,n){"use strict";var o={};o[n(13)("toStringTag")]="z",e.exports="[object z]"===String(o)},function(e,t,n){"use strict";var o=n(0),r=n(205),i=n(35),a=n(49),c=n(42),l=n(29),u=n(22),s=n(13),d=n(37),f=n(64),p=n(139),m=p.IteratorPrototype,h=p.BUGGY_SAFARI_ITERATORS,g=s("iterator"),v=function(){return this};e.exports=function(e,t,n,s,p,b,C){r(n,t,s);var N,y,V,x=function(e){if(e===p&&S)return S;if(!h&&e in _)return _[e];switch(e){case"keys":case"values":case"entries":return function(){return new n(this,e)}}return function(){return new n(this)}},w=t+" Iterator",k=!1,_=e.prototype,L=_[g]||_["@@iterator"]||p&&_[p],S=!h&&L||x(p),B="Array"==t&&_.entries||L;if(B&&(N=i(B.call(new e)),m!==Object.prototype&&N.next&&(d||i(N)===m||(a?a(N,m):"function"!=typeof N[g]&&l(N,g,v)),c(N,w,!0,!0),d&&(f[w]=v))),"values"==p&&L&&"values"!==L.name&&(k=!0,S=function(){return L.call(this)}),d&&!C||_[g]===S||l(_,g,S),f[t]=S,p)if(y={values:x("values"),keys:b?S:x("keys"),entries:x("entries")},C)for(V in y)(h||k||!(V in _))&&u(_,V,y[V]);else o({target:t,proto:!0,forced:h||k},y);return y}},function(e,t,n){"use strict";var o=n(2);e.exports=!o((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},function(e,t,n){"use strict";e.exports="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof DataView},function(e,t,n){"use strict";var o=n(11),r=n(105),i=n(21),a=Math.ceil,c=function(e){return function(t,n,c){var l,u,s=String(i(t)),d=s.length,f=c===undefined?" ":String(c),p=o(n);return p<=d||""==f?s:(l=p-d,(u=r.call(f,a(l/f.length))).length>l&&(u=u.slice(0,l)),e?s+u:u+s)}};e.exports={start:c(!1),end:c(!0)}},function(e,t,n){"use strict";var o=n(30),r=n(21);e.exports="".repeat||function(e){var t=String(r(this)),n="",i=o(e);if(i<0||i==Infinity)throw RangeError("Wrong number of repetitions");for(;i>0;(i>>>=1)&&(t+=t))1&i&&(n+=t);return n}},function(e,t,n){"use strict";e.exports=Math.sign||function(e){return 0==(e=+e)||e!=e?e:e<0?-1:1}},function(e,t,n){"use strict";var o,r,i,a=n(5),c=n(2),l=n(32),u=n(47),s=n(132),d=n(88),f=n(151),p=a.location,m=a.setImmediate,h=a.clearImmediate,g=a.process,v=a.MessageChannel,b=a.Dispatch,C=0,N={},y=function(e){if(N.hasOwnProperty(e)){var t=N[e];delete N[e],t()}},V=function(e){return function(){y(e)}},x=function(e){y(e.data)},w=function(e){a.postMessage(e+"",p.protocol+"//"+p.host)};m&&h||(m=function(e){for(var t=[],n=1;arguments.length>n;)t.push(arguments[n++]);return N[++C]=function(){("function"==typeof e?e:Function(e)).apply(undefined,t)},o(C),C},h=function(e){delete N[e]},"process"==l(g)?o=function(e){g.nextTick(V(e))}:b&&b.now?o=function(e){b.now(V(e))}:v&&!f?(i=(r=new v).port2,r.port1.onmessage=x,o=u(i.postMessage,i,1)):!a.addEventListener||"function"!=typeof postMessage||a.importScripts||c(w)||"file:"===p.protocol?o="onreadystatechange"in d("script")?function(e){s.appendChild(d("script")).onreadystatechange=function(){s.removeChild(this),y(e)}}:function(e){setTimeout(V(e),0)}:(o=w,a.addEventListener("message",x,!1))),e.exports={set:m,clear:h}},function(e,t,n){"use strict";var o=n(7),r=n(32),i=n(13)("match");e.exports=function(e){var t;return o(e)&&((t=e[i])!==undefined?!!t:"RegExp"==r(e))}},function(e,t,n){"use strict";var o=n(2);function r(e,t){return RegExp(e,t)}t.UNSUPPORTED_Y=o((function(){var e=r("a","y");return e.lastIndex=2,null!=e.exec("abcd")})),t.BROKEN_CARET=o((function(){var e=r("^r","gy");return e.lastIndex=2,null!=e.exec("str")}))},function(e,t,n){"use strict";var o=n(30),r=n(21),i=function(e){return function(t,n){var i,a,c=String(r(t)),l=o(n),u=c.length;return l<0||l>=u?e?"":undefined:(i=c.charCodeAt(l))<55296||i>56319||l+1===u||(a=c.charCodeAt(l+1))<56320||a>57343?e?c.charAt(l):i:e?c.slice(l,l+2):a-56320+(i-55296<<10)+65536}};e.exports={codeAt:i(!1),charAt:i(!0)}},function(e,t,n){"use strict";var o=n(108);e.exports=function(e){if(o(e))throw TypeError("The method doesn't accept regular expressions");return e}},function(e,t,n){"use strict";var o=n(13)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(n){try{return t[o]=!1,"/./"[e](t)}catch(r){}}return!1}},function(e,t,n){"use strict";var o=n(110).charAt;e.exports=function(e,t,n){return t+(n?o(e,t).length:1)}},function(e,t,n){"use strict";var o=n(2),r=n(80);e.exports=function(e){return o((function(){return!!r[e]()||"\u200b\x85\u180e"!="\u200b\x85\u180e"[e]()||r[e].name!==e}))}},function(e,t,n){"use strict";var o=n(5),r=n(2),i=n(74),a=n(10).NATIVE_ARRAY_BUFFER_VIEWS,c=o.ArrayBuffer,l=o.Int8Array;e.exports=!a||!r((function(){l(1)}))||!r((function(){new l(-1)}))||!i((function(e){new l,new l(null),new l(1.5),new l(e)}),!0)||r((function(){return 1!==new l(new c(2),1,undefined).length}))},function(e,t,n){"use strict";t.__esModule=!0,t.hotKeyReducer=t.hotKeyMiddleware=t.releaseHeldKeys=t.KEY_MINUS=t.KEY_EQUAL=t.KEY_Z=t.KEY_Y=t.KEY_X=t.KEY_W=t.KEY_V=t.KEY_U=t.KEY_T=t.KEY_S=t.KEY_R=t.KEY_Q=t.KEY_P=t.KEY_O=t.KEY_N=t.KEY_M=t.KEY_L=t.KEY_K=t.KEY_J=t.KEY_I=t.KEY_H=t.KEY_G=t.KEY_F=t.KEY_E=t.KEY_D=t.KEY_C=t.KEY_B=t.KEY_A=t.KEY_9=t.KEY_8=t.KEY_7=t.KEY_6=t.KEY_5=t.KEY_4=t.KEY_3=t.KEY_2=t.KEY_1=t.KEY_0=t.KEY_SPACE=t.KEY_ESCAPE=t.KEY_ALT=t.KEY_CTRL=t.KEY_SHIFT=t.KEY_ENTER=t.KEY_TAB=t.KEY_BACKSPACE=void 0;var o=n(24),r=(0,n(55).createLogger)("hotkeys");t.KEY_BACKSPACE=8;t.KEY_TAB=9;t.KEY_ENTER=13;t.KEY_SHIFT=16;t.KEY_CTRL=17;t.KEY_ALT=18;t.KEY_ESCAPE=27;t.KEY_SPACE=32;t.KEY_0=48;t.KEY_1=49;t.KEY_2=50;t.KEY_3=51;t.KEY_4=52;t.KEY_5=53;t.KEY_6=54;t.KEY_7=55;t.KEY_8=56;t.KEY_9=57;t.KEY_A=65;t.KEY_B=66;t.KEY_C=67;t.KEY_D=68;t.KEY_E=69;t.KEY_F=70;t.KEY_G=71;t.KEY_H=72;t.KEY_I=73;t.KEY_J=74;t.KEY_K=75;t.KEY_L=76;t.KEY_M=77;t.KEY_N=78;t.KEY_O=79;t.KEY_P=80;t.KEY_Q=81;t.KEY_R=82;t.KEY_S=83;t.KEY_T=84;t.KEY_U=85;t.KEY_V=86;t.KEY_W=87;t.KEY_X=88;t.KEY_Y=89;t.KEY_Z=90;t.KEY_EQUAL=187;t.KEY_MINUS=189;var i=[17,18,16],a=[27,13,32,9,17,16],c={},l=function(e,t,n,o){var r="";return e&&(r+="Ctrl+"),t&&(r+="Alt+"),n&&(r+="Shift+"),r+=o>=48&&o<=90?String.fromCharCode(o):"["+o+"]"},u=function(e){var t=window.event?e.which:e.keyCode,n=e.ctrlKey,o=e.altKey,r=e.shiftKey;return{keyCode:t,ctrlKey:n,altKey:o,shiftKey:r,hasModifierKeys:n||o||r,keyString:l(n,o,r,t)}},s=function(){for(var e=0,t=Object.keys(c);e=0||(r[n]=e[n]);return r}var m=(0,l.createLogger)("Button"),h=function(e){var t=e.className,n=e.fluid,l=e.icon,f=e.color,h=e.disabled,g=e.selected,v=e.tooltip,b=e.tooltipPosition,C=e.ellipsis,N=e.content,y=e.iconRotation,V=e.iconSpin,x=e.children,w=e.onclick,k=e.onClick,_=p(e,["className","fluid","icon","color","disabled","selected","tooltip","tooltipPosition","ellipsis","content","iconRotation","iconSpin","children","onclick","onClick"]),L=!(!N&&!x);return w&&m.warn("Lowercase 'onclick' is not supported on Button and lowercase prop names are discouraged in general. Please use a camelCase'onClick' instead and read: https://infernojs.org/docs/guides/event-handling"),(0,o.normalizeProps)((0,o.createComponentVNode)(2,u.Box,Object.assign({className:(0,r.classes)(["Button",n&&"Button--fluid",h&&"Button--disabled",g&&"Button--selected",L&&"Button--hasContent",C&&"Button--ellipsis",f&&"string"==typeof f?"Button--color--"+f:"Button--color--default",t]),tabIndex:!h&&"0",unselectable:i.IS_IE8,onclick:function(e){(0,c.refocusLayout)(),!h&&k&&k(e)},onKeyDown:function(e){var t=window.event?e.which:e.keyCode;return t===a.KEY_SPACE||t===a.KEY_ENTER?(e.preventDefault(),void(!h&&k&&k(e))):t===a.KEY_ESCAPE?(e.preventDefault(),void(0,c.refocusLayout)()):void 0}},_,{children:[l&&(0,o.createComponentVNode)(2,s.Icon,{name:l,rotation:y,spin:V}),N,x,v&&(0,o.createComponentVNode)(2,d.Tooltip,{content:v,position:b})]})))};t.Button=h,h.defaultHooks=r.pureComponentHooks;var g=function(e){var t=e.checked,n=p(e,["checked"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,h,Object.assign({color:"transparent",icon:t?"check-square-o":"square-o",selected:t},n)))};t.ButtonCheckbox=g,h.Checkbox=g;var v=function(e){function t(){var t;return(t=e.call(this)||this).state={clickedOnce:!1},t.handleClick=function(){t.state.clickedOnce&&t.setClickedOnce(!1)},t}f(t,e);var n=t.prototype;return n.setClickedOnce=function(e){var t=this;this.setState({clickedOnce:e}),e?setTimeout((function(){return window.addEventListener("click",t.handleClick)})):window.removeEventListener("click",this.handleClick)},n.render=function(){var e=this,t=this.props,n=t.confirmContent,r=void 0===n?"Confirm?":n,i=t.confirmColor,a=void 0===i?"bad":i,c=t.confirmIcon,l=t.icon,u=t.color,s=t.content,d=t.onClick,f=p(t,["confirmContent","confirmColor","confirmIcon","icon","color","content","onClick"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,h,Object.assign({content:this.state.clickedOnce?r:s,icon:this.state.clickedOnce?c:l,color:this.state.clickedOnce?a:u,onClick:function(){return e.state.clickedOnce?d():e.setClickedOnce(!0)}},f)))},t}(o.Component);t.ButtonConfirm=v,h.Confirm=v;var b=function(e){function t(){var t;return(t=e.call(this)||this).inputRef=(0,o.createRef)(),t.state={inInput:!1},t}f(t,e);var n=t.prototype;return n.setInInput=function(e){if(this.setState({inInput:e}),this.inputRef){var t=this.inputRef.current;if(e){t.value=this.props.currentValue||"";try{t.focus(),t.select()}catch(n){}}}},n.commitResult=function(e){if(this.inputRef){var t=this.inputRef.current;if(""!==t.value)return void this.props.onCommit(e,t.value);if(!this.props.defaultValue)return;this.props.onCommit(e,this.props.defaultValue)}},n.render=function(){var e=this,t=this.props,n=t.fluid,i=t.content,c=t.icon,l=t.iconRotation,f=t.iconSpin,m=t.tooltip,h=t.tooltipPosition,g=t.color,v=void 0===g?"default":g,b=(t.placeholder,t.maxLength,p(t,["fluid","content","icon","iconRotation","iconSpin","tooltip","tooltipPosition","color","placeholder","maxLength"]));return(0,o.normalizeProps)((0,o.createComponentVNode)(2,u.Box,Object.assign({className:(0,r.classes)(["Button",n&&"Button--fluid","Button--color--"+v])},b,{onClick:function(){return e.setInInput(!0)},children:[c&&(0,o.createComponentVNode)(2,s.Icon,{name:c,rotation:l,spin:f}),(0,o.createVNode)(1,"div",null,i,0),(0,o.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:this.state.inInput?undefined:"none","text-align":"left"},onBlur:function(t){e.state.inInput&&(e.setInInput(!1),e.commitResult(t))},onKeyDown:function(t){if(t.keyCode===a.KEY_ENTER)return e.setInInput(!1),void e.commitResult(t);t.keyCode===a.KEY_ESCAPE&&e.setInInput(!1)}},null,this.inputRef),m&&(0,o.createComponentVNode)(2,d.Tooltip,{content:m,position:h})]})))},t}(o.Component);t.ButtonInput=b,h.Input=b},function(e,t,n){"use strict";t.__esModule=!0,t.Icon=void 0;var o=n(1),r=n(12),i=n(16);var a=/-o$/,c=function(e){var t=e.name,n=e.size,c=e.spin,l=e.className,u=e.style,s=void 0===u?{}:u,d=e.rotation,f=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["name","size","spin","className","style","rotation"]);n&&(s["font-size"]=100*n+"%"),"number"==typeof d&&(s.transform="rotate("+d+"deg)");var p=a.test(t),m=t.replace(a,"");return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({as:"i",className:(0,r.classes)([l,p?"far":"fas","fa-"+m,c&&"fa-spin"]),style:s},f)))};t.Icon=c,c.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.NumberInput=void 0;var o=n(1),r=n(20),i=n(12),a=n(24),c=n(118),l=n(16);var u=function(e){var t,n;function u(t){var n;n=e.call(this,t)||this;var i=t.value;return n.inputRef=(0,o.createRef)(),n.state={value:i,dragging:!1,editing:!1,internalValue:null,origin:null,suppressingFlicker:!1},n.flickerTimer=null,n.suppressFlicker=function(){var e=n.props.suppressFlicker;e>0&&(n.setState({suppressingFlicker:!0}),clearTimeout(n.flickerTimer),n.flickerTimer=setTimeout((function(){return n.setState({suppressingFlicker:!1})}),e))},n.handleDragStart=function(e){var t=n.props.value;n.state.editing||(document.body.style["pointer-events"]="none",n.ref=e.target,n.setState({dragging:!1,origin:e.screenY,value:t,internalValue:t}),n.timer=setTimeout((function(){n.setState({dragging:!0})}),250),n.dragInterval=setInterval((function(){var t=n.state,o=t.dragging,r=t.value,i=n.props.onDrag;o&&i&&i(e,r)}),500),document.addEventListener("mousemove",n.handleDragMove),document.addEventListener("mouseup",n.handleDragEnd))},n.handleDragMove=function(e){var t=n.props,o=t.minValue,i=t.maxValue,a=t.step,c=t.stepPixelSize;n.setState((function(t){var n=Object.assign({},t),l=n.origin-e.screenY;if(t.dragging){var u=Number.isFinite(o)?o%a:0;n.internalValue=(0,r.clamp)(n.internalValue+l*a/c,o-a,i+a),n.value=(0,r.clamp)(n.internalValue-n.internalValue%a+u,o,i),n.origin=e.screenY}else Math.abs(l)>4&&(n.dragging=!0);return n}))},n.handleDragEnd=function(e){var t=n.props,o=t.onChange,r=t.onDrag,i=n.state,a=i.dragging,c=i.value,l=i.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(n.timer),clearInterval(n.dragInterval),n.setState({dragging:!1,editing:!a,origin:null}),document.removeEventListener("mousemove",n.handleDragMove),document.removeEventListener("mouseup",n.handleDragEnd),a)n.suppressFlicker(),o&&o(e,c),r&&r(e,c);else if(n.inputRef){var u=n.inputRef.current;u.value=l;try{u.focus(),u.select()}catch(s){}}},n}return n=e,(t=u).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,u.prototype.render=function(){var e=this,t=this.state,n=t.dragging,u=t.editing,s=t.value,d=t.suppressingFlicker,f=this.props,p=f.className,m=f.fluid,h=f.animated,g=f.value,v=f.unit,b=f.minValue,C=f.maxValue,N=f.height,y=f.width,V=f.lineHeight,x=f.fontSize,w=f.format,k=f.onChange,_=f.onDrag,L=g;(n||d)&&(L=s);var S=function(e){return(0,o.createVNode)(1,"div","NumberInput__content",e+(v?" "+v:""),0,{unselectable:a.IS_IE8})},B=h&&!n&&!d&&(0,o.createComponentVNode)(2,c.AnimatedNumber,{value:L,format:w,children:S})||S(w?w(L):L);return(0,o.createComponentVNode)(2,l.Box,{className:(0,i.classes)(["NumberInput",m&&"NumberInput--fluid",p]),minWidth:y,minHeight:N,lineHeight:V,fontSize:x,onMouseDown:this.handleDragStart,children:[(0,o.createVNode)(1,"div","NumberInput__barContainer",(0,o.createVNode)(1,"div","NumberInput__bar",null,1,{style:{height:(0,r.clamp)((L-b)/(C-b)*100,0,100)+"%"}}),2),B,(0,o.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:u?undefined:"none",height:N,"line-height":V,"font-size":x},onBlur:function(t){if(u){var n=(0,r.clamp)(t.target.value,b,C);e.setState({editing:!1,value:n}),e.suppressFlicker(),k&&k(t,n),_&&_(t,n)}},onKeyDown:function(t){if(13===t.keyCode){var n=(0,r.clamp)(t.target.value,b,C);return e.setState({editing:!1,value:n}),e.suppressFlicker(),k&&k(t,n),void(_&&_(t,n))}27!==t.keyCode||e.setState({editing:!1})}},null,this.inputRef)]})},u}(o.Component);t.NumberInput=u,u.defaultHooks=i.pureComponentHooks,u.defaultProps={minValue:-Infinity,maxValue:+Infinity,step:1,stepPixelSize:1,suppressFlicker:50}},function(e,t,n){"use strict";t.__esModule=!0,t.BeakerContents=void 0;var o=n(1),r=n(4),i=n(436),a=function(e){var t=e.beakerLoaded,n=e.beakerContents,i=void 0===n?[]:n,a=e.buttons;return(0,o.createComponentVNode)(2,r.Box,{children:[!t&&(0,o.createComponentVNode)(2,r.Box,{color:"label",children:"No beaker loaded."})||0===i.length&&(0,o.createComponentVNode)(2,r.Box,{color:"label",children:"Beaker is empty."}),i.map((function(e,t){return(0,o.createComponentVNode)(2,r.Box,{width:"100%",children:[(0,o.createComponentVNode)(2,r.Box,{color:"label",display:"inline",verticalAlign:"middle",children:[(n=e.volume,n+" unit"+(1===n?"":"s"))," of ",e.name]}),!!a&&(0,o.createComponentVNode)(2,r.Box,{float:"right",display:"inline",children:a(e,t)}),(0,o.createComponentVNode)(2,r.Box,{clear:"both"})]},e.name);var n}))]})};t.BeakerContents=a,a.propTypes={beakerLoaded:i.bool,beakerContents:i.array,buttons:i.arrayOf(i.element)}},function(e,t,n){"use strict";var o;o=function(){return this}();try{o=o||new Function("return this")()}catch(r){"object"==typeof window&&(o=window)}e.exports=o},function(e,t,n){"use strict";var o=n(8),r=n(2),i=n(88);e.exports=!o&&!r((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(e,t,n){"use strict";var o=n(5),r=n(89),i=o["__core-js_shared__"]||r("__core-js_shared__",{});e.exports=i},function(e,t,n){"use strict";var o=n(5),r=n(90),i=o.WeakMap;e.exports="function"==typeof i&&/native code/.test(r(i))},function(e,t,n){"use strict";var o=n(17),r=n(92),i=n(19),a=n(14);e.exports=function(e,t){for(var n=r(t),c=a.f,l=i.f,u=0;ul;)o(c,n=t[l++])&&(~i(u,n)||u.push(n));return u}},function(e,t,n){"use strict";var o=n(95);e.exports=o&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(e,t,n){"use strict";var o=n(8),r=n(14),i=n(9),a=n(61);e.exports=o?Object.defineProperties:function(e,t){i(e);for(var n,o=a(t),c=o.length,l=0;c>l;)r.f(e,n=o[l++],t[n]);return e}},function(e,t,n){"use strict";var o=n(36);e.exports=o("document","documentElement")},function(e,t,n){"use strict";var o=n(25),r=n(46).f,i={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return a&&"[object Window]"==i.call(e)?function(e){try{return r(e)}catch(t){return a.slice()}}(e):r(o(e))}},function(e,t,n){"use strict";var o=n(13);t.f=o},function(e,t,n){"use strict";var o=n(15),r=n(40),i=n(11),a=Math.min;e.exports=[].copyWithin||function(e,t){var n=o(this),c=i(n.length),l=r(e,c),u=r(t,c),s=arguments.length>2?arguments[2]:undefined,d=a((s===undefined?c:r(s,c))-u,c-l),f=1;for(u0;)u in n?n[l]=n[u]:delete n[l],l+=f,u+=f;return n}},function(e,t,n){"use strict";var o=n(51),r=n(11),i=n(47);e.exports=function a(e,t,n,c,l,u,s,d){for(var f,p=l,m=0,h=!!s&&i(s,d,3);m0&&o(f))p=a(e,t,f,r(f.length),p,u-1)-1;else{if(p>=9007199254740991)throw TypeError("Exceed the acceptable array length");e[p]=f}p++}m++}return p}},function(e,t,n){"use strict";var o=n(9);e.exports=function(e,t,n,r){try{return r?t(o(n)[0],n[1]):t(n)}catch(a){var i=e["return"];throw i!==undefined&&o(i.call(e)),a}}},function(e,t,n){"use strict";var o=n(25),r=n(43),i=n(64),a=n(34),c=n(101),l=a.set,u=a.getterFor("Array Iterator");e.exports=c(Array,"Array",(function(e,t){l(this,{type:"Array Iterator",target:o(e),index:0,kind:t})}),(function(){var e=u(this),t=e.target,n=e.kind,o=e.index++;return!t||o>=t.length?(e.target=undefined,{value:undefined,done:!0}):"keys"==n?{value:o,done:!1}:"values"==n?{value:t[o],done:!1}:{value:[o,t[o]],done:!1}}),"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},function(e,t,n){"use strict";var o,r,i,a=n(35),c=n(29),l=n(17),u=n(13),s=n(37),d=u("iterator"),f=!1;[].keys&&("next"in(i=[].keys())?(r=a(a(i)))!==Object.prototype&&(o=r):f=!0),o==undefined&&(o={}),s||l(o,d)||c(o,d,(function(){return this})),e.exports={IteratorPrototype:o,BUGGY_SAFARI_ITERATORS:f}},function(e,t,n){"use strict";var o=n(7);e.exports=function(e){if(!o(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},function(e,t,n){"use strict";var o=n(25),r=n(30),i=n(11),a=n(38),c=n(23),l=Math.min,u=[].lastIndexOf,s=!!u&&1/[1].lastIndexOf(1,-0)<0,d=a("lastIndexOf"),f=c("indexOf",{ACCESSORS:!0,1:0}),p=s||!d||!f;e.exports=p?function(e){if(s)return u.apply(this,arguments)||0;var t=o(this),n=i(t.length),a=n-1;for(arguments.length>1&&(a=l(a,r(arguments[1]))),a<0&&(a=n+a);a>=0;a--)if(a in t&&t[a]===e)return a||0;return-1}:u},function(e,t,n){"use strict";var o=n(30),r=n(11);e.exports=function(e){if(e===undefined)return 0;var t=o(e),n=r(t);if(t!==n)throw RangeError("Wrong length or index");return n}},function(e,t,n){"use strict";var o=n(31),r=n(7),i=[].slice,a={},c=function(e,t,n){if(!(t in a)){for(var o=[],r=0;r1?arguments[1]:undefined,3);t=t?t.next:n.first;)for(o(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(e){return!!v(this,e)}}),i(s.prototype,n?{get:function(e){var t=v(this,e);return t&&t.value},set:function(e,t){return g(this,0===e?0:e,t)}}:{add:function(e){return g(this,e=0===e?0:e,e)}}),d&&o(s.prototype,"size",{get:function(){return p(this).size}}),s},setStrong:function(e,t,n){var o=t+" Iterator",r=h(t),i=h(o);u(e,t,(function(e,t){m(this,{type:o,target:e,state:r(e),kind:t,last:undefined})}),(function(){for(var e=i(this),t=e.kind,n=e.last;n&&n.removed;)n=n.previous;return e.target&&(e.last=n=n?n.next:e.state.first)?"keys"==t?{value:n.key,done:!1}:"values"==t?{value:n.value,done:!1}:{value:[n.key,n.value],done:!1}:(e.target=undefined,{value:undefined,done:!0})}),n?"entries":"values",!n,!0),s(t)}}},function(e,t,n){"use strict";var o=Math.log;e.exports=Math.log1p||function(e){return(e=+e)>-1e-8&&e<1e-8?e-e*e/2:o(1+e)}},function(e,t,n){"use strict";var o=n(7),r=Math.floor;e.exports=function(e){return!o(e)&&isFinite(e)&&r(e)===e}},function(e,t,n){"use strict";var o=n(5),r=n(54).trim,i=n(80),a=o.parseInt,c=/^[+-]?0[Xx]/,l=8!==a(i+"08")||22!==a(i+"0x16");e.exports=l?function(e,t){var n=r(String(e));return a(n,t>>>0||(c.test(n)?16:10))}:a},function(e,t,n){"use strict";var o=n(8),r=n(61),i=n(25),a=n(70).f,c=function(e){return function(t){for(var n,c=i(t),l=r(c),u=l.length,s=0,d=[];u>s;)n=l[s++],o&&!a.call(c,n)||d.push(e?[n,c[n]]:c[n]);return d}};e.exports={entries:c(!0),values:c(!1)}},function(e,t,n){"use strict";e.exports=Object.is||function(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t}},function(e,t,n){"use strict";var o=n(5);e.exports=o.Promise},function(e,t,n){"use strict";var o=n(72);e.exports=/(iphone|ipod|ipad).*applewebkit/i.test(o)},function(e,t,n){"use strict";var o,r,i,a,c,l,u,s,d=n(5),f=n(19).f,p=n(32),m=n(107).set,h=n(151),g=d.MutationObserver||d.WebKitMutationObserver,v=d.process,b=d.Promise,C="process"==p(v),N=f(d,"queueMicrotask"),y=N&&N.value;y||(o=function(){var e,t;for(C&&(e=v.domain)&&e.exit();r;){t=r.fn,r=r.next;try{t()}catch(n){throw r?a():i=undefined,n}}i=undefined,e&&e.enter()},C?a=function(){v.nextTick(o)}:g&&!h?(c=!0,l=document.createTextNode(""),new g(o).observe(l,{characterData:!0}),a=function(){l.data=c=!c}):b&&b.resolve?(u=b.resolve(undefined),s=u.then,a=function(){s.call(u,o)}):a=function(){m.call(d,o)}),e.exports=y||function(e){var t={fn:e,next:undefined};i&&(i.next=t),r||(r=t,a()),i=t}},function(e,t,n){"use strict";var o=n(9),r=n(7),i=n(154);e.exports=function(e,t){if(o(e),r(t)&&t.constructor===e)return t;var n=i.f(e);return(0,n.resolve)(t),n.promise}},function(e,t,n){"use strict";var o=n(31),r=function(e){var t,n;this.promise=new e((function(e,o){if(t!==undefined||n!==undefined)throw TypeError("Bad Promise constructor");t=e,n=o})),this.resolve=o(t),this.reject=o(n)};e.exports.f=function(e){return new r(e)}},function(e,t,n){"use strict";var o=n(0),r=n(83);o({target:"RegExp",proto:!0,forced:/./.exec!==r},{exec:r})},function(e,t,n){"use strict";var o=n(72);e.exports=/Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(o)},function(e,t,n){"use strict";var o=n(349);e.exports=function(e,t){var n=o(e);if(n%t)throw RangeError("Wrong offset");return n}},function(e,t,n){"use strict";var o=n(15),r=n(11),i=n(99),a=n(98),c=n(47),l=n(10).aTypedArrayConstructor;e.exports=function(e){var t,n,u,s,d,f,p=o(e),m=arguments.length,h=m>1?arguments[1]:undefined,g=h!==undefined,v=i(p);if(v!=undefined&&!a(v))for(f=(d=v.call(p)).next,p=[];!(s=f.call(d)).done;)p.push(s.value);for(g&&m>2&&(h=c(h,arguments[2],2)),n=r(p.length),u=new(l(this))(n),t=0;n>t;t++)u[t]=g?h(p[t],t):p[t];return u}},function(e,t,n){"use strict";var o=n(65),r=n(50).getWeakData,i=n(9),a=n(7),c=n(53),l=n(67),u=n(18),s=n(17),d=n(34),f=d.set,p=d.getterFor,m=u.find,h=u.findIndex,g=0,v=function(e){return e.frozen||(e.frozen=new b)},b=function(){this.entries=[]},C=function(e,t){return m(e.entries,(function(e){return e[0]===t}))};b.prototype={get:function(e){var t=C(this,e);if(t)return t[1]},has:function(e){return!!C(this,e)},set:function(e,t){var n=C(this,e);n?n[1]=t:this.entries.push([e,t])},"delete":function(e){var t=h(this.entries,(function(t){return t[0]===e}));return~t&&this.entries.splice(t,1),!!~t}},e.exports={getConstructor:function(e,t,n,u){var d=e((function(e,o){c(e,d,t),f(e,{type:t,id:g++,frozen:undefined}),o!=undefined&&l(o,e[u],e,n)})),m=p(t),h=function(e,t,n){var o=m(e),a=r(i(t),!0);return!0===a?v(o).set(t,n):a[o.id]=n,e};return o(d.prototype,{"delete":function(e){var t=m(this);if(!a(e))return!1;var n=r(e);return!0===n?v(t)["delete"](e):n&&s(n,t.id)&&delete n[t.id]},has:function(e){var t=m(this);if(!a(e))return!1;var n=r(e);return!0===n?v(t).has(e):n&&s(n,t.id)}}),o(d.prototype,n?{get:function(e){var t=m(this);if(a(e)){var n=r(e);return!0===n?v(t).get(e):n?n[t.id]:undefined}},set:function(e,t){return h(this,e,t)}}:{add:function(e){return h(this,e,!0)}}),d}}},function(e,t,n){"use strict";t.__esModule=!0,t.setupHotReloading=t.sendLogEntry=void 0;t.sendLogEntry=function(e,t){};t.setupHotReloading=function(){0}},function(e,t,n){"use strict";t.__esModule=!0,t.resizeStartHandler=t.dragStartHandler=t.setupDrag=void 0;var o=n(391),r=n(24);function i(e,t,n,o,r,i,a){try{var c=e[i](a),l=c.value}catch(u){return void n(u)}c.done?t(l):Promise.resolve(l).then(o,r)}var a,c,l,u,s,d=(0,n(55).createLogger)("drag"),f=!1,p=!1,m=[0,0],h=function(e){return(0,r.winget)(e,"pos").then((function(e){return[e.x,e.y]}))},g=function(e,t){return(0,r.winset)(e,"pos",t[0]+","+t[1])},v=function(){var e,t=(e=regeneratorRuntime.mark((function n(e){var t,o,r,i;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return d.log("setting up"),a=e.config.window,n.next=4,h(a);case 4:t=n.sent,m=[t[0]-window.screenLeft,t[1]-window.screenTop],o=b(t),r=o[0],i=o[1],r&&g(a,i),d.debug("current state",{ref:a,screenOffset:m});case 9:case"end":return n.stop()}}),n)})),function(){var t=this,n=arguments;return new Promise((function(o,r){var a=e.apply(t,n);function c(e){i(a,o,r,c,l,"next",e)}function l(e){i(a,o,r,c,l,"throw",e)}c(undefined)}))});return function(e){return t.apply(this,arguments)}}();t.setupDrag=v;var b=function(e){var t=e[0],n=e[1],o=!1;return t<0?(t=0,o=!0):t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth,o=!0),n<0?(n=0,o=!0):n+window.innerHeight>window.screen.availHeight&&(n=window.screen.availHeight-window.innerHeight,o=!0),[o,[t,n]]};t.dragStartHandler=function(e){d.log("drag start"),f=!0,c=[window.screenLeft-e.screenX,window.screenTop-e.screenY],document.addEventListener("mousemove",N),document.addEventListener("mouseup",C),N(e)};var C=function x(e){d.log("drag end"),N(e),document.removeEventListener("mousemove",N),document.removeEventListener("mouseup",x),f=!1},N=function(e){f&&(e.preventDefault(),g(a,(0,o.vecAdd)([e.screenX,e.screenY],m,c)))};t.resizeStartHandler=function(e,t){return function(n){l=[e,t],d.log("resize start",l),p=!0,c=[window.screenLeft-n.screenX,window.screenTop-n.screenY],u=[window.innerWidth,window.innerHeight],document.addEventListener("mousemove",V),document.addEventListener("mouseup",y),V(n)}};var y=function w(e){d.log("resize end",s),V(e),document.removeEventListener("mousemove",V),document.removeEventListener("mouseup",w),p=!1},V=function(e){p&&(e.preventDefault(),(s=(0,o.vecAdd)(u,(0,o.vecMultiply)(l,(0,o.vecAdd)([e.screenX,e.screenY],(0,o.vecInverse)([window.screenLeft,window.screenTop]),c,[1,1]))))[0]=Math.max(s[0],250),s[1]=Math.max(s[1],120),function(e,t){(0,r.winset)(e,"size",t[0]+","+t[1])}(a,s))}},function(e,t,n){"use strict";function o(e){var t=0;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(e=function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e)))return function(){return t>=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(t=e[Symbol.iterator]()).next.bind(t)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n1?r-1:0),c=1;c1?o-1:0),i=1;i35;return(0,o.createVNode)(1,"div",(0,r.classes)(["Tooltip",a&&"Tooltip--long",i&&"Tooltip--"+i]),null,1,{"data-tooltip":t})}},function(e,t,n){"use strict";t.__esModule=!0,t.Dimmer=void 0;var o=n(1),r=n(12),i=n(16);t.Dimmer=function(e){var t=e.className,n=e.children,a=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","children"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["Dimmer"].concat(t))},a,{children:(0,o.createVNode)(1,"div","Dimmer__inner",n,0)})))}},function(e,t,n){"use strict";t.__esModule=!0,t.Divider=void 0;var o=n(1),r=n(12);t.Divider=function(e){var t=e.vertical,n=e.hidden;return(0,o.createVNode)(1,"div",(0,r.classes)(["Divider",n&&"Divider--hidden",t?"Divider--vertical":"Divider--horizontal"]))}},function(e,t,n){"use strict";t.__esModule=!0,t.FlexItem=t.computeFlexItemProps=t.Flex=t.computeFlexProps=void 0;var o=n(1),r=n(12),i=n(24),a=n(16);function c(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var l=function(e){var t=e.className,n=e.direction,o=e.wrap,a=e.align,l=e.alignContent,u=e.justify,s=e.inline,d=e.spacing,f=void 0===d?0:d,p=e.spacingPrecise,m=void 0===p?0:p,h=c(e,["className","direction","wrap","align","alignContent","justify","inline","spacing","spacingPrecise"]);return Object.assign({className:(0,r.classes)(["Flex",i.IS_IE8&&("column"===n?"Flex--ie8--column":"Flex--ie8"),s&&"Flex--inline",f>0&&"Flex--spacing--"+f,m>0&&"Flex--spacingPrecise--"+m,t]),style:Object.assign({},h.style,{"flex-direction":n,"flex-wrap":o,"align-items":a,"align-content":l,"justify-content":u})},h)};t.computeFlexProps=l;var u=function(e){return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Box,Object.assign({},l(e))))};t.Flex=u,u.defaultHooks=r.pureComponentHooks;var s=function(e){var t=e.className,n=e.grow,o=e.order,l=e.shrink,u=e.basis,s=void 0===u?e.width:u,d=e.align,f=c(e,["className","grow","order","shrink","basis","align"]);return Object.assign({className:(0,r.classes)(["Flex__item",i.IS_IE8&&"Flex__item--ie8",t]),style:Object.assign({},f.style,{"flex-grow":n,"flex-shrink":l,"flex-basis":(0,a.unit)(s),order:o,"align-self":d})},f)};t.computeFlexItemProps=s;var d=function(e){return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Box,Object.assign({},s(e))))};t.FlexItem=d,d.defaultHooks=r.pureComponentHooks,u.Item=d},function(e,t,n){"use strict";t.__esModule=!0,t.DraggableControl=void 0;var o=n(1),r=n(20),i=n(12),a=n(118);var c=function(e,t){return e.screenX*t[0]+e.screenY*t[1]},l=function(e){var t,n;function i(t){var n;return(n=e.call(this,t)||this).inputRef=(0,o.createRef)(),n.state={value:t.value,dragging:!1,editing:!1,internalValue:null,origin:null,suppressingFlicker:!1},n.flickerTimer=null,n.suppressFlicker=function(){var e=n.props.suppressFlicker;e>0&&(n.setState({suppressingFlicker:!0}),clearTimeout(n.flickerTimer),n.flickerTimer=setTimeout((function(){return n.setState({suppressingFlicker:!1})}),e))},n.handleDragStart=function(e){var t=n.props,o=t.value,r=t.dragMatrix;n.state.editing||(document.body.style["pointer-events"]="none",n.ref=e.target,n.setState({dragging:!1,origin:c(e,r),value:o,internalValue:o}),n.timer=setTimeout((function(){n.setState({dragging:!0})}),250),n.dragInterval=setInterval((function(){var t=n.state,o=t.dragging,r=t.value,i=n.props.onDrag;o&&i&&i(e,r)}),500),document.addEventListener("mousemove",n.handleDragMove),document.addEventListener("mouseup",n.handleDragEnd))},n.handleDragMove=function(e){var t=n.props,o=t.minValue,i=t.maxValue,a=t.step,l=t.stepPixelSize,u=t.dragMatrix;n.setState((function(t){var n=Object.assign({},t),s=c(e,u)-n.origin;if(t.dragging){var d=Number.isFinite(o)?o%a:0;n.internalValue=(0,r.clamp)(n.internalValue+s*a/l,o-a,i+a),n.value=(0,r.clamp)(n.internalValue-n.internalValue%a+d,o,i),n.origin=c(e,u)}else Math.abs(s)>4&&(n.dragging=!0);return n}))},n.handleDragEnd=function(e){var t=n.props,o=t.onChange,r=t.onDrag,i=n.state,a=i.dragging,c=i.value,l=i.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(n.timer),clearInterval(n.dragInterval),n.setState({dragging:!1,editing:!a,origin:null}),document.removeEventListener("mousemove",n.handleDragMove),document.removeEventListener("mouseup",n.handleDragEnd),a)n.suppressFlicker(),o&&o(e,c),r&&r(e,c);else if(n.inputRef){var u=n.inputRef.current;u.value=l;try{u.focus(),u.select()}catch(s){}}},n}return n=e,(t=i).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,i.prototype.render=function(){var e=this,t=this.state,n=t.dragging,i=t.editing,c=t.value,l=t.suppressingFlicker,u=this.props,s=u.animated,d=u.value,f=u.unit,p=u.minValue,m=u.maxValue,h=u.format,g=u.onChange,v=u.onDrag,b=u.children,C=u.height,N=u.lineHeight,y=u.fontSize,V=d;(n||l)&&(V=c);var x=function(e){return e+(f?" "+f:"")},w=s&&!n&&!l&&(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:V,format:h,children:x})||x(h?h(V):V),k=(0,o.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:i?undefined:"none",height:C,"line-height":N,"font-size":y},onBlur:function(t){if(i){var n=(0,r.clamp)(t.target.value,p,m);e.setState({editing:!1,value:n}),e.suppressFlicker(),g&&g(t,n),v&&v(t,n)}},onKeyDown:function(t){if(13===t.keyCode){var n=(0,r.clamp)(t.target.value,p,m);return e.setState({editing:!1,value:n}),e.suppressFlicker(),g&&g(t,n),void(v&&v(t,n))}27!==t.keyCode||e.setState({editing:!1})}},null,this.inputRef);return b({dragging:n,editing:i,value:d,displayValue:V,displayElement:w,inputElement:k,handleDragStart:this.handleDragStart})},i}(o.Component);t.DraggableControl=l,l.defaultHooks=i.pureComponentHooks,l.defaultProps={minValue:-Infinity,maxValue:+Infinity,step:1,stepPixelSize:1,suppressFlicker:50,dragMatrix:[1,0]}},function(e,t,n){"use strict";t.__esModule=!0,t.LabeledListDivider=t.LabeledListItem=t.LabeledList=void 0;var o=n(1),r=n(12),i=n(16),a=n(165),c=function(e){var t=e.children;return(0,o.createVNode)(1,"table","LabeledList",t,0)};t.LabeledList=c,c.defaultHooks=r.pureComponentHooks;var l=function(e){var t=e.className,n=e.label,a=e.labelColor,c=void 0===a?"label":a,l=e.color,u=e.textAlign,s=e.verticalAlign,d=e.buttons,f=e.content,p=e.children;return(0,o.createVNode)(1,"tr",(0,r.classes)(["LabeledList__row",t]),[(0,o.createComponentVNode)(2,i.Box,{as:"td",color:c,verticalAlign:s,className:(0,r.classes)(["LabeledList__cell","LabeledList__label"]),children:n?n+":":null}),(0,o.createComponentVNode)(2,i.Box,{as:"td",color:l,textAlign:u,verticalAlign:s,className:(0,r.classes)(["LabeledList__cell","LabeledList__content"]),colSpan:d?undefined:2,children:[f,p]}),d&&(0,o.createVNode)(1,"td","LabeledList__cell LabeledList__buttons",d,0)],0)};t.LabeledListItem=l,l.defaultHooks=r.pureComponentHooks;var u=function(e){var t=e.size?(0,i.unit)(Math.max(0,e.size-1)):0;return(0,o.createVNode)(1,"tr","LabeledList__row",(0,o.createVNode)(1,"td",null,(0,o.createComponentVNode)(2,a.Divider),2,{colSpan:3,style:{"padding-top":t,"padding-bottom":t}}),2)};t.LabeledListDivider=u,u.defaultHooks=r.pureComponentHooks,c.Item=l,c.Divider=u},function(e,t,n){"use strict";t.__esModule=!0,t.Window=void 0;var o=n(1),r=n(12),i=n(170),a=n(3),c=n(24),l=n(4),u=n(68),s=n(161),d=n(116),f=n(55),p=n(117);var m=(0,f.createLogger)("Window"),h=function(e){var t,n;function l(){return e.apply(this,arguments)||this}n=e,(t=l).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var f=l.prototype;return f.componentDidMount=function(){(0,p.refocusLayout)()},f.render=function(){var e=this.props,t=e.resizable,n=e.theme,l=e.children,f=(0,a.useBackend)(this.context),h=f.config,g=f.debugLayout,b=h.observer?h.status=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(t=e[Symbol.iterator]()).next.bind(t)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n",apos:"'"};return e.replace(/
/gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(/&(nbsp|amp|quot|lt|gt|apos);/g,(function(e,n){return t[n]})).replace(/&#?([0-9]+);/gi,(function(e,t){var n=parseInt(t,10);return String.fromCharCode(n)})).replace(/&#x?([0-9a-f]+);/gi,(function(e,t){var n=parseInt(t,16);return String.fromCharCode(n)}))};t.buildQueryString=function(e){return Object.keys(e).map((function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])})).join("&")}},function(e,t,n){"use strict";t.__esModule=!0,t.formatMoney=t.formatPower=t.formatSiUnit=void 0;var o=n(20),r=["f","p","n","\u03bc","m"," ","k","M","G","T","P","E","Z","Y"],i=r.indexOf(" "),a=function(e,t,n){void 0===t&&(t=-i),void 0===n&&(n="");var a=Math.floor(Math.log10(e)),c=Math.floor(Math.max(3*t,a)),l=Math.floor(a/3),u=Math.floor(c/3),s=(0,o.clamp)(i+u,0,r.length),d=r[s],f=e/Math.pow(1e3,u),p=l>t?2+3*u-c:0;return((0,o.toFixed)(f,p)+" "+d+n).trim()};t.formatSiUnit=a;t.formatPower=function(e,t){return void 0===t&&(t=0),a(e,t,"W")};t.formatMoney=function(e,t){if(void 0===t&&(t=0),!Number.isFinite(e))return e;var n=(0,o.round)(e,t);t>0&&(n=(0,o.toFixed)(e,t));var r=(n=String(n)).length,i=n.indexOf(".");-1===i&&(i=r);for(var a="",c=0;c0&&ci;)r.push(arguments[i++]);if(o=t,(p(t)||e!==undefined)&&!ie(e))return f(t)||(t=function(e,t){if("function"==typeof o&&(t=o.call(this,e,t)),!ie(t))return t}),r[1]=t,H.apply(null,r)}});K.prototype[R]||L(K.prototype,R,K.prototype.valueOf),P(K,"Symbol"),I[F]=!0},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(5),a=n(17),c=n(7),l=n(14).f,u=n(127),s=i.Symbol;if(r&&"function"==typeof s&&(!("description"in s.prototype)||s().description!==undefined)){var d={},f=function(){var e=arguments.length<1||arguments[0]===undefined?undefined:String(arguments[0]),t=this instanceof f?new s(e):e===undefined?s():s(e);return""===e&&(d[t]=!0),t};u(f,s);var p=f.prototype=s.prototype;p.constructor=f;var m=p.toString,h="Symbol(test)"==String(s("test")),g=/^Symbol\((.*)\)[^)]+$/;l(p,"description",{configurable:!0,get:function(){var e=c(this)?this.valueOf():this,t=m.call(e);if(a(d,e))return"";var n=h?t.slice(7,-1):t.replace(g,"$1");return""===n?undefined:n}}),o({global:!0,forced:!0},{Symbol:f})}},function(e,t,n){"use strict";n(26)("asyncIterator")},function(e,t,n){"use strict";n(26)("hasInstance")},function(e,t,n){"use strict";n(26)("isConcatSpreadable")},function(e,t,n){"use strict";n(26)("iterator")},function(e,t,n){"use strict";n(26)("match")},function(e,t,n){"use strict";n(26)("replace")},function(e,t,n){"use strict";n(26)("search")},function(e,t,n){"use strict";n(26)("species")},function(e,t,n){"use strict";n(26)("split")},function(e,t,n){"use strict";n(26)("toPrimitive")},function(e,t,n){"use strict";n(26)("toStringTag")},function(e,t,n){"use strict";n(26)("unscopables")},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(51),a=n(7),c=n(15),l=n(11),u=n(48),s=n(62),d=n(63),f=n(13),p=n(96),m=f("isConcatSpreadable"),h=p>=51||!r((function(){var e=[];return e[m]=!1,e.concat()[0]!==e})),g=d("concat"),v=function(e){if(!a(e))return!1;var t=e[m];return t!==undefined?!!t:i(e)};o({target:"Array",proto:!0,forced:!h||!g},{concat:function(e){var t,n,o,r,i,a=c(this),d=s(a,0),f=0;for(t=-1,o=arguments.length;t9007199254740991)throw TypeError("Maximum allowed index exceeded");for(n=0;n=9007199254740991)throw TypeError("Maximum allowed index exceeded");u(d,f++,i)}return d.length=f,d}})},function(e,t,n){"use strict";var o=n(0),r=n(135),i=n(43);o({target:"Array",proto:!0},{copyWithin:r}),i("copyWithin")},function(e,t,n){"use strict";var o=n(0),r=n(18).every,i=n(38),a=n(23),c=i("every"),l=a("every");o({target:"Array",proto:!0,forced:!c||!l},{every:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(97),i=n(43);o({target:"Array",proto:!0},{fill:r}),i("fill")},function(e,t,n){"use strict";var o=n(0),r=n(18).filter,i=n(63),a=n(23),c=i("filter"),l=a("filter");o({target:"Array",proto:!0,forced:!c||!l},{filter:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(18).find,i=n(43),a=n(23),c=!0,l=a("find");"find"in[]&&Array(1).find((function(){c=!1})),o({target:"Array",proto:!0,forced:c||!l},{find:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}}),i("find")},function(e,t,n){"use strict";var o=n(0),r=n(18).findIndex,i=n(43),a=n(23),c=!0,l=a("findIndex");"findIndex"in[]&&Array(1).findIndex((function(){c=!1})),o({target:"Array",proto:!0,forced:c||!l},{findIndex:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}}),i("findIndex")},function(e,t,n){"use strict";var o=n(0),r=n(136),i=n(15),a=n(11),c=n(30),l=n(62);o({target:"Array",proto:!0},{flat:function(){var e=arguments.length?arguments[0]:undefined,t=i(this),n=a(t.length),o=l(t,0);return o.length=r(o,t,t,n,0,e===undefined?1:c(e)),o}})},function(e,t,n){"use strict";var o=n(0),r=n(136),i=n(15),a=n(11),c=n(31),l=n(62);o({target:"Array",proto:!0},{flatMap:function(e){var t,n=i(this),o=a(n.length);return c(e),(t=l(n,0)).length=r(t,n,n,o,0,1,e,arguments.length>1?arguments[1]:undefined),t}})},function(e,t,n){"use strict";var o=n(0),r=n(199);o({target:"Array",proto:!0,forced:[].forEach!=r},{forEach:r})},function(e,t,n){"use strict";var o=n(18).forEach,r=n(38),i=n(23),a=r("forEach"),c=i("forEach");e.exports=a&&c?[].forEach:function(e){return o(this,e,arguments.length>1?arguments[1]:undefined)}},function(e,t,n){"use strict";var o=n(0),r=n(201);o({target:"Array",stat:!0,forced:!n(74)((function(e){Array.from(e)}))},{from:r})},function(e,t,n){"use strict";var o=n(47),r=n(15),i=n(137),a=n(98),c=n(11),l=n(48),u=n(99);e.exports=function(e){var t,n,s,d,f,p,m=r(e),h="function"==typeof this?this:Array,g=arguments.length,v=g>1?arguments[1]:undefined,b=v!==undefined,C=u(m),N=0;if(b&&(v=o(v,g>2?arguments[2]:undefined,2)),C==undefined||h==Array&&a(C))for(n=new h(t=c(m.length));t>N;N++)p=b?v(m[N],N):m[N],l(n,N,p);else for(f=(d=C.call(m)).next,n=new h;!(s=f.call(d)).done;N++)p=b?i(d,v,[s.value,N],!0):s.value,l(n,N,p);return n.length=N,n}},function(e,t,n){"use strict";var o=n(0),r=n(59).includes,i=n(43);o({target:"Array",proto:!0,forced:!n(23)("indexOf",{ACCESSORS:!0,1:0})},{includes:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}}),i("includes")},function(e,t,n){"use strict";var o=n(0),r=n(59).indexOf,i=n(38),a=n(23),c=[].indexOf,l=!!c&&1/[1].indexOf(1,-0)<0,u=i("indexOf"),s=a("indexOf",{ACCESSORS:!0,1:0});o({target:"Array",proto:!0,forced:l||!u||!s},{indexOf:function(e){return l?c.apply(this,arguments)||0:r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";n(0)({target:"Array",stat:!0},{isArray:n(51)})},function(e,t,n){"use strict";var o=n(139).IteratorPrototype,r=n(41),i=n(45),a=n(42),c=n(64),l=function(){return this};e.exports=function(e,t,n){var u=t+" Iterator";return e.prototype=r(o,{next:i(1,n)}),a(e,u,!1,!0),c[u]=l,e}},function(e,t,n){"use strict";var o=n(0),r=n(56),i=n(25),a=n(38),c=[].join,l=r!=Object,u=a("join",",");o({target:"Array",proto:!0,forced:l||!u},{join:function(e){return c.call(i(this),e===undefined?",":e)}})},function(e,t,n){"use strict";var o=n(0),r=n(141);o({target:"Array",proto:!0,forced:r!==[].lastIndexOf},{lastIndexOf:r})},function(e,t,n){"use strict";var o=n(0),r=n(18).map,i=n(63),a=n(23),c=i("map"),l=a("map");o({target:"Array",proto:!0,forced:!c||!l},{map:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(48);o({target:"Array",stat:!0,forced:r((function(){function e(){}return!(Array.of.call(e)instanceof e)}))},{of:function(){for(var e=0,t=arguments.length,n=new("function"==typeof this?this:Array)(t);t>e;)i(n,e,arguments[e++]);return n.length=t,n}})},function(e,t,n){"use strict";var o=n(0),r=n(75).left,i=n(38),a=n(23),c=i("reduce"),l=a("reduce",{1:0});o({target:"Array",proto:!0,forced:!c||!l},{reduce:function(e){return r(this,e,arguments.length,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(75).right,i=n(38),a=n(23),c=i("reduceRight"),l=a("reduce",{1:0});o({target:"Array",proto:!0,forced:!c||!l},{reduceRight:function(e){return r(this,e,arguments.length,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(51),a=n(40),c=n(11),l=n(25),u=n(48),s=n(13),d=n(63),f=n(23),p=d("slice"),m=f("slice",{ACCESSORS:!0,0:0,1:2}),h=s("species"),g=[].slice,v=Math.max;o({target:"Array",proto:!0,forced:!p||!m},{slice:function(e,t){var n,o,s,d=l(this),f=c(d.length),p=a(e,f),m=a(t===undefined?f:t,f);if(i(d)&&("function"!=typeof(n=d.constructor)||n!==Array&&!i(n.prototype)?r(n)&&null===(n=n[h])&&(n=undefined):n=undefined,n===Array||n===undefined))return g.call(d,p,m);for(o=new(n===undefined?Array:n)(v(m-p,0)),s=0;p1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(31),i=n(15),a=n(2),c=n(38),l=[],u=l.sort,s=a((function(){l.sort(undefined)})),d=a((function(){l.sort(null)})),f=c("sort");o({target:"Array",proto:!0,forced:s||!d||!f},{sort:function(e){return e===undefined?u.call(i(this)):u.call(i(this),r(e))}})},function(e,t,n){"use strict";n(52)("Array")},function(e,t,n){"use strict";var o=n(0),r=n(40),i=n(30),a=n(11),c=n(15),l=n(62),u=n(48),s=n(63),d=n(23),f=s("splice"),p=d("splice",{ACCESSORS:!0,0:0,1:2}),m=Math.max,h=Math.min;o({target:"Array",proto:!0,forced:!f||!p},{splice:function(e,t){var n,o,s,d,f,p,g=c(this),v=a(g.length),b=r(e,v),C=arguments.length;if(0===C?n=o=0:1===C?(n=0,o=v-b):(n=C-2,o=h(m(i(t),0),v-b)),v+n-o>9007199254740991)throw TypeError("Maximum allowed length exceeded");for(s=l(g,o),d=0;dv-o+n;d--)delete g[d-1]}else if(n>o)for(d=v-o;d>b;d--)p=d+n-1,(f=d+o-1)in g?g[p]=g[f]:delete g[p];for(d=0;d>1,h=23===t?r(2,-24)-r(2,-77):0,g=e<0||0===e&&1/e<0?1:0,v=0;for((e=o(e))!=e||e===1/0?(u=e!=e?1:0,l=p):(l=i(a(e)/c),e*(s=r(2,-l))<1&&(l--,s*=2),(e+=l+m>=1?h/s:h*r(2,1-m))*s>=2&&(l++,s/=2),l+m>=p?(u=0,l=p):l+m>=1?(u=(e*s-1)*r(2,t),l+=m):(u=e*r(2,m-1)*r(2,t),l=0));t>=8;d[v++]=255&u,u/=256,t-=8);for(l=l<0;d[v++]=255&l,l/=256,f-=8);return d[--v]|=128*g,d},unpack:function(e,t){var n,o=e.length,i=8*o-t-1,a=(1<>1,l=i-7,u=o-1,s=e[u--],d=127&s;for(s>>=7;l>0;d=256*d+e[u],u--,l-=8);for(n=d&(1<<-l)-1,d>>=-l,l+=t;l>0;n=256*n+e[u],u--,l-=8);if(0===d)d=1-c;else{if(d===a)return n?NaN:s?-1/0:1/0;n+=r(2,t),d-=c}return(s?-1:1)*n*r(2,d-t)}}},function(e,t,n){"use strict";var o=n(0),r=n(10);o({target:"ArrayBuffer",stat:!0,forced:!r.NATIVE_ARRAY_BUFFER_VIEWS},{isView:r.isView})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(76),a=n(9),c=n(40),l=n(11),u=n(44),s=i.ArrayBuffer,d=i.DataView,f=s.prototype.slice;o({target:"ArrayBuffer",proto:!0,unsafe:!0,forced:r((function(){return!new s(2).slice(1,undefined).byteLength}))},{slice:function(e,t){if(f!==undefined&&t===undefined)return f.call(a(this),e);for(var n=a(this).byteLength,o=c(e,n),r=c(t===undefined?n:t,n),i=new(u(this,s))(l(r-o)),p=new d(this),m=new d(i),h=0;o9999?"+":"";return n+r(i(e),n?6:4,0)+"-"+r(this.getUTCMonth()+1,2,0)+"-"+r(this.getUTCDate(),2,0)+"T"+r(this.getUTCHours(),2,0)+":"+r(this.getUTCMinutes(),2,0)+":"+r(this.getUTCSeconds(),2,0)+"."+r(t,3,0)+"Z"}:l},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(15),a=n(33);o({target:"Date",proto:!0,forced:r((function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}))},{toJSON:function(e){var t=i(this),n=a(t);return"number"!=typeof n||isFinite(n)?t.toISOString():null}})},function(e,t,n){"use strict";var o=n(29),r=n(229),i=n(13)("toPrimitive"),a=Date.prototype;i in a||o(a,i,r)},function(e,t,n){"use strict";var o=n(9),r=n(33);e.exports=function(e){if("string"!==e&&"number"!==e&&"default"!==e)throw TypeError("Incorrect hint");return r(o(this),"number"!==e)}},function(e,t,n){"use strict";var o=n(22),r=Date.prototype,i=r.toString,a=r.getTime;new Date(NaN)+""!="Invalid Date"&&o(r,"toString",(function(){var e=a.call(this);return e==e?i.call(this):"Invalid Date"}))},function(e,t,n){"use strict";n(0)({target:"Function",proto:!0},{bind:n(143)})},function(e,t,n){"use strict";var o=n(7),r=n(14),i=n(35),a=n(13)("hasInstance"),c=Function.prototype;a in c||r.f(c,a,{value:function(e){if("function"!=typeof this||!o(e))return!1;if(!o(this.prototype))return e instanceof this;for(;e=i(e);)if(this.prototype===e)return!0;return!1}})},function(e,t,n){"use strict";var o=n(8),r=n(14).f,i=Function.prototype,a=i.toString,c=/^\s*function ([^ (]*)/;o&&!("name"in i)&&r(i,"name",{configurable:!0,get:function(){try{return a.call(this).match(c)[1]}catch(e){return""}}})},function(e,t,n){"use strict";var o=n(5);n(42)(o.JSON,"JSON",!0)},function(e,t,n){"use strict";var o=n(77),r=n(144);e.exports=o("Map",(function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}}),r)},function(e,t,n){"use strict";var o=n(0),r=n(145),i=Math.acosh,a=Math.log,c=Math.sqrt,l=Math.LN2;o({target:"Math",stat:!0,forced:!i||710!=Math.floor(i(Number.MAX_VALUE))||i(Infinity)!=Infinity},{acosh:function(e){return(e=+e)<1?NaN:e>94906265.62425156?a(e)+l:r(e-1+c(e-1)*c(e+1))}})},function(e,t,n){"use strict";var o=n(0),r=Math.asinh,i=Math.log,a=Math.sqrt;o({target:"Math",stat:!0,forced:!(r&&1/r(0)>0)},{asinh:function c(e){return isFinite(e=+e)&&0!=e?e<0?-c(-e):i(e+a(e*e+1)):e}})},function(e,t,n){"use strict";var o=n(0),r=Math.atanh,i=Math.log;o({target:"Math",stat:!0,forced:!(r&&1/r(-0)<0)},{atanh:function(e){return 0==(e=+e)?e:i((1+e)/(1-e))/2}})},function(e,t,n){"use strict";var o=n(0),r=n(106),i=Math.abs,a=Math.pow;o({target:"Math",stat:!0},{cbrt:function(e){return r(e=+e)*a(i(e),1/3)}})},function(e,t,n){"use strict";var o=n(0),r=Math.floor,i=Math.log,a=Math.LOG2E;o({target:"Math",stat:!0},{clz32:function(e){return(e>>>=0)?31-r(i(e+.5)*a):32}})},function(e,t,n){"use strict";var o=n(0),r=n(79),i=Math.cosh,a=Math.abs,c=Math.E;o({target:"Math",stat:!0,forced:!i||i(710)===Infinity},{cosh:function(e){var t=r(a(e)-1)+1;return(t+1/(t*c*c))*(c/2)}})},function(e,t,n){"use strict";var o=n(0),r=n(79);o({target:"Math",stat:!0,forced:r!=Math.expm1},{expm1:r})},function(e,t,n){"use strict";n(0)({target:"Math",stat:!0},{fround:n(244)})},function(e,t,n){"use strict";var o=n(106),r=Math.abs,i=Math.pow,a=i(2,-52),c=i(2,-23),l=i(2,127)*(2-c),u=i(2,-126);e.exports=Math.fround||function(e){var t,n,i=r(e),s=o(e);return il||n!=n?s*Infinity:s*n}},function(e,t,n){"use strict";var o=n(0),r=Math.hypot,i=Math.abs,a=Math.sqrt;o({target:"Math",stat:!0,forced:!!r&&r(Infinity,NaN)!==Infinity},{hypot:function(e,t){for(var n,o,r=0,c=0,l=arguments.length,u=0;c0?(o=n/u)*o:n;return u===Infinity?Infinity:u*a(r)}})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=Math.imul;o({target:"Math",stat:!0,forced:r((function(){return-5!=i(4294967295,5)||2!=i.length}))},{imul:function(e,t){var n=+e,o=+t,r=65535&n,i=65535&o;return 0|r*i+((65535&n>>>16)*i+r*(65535&o>>>16)<<16>>>0)}})},function(e,t,n){"use strict";var o=n(0),r=Math.log,i=Math.LOG10E;o({target:"Math",stat:!0},{log10:function(e){return r(e)*i}})},function(e,t,n){"use strict";n(0)({target:"Math",stat:!0},{log1p:n(145)})},function(e,t,n){"use strict";var o=n(0),r=Math.log,i=Math.LN2;o({target:"Math",stat:!0},{log2:function(e){return r(e)/i}})},function(e,t,n){"use strict";n(0)({target:"Math",stat:!0},{sign:n(106)})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(79),a=Math.abs,c=Math.exp,l=Math.E;o({target:"Math",stat:!0,forced:r((function(){return-2e-17!=Math.sinh(-2e-17)}))},{sinh:function(e){return a(e=+e)<1?(i(e)-i(-e))/2:(c(e-1)-c(-e-1))*(l/2)}})},function(e,t,n){"use strict";var o=n(0),r=n(79),i=Math.exp;o({target:"Math",stat:!0},{tanh:function(e){var t=r(e=+e),n=r(-e);return t==Infinity?1:n==Infinity?-1:(t-n)/(i(e)+i(-e))}})},function(e,t,n){"use strict";n(42)(Math,"Math",!0)},function(e,t,n){"use strict";var o=n(0),r=Math.ceil,i=Math.floor;o({target:"Math",stat:!0},{trunc:function(e){return(e>0?i:r)(e)}})},function(e,t,n){"use strict";var o=n(8),r=n(5),i=n(60),a=n(22),c=n(17),l=n(32),u=n(78),s=n(33),d=n(2),f=n(41),p=n(46).f,m=n(19).f,h=n(14).f,g=n(54).trim,v=r.Number,b=v.prototype,C="Number"==l(f(b)),N=function(e){var t,n,o,r,i,a,c,l,u=s(e,!1);if("string"==typeof u&&u.length>2)if(43===(t=(u=g(u)).charCodeAt(0))||45===t){if(88===(n=u.charCodeAt(2))||120===n)return NaN}else if(48===t){switch(u.charCodeAt(1)){case 66:case 98:o=2,r=49;break;case 79:case 111:o=8,r=55;break;default:return+u}for(a=(i=u.slice(2)).length,c=0;cr)return NaN;return parseInt(i,o)}return+u};if(i("Number",!v(" 0o1")||!v("0b1")||v("+0x1"))){for(var y,V=function(e){var t=arguments.length<1?0:e,n=this;return n instanceof V&&(C?d((function(){b.valueOf.call(n)})):"Number"!=l(n))?u(new v(N(t)),n,V):N(t)},x=o?p(v):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),w=0;x.length>w;w++)c(v,y=x[w])&&!c(V,y)&&h(V,y,m(v,y));V.prototype=b,b.constructor=V,a(r,"Number",V)}},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{EPSILON:Math.pow(2,-52)})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{isFinite:n(258)})},function(e,t,n){"use strict";var o=n(5).isFinite;e.exports=Number.isFinite||function(e){return"number"==typeof e&&o(e)}},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{isInteger:n(146)})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{isNaN:function(e){return e!=e}})},function(e,t,n){"use strict";var o=n(0),r=n(146),i=Math.abs;o({target:"Number",stat:!0},{isSafeInteger:function(e){return r(e)&&i(e)<=9007199254740991}})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{MAX_SAFE_INTEGER:9007199254740991})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{MIN_SAFE_INTEGER:-9007199254740991})},function(e,t,n){"use strict";var o=n(0),r=n(265);o({target:"Number",stat:!0,forced:Number.parseFloat!=r},{parseFloat:r})},function(e,t,n){"use strict";var o=n(5),r=n(54).trim,i=n(80),a=o.parseFloat,c=1/a(i+"-0")!=-Infinity;e.exports=c?function(e){var t=r(String(e)),n=a(t);return 0===n&&"-"==t.charAt(0)?-0:n}:a},function(e,t,n){"use strict";var o=n(0),r=n(147);o({target:"Number",stat:!0,forced:Number.parseInt!=r},{parseInt:r})},function(e,t,n){"use strict";var o=n(0),r=n(30),i=n(268),a=n(105),c=n(2),l=1..toFixed,u=Math.floor,s=function d(e,t,n){return 0===t?n:t%2==1?d(e,t-1,n*e):d(e*e,t/2,n)};o({target:"Number",proto:!0,forced:l&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!c((function(){l.call({})}))},{toFixed:function(e){var t,n,o,c,l=i(this),d=r(e),f=[0,0,0,0,0,0],p="",m="0",h=function(e,t){for(var n=-1,o=t;++n<6;)o+=e*f[n],f[n]=o%1e7,o=u(o/1e7)},g=function(e){for(var t=6,n=0;--t>=0;)n+=f[t],f[t]=u(n/e),n=n%e*1e7},v=function(){for(var e=6,t="";--e>=0;)if(""!==t||0===e||0!==f[e]){var n=String(f[e]);t=""===t?n:t+a.call("0",7-n.length)+n}return t};if(d<0||d>20)throw RangeError("Incorrect fraction digits");if(l!=l)return"NaN";if(l<=-1e21||l>=1e21)return String(l);if(l<0&&(p="-",l=-l),l>1e-21)if(n=(t=function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}(l*s(2,69,1))-69)<0?l*s(2,-t,1):l/s(2,t,1),n*=4503599627370496,(t=52-t)>0){for(h(0,n),o=d;o>=7;)h(1e7,0),o-=7;for(h(s(10,o,1),0),o=t-1;o>=23;)g(1<<23),o-=23;g(1<0?p+((c=m.length)<=d?"0."+a.call("0",d-c)+m:m.slice(0,c-d)+"."+m.slice(c-d)):p+m}})},function(e,t,n){"use strict";var o=n(32);e.exports=function(e){if("number"!=typeof e&&"Number"!=o(e))throw TypeError("Incorrect invocation");return+e}},function(e,t,n){"use strict";var o=n(0),r=n(270);o({target:"Object",stat:!0,forced:Object.assign!==r},{assign:r})},function(e,t,n){"use strict";var o=n(8),r=n(2),i=n(61),a=n(94),c=n(70),l=n(15),u=n(56),s=Object.assign,d=Object.defineProperty;e.exports=!s||r((function(){if(o&&1!==s({b:1},s(d({},"a",{enumerable:!0,get:function(){d(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},n=Symbol();return e[n]=7,"abcdefghijklmnopqrst".split("").forEach((function(e){t[e]=e})),7!=s({},e)[n]||"abcdefghijklmnopqrst"!=i(s({},t)).join("")}))?function(e,t){for(var n=l(e),r=arguments.length,s=1,d=a.f,f=c.f;r>s;)for(var p,m=u(arguments[s++]),h=d?i(m).concat(d(m)):i(m),g=h.length,v=0;g>v;)p=h[v++],o&&!f.call(m,p)||(n[p]=m[p]);return n}:s},function(e,t,n){"use strict";n(0)({target:"Object",stat:!0,sham:!n(8)},{create:n(41)})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(31),l=n(14);r&&o({target:"Object",proto:!0,forced:i},{__defineGetter__:function(e,t){l.f(a(this),e,{get:c(t),enumerable:!0,configurable:!0})}})},function(e,t,n){"use strict";var o=n(0),r=n(8);o({target:"Object",stat:!0,forced:!r,sham:!r},{defineProperties:n(131)})},function(e,t,n){"use strict";var o=n(0),r=n(8);o({target:"Object",stat:!0,forced:!r,sham:!r},{defineProperty:n(14).f})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(31),l=n(14);r&&o({target:"Object",proto:!0,forced:i},{__defineSetter__:function(e,t){l.f(a(this),e,{set:c(t),enumerable:!0,configurable:!0})}})},function(e,t,n){"use strict";var o=n(0),r=n(148).entries;o({target:"Object",stat:!0},{entries:function(e){return r(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(66),i=n(2),a=n(7),c=n(50).onFreeze,l=Object.freeze;o({target:"Object",stat:!0,forced:i((function(){l(1)})),sham:!r},{freeze:function(e){return l&&a(e)?l(c(e)):e}})},function(e,t,n){"use strict";var o=n(0),r=n(67),i=n(48);o({target:"Object",stat:!0},{fromEntries:function(e){var t={};return r(e,(function(e,n){i(t,e,n)}),undefined,!0),t}})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(25),a=n(19).f,c=n(8),l=r((function(){a(1)}));o({target:"Object",stat:!0,forced:!c||l,sham:!c},{getOwnPropertyDescriptor:function(e,t){return a(i(e),t)}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(92),a=n(25),c=n(19),l=n(48);o({target:"Object",stat:!0,sham:!r},{getOwnPropertyDescriptors:function(e){for(var t,n,o=a(e),r=c.f,u=i(o),s={},d=0;u.length>d;)(n=r(o,t=u[d++]))!==undefined&&l(s,t,n);return s}})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(133).f;o({target:"Object",stat:!0,forced:r((function(){return!Object.getOwnPropertyNames(1)}))},{getOwnPropertyNames:i})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(15),a=n(35),c=n(102);o({target:"Object",stat:!0,forced:r((function(){a(1)})),sham:!c},{getPrototypeOf:function(e){return a(i(e))}})},function(e,t,n){"use strict";n(0)({target:"Object",stat:!0},{is:n(149)})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(7),a=Object.isExtensible;o({target:"Object",stat:!0,forced:r((function(){a(1)}))},{isExtensible:function(e){return!!i(e)&&(!a||a(e))}})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(7),a=Object.isFrozen;o({target:"Object",stat:!0,forced:r((function(){a(1)}))},{isFrozen:function(e){return!i(e)||!!a&&a(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(2),i=n(7),a=Object.isSealed;o({target:"Object",stat:!0,forced:r((function(){a(1)}))},{isSealed:function(e){return!i(e)||!!a&&a(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(15),i=n(61);o({target:"Object",stat:!0,forced:n(2)((function(){i(1)}))},{keys:function(e){return i(r(e))}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(33),l=n(35),u=n(19).f;r&&o({target:"Object",proto:!0,forced:i},{__lookupGetter__:function(e){var t,n=a(this),o=c(e,!0);do{if(t=u(n,o))return t.get}while(n=l(n))}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(33),l=n(35),u=n(19).f;r&&o({target:"Object",proto:!0,forced:i},{__lookupSetter__:function(e){var t,n=a(this),o=c(e,!0);do{if(t=u(n,o))return t.set}while(n=l(n))}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(50).onFreeze,a=n(66),c=n(2),l=Object.preventExtensions;o({target:"Object",stat:!0,forced:c((function(){l(1)})),sham:!a},{preventExtensions:function(e){return l&&r(e)?l(i(e)):e}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(50).onFreeze,a=n(66),c=n(2),l=Object.seal;o({target:"Object",stat:!0,forced:c((function(){l(1)})),sham:!a},{seal:function(e){return l&&r(e)?l(i(e)):e}})},function(e,t,n){"use strict";n(0)({target:"Object",stat:!0},{setPrototypeOf:n(49)})},function(e,t,n){"use strict";var o=n(100),r=n(22),i=n(294);o||r(Object.prototype,"toString",i,{unsafe:!0})},function(e,t,n){"use strict";var o=n(100),r=n(73);e.exports=o?{}.toString:function(){return"[object "+r(this)+"]"}},function(e,t,n){"use strict";var o=n(0),r=n(148).values;o({target:"Object",stat:!0},{values:function(e){return r(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(147);o({global:!0,forced:parseInt!=r},{parseInt:r})},function(e,t,n){"use strict";var o,r,i,a,c=n(0),l=n(37),u=n(5),s=n(36),d=n(150),f=n(22),p=n(65),m=n(42),h=n(52),g=n(7),v=n(31),b=n(53),C=n(32),N=n(90),y=n(67),V=n(74),x=n(44),w=n(107).set,k=n(152),_=n(153),L=n(298),S=n(154),B=n(299),E=n(34),I=n(60),T=n(13),A=n(96),O=T("species"),M="Promise",P=E.get,j=E.set,D=E.getterFor(M),F=d,R=u.TypeError,z=u.document,W=u.process,U=s("fetch"),K=S.f,H=K,Y="process"==C(W),$=!!(z&&z.createEvent&&u.dispatchEvent),q=I(M,(function(){if(!(N(F)!==String(F))){if(66===A)return!0;if(!Y&&"function"!=typeof PromiseRejectionEvent)return!0}if(l&&!F.prototype["finally"])return!0;if(A>=51&&/native code/.test(F))return!1;var e=F.resolve(1),t=function(e){e((function(){}),(function(){}))};return(e.constructor={})[O]=t,!(e.then((function(){}))instanceof t)})),G=q||!V((function(e){F.all(e)["catch"]((function(){}))})),X=function(e){var t;return!(!g(e)||"function"!=typeof(t=e.then))&&t},Q=function(e,t,n){if(!t.notified){t.notified=!0;var o=t.reactions;k((function(){for(var r=t.value,i=1==t.state,a=0;o.length>a;){var c,l,u,s=o[a++],d=i?s.ok:s.fail,f=s.resolve,p=s.reject,m=s.domain;try{d?(i||(2===t.rejection&&te(e,t),t.rejection=1),!0===d?c=r:(m&&m.enter(),c=d(r),m&&(m.exit(),u=!0)),c===s.promise?p(R("Promise-chain cycle")):(l=X(c))?l.call(c,f,p):f(c)):p(r)}catch(h){m&&!u&&m.exit(),p(h)}}t.reactions=[],t.notified=!1,n&&!t.rejection&&Z(e,t)}))}},J=function(e,t,n){var o,r;$?((o=z.createEvent("Event")).promise=t,o.reason=n,o.initEvent(e,!1,!0),u.dispatchEvent(o)):o={promise:t,reason:n},(r=u["on"+e])?r(o):"unhandledrejection"===e&&L("Unhandled promise rejection",n)},Z=function(e,t){w.call(u,(function(){var n,o=t.value;if(ee(t)&&(n=B((function(){Y?W.emit("unhandledRejection",o,e):J("unhandledrejection",e,o)})),t.rejection=Y||ee(t)?2:1,n.error))throw n.value}))},ee=function(e){return 1!==e.rejection&&!e.parent},te=function(e,t){w.call(u,(function(){Y?W.emit("rejectionHandled",e):J("rejectionhandled",e,t.value)}))},ne=function(e,t,n,o){return function(r){e(t,n,r,o)}},oe=function(e,t,n,o){t.done||(t.done=!0,o&&(t=o),t.value=n,t.state=2,Q(e,t,!0))},re=function ie(e,t,n,o){if(!t.done){t.done=!0,o&&(t=o);try{if(e===n)throw R("Promise can't be resolved itself");var r=X(n);r?k((function(){var o={done:!1};try{r.call(n,ne(ie,e,o,t),ne(oe,e,o,t))}catch(i){oe(e,o,i,t)}})):(t.value=n,t.state=1,Q(e,t,!1))}catch(i){oe(e,{done:!1},i,t)}}};q&&(F=function(e){b(this,F,M),v(e),o.call(this);var t=P(this);try{e(ne(re,this,t),ne(oe,this,t))}catch(n){oe(this,t,n)}},(o=function(e){j(this,{type:M,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:undefined})}).prototype=p(F.prototype,{then:function(e,t){var n=D(this),o=K(x(this,F));return o.ok="function"!=typeof e||e,o.fail="function"==typeof t&&t,o.domain=Y?W.domain:undefined,n.parent=!0,n.reactions.push(o),0!=n.state&&Q(this,n,!1),o.promise},"catch":function(e){return this.then(undefined,e)}}),r=function(){var e=new o,t=P(e);this.promise=e,this.resolve=ne(re,e,t),this.reject=ne(oe,e,t)},S.f=K=function(e){return e===F||e===i?new r(e):H(e)},l||"function"!=typeof d||(a=d.prototype.then,f(d.prototype,"then",(function(e,t){var n=this;return new F((function(e,t){a.call(n,e,t)})).then(e,t)}),{unsafe:!0}),"function"==typeof U&&c({global:!0,enumerable:!0,forced:!0},{fetch:function(e){return _(F,U.apply(u,arguments))}}))),c({global:!0,wrap:!0,forced:q},{Promise:F}),m(F,M,!1,!0),h(M),i=s(M),c({target:M,stat:!0,forced:q},{reject:function(e){var t=K(this);return t.reject.call(undefined,e),t.promise}}),c({target:M,stat:!0,forced:l||q},{resolve:function(e){return _(l&&this===i?F:this,e)}}),c({target:M,stat:!0,forced:G},{all:function(e){var t=this,n=K(t),o=n.resolve,r=n.reject,i=B((function(){var n=v(t.resolve),i=[],a=0,c=1;y(e,(function(e){var l=a++,u=!1;i.push(undefined),c++,n.call(t,e).then((function(e){u||(u=!0,i[l]=e,--c||o(i))}),r)})),--c||o(i)}));return i.error&&r(i.value),n.promise},race:function(e){var t=this,n=K(t),o=n.reject,r=B((function(){var r=v(t.resolve);y(e,(function(e){r.call(t,e).then(n.resolve,o)}))}));return r.error&&o(r.value),n.promise}})},function(e,t,n){"use strict";var o=n(5);e.exports=function(e,t){var n=o.console;n&&n.error&&(1===arguments.length?n.error(e):n.error(e,t))}},function(e,t,n){"use strict";e.exports=function(e){try{return{error:!1,value:e()}}catch(t){return{error:!0,value:t}}}},function(e,t,n){"use strict";var o=n(0),r=n(37),i=n(150),a=n(2),c=n(36),l=n(44),u=n(153),s=n(22);o({target:"Promise",proto:!0,real:!0,forced:!!i&&a((function(){i.prototype["finally"].call({then:function(){}},(function(){}))}))},{"finally":function(e){var t=l(this,c("Promise")),n="function"==typeof e;return this.then(n?function(n){return u(t,e()).then((function(){return n}))}:e,n?function(n){return u(t,e()).then((function(){throw n}))}:e)}}),r||"function"!=typeof i||i.prototype["finally"]||s(i.prototype,"finally",c("Promise").prototype["finally"])},function(e,t,n){"use strict";var o=n(0),r=n(36),i=n(31),a=n(9),c=n(2),l=r("Reflect","apply"),u=Function.apply;o({target:"Reflect",stat:!0,forced:!c((function(){l((function(){}))}))},{apply:function(e,t,n){return i(e),a(n),l?l(e,t,n):u.call(e,t,n)}})},function(e,t,n){"use strict";var o=n(0),r=n(36),i=n(31),a=n(9),c=n(7),l=n(41),u=n(143),s=n(2),d=r("Reflect","construct"),f=s((function(){function e(){}return!(d((function(){}),[],e)instanceof e)})),p=!s((function(){d((function(){}))})),m=f||p;o({target:"Reflect",stat:!0,forced:m,sham:m},{construct:function(e,t){i(e),a(t);var n=arguments.length<3?e:i(arguments[2]);if(p&&!f)return d(e,t,n);if(e==n){switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3])}var o=[null];return o.push.apply(o,t),new(u.apply(e,o))}var r=n.prototype,s=l(c(r)?r:Object.prototype),m=Function.apply.call(e,s,t);return c(m)?m:s}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(9),a=n(33),c=n(14);o({target:"Reflect",stat:!0,forced:n(2)((function(){Reflect.defineProperty(c.f({},1,{value:1}),1,{value:2})})),sham:!r},{defineProperty:function(e,t,n){i(e);var o=a(t,!0);i(n);try{return c.f(e,o,n),!0}catch(r){return!1}}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(19).f;o({target:"Reflect",stat:!0},{deleteProperty:function(e,t){var n=i(r(e),t);return!(n&&!n.configurable)&&delete e[t]}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(9),a=n(17),c=n(19),l=n(35);o({target:"Reflect",stat:!0},{get:function u(e,t){var n,o,s=arguments.length<3?e:arguments[2];return i(e)===s?e[t]:(n=c.f(e,t))?a(n,"value")?n.value:n.get===undefined?undefined:n.get.call(s):r(o=l(e))?u(o,t,s):void 0}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(9),a=n(19);o({target:"Reflect",stat:!0,sham:!r},{getOwnPropertyDescriptor:function(e,t){return a.f(i(e),t)}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(35);o({target:"Reflect",stat:!0,sham:!n(102)},{getPrototypeOf:function(e){return i(r(e))}})},function(e,t,n){"use strict";n(0)({target:"Reflect",stat:!0},{has:function(e,t){return t in e}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=Object.isExtensible;o({target:"Reflect",stat:!0},{isExtensible:function(e){return r(e),!i||i(e)}})},function(e,t,n){"use strict";n(0)({target:"Reflect",stat:!0},{ownKeys:n(92)})},function(e,t,n){"use strict";var o=n(0),r=n(36),i=n(9);o({target:"Reflect",stat:!0,sham:!n(66)},{preventExtensions:function(e){i(e);try{var t=r("Object","preventExtensions");return t&&t(e),!0}catch(n){return!1}}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(7),a=n(17),c=n(2),l=n(14),u=n(19),s=n(35),d=n(45);o({target:"Reflect",stat:!0,forced:c((function(){var e=l.f({},"a",{configurable:!0});return!1!==Reflect.set(s(e),"a",1,e)}))},{set:function f(e,t,n){var o,c,p=arguments.length<4?e:arguments[3],m=u.f(r(e),t);if(!m){if(i(c=s(e)))return f(c,t,n,p);m=d(0)}if(a(m,"value")){if(!1===m.writable||!i(p))return!1;if(o=u.f(p,t)){if(o.get||o.set||!1===o.writable)return!1;o.value=n,l.f(p,t,o)}else l.f(p,t,d(0,n));return!0}return m.set!==undefined&&(m.set.call(p,n),!0)}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(140),a=n(49);a&&o({target:"Reflect",stat:!0},{setPrototypeOf:function(e,t){r(e),i(t);try{return a(e,t),!0}catch(n){return!1}}})},function(e,t,n){"use strict";var o=n(8),r=n(5),i=n(60),a=n(78),c=n(14).f,l=n(46).f,u=n(108),s=n(82),d=n(109),f=n(22),p=n(2),m=n(34).set,h=n(52),g=n(13)("match"),v=r.RegExp,b=v.prototype,C=/a/g,N=/a/g,y=new v(C)!==C,V=d.UNSUPPORTED_Y;if(o&&i("RegExp",!y||V||p((function(){return N[g]=!1,v(C)!=C||v(N)==N||"/a/i"!=v(C,"i")})))){for(var x=function(e,t){var n,o=this instanceof x,r=u(e),i=t===undefined;if(!o&&r&&e.constructor===x&&i)return e;y?r&&!i&&(e=e.source):e instanceof x&&(i&&(t=s.call(e)),e=e.source),V&&(n=!!t&&t.indexOf("y")>-1)&&(t=t.replace(/y/g,""));var c=a(y?new v(e,t):v(e,t),o?this:b,x);return V&&n&&m(c,{sticky:n}),c},w=function(e){e in x||c(x,e,{configurable:!0,get:function(){return v[e]},set:function(t){v[e]=t}})},k=l(v),_=0;k.length>_;)w(k[_++]);b.constructor=x,x.prototype=b,f(r,"RegExp",x)}h("RegExp")},function(e,t,n){"use strict";var o=n(8),r=n(14),i=n(82),a=n(109).UNSUPPORTED_Y;o&&("g"!=/./g.flags||a)&&r.f(RegExp.prototype,"flags",{configurable:!0,get:i})},function(e,t,n){"use strict";var o=n(22),r=n(9),i=n(2),a=n(82),c=RegExp.prototype,l=c.toString,u=i((function(){return"/a/b"!=l.call({source:"a",flags:"b"})})),s="toString"!=l.name;(u||s)&&o(RegExp.prototype,"toString",(function(){var e=r(this),t=String(e.source),n=e.flags;return"/"+t+"/"+String(n===undefined&&e instanceof RegExp&&!("flags"in c)?a.call(e):n)}),{unsafe:!0})},function(e,t,n){"use strict";var o=n(77),r=n(144);e.exports=o("Set",(function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}}),r)},function(e,t,n){"use strict";var o=n(0),r=n(110).codeAt;o({target:"String",proto:!0},{codePointAt:function(e){return r(this,e)}})},function(e,t,n){"use strict";var o,r=n(0),i=n(19).f,a=n(11),c=n(111),l=n(21),u=n(112),s=n(37),d="".endsWith,f=Math.min,p=u("endsWith");r({target:"String",proto:!0,forced:!!(s||p||(o=i(String.prototype,"endsWith"),!o||o.writable))&&!p},{endsWith:function(e){var t=String(l(this));c(e);var n=arguments.length>1?arguments[1]:undefined,o=a(t.length),r=n===undefined?o:f(a(n),o),i=String(e);return d?d.call(t,i,r):t.slice(r-i.length,r)===i}})},function(e,t,n){"use strict";var o=n(0),r=n(40),i=String.fromCharCode,a=String.fromCodePoint;o({target:"String",stat:!0,forced:!!a&&1!=a.length},{fromCodePoint:function(e){for(var t,n=[],o=arguments.length,a=0;o>a;){if(t=+arguments[a++],r(t,1114111)!==t)throw RangeError(t+" is not a valid code point");n.push(t<65536?i(t):i(55296+((t-=65536)>>10),t%1024+56320))}return n.join("")}})},function(e,t,n){"use strict";var o=n(0),r=n(111),i=n(21);o({target:"String",proto:!0,forced:!n(112)("includes")},{includes:function(e){return!!~String(i(this)).indexOf(r(e),arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(110).charAt,r=n(34),i=n(101),a=r.set,c=r.getterFor("String Iterator");i(String,"String",(function(e){a(this,{type:"String Iterator",string:String(e),index:0})}),(function(){var e,t=c(this),n=t.string,r=t.index;return r>=n.length?{value:undefined,done:!0}:(e=o(n,r),t.index+=e.length,{value:e,done:!1})}))},function(e,t,n){"use strict";var o=n(84),r=n(9),i=n(11),a=n(21),c=n(113),l=n(85);o("match",1,(function(e,t,n){return[function(t){var n=a(this),o=t==undefined?undefined:t[e];return o!==undefined?o.call(t,n):new RegExp(t)[e](String(n))},function(e){var o=n(t,e,this);if(o.done)return o.value;var a=r(e),u=String(this);if(!a.global)return l(a,u);var s=a.unicode;a.lastIndex=0;for(var d,f=[],p=0;null!==(d=l(a,u));){var m=String(d[0]);f[p]=m,""===m&&(a.lastIndex=c(u,i(a.lastIndex),s)),p++}return 0===p?null:f}]}))},function(e,t,n){"use strict";var o=n(0),r=n(104).end;o({target:"String",proto:!0,forced:n(156)},{padEnd:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(104).start;o({target:"String",proto:!0,forced:n(156)},{padStart:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(25),i=n(11);o({target:"String",stat:!0},{raw:function(e){for(var t=r(e.raw),n=i(t.length),o=arguments.length,a=[],c=0;n>c;)a.push(String(t[c++])),c]*>)/g,h=/\$([$&'`]|\d\d?)/g;o("replace",2,(function(e,t,n,o){var g=o.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,v=o.REPLACE_KEEPS_$0,b=g?"$":"$0";return[function(n,o){var r=l(this),i=n==undefined?undefined:n[e];return i!==undefined?i.call(n,r,o):t.call(String(r),n,o)},function(e,o){if(!g&&v||"string"==typeof o&&-1===o.indexOf(b)){var i=n(t,e,this,o);if(i.done)return i.value}var l=r(e),p=String(this),m="function"==typeof o;m||(o=String(o));var h=l.global;if(h){var N=l.unicode;l.lastIndex=0}for(var y=[];;){var V=s(l,p);if(null===V)break;if(y.push(V),!h)break;""===String(V[0])&&(l.lastIndex=u(p,a(l.lastIndex),N))}for(var x,w="",k=0,_=0;_=k&&(w+=p.slice(k,S)+A,k=S+L.length)}return w+p.slice(k)}];function C(e,n,o,r,a,c){var l=o+e.length,u=r.length,s=h;return a!==undefined&&(a=i(a),s=m),t.call(c,s,(function(t,i){var c;switch(i.charAt(0)){case"$":return"$";case"&":return e;case"`":return n.slice(0,o);case"'":return n.slice(l);case"<":c=a[i.slice(1,-1)];break;default:var s=+i;if(0===s)return t;if(s>u){var d=p(s/10);return 0===d?t:d<=u?r[d-1]===undefined?i.charAt(1):r[d-1]+i.charAt(1):t}c=r[s-1]}return c===undefined?"":c}))}}))},function(e,t,n){"use strict";var o=n(84),r=n(9),i=n(21),a=n(149),c=n(85);o("search",1,(function(e,t,n){return[function(t){var n=i(this),o=t==undefined?undefined:t[e];return o!==undefined?o.call(t,n):new RegExp(t)[e](String(n))},function(e){var o=n(t,e,this);if(o.done)return o.value;var i=r(e),l=String(this),u=i.lastIndex;a(u,0)||(i.lastIndex=0);var s=c(i,l);return a(i.lastIndex,u)||(i.lastIndex=u),null===s?-1:s.index}]}))},function(e,t,n){"use strict";var o=n(84),r=n(108),i=n(9),a=n(21),c=n(44),l=n(113),u=n(11),s=n(85),d=n(83),f=n(2),p=[].push,m=Math.min,h=!f((function(){return!RegExp(4294967295,"y")}));o("split",2,(function(e,t,n){var o;return o="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(e,n){var o=String(a(this)),i=n===undefined?4294967295:n>>>0;if(0===i)return[];if(e===undefined)return[o];if(!r(e))return t.call(o,e,i);for(var c,l,u,s=[],f=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),m=0,h=new RegExp(e.source,f+"g");(c=d.call(h,o))&&!((l=h.lastIndex)>m&&(s.push(o.slice(m,c.index)),c.length>1&&c.index=i));)h.lastIndex===c.index&&h.lastIndex++;return m===o.length?!u&&h.test("")||s.push(""):s.push(o.slice(m)),s.length>i?s.slice(0,i):s}:"0".split(undefined,0).length?function(e,n){return e===undefined&&0===n?[]:t.call(this,e,n)}:t,[function(t,n){var r=a(this),i=t==undefined?undefined:t[e];return i!==undefined?i.call(t,r,n):o.call(String(r),t,n)},function(e,r){var a=n(o,e,this,r,o!==t);if(a.done)return a.value;var d=i(e),f=String(this),p=c(d,RegExp),g=d.unicode,v=(d.ignoreCase?"i":"")+(d.multiline?"m":"")+(d.unicode?"u":"")+(h?"y":"g"),b=new p(h?d:"^(?:"+d.source+")",v),C=r===undefined?4294967295:r>>>0;if(0===C)return[];if(0===f.length)return null===s(b,f)?[f]:[];for(var N=0,y=0,V=[];y1?arguments[1]:undefined,t.length)),o=String(e);return d?d.call(t,o,n):t.slice(n,n+o.length)===o}})},function(e,t,n){"use strict";var o=n(0),r=n(54).trim;o({target:"String",proto:!0,forced:n(114)("trim")},{trim:function(){return r(this)}})},function(e,t,n){"use strict";var o=n(0),r=n(54).end,i=n(114)("trimEnd"),a=i?function(){return r(this)}:"".trimEnd;o({target:"String",proto:!0,forced:i},{trimEnd:a,trimRight:a})},function(e,t,n){"use strict";var o=n(0),r=n(54).start,i=n(114)("trimStart"),a=i?function(){return r(this)}:"".trimStart;o({target:"String",proto:!0,forced:i},{trimStart:a,trimLeft:a})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("anchor")},{anchor:function(e){return r(this,"a","name",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("big")},{big:function(){return r(this,"big","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("blink")},{blink:function(){return r(this,"blink","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("bold")},{bold:function(){return r(this,"b","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("fixed")},{fixed:function(){return r(this,"tt","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("fontcolor")},{fontcolor:function(e){return r(this,"font","color",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("fontsize")},{fontsize:function(e){return r(this,"font","size",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("italics")},{italics:function(){return r(this,"i","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("link")},{link:function(e){return r(this,"a","href",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("small")},{small:function(){return r(this,"small","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("strike")},{strike:function(){return r(this,"strike","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("sub")},{sub:function(){return r(this,"sub","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("sup")},{sup:function(){return r(this,"sup","","")}})},function(e,t,n){"use strict";n(39)("Float32",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";var o=n(30);e.exports=function(e){var t=o(e);if(t<0)throw RangeError("The argument can't be less than 0");return t}},function(e,t,n){"use strict";n(39)("Float64",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Int8",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Int16",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Int32",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Uint8",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Uint8",(function(e){return function(t,n,o){return e(this,t,n,o)}}),!0)},function(e,t,n){"use strict";n(39)("Uint16",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Uint32",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";var o=n(10),r=n(135),i=o.aTypedArray;(0,o.exportTypedArrayMethod)("copyWithin",(function(e,t){return r.call(i(this),e,t,arguments.length>2?arguments[2]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).every,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("every",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(97),i=o.aTypedArray;(0,o.exportTypedArrayMethod)("fill",(function(e){return r.apply(i(this),arguments)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).filter,i=n(44),a=o.aTypedArray,c=o.aTypedArrayConstructor;(0,o.exportTypedArrayMethod)("filter",(function(e){for(var t=r(a(this),e,arguments.length>1?arguments[1]:undefined),n=i(this,this.constructor),o=0,l=t.length,u=new(c(n))(l);l>o;)u[o]=t[o++];return u}))},function(e,t,n){"use strict";var o=n(10),r=n(18).find,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("find",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).findIndex,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("findIndex",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).forEach,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("forEach",(function(e){r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(115);(0,n(10).exportTypedArrayStaticMethod)("from",n(158),o)},function(e,t,n){"use strict";var o=n(10),r=n(59).includes,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("includes",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(59).indexOf,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("indexOf",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(5),r=n(10),i=n(138),a=n(13)("iterator"),c=o.Uint8Array,l=i.values,u=i.keys,s=i.entries,d=r.aTypedArray,f=r.exportTypedArrayMethod,p=c&&c.prototype[a],m=!!p&&("values"==p.name||p.name==undefined),h=function(){return l.call(d(this))};f("entries",(function(){return s.call(d(this))})),f("keys",(function(){return u.call(d(this))})),f("values",h,!m),f(a,h,!m)},function(e,t,n){"use strict";var o=n(10),r=o.aTypedArray,i=o.exportTypedArrayMethod,a=[].join;i("join",(function(e){return a.apply(r(this),arguments)}))},function(e,t,n){"use strict";var o=n(10),r=n(141),i=o.aTypedArray;(0,o.exportTypedArrayMethod)("lastIndexOf",(function(e){return r.apply(i(this),arguments)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).map,i=n(44),a=o.aTypedArray,c=o.aTypedArrayConstructor;(0,o.exportTypedArrayMethod)("map",(function(e){return r(a(this),e,arguments.length>1?arguments[1]:undefined,(function(e,t){return new(c(i(e,e.constructor)))(t)}))}))},function(e,t,n){"use strict";var o=n(10),r=n(115),i=o.aTypedArrayConstructor;(0,o.exportTypedArrayStaticMethod)("of",(function(){for(var e=0,t=arguments.length,n=new(i(this))(t);t>e;)n[e]=arguments[e++];return n}),r)},function(e,t,n){"use strict";var o=n(10),r=n(75).left,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("reduce",(function(e){return r(i(this),e,arguments.length,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(75).right,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("reduceRight",(function(e){return r(i(this),e,arguments.length,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=o.aTypedArray,i=o.exportTypedArrayMethod,a=Math.floor;i("reverse",(function(){for(var e,t=r(this).length,n=a(t/2),o=0;o1?arguments[1]:undefined,1),n=this.length,o=a(e),c=r(o.length),u=0;if(c+t>n)throw RangeError("Wrong length");for(;ui;)s[i]=n[i++];return s}),i((function(){new Int8Array(1).slice()})))},function(e,t,n){"use strict";var o=n(10),r=n(18).some,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("some",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=o.aTypedArray,i=o.exportTypedArrayMethod,a=[].sort;i("sort",(function(e){return a.call(r(this),e)}))},function(e,t,n){"use strict";var o=n(10),r=n(11),i=n(40),a=n(44),c=o.aTypedArray;(0,o.exportTypedArrayMethod)("subarray",(function(e,t){var n=c(this),o=n.length,l=i(e,o);return new(a(n,n.constructor))(n.buffer,n.byteOffset+l*n.BYTES_PER_ELEMENT,r((t===undefined?o:i(t,o))-l))}))},function(e,t,n){"use strict";var o=n(5),r=n(10),i=n(2),a=o.Int8Array,c=r.aTypedArray,l=r.exportTypedArrayMethod,u=[].toLocaleString,s=[].slice,d=!!a&&i((function(){u.call(new a(1))}));l("toLocaleString",(function(){return u.apply(d?s.call(c(this)):c(this),arguments)}),i((function(){return[1,2].toLocaleString()!=new a([1,2]).toLocaleString()}))||!i((function(){a.prototype.toLocaleString.call([1,2])})))},function(e,t,n){"use strict";var o=n(10).exportTypedArrayMethod,r=n(2),i=n(5).Uint8Array,a=i&&i.prototype||{},c=[].toString,l=[].join;r((function(){c.call({})}))&&(c=function(){return l.call(this)});var u=a.toString!=c;o("toString",c,u)},function(e,t,n){"use strict";var o,r=n(5),i=n(65),a=n(50),c=n(77),l=n(159),u=n(7),s=n(34).enforce,d=n(126),f=!r.ActiveXObject&&"ActiveXObject"in r,p=Object.isExtensible,m=function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}},h=e.exports=c("WeakMap",m,l);if(d&&f){o=l.getConstructor(m,"WeakMap",!0),a.REQUIRED=!0;var g=h.prototype,v=g["delete"],b=g.has,C=g.get,N=g.set;i(g,{"delete":function(e){if(u(e)&&!p(e)){var t=s(this);return t.frozen||(t.frozen=new o),v.call(this,e)||t.frozen["delete"](e)}return v.call(this,e)},has:function(e){if(u(e)&&!p(e)){var t=s(this);return t.frozen||(t.frozen=new o),b.call(this,e)||t.frozen.has(e)}return b.call(this,e)},get:function(e){if(u(e)&&!p(e)){var t=s(this);return t.frozen||(t.frozen=new o),b.call(this,e)?C.call(this,e):t.frozen.get(e)}return C.call(this,e)},set:function(e,t){if(u(e)&&!p(e)){var n=s(this);n.frozen||(n.frozen=new o),b.call(this,e)?N.call(this,e,t):n.frozen.set(e,t)}else N.call(this,e,t);return this}})}},function(e,t,n){"use strict";n(77)("WeakSet",(function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}}),n(159))},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(107);o({global:!0,bind:!0,enumerable:!0,forced:!r.setImmediate||!r.clearImmediate},{setImmediate:i.set,clearImmediate:i.clear})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(152),a=n(32),c=r.process,l="process"==a(c);o({global:!0,enumerable:!0,noTargetGet:!0},{queueMicrotask:function(e){var t=l&&c.domain;i(t?t.bind(e):e)}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(72),a=[].slice,c=function(e){return function(t,n){var o=arguments.length>2,r=o?a.call(arguments,2):undefined;return e(o?function(){("function"==typeof t?t:Function(t)).apply(this,r)}:t,n)}};o({global:!0,bind:!0,forced:/MSIE .\./.test(i)},{setTimeout:c(r.setTimeout),setInterval:c(r.setInterval)})},function(e,t,n){"use strict";t.__esModule=!0,t._CI=Se,t._HI=j,t._M=Be,t._MCCC=Ae,t._ME=Ie,t._MFCC=Oe,t._MP=_e,t._MR=be,t.__render=Fe,t.createComponentVNode=function(e,t,n,o,r){var a=new B(1,null,null,e=function(e,t){if(12&e)return e;if(t.prototype&&t.prototype.render)return 4;if(t.render)return 32776;return 8}(e,t),o,function(e,t,n){var o=(32768&e?t.render:t).defaultProps;if(i(o))return n;if(i(n))return s(o,null);return L(n,o)}(e,t,n),function(e,t,n){if(4&e)return n;var o=(32768&e?t.render:t).defaultHooks;if(i(o))return n;if(i(n))return o;return L(n,o)}(e,t,r),t);w.createVNode&&w.createVNode(a);return a},t.createFragment=T,t.createPortal=function(e,t){var n=j(e);return E(1024,1024,null,n,0,null,n.key,t)},t.createRef=function(){return{current:null}},t.createRenderer=function(e){return function(t,n,o,r){e||(e=t),Re(n,e,o,r)}},t.createTextVNode=I,t.createVNode=E,t.directClone=A,t.findDOMfromVNode=C,t.forwardRef=function(e){return{render:e}},t.getFlagsForElementVnode=function(e){switch(e){case"svg":return 32;case"input":return 64;case"select":return 256;case"textarea":return 128;case"$F":return 8192;default:return 1}},t.linkEvent=function(e,t){if(c(t))return{data:e,event:t};return null},t.normalizeProps=function(e){var t=e.props;if(t){var n=e.flags;481&n&&(void 0!==t.children&&i(e.children)&&P(e,t.children),void 0!==t.className&&(e.className=t.className||null,t.className=undefined)),void 0!==t.key&&(e.key=t.key,t.key=undefined),void 0!==t.ref&&(e.ref=8&n?s(e.ref,t.ref):t.ref,t.ref=undefined)}return e},t.render=Re,t.rerender=Ye,t.version=t.options=t.Fragment=t.EMPTY_OBJ=t.Component=void 0;var o=Array.isArray;function r(e){var t=typeof e;return"string"===t||"number"===t}function i(e){return null==e}function a(e){return null===e||!1===e||!0===e||void 0===e}function c(e){return"function"==typeof e}function l(e){return"string"==typeof e}function u(e){return null===e}function s(e,t){var n={};if(e)for(var o in e)n[o]=e[o];if(t)for(var r in t)n[r]=t[r];return n}function d(e){return!u(e)&&"object"==typeof e}var f={};t.EMPTY_OBJ=f;function p(e){return e.substr(2).toLowerCase()}function m(e,t){e.appendChild(t)}function h(e,t,n){u(n)?m(e,t):e.insertBefore(t,n)}function g(e,t){e.removeChild(t)}function v(e){for(var t=0;t0,m=u(f),h=l(f)&&"$"===f[0];p||m||h?(n=n||t.slice(0,s),(p||h)&&(d=A(d)),(m||h)&&(d.key="$"+s),n.push(d)):n&&n.push(d),d.flags|=65536}}i=0===(n=n||t).length?1:8}else(n=t).flags|=65536,81920&t.flags&&(n=A(t)),i=2;return e.children=n,e.childFlags=i,e}function j(e){return a(e)||r(e)?I(e,null):o(e)?T(e,0,null):16384&e.flags?A(e):e}var D="http://www.w3.org/1999/xlink",F="http://www.w3.org/XML/1998/namespace",R={"xlink:actuate":D,"xlink:arcrole":D,"xlink:href":D,"xlink:role":D,"xlink:show":D,"xlink:title":D,"xlink:type":D,"xml:base":F,"xml:lang":F,"xml:space":F};function z(e){return{onClick:e,onDblClick:e,onFocusIn:e,onFocusOut:e,onKeyDown:e,onKeyPress:e,onKeyUp:e,onMouseDown:e,onMouseMove:e,onMouseUp:e,onTouchEnd:e,onTouchMove:e,onTouchStart:e}}var W=z(0),U=z(null),K=z(!0);function H(e,t){var n=t.$EV;return n||(n=t.$EV=z(null)),n[e]||1==++W[e]&&(U[e]=function(e){var t="onClick"===e||"onDblClick"===e?function(e){return function(t){0===t.button?$(t,!0,e,Q(t)):t.stopPropagation()}}(e):function(e){return function(t){$(t,!1,e,Q(t))}}(e);return document.addEventListener(p(e),t),t}(e)),n}function Y(e,t){var n=t.$EV;n&&n[e]&&(0==--W[e]&&(document.removeEventListener(p(e),U[e]),U[e]=null),n[e]=null)}function $(e,t,n,o){var r=function(e){return c(e.composedPath)?e.composedPath()[0]:e.target}(e);do{if(t&&r.disabled)return;var i=r.$EV;if(i){var a=i[n];if(a&&(o.dom=r,a.event?a.event(a.data,e):a(e),e.cancelBubble))return}r=r.parentNode}while(!u(r))}function q(){this.cancelBubble=!0,this.immediatePropagationStopped||this.stopImmediatePropagation()}function G(){return this.defaultPrevented}function X(){return this.cancelBubble}function Q(e){var t={dom:document};return e.isDefaultPrevented=G,e.isPropagationStopped=X,e.stopPropagation=q,Object.defineProperty(e,"currentTarget",{configurable:!0,get:function(){return t.dom}}),t}function J(e,t,n){if(e[t]){var o=e[t];o.event?o.event(o.data,n):o(n)}else{var r=t.toLowerCase();e[r]&&e[r](n)}}function Z(e,t){var n=function(n){var o=this.$V;if(o){var r=o.props||f,i=o.dom;if(l(e))J(r,e,n);else for(var a=0;a-1&&t.options[a]&&(c=t.options[a].value),n&&i(c)&&(c=e.defaultValue),ae(o,c)}}var ue,se,de=Z("onInput",pe),fe=Z("onChange");function pe(e,t,n){var o=e.value,r=t.value;if(i(o)){if(n){var a=e.defaultValue;i(a)||a===r||(t.defaultValue=a,t.value=a)}}else r!==o&&(t.defaultValue=o,t.value=o)}function me(e,t,n,o,r,i){64&e?ie(o,n):256&e?le(o,n,r,t):128&e&&pe(o,n,r),i&&(n.$V=t)}function he(e,t,n){64&e?function(e,t){te(t.type)?(ee(e,"change",oe),ee(e,"click",re)):ee(e,"input",ne)}(t,n):256&e?function(e){ee(e,"change",ce)}(t):128&e&&function(e,t){ee(e,"input",de),t.onChange&&ee(e,"change",fe)}(t,n)}function ge(e){return e.type&&te(e.type)?!i(e.checked):!i(e.value)}function ve(e){e&&!S(e,null)&&e.current&&(e.current=null)}function be(e,t,n){e&&(c(e)||void 0!==e.current)&&n.push((function(){S(e,t)||void 0===e.current||(e.current=t)}))}function Ce(e,t){Ne(e),N(e,t)}function Ne(e){var t,n=e.flags,o=e.children;if(481&n){t=e.ref;var r=e.props;ve(t);var a=e.childFlags;if(!u(r))for(var l=Object.keys(r),s=0,d=l.length;s0;for(var c in a&&(i=ge(n))&&he(t,o,n),n)ke(c,null,n[c],o,r,i,null);a&&me(t,e,o,n,!0,i)}function Le(e,t,n){var o=j(e.render(t,e.state,n)),r=n;return c(e.getChildContext)&&(r=s(n,e.getChildContext())),e.$CX=r,o}function Se(e,t,n,o,r,i){var a=new t(n,o),l=a.$N=Boolean(t.getDerivedStateFromProps||a.getSnapshotBeforeUpdate);if(a.$SVG=r,a.$L=i,e.children=a,a.$BS=!1,a.context=o,a.props===f&&(a.props=n),l)a.state=V(a,n,a.state);else if(c(a.componentWillMount)){a.$BR=!0,a.componentWillMount();var s=a.$PS;if(!u(s)){var d=a.state;if(u(d))a.state=s;else for(var p in s)d[p]=s[p];a.$PS=null}a.$BR=!1}return a.$LI=Le(a,n,o),a}function Be(e,t,n,o,r,i){var a=e.flags|=16384;481&a?Ie(e,t,n,o,r,i):4&a?function(e,t,n,o,r,i){var a=Se(e,e.type,e.props||f,n,o,i);Be(a.$LI,t,a.$CX,o,r,i),Ae(e.ref,a,i)}(e,t,n,o,r,i):8&a?(!function(e,t,n,o,r,i){Be(e.children=j(function(e,t){return 32768&e.flags?e.type.render(e.props||f,e.ref,t):e.type(e.props||f,t)}(e,n)),t,n,o,r,i)}(e,t,n,o,r,i),Oe(e,i)):512&a||16&a?Ee(e,t,r):8192&a?function(e,t,n,o,r,i){var a=e.children,c=e.childFlags;12&c&&0===a.length&&(c=e.childFlags=2,a=e.children=O());2===c?Be(a,n,r,o,r,i):Te(a,n,t,o,r,i)}(e,n,t,o,r,i):1024&a&&function(e,t,n,o,r){Be(e.children,e.ref,t,!1,null,r);var i=O();Ee(i,n,o),e.dom=i.dom}(e,n,t,r,i)}function Ee(e,t,n){var o=e.dom=document.createTextNode(e.children);u(t)||h(t,o,n)}function Ie(e,t,n,o,r,a){var c=e.flags,l=e.props,s=e.className,d=e.children,f=e.childFlags,p=e.dom=function(e,t){return t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}(e.type,o=o||(32&c)>0);if(i(s)||""===s||(o?p.setAttribute("class",s):p.className=s),16===f)k(p,d);else if(1!==f){var m=o&&"foreignObject"!==e.type;2===f?(16384&d.flags&&(e.children=d=A(d)),Be(d,p,n,m,null,a)):8!==f&&4!==f||Te(d,p,n,m,null,a)}u(t)||h(t,p,r),u(l)||_e(e,c,l,p,o),be(e.ref,p,a)}function Te(e,t,n,o,r,i){for(var a=0;a0,u!==s){var m=u||f;if((c=s||f)!==f)for(var h in(d=(448&r)>0)&&(p=ge(c)),c){var g=m[h],v=c[h];g!==v&&ke(h,g,v,l,o,p,e)}if(m!==f)for(var b in m)i(c[b])&&!i(m[b])&&ke(b,m[b],null,l,o,p,e)}var C=t.children,N=t.className;e.className!==N&&(i(N)?l.removeAttribute("class"):o?l.setAttribute("class",N):l.className=N);4096&r?function(e,t){e.textContent!==t&&(e.textContent=t)}(l,C):Pe(e.childFlags,t.childFlags,e.children,C,l,n,o&&"foreignObject"!==t.type,null,e,a);d&&me(r,t,l,c,!1,p);var y=t.ref,V=e.ref;V!==y&&(ve(V),be(y,l,a))}(e,t,o,r,p,d):4&p?function(e,t,n,o,r,i,a){var l=t.children=e.children;if(u(l))return;l.$L=a;var d=t.props||f,p=t.ref,m=e.ref,h=l.state;if(!l.$N){if(c(l.componentWillReceiveProps)){if(l.$BR=!0,l.componentWillReceiveProps(d,o),l.$UN)return;l.$BR=!1}u(l.$PS)||(h=s(h,l.$PS),l.$PS=null)}je(l,h,d,n,o,r,!1,i,a),m!==p&&(ve(m),be(p,l,a))}(e,t,n,o,r,l,d):8&p?function(e,t,n,o,r,a,l){var u=!0,s=t.props||f,d=t.ref,p=e.props,m=!i(d),h=e.children;m&&c(d.onComponentShouldUpdate)&&(u=d.onComponentShouldUpdate(p,s));if(!1!==u){m&&c(d.onComponentWillUpdate)&&d.onComponentWillUpdate(p,s);var g=t.type,v=j(32768&t.flags?g.render(s,d,o):g(s,o));Me(h,v,n,o,r,a,l),t.children=v,m&&c(d.onComponentDidUpdate)&&d.onComponentDidUpdate(p,s)}else t.children=h}(e,t,n,o,r,l,d):16&p?function(e,t){var n=t.children,o=t.dom=e.dom;n!==e.children&&(o.nodeValue=n)}(e,t):512&p?t.dom=e.dom:8192&p?function(e,t,n,o,r,i){var a=e.children,c=t.children,l=e.childFlags,u=t.childFlags,s=null;12&u&&0===c.length&&(u=t.childFlags=2,c=t.children=O());var d=0!=(2&u);if(12&l){var f=a.length;(8&l&&8&u||d||!d&&c.length>f)&&(s=C(a[f-1],!1).nextSibling)}Pe(l,u,a,c,n,o,r,s,e,i)}(e,t,n,o,r,d):function(e,t,n,o){var r=e.ref,i=t.ref,c=t.children;if(Pe(e.childFlags,t.childFlags,e.children,c,r,n,!1,null,e,o),t.dom=e.dom,r!==i&&!a(c)){var l=c.dom;g(r,l),m(i,l)}}(e,t,o,d)}function Pe(e,t,n,o,r,i,a,c,l,u){switch(e){case 2:switch(t){case 2:Me(n,o,r,i,a,c,u);break;case 1:Ce(n,r);break;case 16:Ne(n),k(r,o);break;default:!function(e,t,n,o,r,i){Ne(e),Te(t,n,o,r,C(e,!0),i),N(e,n)}(n,o,r,i,a,u)}break;case 1:switch(t){case 2:Be(o,r,i,a,c,u);break;case 1:break;case 16:k(r,o);break;default:Te(o,r,i,a,c,u)}break;case 16:switch(t){case 16:!function(e,t,n){e!==t&&(""!==e?n.firstChild.nodeValue=t:k(n,t))}(n,o,r);break;case 2:Ve(r),Be(o,r,i,a,c,u);break;case 1:Ve(r);break;default:Ve(r),Te(o,r,i,a,c,u)}break;default:switch(t){case 16:ye(n),k(r,o);break;case 2:xe(r,l,n),Be(o,r,i,a,c,u);break;case 1:xe(r,l,n);break;default:var s=0|n.length,d=0|o.length;0===s?d>0&&Te(o,r,i,a,c,u):0===d?xe(r,l,n):8===t&&8===e?function(e,t,n,o,r,i,a,c,l,u){var s,d,f=i-1,p=a-1,m=0,h=e[m],g=t[m];e:{for(;h.key===g.key;){if(16384&g.flags&&(t[m]=g=A(g)),Me(h,g,n,o,r,c,u),e[m]=g,++m>f||m>p)break e;h=e[m],g=t[m]}for(h=e[f],g=t[p];h.key===g.key;){if(16384&g.flags&&(t[p]=g=A(g)),Me(h,g,n,o,r,c,u),e[f]=g,f--,p--,m>f||m>p)break e;h=e[f],g=t[p]}}if(m>f){if(m<=p)for(d=(s=p+1)p)for(;m<=f;)Ce(e[m++],n);else!function(e,t,n,o,r,i,a,c,l,u,s,d,f){var p,m,h,g=0,v=c,b=c,N=i-c+1,V=a-c+1,x=new Int32Array(V+1),w=N===o,k=!1,_=0,L=0;if(r<4||(N|V)<32)for(g=v;g<=i;++g)if(p=e[g],Lc?k=!0:_=c,16384&m.flags&&(t[c]=m=A(m)),Me(p,m,l,n,u,s,f),++L;break}!w&&c>a&&Ce(p,l)}else w||Ce(p,l);else{var S={};for(g=b;g<=a;++g)S[t[g].key]=g;for(g=v;g<=i;++g)if(p=e[g],Lv;)Ce(e[v++],l);x[c-b]=g+1,_>c?k=!0:_=c,16384&(m=t[c]).flags&&(t[c]=m=A(m)),Me(p,m,l,n,u,s,f),++L}else w||Ce(p,l);else w||Ce(p,l)}if(w)xe(l,d,e),Te(t,l,n,u,s,f);else if(k){var B=function(e){var t=0,n=0,o=0,r=0,i=0,a=0,c=0,l=e.length;l>De&&(De=l,ue=new Int32Array(l),se=new Int32Array(l));for(;n>1]]0&&(se[n]=ue[i-1]),ue[i]=n)}i=r+1;var u=new Int32Array(i);a=ue[i-1];for(;i-- >0;)u[i]=a,a=se[a],ue[i]=0;return u}(x);for(c=B.length-1,g=V-1;g>=0;g--)0===x[g]?(16384&(m=t[_=g+b]).flags&&(t[_]=m=A(m)),Be(m,l,n,u,(h=_+1)=0;g--)0===x[g]&&(16384&(m=t[_=g+b]).flags&&(t[_]=m=A(m)),Be(m,l,n,u,(h=_+1)a?a:i,f=0;fa)for(f=d;f0?r(o(e),9007199254740991):0}},function(e,t,n){"use strict";t.__esModule=!0,t.isFalsy=t.pureComponentHooks=t.shallowDiffers=t.normalizeChildren=t.classes=void 0;t.classes=function(e){for(var t="",n=0;n0&&(t.style=l),t};t.computeBoxProps=g;var C=function(e){var t=e.textColor||e.color,n=e.backgroundColor;return(0,o.classes)([d(t)&&"color-"+t,d(n)&&"color-bg-"+n])};t.computeBoxClassName=C;var b=function(e){var t=e.as,n=void 0===t?"div":t,o=e.className,a=e.children,c=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["as","className","children"]);if("function"==typeof a)return a(g(e));var l="string"==typeof o?o+" "+C(c):C(c),d=g(c);return(0,r.createVNode)(i.VNodeFlags.HtmlElement,n,l,a,i.ChildFlags.UnknownChildren,d)};t.Box=b,b.defaultHooks=o.pureComponentHooks},function(e,t,n){"use strict";var o={}.hasOwnProperty;e.exports=function(e,t){return o.call(e,t)}},function(e,t,n){"use strict";var o=n(47),r=n(58),i=n(15),a=n(11),c=n(64),l=[].push,d=function(e){var t=1==e,n=2==e,d=3==e,u=4==e,s=6==e,p=5==e||s;return function(f,m,h,g){for(var C,b,v=i(f),N=r(v),V=o(m,h,3),y=a(N.length),x=0,k=g||c,_=t?k(f,y):n?k(f,0):undefined;y>x;x++)if((p||x in N)&&(b=V(C=N[x],x,v),e))if(t)_[x]=b;else if(b)switch(e){case 3:return!0;case 5:return C;case 6:return x;case 2:l.call(_,C)}else if(u)return!1;return s?-1:d||u?u:_}};e.exports={forEach:d(0),map:d(1),filter:d(2),some:d(3),every:d(4),find:d(5),findIndex:d(6)}},function(e,t,n){"use strict";var o=n(8),r=n(70),i=n(45),a=n(25),c=n(33),l=n(17),d=n(127),u=Object.getOwnPropertyDescriptor;t.f=o?u:function(e,t){if(e=a(e),t=c(t,!0),d)try{return u(e,t)}catch(n){}if(l(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t,n){"use strict";t.__esModule=!0,t.keyOfMatchingRange=t.inRange=t.toFixed=t.round=t.scale=t.clamp01=t.clamp=void 0;t.clamp=function(e,t,n){return en?n:e};t.clamp01=function(e){return e<0?0:e>1?1:e};t.scale=function(e,t,n){return(e-t)/(n-t)};t.round=function(e,t){return!e||isNaN(e)?e:(t|=0,i=(e*=n=Math.pow(10,t))>0|-(e<0),r=Math.abs(e%1)>=.4999999999854481,o=Math.floor(e),r&&(e=o+(i>0)),(r?e:Math.round(e))/n);var n,o,r,i};t.toFixed=function(e,t){return void 0===t&&(t=0),Number(e).toFixed(Math.max(t,0))};var o=function(e,t){return t&&e>=t[0]&&e<=t[1]};t.inRange=o;t.keyOfMatchingRange=function(e,t){for(var n=0,r=Object.keys(t);n"+a+""}},function(e,t,n){"use strict";var o=n(5);e.exports=function(e){return o((function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}))}},function(e,t,n){"use strict";var o=n(8),r=n(14),i=n(45);e.exports=o?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";var o=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:o)(e)}},function(e,t,n){"use strict";e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},function(e,t,n){"use strict";var o={}.toString;e.exports=function(e){return o.call(e).slice(8,-1)}},function(e,t,n){"use strict";var o=n(7);e.exports=function(e,t){if(!o(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!o(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!o(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},function(e,t,n){"use strict";var o,r,i,a=n(129),c=n(6),l=n(7),d=n(29),u=n(17),s=n(71),p=n(60),f=c.WeakMap;if(a){var m=new f,h=m.get,g=m.has,C=m.set;o=function(e,t){return C.call(m,e,t),t},r=function(e){return h.call(m,e)||{}},i=function(e){return g.call(m,e)}}else{var b=s("state");p[b]=!0,o=function(e,t){return d(e,b,t),t},r=function(e){return u(e,b)?e[b]:{}},i=function(e){return u(e,b)}}e.exports={set:o,get:r,has:i,enforce:function(e){return i(e)?r(e):o(e,{})},getterFor:function(e){return function(t){var n;if(!l(t)||(n=r(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){"use strict";var o=n(17),r=n(15),i=n(71),a=n(103),c=i("IE_PROTO"),l=Object.prototype;e.exports=a?Object.getPrototypeOf:function(e){return e=r(e),o(e,c)?e[c]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?l:null}},function(e,t,n){"use strict";var o=n(131),r=n(6),i=function(e){return"function"==typeof e?e:undefined};e.exports=function(e,t){return arguments.length<2?i(o[e])||i(r[e]):o[e]&&o[e][t]||r[e]&&r[e][t]}},function(e,t,n){"use strict";e.exports=!1},function(e,t,n){"use strict";var o=n(5);e.exports=function(e,t){var n=[][e];return!!n&&o((function(){n.call(null,t||function(){throw 1},1)}))}},function(e,t,n){"use strict";var o=n(0),r=n(6),i=n(8),a=n(116),c=n(10),l=n(76),d=n(53),u=n(45),s=n(29),p=n(11),f=n(145),m=n(160),h=n(33),g=n(17),C=n(73),b=n(7),v=n(41),N=n(49),V=n(46).f,y=n(161),x=n(18).forEach,k=n(52),_=n(14),w=n(19),L=n(34),B=n(78),S=L.get,I=L.set,E=_.f,T=w.f,A=Math.round,O=r.RangeError,M=l.ArrayBuffer,P=l.DataView,j=c.NATIVE_ARRAY_BUFFER_VIEWS,D=c.TYPED_ARRAY_TAG,F=c.TypedArray,R=c.TypedArrayPrototype,z=c.aTypedArrayConstructor,W=c.isTypedArray,U=function(e,t){for(var n=0,o=t.length,r=new(z(e))(o);o>n;)r[n]=t[n++];return r},K=function(e,t){E(e,t,{get:function(){return S(this)[t]}})},H=function(e){var t;return e instanceof M||"ArrayBuffer"==(t=C(e))||"SharedArrayBuffer"==t},Y=function(e,t){return W(e)&&"symbol"!=typeof t&&t in e&&String(+t)==String(t)},q=function(e,t){return Y(e,t=h(t,!0))?u(2,e[t]):T(e,t)},G=function(e,t,n){return!(Y(e,t=h(t,!0))&&b(n)&&g(n,"value"))||g(n,"get")||g(n,"set")||n.configurable||g(n,"writable")&&!n.writable||g(n,"enumerable")&&!n.enumerable?E(e,t,n):(e[t]=n.value,e)};i?(j||(w.f=q,_.f=G,K(R,"buffer"),K(R,"byteOffset"),K(R,"byteLength"),K(R,"length")),o({target:"Object",stat:!0,forced:!j},{getOwnPropertyDescriptor:q,defineProperty:G}),e.exports=function(e,t,n){var i=e.match(/\d+$/)[0]/8,c=e+(n?"Clamped":"")+"Array",l="get"+e,u="set"+e,h=r[c],g=h,C=g&&g.prototype,_={},w=function(e,t){E(e,t,{get:function(){return function(e,t){var n=S(e);return n.view[l](t*i+n.byteOffset,!0)}(this,t)},set:function(e){return function(e,t,o){var r=S(e);n&&(o=(o=A(o))<0?0:o>255?255:255&o),r.view[u](t*i+r.byteOffset,o,!0)}(this,t,e)},enumerable:!0})};j?a&&(g=t((function(e,t,n,o){return d(e,g,c),B(b(t)?H(t)?o!==undefined?new h(t,m(n,i),o):n!==undefined?new h(t,m(n,i)):new h(t):W(t)?U(g,t):y.call(g,t):new h(f(t)),e,g)})),N&&N(g,F),x(V(h),(function(e){e in g||s(g,e,h[e])})),g.prototype=C):(g=t((function(e,t,n,o){d(e,g,c);var r,a,l,u=0,s=0;if(b(t)){if(!H(t))return W(t)?U(g,t):y.call(g,t);r=t,s=m(n,i);var h=t.byteLength;if(o===undefined){if(h%i)throw O("Wrong length");if((a=h-s)<0)throw O("Wrong length")}else if((a=p(o)*i)+s>h)throw O("Wrong length");l=a/i}else l=f(t),r=new M(a=l*i);for(I(e,{buffer:r,byteOffset:s,byteLength:a,length:l,view:new P(r)});u"+e+"<\/script>"},m=function(){try{o=document.domain&&new ActiveXObject("htmlfile")}catch(r){}var e,t;m=o?function(e){e.write(f("")),e.close();var t=e.parentWindow.Object;return e=null,t}(o):((t=d("iframe")).style.display="none",l.appendChild(t),t.src=String("javascript:"),(e=t.contentWindow.document).open(),e.write(f("document.F=Object")),e.close(),e.F);for(var n=a.length;n--;)delete m.prototype[a[n]];return m()};c[s]=!0,e.exports=Object.create||function(e,t){var n;return null!==e?(p.prototype=r(e),n=new p,p.prototype=null,n[s]=e):n=m(),t===undefined?n:i(n,t)}},function(e,t,n){"use strict";var o=n(14).f,r=n(17),i=n(13)("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,i)&&o(e,i,{configurable:!0,value:t})}},function(e,t,n){"use strict";var o=n(13),r=n(41),i=n(14),a=o("unscopables"),c=Array.prototype;c[a]==undefined&&i.f(c,a,{configurable:!0,value:r(null)}),e.exports=function(e){c[a][e]=!0}},function(e,t,n){"use strict";var o=n(9),r=n(31),i=n(13)("species");e.exports=function(e,t){var n,a=o(e).constructor;return a===undefined||(n=o(a)[i])==undefined?t:r(n)}},function(e,t,n){"use strict";e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){"use strict";var o=n(132),r=n(94).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return o(e,r)}},function(e,t,n){"use strict";var o=n(31);e.exports=function(e,t,n){if(o(e),t===undefined)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,o){return e.call(t,n,o)};case 3:return function(n,o,r){return e.call(t,n,o,r)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){"use strict";var o=n(33),r=n(14),i=n(45);e.exports=function(e,t,n){var a=o(t);a in e?r.f(e,a,i(0,n)):e[a]=n}},function(e,t,n){"use strict";var o=n(9),r=n(143);e.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var e,t=!1,n={};try{(e=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set).call(n,[]),t=n instanceof Array}catch(i){}return function(n,i){return o(n),r(i),t?e.call(n,i):n.__proto__=i,n}}():undefined)},function(e,t,n){"use strict";var o=n(60),r=n(7),i=n(17),a=n(14).f,c=n(59),l=n(68),d=c("meta"),u=0,s=Object.isExtensible||function(){return!0},p=function(e){a(e,d,{value:{objectID:"O"+ ++u,weakData:{}}})},f=e.exports={REQUIRED:!1,fastKey:function(e,t){if(!r(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,d)){if(!s(e))return"F";if(!t)return"E";p(e)}return e[d].objectID},getWeakData:function(e,t){if(!i(e,d)){if(!s(e))return!0;if(!t)return!1;p(e)}return e[d].weakData},onFreeze:function(e){return l&&f.REQUIRED&&s(e)&&!i(e,d)&&p(e),e}};o[d]=!0},function(e,t,n){"use strict";var o=n(32);e.exports=Array.isArray||function(e){return"Array"==o(e)}},function(e,t,n){"use strict";var o=n(36),r=n(14),i=n(13),a=n(8),c=i("species");e.exports=function(e){var t=o(e),n=r.f;a&&t&&!t[c]&&n(t,c,{configurable:!0,get:function(){return this}})}},function(e,t,n){"use strict";e.exports=function(e,t,n){if(!(e instanceof t))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return e}},function(e,t,n){"use strict";var o=n(21),r="["+n(80)+"]",i=RegExp("^"+r+r+"*"),a=RegExp(r+r+"*$"),c=function(e){return function(t){var n=String(o(t));return 1&e&&(n=n.replace(i,"")),2&e&&(n=n.replace(a,"")),n}};e.exports={start:c(1),end:c(2),trim:c(3)}},function(e,t,n){"use strict";t.__esModule=!0,t.getGasColor=t.getGasLabel=t.RADIO_CHANNELS=t.CSS_COLORS=t.COLORS=t.UI_CLOSE=t.UI_DISABLED=t.UI_UPDATE=t.UI_INTERACTIVE=void 0;t.UI_INTERACTIVE=2;t.UI_UPDATE=1;t.UI_DISABLED=0;t.UI_CLOSE=-1;t.COLORS={department:{captain:"#c06616",security:"#e74c3c",medbay:"#3498db",science:"#9b59b6",engineering:"#f1c40f",cargo:"#f39c12",centcom:"#00c100",other:"#c38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}};t.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"];t.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Medical(I)",freq:1485,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"Security(I)",freq:1475,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}];var o=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"}];t.getGasLabel=function(e,t){var n=String(e).toLowerCase(),r=o.find((function(e){return e.id===n||e.name.toLowerCase()===n}));return r&&r.label||t||e};t.getGasColor=function(e){var t=String(e).toLowerCase(),n=o.find((function(e){return e.id===t||e.name.toLowerCase()===t}));return n&&n.color}},function(e,t,n){"use strict";t.__esModule=!0,t.zipWith=t.zip=t.uniqBy=t.reduce=t.sortBy=t.map=t.filter=t.toKeyedArray=t.toArray=void 0;t.toArray=function(e){if(Array.isArray(e))return e;if("object"==typeof e){var t=Object.prototype.hasOwnProperty,n=[];for(var o in e)t.call(e,o)&&n.push(e[o]);return n}return[]};t.toKeyedArray=function(e,t){return void 0===t&&(t="key"),o((function(e,n){var o;return Object.assign(((o={})[t]=n,o),e)}))(e)};t.filter=function(e){return function(t){if(null===t&&t===undefined)return t;if(Array.isArray(t)){for(var n=[],o=0;oc)return 1}return 0};t.sortBy=function(){for(var e=arguments.length,t=new Array(e),n=0;n2?n-2:0),i=2;i=a){var c=[t].concat(r).map((function(e){return"string"==typeof e?e:e instanceof Error?e.stack||String(e):JSON.stringify(e)})).filter((function(e){return e})).join(" ")+"\nUser Agent: "+navigator.userAgent;(0,o.callByond)("",{src:window.__ref__,action:"tgui:log",log:c})}},u=function(e){return{debug:function(){for(var t=arguments.length,n=new Array(t),o=0;ou;)if((c=l[u++])!=c)return!0}else for(;d>u;u++)if((e||u in l)&&l[u]===n)return e||u||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},function(e,t,n){"use strict";var o=n(5),r=/#|\.prototype\./,i=function(e,t){var n=c[a(e)];return n==d||n!=l&&("function"==typeof t?o(t):!!t)},a=i.normalize=function(e){return String(e).replace(r,".").toLowerCase()},c=i.data={},l=i.NATIVE="N",d=i.POLYFILL="P";e.exports=i},function(e,t,n){"use strict";var o=n(132),r=n(94);e.exports=Object.keys||function(e){return o(e,r)}},function(e,t,n){"use strict";var o=n(7),r=n(51),i=n(13)("species");e.exports=function(e,t){var n;return r(e)&&("function"!=typeof(n=e.constructor)||n!==Array&&!r(n.prototype)?o(n)&&null===(n=n[i])&&(n=undefined):n=undefined),new(n===undefined?Array:n)(0===t?0:t)}},function(e,t,n){"use strict";var o=n(5),r=n(13),i=n(97),a=r("species");e.exports=function(e){return i>=51||!o((function(){var t=[];return(t.constructor={})[a]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},function(e,t,n){"use strict";e.exports={}},function(e,t,n){"use strict";var o=n(22);e.exports=function(e,t,n){for(var r in t)o(e,r,t[r],n);return e}},function(e,t,n){"use strict";var o=n(5);e.exports=!o((function(){return Object.isExtensible(Object.preventExtensions({}))}))},function(e,t,n){"use strict";var o=n(9),r=n(99),i=n(11),a=n(47),c=n(100),l=n(140),d=function(e,t){this.stopped=e,this.result=t};(e.exports=function(e,t,n,u,s){var p,f,m,h,g,C,b,v=a(t,n,u?2:1);if(s)p=e;else{if("function"!=typeof(f=c(e)))throw TypeError("Target is not iterable");if(r(f)){for(m=0,h=i(e.length);h>m;m++)if((g=u?v(o(b=e[m])[0],b[1]):v(e[m]))&&g instanceof d)return g;return new d(!1)}p=f.call(e)}for(C=p.next;!(b=C.call(p)).done;)if("object"==typeof(g=l(p,v,b.value,u))&&g&&g instanceof d)return g;return new d(!1)}).stop=function(e){return new d(!0,e)}},function(e,t,n){"use strict";var o={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,i=r&&!o.call({1:2},1);t.f=i?function(e){var t=r(this,e);return!!t&&t.enumerable}:o},function(e,t,n){"use strict";var o=n(92),r=n(59),i=o("keys");e.exports=function(e){return i[e]||(i[e]=r(e))}},function(e,t,n){"use strict";var o=n(36);e.exports=o("navigator","userAgent")||""},function(e,t,n){"use strict";var o=n(101),r=n(32),i=n(13)("toStringTag"),a="Arguments"==r(function(){return arguments}());e.exports=o?r:function(e){var t,n,o;return e===undefined?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(n){}}(t=Object(e),i))?n:a?r(t):"Object"==(o=r(t))&&"function"==typeof t.callee?"Arguments":o}},function(e,t,n){"use strict";var o=n(13)("iterator"),r=!1;try{var i=0,a={next:function(){return{done:!!i++}},"return":function(){r=!0}};a[o]=function(){return this},Array.from(a,(function(){throw 2}))}catch(c){}e.exports=function(e,t){if(!t&&!r)return!1;var n=!1;try{var i={};i[o]=function(){return{next:function(){return{done:n=!0}}}},e(i)}catch(c){}return n}},function(e,t,n){"use strict";var o=n(31),r=n(15),i=n(58),a=n(11),c=function(e){return function(t,n,c,l){o(n);var d=r(t),u=i(d),s=a(d.length),p=e?s-1:0,f=e?-1:1;if(c<2)for(;;){if(p in u){l=u[p],p+=f;break}if(p+=f,e?p<0:s<=p)throw TypeError("Reduce of empty array with no initial value")}for(;e?p>=0:s>p;p+=f)p in u&&(l=n(l,u[p],p,d));return l}};e.exports={left:c(!1),right:c(!0)}},function(e,t,n){"use strict";var o=n(6),r=n(8),i=n(104),a=n(29),c=n(67),l=n(5),d=n(53),u=n(30),s=n(11),p=n(145),f=n(222),m=n(35),h=n(49),g=n(46).f,C=n(14).f,b=n(98),v=n(42),N=n(34),V=N.get,y=N.set,x=o.ArrayBuffer,k=x,_=o.DataView,w=_&&_.prototype,L=Object.prototype,B=o.RangeError,S=f.pack,I=f.unpack,E=function(e){return[255&e]},T=function(e){return[255&e,e>>8&255]},A=function(e){return[255&e,e>>8&255,e>>16&255,e>>24&255]},O=function(e){return e[3]<<24|e[2]<<16|e[1]<<8|e[0]},M=function(e){return S(e,23,4)},P=function(e){return S(e,52,8)},j=function(e,t){C(e.prototype,t,{get:function(){return V(this)[t]}})},D=function(e,t,n,o){var r=p(n),i=V(e);if(r+t>i.byteLength)throw B("Wrong index");var a=V(i.buffer).bytes,c=r+i.byteOffset,l=a.slice(c,c+t);return o?l:l.reverse()},F=function(e,t,n,o,r,i){var a=p(n),c=V(e);if(a+t>c.byteLength)throw B("Wrong index");for(var l=V(c.buffer).bytes,d=a+c.byteOffset,u=o(+r),s=0;sU;)(R=W[U++])in k||a(k,R,x[R]);z.constructor=k}h&&m(w)!==L&&h(w,L);var K=new _(new k(2)),H=w.setInt8;K.setInt8(0,2147483648),K.setInt8(1,2147483649),!K.getInt8(0)&&K.getInt8(1)||c(w,{setInt8:function(e,t){H.call(this,e,t<<24>>24)},setUint8:function(e,t){H.call(this,e,t<<24>>24)}},{unsafe:!0})}else k=function(e){d(this,k,"ArrayBuffer");var t=p(e);y(this,{bytes:b.call(new Array(t),0),byteLength:t}),r||(this.byteLength=t)},_=function(e,t,n){d(this,_,"DataView"),d(e,k,"DataView");var o=V(e).byteLength,i=u(t);if(i<0||i>o)throw B("Wrong offset");if(i+(n=n===undefined?o-i:s(n))>o)throw B("Wrong length");y(this,{buffer:e,byteLength:n,byteOffset:i}),r||(this.buffer=e,this.byteLength=n,this.byteOffset=i)},r&&(j(k,"byteLength"),j(_,"buffer"),j(_,"byteLength"),j(_,"byteOffset")),c(_.prototype,{getInt8:function(e){return D(this,1,e)[0]<<24>>24},getUint8:function(e){return D(this,1,e)[0]},getInt16:function(e){var t=D(this,2,e,arguments.length>1?arguments[1]:undefined);return(t[1]<<8|t[0])<<16>>16},getUint16:function(e){var t=D(this,2,e,arguments.length>1?arguments[1]:undefined);return t[1]<<8|t[0]},getInt32:function(e){return O(D(this,4,e,arguments.length>1?arguments[1]:undefined))},getUint32:function(e){return O(D(this,4,e,arguments.length>1?arguments[1]:undefined))>>>0},getFloat32:function(e){return I(D(this,4,e,arguments.length>1?arguments[1]:undefined),23)},getFloat64:function(e){return I(D(this,8,e,arguments.length>1?arguments[1]:undefined),52)},setInt8:function(e,t){F(this,1,e,E,t)},setUint8:function(e,t){F(this,1,e,E,t)},setInt16:function(e,t){F(this,2,e,T,t,arguments.length>2?arguments[2]:undefined)},setUint16:function(e,t){F(this,2,e,T,t,arguments.length>2?arguments[2]:undefined)},setInt32:function(e,t){F(this,4,e,A,t,arguments.length>2?arguments[2]:undefined)},setUint32:function(e,t){F(this,4,e,A,t,arguments.length>2?arguments[2]:undefined)},setFloat32:function(e,t){F(this,4,e,M,t,arguments.length>2?arguments[2]:undefined)},setFloat64:function(e,t){F(this,8,e,P,t,arguments.length>2?arguments[2]:undefined)}});v(k,"ArrayBuffer"),v(_,"DataView"),e.exports={ArrayBuffer:k,DataView:_}},function(e,t,n){"use strict";var o=n(0),r=n(6),i=n(62),a=n(22),c=n(50),l=n(69),d=n(53),u=n(7),s=n(5),p=n(74),f=n(42),m=n(78);e.exports=function(e,t,n){var h=-1!==e.indexOf("Map"),g=-1!==e.indexOf("Weak"),C=h?"set":"add",b=r[e],v=b&&b.prototype,N=b,V={},y=function(e){var t=v[e];a(v,e,"add"==e?function(e){return t.call(this,0===e?0:e),this}:"delete"==e?function(e){return!(g&&!u(e))&&t.call(this,0===e?0:e)}:"get"==e?function(e){return g&&!u(e)?undefined:t.call(this,0===e?0:e)}:"has"==e?function(e){return!(g&&!u(e))&&t.call(this,0===e?0:e)}:function(e,n){return t.call(this,0===e?0:e,n),this})};if(i(e,"function"!=typeof b||!(g||v.forEach&&!s((function(){(new b).entries().next()})))))N=n.getConstructor(t,e,h,C),c.REQUIRED=!0;else if(i(e,!0)){var x=new N,k=x[C](g?{}:-0,1)!=x,_=s((function(){x.has(1)})),w=p((function(e){new b(e)})),L=!g&&s((function(){for(var e=new b,t=5;t--;)e[C](t,t);return!e.has(-0)}));w||((N=t((function(t,n){d(t,N,e);var o=m(new b,t,N);return n!=undefined&&l(n,o[C],o,h),o}))).prototype=v,v.constructor=N),(_||L)&&(y("delete"),y("has"),h&&y("get")),(L||k)&&y(C),g&&v.clear&&delete v.clear}return V[e]=N,o({global:!0,forced:N!=b},V),f(N,e),g||n.setStrong(N,e,h),N}},function(e,t,n){"use strict";var o=n(7),r=n(49);e.exports=function(e,t,n){var i,a;return r&&"function"==typeof(i=t.constructor)&&i!==n&&o(a=i.prototype)&&a!==n.prototype&&r(e,a),e}},function(e,t,n){"use strict";var o=Math.expm1,r=Math.exp;e.exports=!o||o(10)>22025.465794806718||o(10)<22025.465794806718||-2e-17!=o(-2e-17)?function(e){return 0==(e=+e)?e:e>-1e-6&&e<1e-6?e+e*e/2:r(e)-1}:o},function(e,t,n){"use strict";e.exports="\t\n\x0B\f\r \xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff"},function(e,t,n){"use strict";var o=n(37),r=n(6),i=n(5);e.exports=o||!i((function(){var e=Math.random();__defineSetter__.call(null,e,(function(){})),delete r[e]}))},function(e,t,n){"use strict";var o=n(9);e.exports=function(){var e=o(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.dotAll&&(t+="s"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t}},function(e,t,n){"use strict";var o,r,i=n(82),a=n(110),c=RegExp.prototype.exec,l=String.prototype.replace,d=c,u=(o=/a/,r=/b*/g,c.call(o,"a"),c.call(r,"a"),0!==o.lastIndex||0!==r.lastIndex),s=a.UNSUPPORTED_Y||a.BROKEN_CARET,p=/()??/.exec("")[1]!==undefined;(u||p||s)&&(d=function(e){var t,n,o,r,a=this,d=s&&a.sticky,f=i.call(a),m=a.source,h=0,g=e;return d&&(-1===(f=f.replace("y","")).indexOf("g")&&(f+="g"),g=String(e).slice(a.lastIndex),a.lastIndex>0&&(!a.multiline||a.multiline&&"\n"!==e[a.lastIndex-1])&&(m="(?: "+m+")",g=" "+g,h++),n=new RegExp("^(?:"+m+")",f)),p&&(n=new RegExp("^"+m+"$(?!\\s)",f)),u&&(t=a.lastIndex),o=c.call(d?n:a,g),d?o?(o.input=o.input.slice(h),o[0]=o[0].slice(h),o.index=a.lastIndex,a.lastIndex+=o[0].length):a.lastIndex=0:u&&o&&(a.lastIndex=a.global?o.index+o[0].length:t),p&&o&&o.length>1&&l.call(o[0],n,(function(){for(r=1;r")})),u="$0"==="a".replace(/./,"$0"),s=i("replace"),p=!!/./[s]&&""===/./[s]("a","$0"),f=!r((function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var n="ab".split(e);return 2!==n.length||"a"!==n[0]||"b"!==n[1]}));e.exports=function(e,t,n,s){var m=i(e),h=!r((function(){var t={};return t[m]=function(){return 7},7!=""[e](t)})),g=h&&!r((function(){var t=!1,n=/a/;return"split"===e&&((n={}).constructor={},n.constructor[l]=function(){return n},n.flags="",n[m]=/./[m]),n.exec=function(){return t=!0,null},n[m](""),!t}));if(!h||!g||"replace"===e&&(!d||!u||p)||"split"===e&&!f){var C=/./[m],b=n(m,""[e],(function(e,t,n,o,r){return t.exec===a?h&&!r?{done:!0,value:C.call(t,n,o)}:{done:!0,value:e.call(n,t,o)}:{done:!1}}),{REPLACE_KEEPS_$0:u,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:p}),v=b[0],N=b[1];o(String.prototype,e,v),o(RegExp.prototype,m,2==t?function(e,t){return N.call(e,this,t)}:function(e){return N.call(e,this)})}s&&c(RegExp.prototype[m],"sham",!0)}},function(e,t,n){"use strict";var o=n(32),r=n(83);e.exports=function(e,t){var n=e.exec;if("function"==typeof n){var i=n.call(e,t);if("object"!=typeof i)throw TypeError("RegExp exec method returned something other than an Object or null");return i}if("RegExp"!==o(e))throw TypeError("RegExp#exec called on incompatible receiver");return r.call(e,t)}},function(e,t,n){"use strict";t.__esModule=!0,t.TableCell=t.TableRow=t.Table=void 0;var o=n(1),r=n(12),i=n(16);function a(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var c=function(e){var t=e.className,n=e.collapsing,c=e.children,l=a(e,["className","collapsing","children"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"table",(0,r.classes)(["Table",n&&"Table--collapsing",t,(0,i.computeBoxClassName)(l)]),(0,o.createVNode)(1,"tbody",null,c,0),2,Object.assign({},(0,i.computeBoxProps)(l))))};t.Table=c,c.defaultHooks=r.pureComponentHooks;var l=function(e){var t=e.className,n=e.header,c=a(e,["className","header"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"tr",(0,r.classes)(["Table__row",n&&"Table__row--header",t,(0,i.computeBoxClassName)(e)]),null,1,Object.assign({},(0,i.computeBoxProps)(c))))};t.TableRow=l,l.defaultHooks=r.pureComponentHooks;var d=function(e){var t=e.className,n=e.collapsing,c=e.header,l=a(e,["className","collapsing","header"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"td",(0,r.classes)(["Table__cell",n&&"Table__cell--collapsing",c&&"Table__cell--header",t,(0,i.computeBoxClassName)(e)]),null,1,Object.assign({},(0,i.computeBoxProps)(l))))};t.TableCell=d,d.defaultHooks=r.pureComponentHooks,c.Row=l,c.Cell=d},function(e,t,n){"use strict";function o(e){var t=0;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(e=function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e)))return function(){return t>=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(t=e[Symbol.iterator]()).next.bind(t)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n",apos:"'"};return e.replace(/
/gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(/&(nbsp|amp|quot|lt|gt|apos);/g,(function(e,n){return t[n]})).replace(/&#?([0-9]+);/gi,(function(e,t){var n=parseInt(t,10);return String.fromCharCode(n)})).replace(/&#x?([0-9a-f]+);/gi,(function(e,t){var n=parseInt(t,16);return String.fromCharCode(n)}))};t.buildQueryString=function(e){return Object.keys(e).map((function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])})).join("&")}},function(e,t,n){"use strict";t.__esModule=!0,t.ComplexModal=t.modalRegisterBodyOverride=t.modalOpen=void 0;var o=n(1),r=n(2),i=n(3),a={};t.modalOpen=function(e,t,n){var o=(0,r.useBackend)(e),i=o.act,a=o.data,c=Object.assign(a.modal?a.modal.args:{},n||{});i("modal_open",{id:t,arguments:JSON.stringify(c)})};t.modalRegisterBodyOverride=function(e,t){a[e]=t};var c=function(e,t,n,o){var i=(0,r.useBackend)(e),a=i.act,c=i.data;if(c.modal){var l=Object.assign(c.modal.args||{},o||{});a("modal_answer",{id:t,answer:n,arguments:JSON.stringify(l)})}},l=function(e,t){(0,(0,r.useBackend)(e).act)("modal_close",{id:t})};t.ComplexModal=function(e,t){var n=(0,r.useBackend)(t).data;if(n.modal){var d,u,s=n.modal,p=s.id,f=s.text,m=s.type,h=(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}});if(a[p])u=a[p](n.modal,t);else if("input"===m){var g=n.modal.value;d=function(e){return c(t,p,g)},u=(0,o.createComponentVNode)(2,i.Input,{value:n.modal.value,placeholder:"ENTER to submit",width:"100%",my:"0.5rem",autofocus:!0,onChange:function(e,t){g=t}}),h=(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"check",content:"Confirm",color:"good",float:"right",m:"0",onClick:function(){return c(t,p,g)}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]})}else if("choice"===m){var C="object"==typeof n.modal.choices?Object.values(n.modal.choices):n.modal.choices;u=(0,o.createComponentVNode)(2,i.Dropdown,{options:C,selected:n.modal.value,width:"100%",my:"0.5rem",onSelected:function(e){return c(t,p,e)}})}else"bento"===m?u=(0,o.createComponentVNode)(2,i.Flex,{spacingPrecise:"1",wrap:"wrap",my:"0.5rem",maxHeight:"1%",children:n.modal.choices.map((function(e,r){return(0,o.createComponentVNode)(2,i.Flex.Item,{flex:"1 1 auto",children:(0,o.createComponentVNode)(2,i.Button,{selected:r+1===parseInt(n.modal.value,10),onClick:function(){return c(t,p,r+1)},children:(0,o.createVNode)(1,"img",null,null,1,{src:e})})},r)}))}):"boolean"===m&&(h=(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:n.modal.no_text,color:"bad",float:"left",mb:"0",onClick:function(){return c(t,p,0)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"check",content:n.modal.yes_text,color:"good",float:"right",m:"0",onClick:function(){return c(t,p,1)}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]}));return(0,o.createComponentVNode)(2,i.Modal,{maxWidth:e.maxWidth||window.innerWidth/2+"px",maxHeight:e.maxHeight||window.innerHeight/2+"px",onEnter:d,mx:"auto",overflowY:"auto",children:[(0,o.createComponentVNode)(2,i.Box,{display:"inline",children:f}),u,h]})}}},function(e,t,n){"use strict";var o=n(6),r=n(7),i=o.document,a=r(i)&&r(i.createElement);e.exports=function(e){return a?i.createElement(e):{}}},function(e,t,n){"use strict";var o=n(6),r=n(29);e.exports=function(e,t){try{r(o,e,t)}catch(n){o[e]=t}return t}},function(e,t,n){"use strict";var o=n(128),r=Function.toString;"function"!=typeof o.inspectSource&&(o.inspectSource=function(e){return r.call(e)}),e.exports=o.inspectSource},function(e,t,n){"use strict";var o=n(37),r=n(128);(e.exports=function(e,t){return r[e]||(r[e]=t!==undefined?t:{})})("versions",[]).push({version:"3.6.5",mode:o?"pure":"global",copyright:"\xa9 2020 Denis Pushkarev (zloirock.ru)"})},function(e,t,n){"use strict";var o=n(36),r=n(46),i=n(95),a=n(9);e.exports=o("Reflect","ownKeys")||function(e){var t=r.f(a(e)),n=i.f;return n?t.concat(n(e)):t}},function(e,t,n){"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t,n){"use strict";t.f=Object.getOwnPropertySymbols},function(e,t,n){"use strict";var o=n(5);e.exports=!!Object.getOwnPropertySymbols&&!o((function(){return!String(Symbol())}))},function(e,t,n){"use strict";var o,r,i=n(6),a=n(72),c=i.process,l=c&&c.versions,d=l&&l.v8;d?r=(o=d.split("."))[0]+o[1]:a&&(!(o=a.match(/Edge\/(\d+)/))||o[1]>=74)&&(o=a.match(/Chrome\/(\d+)/))&&(r=o[1]),e.exports=r&&+r},function(e,t,n){"use strict";var o=n(15),r=n(40),i=n(11);e.exports=function(e){for(var t=o(this),n=i(t.length),a=arguments.length,c=r(a>1?arguments[1]:undefined,n),l=a>2?arguments[2]:undefined,d=l===undefined?n:r(l,n);d>c;)t[c++]=e;return t}},function(e,t,n){"use strict";var o=n(13),r=n(66),i=o("iterator"),a=Array.prototype;e.exports=function(e){return e!==undefined&&(r.Array===e||a[i]===e)}},function(e,t,n){"use strict";var o=n(73),r=n(66),i=n(13)("iterator");e.exports=function(e){if(e!=undefined)return e[i]||e["@@iterator"]||r[o(e)]}},function(e,t,n){"use strict";var o={};o[n(13)("toStringTag")]="z",e.exports="[object z]"===String(o)},function(e,t,n){"use strict";var o=n(0),r=n(207),i=n(35),a=n(49),c=n(42),l=n(29),d=n(22),u=n(13),s=n(37),p=n(66),f=n(142),m=f.IteratorPrototype,h=f.BUGGY_SAFARI_ITERATORS,g=u("iterator"),C=function(){return this};e.exports=function(e,t,n,u,f,b,v){r(n,t,u);var N,V,y,x=function(e){if(e===f&&B)return B;if(!h&&e in w)return w[e];switch(e){case"keys":case"values":case"entries":return function(){return new n(this,e)}}return function(){return new n(this)}},k=t+" Iterator",_=!1,w=e.prototype,L=w[g]||w["@@iterator"]||f&&w[f],B=!h&&L||x(f),S="Array"==t&&w.entries||L;if(S&&(N=i(S.call(new e)),m!==Object.prototype&&N.next&&(s||i(N)===m||(a?a(N,m):"function"!=typeof N[g]&&l(N,g,C)),c(N,k,!0,!0),s&&(p[k]=C))),"values"==f&&L&&"values"!==L.name&&(_=!0,B=function(){return L.call(this)}),s&&!v||w[g]===B||l(w,g,B),p[t]=B,f)if(V={values:x("values"),keys:b?B:x("keys"),entries:x("entries")},v)for(y in V)(h||_||!(y in w))&&d(w,y,V[y]);else o({target:t,proto:!0,forced:h||_},V);return V}},function(e,t,n){"use strict";var o=n(5);e.exports=!o((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},function(e,t,n){"use strict";e.exports="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof DataView},function(e,t,n){"use strict";var o=n(11),r=n(106),i=n(21),a=Math.ceil,c=function(e){return function(t,n,c){var l,d,u=String(i(t)),s=u.length,p=c===undefined?" ":String(c),f=o(n);return f<=s||""==p?u:(l=f-s,(d=r.call(p,a(l/p.length))).length>l&&(d=d.slice(0,l)),e?u+d:d+u)}};e.exports={start:c(!1),end:c(!0)}},function(e,t,n){"use strict";var o=n(30),r=n(21);e.exports="".repeat||function(e){var t=String(r(this)),n="",i=o(e);if(i<0||i==Infinity)throw RangeError("Wrong number of repetitions");for(;i>0;(i>>>=1)&&(t+=t))1&i&&(n+=t);return n}},function(e,t,n){"use strict";e.exports=Math.sign||function(e){return 0==(e=+e)||e!=e?e:e<0?-1:1}},function(e,t,n){"use strict";var o,r,i,a=n(6),c=n(5),l=n(32),d=n(47),u=n(135),s=n(89),p=n(154),f=a.location,m=a.setImmediate,h=a.clearImmediate,g=a.process,C=a.MessageChannel,b=a.Dispatch,v=0,N={},V=function(e){if(N.hasOwnProperty(e)){var t=N[e];delete N[e],t()}},y=function(e){return function(){V(e)}},x=function(e){V(e.data)},k=function(e){a.postMessage(e+"",f.protocol+"//"+f.host)};m&&h||(m=function(e){for(var t=[],n=1;arguments.length>n;)t.push(arguments[n++]);return N[++v]=function(){("function"==typeof e?e:Function(e)).apply(undefined,t)},o(v),v},h=function(e){delete N[e]},"process"==l(g)?o=function(e){g.nextTick(y(e))}:b&&b.now?o=function(e){b.now(y(e))}:C&&!p?(i=(r=new C).port2,r.port1.onmessage=x,o=d(i.postMessage,i,1)):!a.addEventListener||"function"!=typeof postMessage||a.importScripts||c(k)||"file:"===f.protocol?o="onreadystatechange"in s("script")?function(e){u.appendChild(s("script")).onreadystatechange=function(){u.removeChild(this),V(e)}}:function(e){setTimeout(y(e),0)}:(o=k,a.addEventListener("message",x,!1))),e.exports={set:m,clear:h}},function(e,t,n){"use strict";var o=n(7),r=n(32),i=n(13)("match");e.exports=function(e){var t;return o(e)&&((t=e[i])!==undefined?!!t:"RegExp"==r(e))}},function(e,t,n){"use strict";var o=n(5);function r(e,t){return RegExp(e,t)}t.UNSUPPORTED_Y=o((function(){var e=r("a","y");return e.lastIndex=2,null!=e.exec("abcd")})),t.BROKEN_CARET=o((function(){var e=r("^r","gy");return e.lastIndex=2,null!=e.exec("str")}))},function(e,t,n){"use strict";var o=n(30),r=n(21),i=function(e){return function(t,n){var i,a,c=String(r(t)),l=o(n),d=c.length;return l<0||l>=d?e?"":undefined:(i=c.charCodeAt(l))<55296||i>56319||l+1===d||(a=c.charCodeAt(l+1))<56320||a>57343?e?c.charAt(l):i:e?c.slice(l,l+2):a-56320+(i-55296<<10)+65536}};e.exports={codeAt:i(!1),charAt:i(!0)}},function(e,t,n){"use strict";var o=n(109);e.exports=function(e){if(o(e))throw TypeError("The method doesn't accept regular expressions");return e}},function(e,t,n){"use strict";var o=n(13)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(n){try{return t[o]=!1,"/./"[e](t)}catch(r){}}return!1}},function(e,t,n){"use strict";var o=n(111).charAt;e.exports=function(e,t,n){return t+(n?o(e,t).length:1)}},function(e,t,n){"use strict";var o=n(5),r=n(80);e.exports=function(e){return o((function(){return!!r[e]()||"\u200b\x85\u180e"!="\u200b\x85\u180e"[e]()||r[e].name!==e}))}},function(e,t,n){"use strict";var o=n(6),r=n(5),i=n(74),a=n(10).NATIVE_ARRAY_BUFFER_VIEWS,c=o.ArrayBuffer,l=o.Int8Array;e.exports=!a||!r((function(){l(1)}))||!r((function(){new l(-1)}))||!i((function(e){new l,new l(null),new l(1.5),new l(e)}),!0)||r((function(){return 1!==new l(new c(2),1,undefined).length}))},function(e,t,n){"use strict";function o(e){var t=0;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(e=function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e)))return function(){return t>=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(t=e[Symbol.iterator]()).next.bind(t)}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n1?r-1:0),c=1;c1?o-1:0),i=1;i=48&&o<=90?String.fromCharCode(o):"["+o+"]"},d=function(e){var t=window.event?e.which:e.keyCode,n=e.ctrlKey,o=e.altKey,r=e.shiftKey;return{keyCode:t,ctrlKey:n,altKey:o,shiftKey:r,hasModifierKeys:n||o||r,keyString:l(n,o,r,t)}},u=function(){for(var e=0,t=Object.keys(c);e=0||(r[n]=e[n]);return r}var m=(0,l.createLogger)("Button"),h=function(e){var t=e.className,n=e.fluid,l=e.icon,p=e.color,h=e.disabled,g=e.selected,C=e.tooltip,b=e.tooltipPosition,v=e.ellipsis,N=e.content,V=e.iconRotation,y=e.iconSpin,x=e.children,k=e.onclick,_=e.onClick,w=f(e,["className","fluid","icon","color","disabled","selected","tooltip","tooltipPosition","ellipsis","content","iconRotation","iconSpin","children","onclick","onClick"]),L=!(!N&&!x);return k&&m.warn("Lowercase 'onclick' is not supported on Button and lowercase prop names are discouraged in general. Please use a camelCase'onClick' instead and read: https://infernojs.org/docs/guides/event-handling"),(0,o.normalizeProps)((0,o.createComponentVNode)(2,d.Box,Object.assign({className:(0,r.classes)(["Button",n&&"Button--fluid",h&&"Button--disabled",g&&"Button--selected",L&&"Button--hasContent",v&&"Button--ellipsis",p&&"string"==typeof p?"Button--color--"+p:"Button--color--default",t]),tabIndex:!h&&"0",unselectable:i.IS_IE8,onclick:function(e){(0,c.refocusLayout)(),!h&&_&&_(e)},onKeyDown:function(e){var t=window.event?e.which:e.keyCode;return t===a.KEY_SPACE||t===a.KEY_ENTER?(e.preventDefault(),void(!h&&_&&_(e))):t===a.KEY_ESCAPE?(e.preventDefault(),void(0,c.refocusLayout)()):void 0}},w,{children:[l&&(0,o.createComponentVNode)(2,u.Icon,{name:l,rotation:V,spin:y}),N,x,C&&(0,o.createComponentVNode)(2,s.Tooltip,{content:C,position:b})]})))};t.Button=h,h.defaultHooks=r.pureComponentHooks;var g=function(e){var t=e.checked,n=f(e,["checked"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,h,Object.assign({color:"transparent",icon:t?"check-square-o":"square-o",selected:t},n)))};t.ButtonCheckbox=g,h.Checkbox=g;var C=function(e){function t(){var t;return(t=e.call(this)||this).state={clickedOnce:!1},t.handleClick=function(){t.state.clickedOnce&&t.setClickedOnce(!1)},t}p(t,e);var n=t.prototype;return n.setClickedOnce=function(e){var t=this;this.setState({clickedOnce:e}),e?setTimeout((function(){return window.addEventListener("click",t.handleClick)})):window.removeEventListener("click",this.handleClick)},n.render=function(){var e=this,t=this.props,n=t.confirmContent,r=void 0===n?"Confirm?":n,i=t.confirmColor,a=void 0===i?"bad":i,c=t.confirmIcon,l=t.icon,d=t.color,u=t.content,s=t.onClick,p=f(t,["confirmContent","confirmColor","confirmIcon","icon","color","content","onClick"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,h,Object.assign({content:this.state.clickedOnce?r:u,icon:this.state.clickedOnce?c:l,color:this.state.clickedOnce?a:d,onClick:function(){return e.state.clickedOnce?s():e.setClickedOnce(!0)}},p)))},t}(o.Component);t.ButtonConfirm=C,h.Confirm=C;var b=function(e){function t(){var t;return(t=e.call(this)||this).inputRef=(0,o.createRef)(),t.state={inInput:!1},t}p(t,e);var n=t.prototype;return n.setInInput=function(e){if(this.setState({inInput:e}),this.inputRef){var t=this.inputRef.current;if(e){t.value=this.props.currentValue||"";try{t.focus(),t.select()}catch(n){}}}},n.commitResult=function(e){if(this.inputRef){var t=this.inputRef.current;if(""!==t.value)return void this.props.onCommit(e,t.value);if(!this.props.defaultValue)return;this.props.onCommit(e,this.props.defaultValue)}},n.render=function(){var e=this,t=this.props,n=t.fluid,i=t.content,c=t.icon,l=t.iconRotation,p=t.iconSpin,m=t.tooltip,h=t.tooltipPosition,g=t.color,C=void 0===g?"default":g,b=(t.placeholder,t.maxLength,f(t,["fluid","content","icon","iconRotation","iconSpin","tooltip","tooltipPosition","color","placeholder","maxLength"]));return(0,o.normalizeProps)((0,o.createComponentVNode)(2,d.Box,Object.assign({className:(0,r.classes)(["Button",n&&"Button--fluid","Button--color--"+C])},b,{onClick:function(){return e.setInInput(!0)},children:[c&&(0,o.createComponentVNode)(2,u.Icon,{name:c,rotation:l,spin:p}),(0,o.createVNode)(1,"div",null,i,0),(0,o.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:this.state.inInput?undefined:"none","text-align":"left"},onBlur:function(t){e.state.inInput&&(e.setInInput(!1),e.commitResult(t))},onKeyDown:function(t){if(t.keyCode===a.KEY_ENTER)return e.setInInput(!1),void e.commitResult(t);t.keyCode===a.KEY_ESCAPE&&e.setInInput(!1)}},null,this.inputRef),m&&(0,o.createComponentVNode)(2,s.Tooltip,{content:m,position:h})]})))},t}(o.Component);t.ButtonInput=b,h.Input=b},function(e,t,n){"use strict";t.__esModule=!0,t.Icon=void 0;var o=n(1),r=n(12),i=n(16);var a=/-o$/,c=function(e){var t=e.name,n=e.size,c=e.spin,l=e.className,d=e.style,u=void 0===d?{}:d,s=e.rotation,p=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["name","size","spin","className","style","rotation"]);n&&(u["font-size"]=100*n+"%"),"number"==typeof s&&(u.transform="rotate("+s+"deg)");var f=a.test(t),m=t.replace(a,"");return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({as:"i",className:(0,r.classes)([l,f?"far":"fas","fa-"+m,c&&"fa-spin"]),style:u},p)))};t.Icon=c,c.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.NumberInput=void 0;var o=n(1),r=n(20),i=n(12),a=n(24),c=n(120),l=n(16);var d=function(e){var t,n;function d(t){var n;n=e.call(this,t)||this;var i=t.value;return n.inputRef=(0,o.createRef)(),n.state={value:i,dragging:!1,editing:!1,internalValue:null,origin:null,suppressingFlicker:!1},n.flickerTimer=null,n.suppressFlicker=function(){var e=n.props.suppressFlicker;e>0&&(n.setState({suppressingFlicker:!0}),clearTimeout(n.flickerTimer),n.flickerTimer=setTimeout((function(){return n.setState({suppressingFlicker:!1})}),e))},n.handleDragStart=function(e){var t=n.props.value;n.state.editing||(document.body.style["pointer-events"]="none",n.ref=e.target,n.setState({dragging:!1,origin:e.screenY,value:t,internalValue:t}),n.timer=setTimeout((function(){n.setState({dragging:!0})}),250),n.dragInterval=setInterval((function(){var t=n.state,o=t.dragging,r=t.value,i=n.props.onDrag;o&&i&&i(e,r)}),500),document.addEventListener("mousemove",n.handleDragMove),document.addEventListener("mouseup",n.handleDragEnd))},n.handleDragMove=function(e){var t=n.props,o=t.minValue,i=t.maxValue,a=t.step,c=t.stepPixelSize;n.setState((function(t){var n=Object.assign({},t),l=n.origin-e.screenY;if(t.dragging){var d=Number.isFinite(o)?o%a:0;n.internalValue=(0,r.clamp)(n.internalValue+l*a/c,o-a,i+a),n.value=(0,r.clamp)(n.internalValue-n.internalValue%a+d,o,i),n.origin=e.screenY}else Math.abs(l)>4&&(n.dragging=!0);return n}))},n.handleDragEnd=function(e){var t=n.props,o=t.onChange,r=t.onDrag,i=n.state,a=i.dragging,c=i.value,l=i.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(n.timer),clearInterval(n.dragInterval),n.setState({dragging:!1,editing:!a,origin:null}),document.removeEventListener("mousemove",n.handleDragMove),document.removeEventListener("mouseup",n.handleDragEnd),a)n.suppressFlicker(),o&&o(e,c),r&&r(e,c);else if(n.inputRef){var d=n.inputRef.current;d.value=l;try{d.focus(),d.select()}catch(u){}}},n}return n=e,(t=d).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,d.prototype.render=function(){var e=this,t=this.state,n=t.dragging,d=t.editing,u=t.value,s=t.suppressingFlicker,p=this.props,f=p.className,m=p.fluid,h=p.animated,g=p.value,C=p.unit,b=p.minValue,v=p.maxValue,N=p.height,V=p.width,y=p.lineHeight,x=p.fontSize,k=p.format,_=p.onChange,w=p.onDrag,L=g;(n||s)&&(L=u);var B=function(e){return(0,o.createVNode)(1,"div","NumberInput__content",e+(C?" "+C:""),0,{unselectable:a.IS_IE8})},S=h&&!n&&!s&&(0,o.createComponentVNode)(2,c.AnimatedNumber,{value:L,format:k,children:B})||B(k?k(L):L);return(0,o.createComponentVNode)(2,l.Box,{className:(0,i.classes)(["NumberInput",m&&"NumberInput--fluid",f]),minWidth:V,minHeight:N,lineHeight:y,fontSize:x,onMouseDown:this.handleDragStart,children:[(0,o.createVNode)(1,"div","NumberInput__barContainer",(0,o.createVNode)(1,"div","NumberInput__bar",null,1,{style:{height:(0,r.clamp)((L-b)/(v-b)*100,0,100)+"%"}}),2),S,(0,o.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:d?undefined:"none",height:N,"line-height":y,"font-size":x},onBlur:function(t){if(d){var n=(0,r.clamp)(t.target.value,b,v);e.setState({editing:!1,value:n}),e.suppressFlicker(),_&&_(t,n),w&&w(t,n)}},onKeyDown:function(t){if(13===t.keyCode){var n=(0,r.clamp)(t.target.value,b,v);return e.setState({editing:!1,value:n}),e.suppressFlicker(),_&&_(t,n),void(w&&w(t,n))}27!==t.keyCode||e.setState({editing:!1})}},null,this.inputRef)]})},d}(o.Component);t.NumberInput=d,d.defaultHooks=i.pureComponentHooks,d.defaultProps={minValue:-Infinity,maxValue:+Infinity,step:1,stepPixelSize:1,suppressFlicker:50}},function(e,t,n){"use strict";t.__esModule=!0,t.LabeledListDivider=t.LabeledListItem=t.LabeledList=void 0;var o=n(1),r=n(12),i=n(16),a=n(167),c=function(e){var t=e.children;return(0,o.createVNode)(1,"table","LabeledList",t,0)};t.LabeledList=c,c.defaultHooks=r.pureComponentHooks;var l=function(e){var t=e.className,n=e.label,a=e.labelColor,c=void 0===a?"label":a,l=e.color,d=e.textAlign,u=e.verticalAlign,s=e.buttons,p=e.content,f=e.children;return(0,o.createVNode)(1,"tr",(0,r.classes)(["LabeledList__row",t]),[(0,o.createComponentVNode)(2,i.Box,{as:"td",color:c,verticalAlign:u,className:(0,r.classes)(["LabeledList__cell","LabeledList__label"]),children:n?n+":":null}),(0,o.createComponentVNode)(2,i.Box,{as:"td",color:l,textAlign:d,verticalAlign:u,className:(0,r.classes)(["LabeledList__cell","LabeledList__content"]),colSpan:s?undefined:2,children:[p,f]}),s&&(0,o.createVNode)(1,"td","LabeledList__cell LabeledList__buttons",s,0)],0)};t.LabeledListItem=l,l.defaultHooks=r.pureComponentHooks;var d=function(e){var t=e.size?(0,i.unit)(Math.max(0,e.size-1)):0;return(0,o.createVNode)(1,"tr","LabeledList__row",(0,o.createVNode)(1,"td",null,(0,o.createComponentVNode)(2,a.Divider),2,{colSpan:3,style:{"padding-top":t,"padding-bottom":t}}),2)};t.LabeledListDivider=d,d.defaultHooks=r.pureComponentHooks,c.Item=l,c.Divider=d},function(e,t,n){"use strict";t.__esModule=!0,t.BeakerContents=void 0;var o=n(1),r=n(3),i=n(444),a=function(e){var t=e.beakerLoaded,n=e.beakerContents,i=void 0===n?[]:n,a=e.buttons;return(0,o.createComponentVNode)(2,r.Box,{children:[!t&&(0,o.createComponentVNode)(2,r.Box,{color:"label",children:"No beaker loaded."})||0===i.length&&(0,o.createComponentVNode)(2,r.Box,{color:"label",children:"Beaker is empty."}),i.map((function(e,t){return(0,o.createComponentVNode)(2,r.Box,{width:"100%",children:[(0,o.createComponentVNode)(2,r.Box,{color:"label",display:"inline",verticalAlign:"middle",children:[(n=e.volume,n+" unit"+(1===n?"":"s"))," of ",e.name]}),!!a&&(0,o.createComponentVNode)(2,r.Box,{float:"right",display:"inline",children:a(e,t)}),(0,o.createComponentVNode)(2,r.Box,{clear:"both"})]},e.name);var n}))]})};t.BeakerContents=a,a.propTypes={beakerLoaded:i.bool,beakerContents:i.array,buttons:i.arrayOf(i.element)}},function(e,t,n){"use strict";var o;o=function(){return this}();try{o=o||new Function("return this")()}catch(r){"object"==typeof window&&(o=window)}e.exports=o},function(e,t,n){"use strict";var o=n(8),r=n(5),i=n(89);e.exports=!o&&!r((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(e,t,n){"use strict";var o=n(6),r=n(90),i=o["__core-js_shared__"]||r("__core-js_shared__",{});e.exports=i},function(e,t,n){"use strict";var o=n(6),r=n(91),i=o.WeakMap;e.exports="function"==typeof i&&/native code/.test(r(i))},function(e,t,n){"use strict";var o=n(17),r=n(93),i=n(19),a=n(14);e.exports=function(e,t){for(var n=r(t),c=a.f,l=i.f,d=0;dl;)o(c,n=t[l++])&&(~i(d,n)||d.push(n));return d}},function(e,t,n){"use strict";var o=n(96);e.exports=o&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(e,t,n){"use strict";var o=n(8),r=n(14),i=n(9),a=n(63);e.exports=o?Object.defineProperties:function(e,t){i(e);for(var n,o=a(t),c=o.length,l=0;c>l;)r.f(e,n=o[l++],t[n]);return e}},function(e,t,n){"use strict";var o=n(36);e.exports=o("document","documentElement")},function(e,t,n){"use strict";var o=n(25),r=n(46).f,i={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return a&&"[object Window]"==i.call(e)?function(e){try{return r(e)}catch(t){return a.slice()}}(e):r(o(e))}},function(e,t,n){"use strict";var o=n(13);t.f=o},function(e,t,n){"use strict";var o=n(15),r=n(40),i=n(11),a=Math.min;e.exports=[].copyWithin||function(e,t){var n=o(this),c=i(n.length),l=r(e,c),d=r(t,c),u=arguments.length>2?arguments[2]:undefined,s=a((u===undefined?c:r(u,c))-d,c-l),p=1;for(d0;)d in n?n[l]=n[d]:delete n[l],l+=p,d+=p;return n}},function(e,t,n){"use strict";var o=n(51),r=n(11),i=n(47);e.exports=function a(e,t,n,c,l,d,u,s){for(var p,f=l,m=0,h=!!u&&i(u,s,3);m0&&o(p))f=a(e,t,p,r(p.length),f,d-1)-1;else{if(f>=9007199254740991)throw TypeError("Exceed the acceptable array length");e[f]=p}f++}m++}return f}},function(e,t,n){"use strict";var o=n(9);e.exports=function(e,t,n,r){try{return r?t(o(n)[0],n[1]):t(n)}catch(a){var i=e["return"];throw i!==undefined&&o(i.call(e)),a}}},function(e,t,n){"use strict";var o=n(25),r=n(43),i=n(66),a=n(34),c=n(102),l=a.set,d=a.getterFor("Array Iterator");e.exports=c(Array,"Array",(function(e,t){l(this,{type:"Array Iterator",target:o(e),index:0,kind:t})}),(function(){var e=d(this),t=e.target,n=e.kind,o=e.index++;return!t||o>=t.length?(e.target=undefined,{value:undefined,done:!0}):"keys"==n?{value:o,done:!1}:"values"==n?{value:t[o],done:!1}:{value:[o,t[o]],done:!1}}),"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},function(e,t,n){"use strict";var o,r,i,a=n(35),c=n(29),l=n(17),d=n(13),u=n(37),s=d("iterator"),p=!1;[].keys&&("next"in(i=[].keys())?(r=a(a(i)))!==Object.prototype&&(o=r):p=!0),o==undefined&&(o={}),u||l(o,s)||c(o,s,(function(){return this})),e.exports={IteratorPrototype:o,BUGGY_SAFARI_ITERATORS:p}},function(e,t,n){"use strict";var o=n(7);e.exports=function(e){if(!o(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},function(e,t,n){"use strict";var o=n(25),r=n(30),i=n(11),a=n(38),c=n(23),l=Math.min,d=[].lastIndexOf,u=!!d&&1/[1].lastIndexOf(1,-0)<0,s=a("lastIndexOf"),p=c("indexOf",{ACCESSORS:!0,1:0}),f=u||!s||!p;e.exports=f?function(e){if(u)return d.apply(this,arguments)||0;var t=o(this),n=i(t.length),a=n-1;for(arguments.length>1&&(a=l(a,r(arguments[1]))),a<0&&(a=n+a);a>=0;a--)if(a in t&&t[a]===e)return a||0;return-1}:d},function(e,t,n){"use strict";var o=n(30),r=n(11);e.exports=function(e){if(e===undefined)return 0;var t=o(e),n=r(t);if(t!==n)throw RangeError("Wrong length or index");return n}},function(e,t,n){"use strict";var o=n(31),r=n(7),i=[].slice,a={},c=function(e,t,n){if(!(t in a)){for(var o=[],r=0;r1?arguments[1]:undefined,3);t=t?t.next:n.first;)for(o(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(e){return!!C(this,e)}}),i(u.prototype,n?{get:function(e){var t=C(this,e);return t&&t.value},set:function(e,t){return g(this,0===e?0:e,t)}}:{add:function(e){return g(this,e=0===e?0:e,e)}}),s&&o(u.prototype,"size",{get:function(){return f(this).size}}),u},setStrong:function(e,t,n){var o=t+" Iterator",r=h(t),i=h(o);d(e,t,(function(e,t){m(this,{type:o,target:e,state:r(e),kind:t,last:undefined})}),(function(){for(var e=i(this),t=e.kind,n=e.last;n&&n.removed;)n=n.previous;return e.target&&(e.last=n=n?n.next:e.state.first)?"keys"==t?{value:n.key,done:!1}:"values"==t?{value:n.value,done:!1}:{value:[n.key,n.value],done:!1}:(e.target=undefined,{value:undefined,done:!0})}),n?"entries":"values",!n,!0),u(t)}}},function(e,t,n){"use strict";var o=Math.log;e.exports=Math.log1p||function(e){return(e=+e)>-1e-8&&e<1e-8?e-e*e/2:o(1+e)}},function(e,t,n){"use strict";var o=n(7),r=Math.floor;e.exports=function(e){return!o(e)&&isFinite(e)&&r(e)===e}},function(e,t,n){"use strict";var o=n(6),r=n(54).trim,i=n(80),a=o.parseInt,c=/^[+-]?0[Xx]/,l=8!==a(i+"08")||22!==a(i+"0x16");e.exports=l?function(e,t){var n=r(String(e));return a(n,t>>>0||(c.test(n)?16:10))}:a},function(e,t,n){"use strict";var o=n(8),r=n(63),i=n(25),a=n(70).f,c=function(e){return function(t){for(var n,c=i(t),l=r(c),d=l.length,u=0,s=[];d>u;)n=l[u++],o&&!a.call(c,n)||s.push(e?[n,c[n]]:c[n]);return s}};e.exports={entries:c(!0),values:c(!1)}},function(e,t,n){"use strict";e.exports=Object.is||function(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t}},function(e,t,n){"use strict";var o=n(6);e.exports=o.Promise},function(e,t,n){"use strict";var o=n(72);e.exports=/(iphone|ipod|ipad).*applewebkit/i.test(o)},function(e,t,n){"use strict";var o,r,i,a,c,l,d,u,s=n(6),p=n(19).f,f=n(32),m=n(108).set,h=n(154),g=s.MutationObserver||s.WebKitMutationObserver,C=s.process,b=s.Promise,v="process"==f(C),N=p(s,"queueMicrotask"),V=N&&N.value;V||(o=function(){var e,t;for(v&&(e=C.domain)&&e.exit();r;){t=r.fn,r=r.next;try{t()}catch(n){throw r?a():i=undefined,n}}i=undefined,e&&e.enter()},v?a=function(){C.nextTick(o)}:g&&!h?(c=!0,l=document.createTextNode(""),new g(o).observe(l,{characterData:!0}),a=function(){l.data=c=!c}):b&&b.resolve?(d=b.resolve(undefined),u=d.then,a=function(){u.call(d,o)}):a=function(){m.call(s,o)}),e.exports=V||function(e){var t={fn:e,next:undefined};i&&(i.next=t),r||(r=t,a()),i=t}},function(e,t,n){"use strict";var o=n(9),r=n(7),i=n(157);e.exports=function(e,t){if(o(e),r(t)&&t.constructor===e)return t;var n=i.f(e);return(0,n.resolve)(t),n.promise}},function(e,t,n){"use strict";var o=n(31),r=function(e){var t,n;this.promise=new e((function(e,o){if(t!==undefined||n!==undefined)throw TypeError("Bad Promise constructor");t=e,n=o})),this.resolve=o(t),this.reject=o(n)};e.exports.f=function(e){return new r(e)}},function(e,t,n){"use strict";var o=n(0),r=n(83);o({target:"RegExp",proto:!0,forced:/./.exec!==r},{exec:r})},function(e,t,n){"use strict";var o=n(72);e.exports=/Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(o)},function(e,t,n){"use strict";var o=n(351);e.exports=function(e,t){var n=o(e);if(n%t)throw RangeError("Wrong offset");return n}},function(e,t,n){"use strict";var o=n(15),r=n(11),i=n(100),a=n(99),c=n(47),l=n(10).aTypedArrayConstructor;e.exports=function(e){var t,n,d,u,s,p,f=o(e),m=arguments.length,h=m>1?arguments[1]:undefined,g=h!==undefined,C=i(f);if(C!=undefined&&!a(C))for(p=(s=C.call(f)).next,f=[];!(u=p.call(s)).done;)f.push(u.value);for(g&&m>2&&(h=c(h,arguments[2],2)),n=r(f.length),d=new(l(this))(n),t=0;n>t;t++)d[t]=g?h(f[t],t):f[t];return d}},function(e,t,n){"use strict";var o=n(67),r=n(50).getWeakData,i=n(9),a=n(7),c=n(53),l=n(69),d=n(18),u=n(17),s=n(34),p=s.set,f=s.getterFor,m=d.find,h=d.findIndex,g=0,C=function(e){return e.frozen||(e.frozen=new b)},b=function(){this.entries=[]},v=function(e,t){return m(e.entries,(function(e){return e[0]===t}))};b.prototype={get:function(e){var t=v(this,e);if(t)return t[1]},has:function(e){return!!v(this,e)},set:function(e,t){var n=v(this,e);n?n[1]=t:this.entries.push([e,t])},"delete":function(e){var t=h(this.entries,(function(t){return t[0]===e}));return~t&&this.entries.splice(t,1),!!~t}},e.exports={getConstructor:function(e,t,n,d){var s=e((function(e,o){c(e,s,t),p(e,{type:t,id:g++,frozen:undefined}),o!=undefined&&l(o,e[d],e,n)})),m=f(t),h=function(e,t,n){var o=m(e),a=r(i(t),!0);return!0===a?C(o).set(t,n):a[o.id]=n,e};return o(s.prototype,{"delete":function(e){var t=m(this);if(!a(e))return!1;var n=r(e);return!0===n?C(t)["delete"](e):n&&u(n,t.id)&&delete n[t.id]},has:function(e){var t=m(this);if(!a(e))return!1;var n=r(e);return!0===n?C(t).has(e):n&&u(n,t.id)}}),o(s.prototype,n?{get:function(e){var t=m(this);if(a(e)){var n=r(e);return!0===n?C(t).get(e):n?n[t.id]:undefined}},set:function(e,t){return h(this,e,t)}}:{add:function(e){return h(this,e,!0)}}),s}}},function(e,t,n){"use strict";t.__esModule=!0,t.setupHotReloading=t.sendLogEntry=void 0;t.sendLogEntry=function(e,t){};t.setupHotReloading=function(){0}},function(e,t,n){"use strict";t.__esModule=!0,t.resizeStartHandler=t.dragStartHandler=t.setupDrag=void 0;var o=n(393),r=n(24);function i(e,t,n,o,r,i,a){try{var c=e[i](a),l=c.value}catch(d){return void n(d)}c.done?t(l):Promise.resolve(l).then(o,r)}var a,c,l,d,u,s=(0,n(57).createLogger)("drag"),p=!1,f=!1,m=[0,0],h=function(e){return(0,r.winget)(e,"pos").then((function(e){return[e.x,e.y]}))},g=function(e,t){return(0,r.winset)(e,"pos",t[0]+","+t[1])},C=function(){var e,t=(e=regeneratorRuntime.mark((function n(e){var t,o,r,i;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return s.log("setting up"),a=e.config.window,n.next=4,h(a);case 4:t=n.sent,m=[t[0]-window.screenLeft,t[1]-window.screenTop],o=b(t),r=o[0],i=o[1],r&&g(a,i),s.debug("current state",{ref:a,screenOffset:m});case 9:case"end":return n.stop()}}),n)})),function(){var t=this,n=arguments;return new Promise((function(o,r){var a=e.apply(t,n);function c(e){i(a,o,r,c,l,"next",e)}function l(e){i(a,o,r,c,l,"throw",e)}c(undefined)}))});return function(e){return t.apply(this,arguments)}}();t.setupDrag=C;var b=function(e){var t=e[0],n=e[1],o=!1;return t<0?(t=0,o=!0):t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth,o=!0),n<0?(n=0,o=!0):n+window.innerHeight>window.screen.availHeight&&(n=window.screen.availHeight-window.innerHeight,o=!0),[o,[t,n]]};t.dragStartHandler=function(e){s.log("drag start"),p=!0,c=[window.screenLeft-e.screenX,window.screenTop-e.screenY],document.addEventListener("mousemove",N),document.addEventListener("mouseup",v),N(e)};var v=function x(e){s.log("drag end"),N(e),document.removeEventListener("mousemove",N),document.removeEventListener("mouseup",x),p=!1},N=function(e){p&&(e.preventDefault(),g(a,(0,o.vecAdd)([e.screenX,e.screenY],m,c)))};t.resizeStartHandler=function(e,t){return function(n){l=[e,t],s.log("resize start",l),f=!0,c=[window.screenLeft-n.screenX,window.screenTop-n.screenY],d=[window.innerWidth,window.innerHeight],document.addEventListener("mousemove",y),document.addEventListener("mouseup",V),y(n)}};var V=function k(e){s.log("resize end",u),y(e),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",k),f=!1},y=function(e){f&&(e.preventDefault(),(u=(0,o.vecAdd)(d,(0,o.vecMultiply)(l,(0,o.vecAdd)([e.screenX,e.screenY],(0,o.vecInverse)([window.screenLeft,window.screenTop]),c,[1,1]))))[0]=Math.max(u[0],250),u[1]=Math.max(u[1],120),function(e,t){(0,r.winset)(e,"size",t[0]+","+t[1])}(a,u))}},function(e,t,n){"use strict";t.__esModule=!0,t.Tooltip=void 0;var o=n(1),r=n(12);t.Tooltip=function(e){var t=e.content,n=e.position,i=void 0===n?"bottom":n,a="string"==typeof t&&t.length>35;return(0,o.createVNode)(1,"div",(0,r.classes)(["Tooltip",a&&"Tooltip--long",i&&"Tooltip--"+i]),null,1,{"data-tooltip":t})}},function(e,t,n){"use strict";t.__esModule=!0,t.Dimmer=void 0;var o=n(1),r=n(12),i=n(16);t.Dimmer=function(e){var t=e.className,n=e.children,a=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","children"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["Dimmer"].concat(t))},a,{children:(0,o.createVNode)(1,"div","Dimmer__inner",n,0)})))}},function(e,t,n){"use strict";t.__esModule=!0,t.Divider=void 0;var o=n(1),r=n(12);t.Divider=function(e){var t=e.vertical,n=e.hidden;return(0,o.createVNode)(1,"div",(0,r.classes)(["Divider",n&&"Divider--hidden",t?"Divider--vertical":"Divider--horizontal"]))}},function(e,t,n){"use strict";t.__esModule=!0,t.FlexItem=t.computeFlexItemProps=t.Flex=t.computeFlexProps=void 0;var o=n(1),r=n(12),i=n(24),a=n(16);function c(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var l=function(e){var t=e.className,n=e.direction,o=e.wrap,a=e.align,l=e.alignContent,d=e.justify,u=e.inline,s=e.spacing,p=void 0===s?0:s,f=e.spacingPrecise,m=void 0===f?0:f,h=c(e,["className","direction","wrap","align","alignContent","justify","inline","spacing","spacingPrecise"]);return Object.assign({className:(0,r.classes)(["Flex",i.IS_IE8&&("column"===n?"Flex--ie8--column":"Flex--ie8"),u&&"Flex--inline",p>0&&"Flex--spacing--"+p,m>0&&"Flex--spacingPrecise--"+m,t]),style:Object.assign({},h.style,{"flex-direction":n,"flex-wrap":o,"align-items":a,"align-content":l,"justify-content":d})},h)};t.computeFlexProps=l;var d=function(e){return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Box,Object.assign({},l(e))))};t.Flex=d,d.defaultHooks=r.pureComponentHooks;var u=function(e){var t=e.className,n=e.grow,o=e.order,l=e.shrink,d=e.basis,u=void 0===d?e.width:d,s=e.align,p=c(e,["className","grow","order","shrink","basis","align"]);return Object.assign({className:(0,r.classes)(["Flex__item",i.IS_IE8&&"Flex__item--ie8",t]),style:Object.assign({},p.style,{"flex-grow":n,"flex-shrink":l,"flex-basis":(0,a.unit)(u),order:o,"align-self":s})},p)};t.computeFlexItemProps=u;var s=function(e){return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Box,Object.assign({},u(e))))};t.FlexItem=s,s.defaultHooks=r.pureComponentHooks,d.Item=s},function(e,t,n){"use strict";t.__esModule=!0,t.GridColumn=t.Grid=void 0;var o=n(1),r=n(86),i=n(12);function a(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var c=function(e){var t=e.children,n=a(e,["children"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Table,Object.assign({},n,{children:(0,o.createComponentVNode)(2,r.Table.Row,{children:t})})))};t.Grid=c,c.defaultHooks=i.pureComponentHooks;var l=function(e){var t=e.size,n=void 0===t?1:t,i=e.style,c=a(e,["size","style"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Table.Cell,Object.assign({style:Object.assign({width:n+"%"},i)},c)))};t.GridColumn=l,c.defaultHooks=i.pureComponentHooks,c.Column=l},function(e,t,n){"use strict";t.__esModule=!0,t.DraggableControl=void 0;var o=n(1),r=n(20),i=n(12),a=n(120);var c=function(e,t){return e.screenX*t[0]+e.screenY*t[1]},l=function(e){var t,n;function i(t){var n;return(n=e.call(this,t)||this).inputRef=(0,o.createRef)(),n.state={value:t.value,dragging:!1,editing:!1,internalValue:null,origin:null,suppressingFlicker:!1},n.flickerTimer=null,n.suppressFlicker=function(){var e=n.props.suppressFlicker;e>0&&(n.setState({suppressingFlicker:!0}),clearTimeout(n.flickerTimer),n.flickerTimer=setTimeout((function(){return n.setState({suppressingFlicker:!1})}),e))},n.handleDragStart=function(e){var t=n.props,o=t.value,r=t.dragMatrix;n.state.editing||(document.body.style["pointer-events"]="none",n.ref=e.target,n.setState({dragging:!1,origin:c(e,r),value:o,internalValue:o}),n.timer=setTimeout((function(){n.setState({dragging:!0})}),250),n.dragInterval=setInterval((function(){var t=n.state,o=t.dragging,r=t.value,i=n.props.onDrag;o&&i&&i(e,r)}),500),document.addEventListener("mousemove",n.handleDragMove),document.addEventListener("mouseup",n.handleDragEnd))},n.handleDragMove=function(e){var t=n.props,o=t.minValue,i=t.maxValue,a=t.step,l=t.stepPixelSize,d=t.dragMatrix;n.setState((function(t){var n=Object.assign({},t),u=c(e,d)-n.origin;if(t.dragging){var s=Number.isFinite(o)?o%a:0;n.internalValue=(0,r.clamp)(n.internalValue+u*a/l,o-a,i+a),n.value=(0,r.clamp)(n.internalValue-n.internalValue%a+s,o,i),n.origin=c(e,d)}else Math.abs(u)>4&&(n.dragging=!0);return n}))},n.handleDragEnd=function(e){var t=n.props,o=t.onChange,r=t.onDrag,i=n.state,a=i.dragging,c=i.value,l=i.internalValue;if(document.body.style["pointer-events"]="auto",clearTimeout(n.timer),clearInterval(n.dragInterval),n.setState({dragging:!1,editing:!a,origin:null}),document.removeEventListener("mousemove",n.handleDragMove),document.removeEventListener("mouseup",n.handleDragEnd),a)n.suppressFlicker(),o&&o(e,c),r&&r(e,c);else if(n.inputRef){var d=n.inputRef.current;d.value=l;try{d.focus(),d.select()}catch(u){}}},n}return n=e,(t=i).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,i.prototype.render=function(){var e=this,t=this.state,n=t.dragging,i=t.editing,c=t.value,l=t.suppressingFlicker,d=this.props,u=d.animated,s=d.value,p=d.unit,f=d.minValue,m=d.maxValue,h=d.format,g=d.onChange,C=d.onDrag,b=d.children,v=d.height,N=d.lineHeight,V=d.fontSize,y=s;(n||l)&&(y=c);var x=function(e){return e+(p?" "+p:"")},k=u&&!n&&!l&&(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:y,format:h,children:x})||x(h?h(y):y),_=(0,o.createVNode)(64,"input","NumberInput__input",null,1,{style:{display:i?undefined:"none",height:v,"line-height":N,"font-size":V},onBlur:function(t){if(i){var n=(0,r.clamp)(t.target.value,f,m);e.setState({editing:!1,value:n}),e.suppressFlicker(),g&&g(t,n),C&&C(t,n)}},onKeyDown:function(t){if(13===t.keyCode){var n=(0,r.clamp)(t.target.value,f,m);return e.setState({editing:!1,value:n}),e.suppressFlicker(),g&&g(t,n),void(C&&C(t,n))}27!==t.keyCode||e.setState({editing:!1})}},null,this.inputRef);return b({dragging:n,editing:i,value:s,displayValue:y,displayElement:k,inputElement:_,handleDragStart:this.handleDragStart})},i}(o.Component);t.DraggableControl=l,l.defaultHooks=i.pureComponentHooks,l.defaultProps={minValue:-Infinity,maxValue:+Infinity,step:1,stepPixelSize:1,suppressFlicker:50,dragMatrix:[1,0]}},function(e,t,n){"use strict";t.__esModule=!0,t.Slider=void 0;var o=n(1),r=n(20),i=n(12),a=n(24),c=n(16),l=n(170),d=n(123);t.Slider=function(e){if(a.IS_IE8)return(0,o.normalizeProps)((0,o.createComponentVNode)(2,d.NumberInput,Object.assign({},e)));var t=e.animated,n=e.format,u=e.maxValue,s=e.minValue,p=e.onChange,f=e.onDrag,m=e.step,h=e.stepPixelSize,g=e.suppressFlicker,C=e.unit,b=e.value,v=e.className,N=e.fillValue,V=e.color,y=e.ranges,x=void 0===y?{}:y,k=e.children,_=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","fillValue","color","ranges","children"]),w=k!==undefined;return(0,o.normalizeProps)((0,o.createComponentVNode)(2,l.DraggableControl,Object.assign({dragMatrix:[1,0]},{animated:t,format:n,maxValue:u,minValue:s,onChange:p,onDrag:f,step:m,stepPixelSize:h,suppressFlicker:g,unit:C,value:b},{children:function(e){var t=e.dragging,n=(e.editing,e.value),a=e.displayValue,l=e.displayElement,d=e.inputElement,p=e.handleDragStart,f=N!==undefined&&null!==N,m=((0,r.scale)(n,s,u),(0,r.scale)(null!=N?N:a,s,u)),h=(0,r.scale)(a,s,u),g=V||(0,r.keyOfMatchingRange)(null!=N?N:n,x)||"default";return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,i.classes)(["Slider","ProgressBar","ProgressBar--color--"+g,v,(0,c.computeBoxClassName)(_)]),[(0,o.createVNode)(1,"div",(0,i.classes)(["ProgressBar__fill",f&&"ProgressBar__fill--animated"]),null,1,{style:{width:100*(0,r.clamp01)(m)+"%",opacity:.4}}),(0,o.createVNode)(1,"div","ProgressBar__fill",null,1,{style:{width:100*(0,r.clamp01)(Math.min(m,h))+"%"}}),(0,o.createVNode)(1,"div","Slider__cursorOffset",[(0,o.createVNode)(1,"div","Slider__cursor"),(0,o.createVNode)(1,"div","Slider__pointer"),t&&(0,o.createVNode)(1,"div","Slider__popupValue",l,0)],0,{style:{width:100*(0,r.clamp01)(h)+"%"}}),(0,o.createVNode)(1,"div","ProgressBar__content",w?k:l,0),d],0,Object.assign({},(0,c.computeBoxProps)(_),{onMouseDown:p})))}})))}},function(e,t,n){"use strict";t.__esModule=!0,t.Window=void 0;var o=n(1),r=n(12),i=n(87),a=n(2),c=n(24),l=n(3),d=n(55),u=n(164),s=n(118),p=n(57),f=n(119);var m=(0,p.createLogger)("Window"),h=function(e){var t,n;function l(){return e.apply(this,arguments)||this}n=e,(t=l).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var p=l.prototype;return p.componentDidMount=function(){(0,f.refocusLayout)()},p.render=function(){var e=this.props,t=e.resizable,n=e.theme,l=e.children,p=(0,a.useBackend)(this.context),h=p.config,g=p.debugLayout,b=h.observer?h.statust?2+3*d-c:0;return((0,o.toFixed)(p,f)+" "+s+n).trim()};t.formatSiUnit=a;t.formatPower=function(e,t){return void 0===t&&(t=0),a(e,t,"W")};t.formatMoney=function(e,t){if(void 0===t&&(t=0),!Number.isFinite(e))return e;var n=(0,o.round)(e,t);t>0&&(n=(0,o.toFixed)(e,t));var r=(n=String(n)).length,i=n.indexOf(".");-1===i&&(i=r);for(var a="",c=0;c0&&c=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(t=e[Symbol.iterator]()).next.bind(t)}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ni;)r.push(arguments[i++]);if(o=t,(f(t)||e!==undefined)&&!ie(e))return p(t)||(t=function(e,t){if("function"==typeof o&&(t=o.call(this,e,t)),!ie(t))return t}),r[1]=t,H.apply(null,r)}});K.prototype[R]||L(K.prototype,R,K.prototype.valueOf),P(K,"Symbol"),E[F]=!0},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(6),a=n(17),c=n(7),l=n(14).f,d=n(130),u=i.Symbol;if(r&&"function"==typeof u&&(!("description"in u.prototype)||u().description!==undefined)){var s={},p=function(){var e=arguments.length<1||arguments[0]===undefined?undefined:String(arguments[0]),t=this instanceof p?new u(e):e===undefined?u():u(e);return""===e&&(s[t]=!0),t};d(p,u);var f=p.prototype=u.prototype;f.constructor=p;var m=f.toString,h="Symbol(test)"==String(u("test")),g=/^Symbol\((.*)\)[^)]+$/;l(f,"description",{configurable:!0,get:function(){var e=c(this)?this.valueOf():this,t=m.call(e);if(a(s,e))return"";var n=h?t.slice(7,-1):t.replace(g,"$1");return""===n?undefined:n}}),o({global:!0,forced:!0},{Symbol:p})}},function(e,t,n){"use strict";n(26)("asyncIterator")},function(e,t,n){"use strict";n(26)("hasInstance")},function(e,t,n){"use strict";n(26)("isConcatSpreadable")},function(e,t,n){"use strict";n(26)("iterator")},function(e,t,n){"use strict";n(26)("match")},function(e,t,n){"use strict";n(26)("replace")},function(e,t,n){"use strict";n(26)("search")},function(e,t,n){"use strict";n(26)("species")},function(e,t,n){"use strict";n(26)("split")},function(e,t,n){"use strict";n(26)("toPrimitive")},function(e,t,n){"use strict";n(26)("toStringTag")},function(e,t,n){"use strict";n(26)("unscopables")},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(51),a=n(7),c=n(15),l=n(11),d=n(48),u=n(64),s=n(65),p=n(13),f=n(97),m=p("isConcatSpreadable"),h=f>=51||!r((function(){var e=[];return e[m]=!1,e.concat()[0]!==e})),g=s("concat"),C=function(e){if(!a(e))return!1;var t=e[m];return t!==undefined?!!t:i(e)};o({target:"Array",proto:!0,forced:!h||!g},{concat:function(e){var t,n,o,r,i,a=c(this),s=u(a,0),p=0;for(t=-1,o=arguments.length;t9007199254740991)throw TypeError("Maximum allowed index exceeded");for(n=0;n=9007199254740991)throw TypeError("Maximum allowed index exceeded");d(s,p++,i)}return s.length=p,s}})},function(e,t,n){"use strict";var o=n(0),r=n(138),i=n(43);o({target:"Array",proto:!0},{copyWithin:r}),i("copyWithin")},function(e,t,n){"use strict";var o=n(0),r=n(18).every,i=n(38),a=n(23),c=i("every"),l=a("every");o({target:"Array",proto:!0,forced:!c||!l},{every:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(98),i=n(43);o({target:"Array",proto:!0},{fill:r}),i("fill")},function(e,t,n){"use strict";var o=n(0),r=n(18).filter,i=n(65),a=n(23),c=i("filter"),l=a("filter");o({target:"Array",proto:!0,forced:!c||!l},{filter:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(18).find,i=n(43),a=n(23),c=!0,l=a("find");"find"in[]&&Array(1).find((function(){c=!1})),o({target:"Array",proto:!0,forced:c||!l},{find:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}}),i("find")},function(e,t,n){"use strict";var o=n(0),r=n(18).findIndex,i=n(43),a=n(23),c=!0,l=a("findIndex");"findIndex"in[]&&Array(1).findIndex((function(){c=!1})),o({target:"Array",proto:!0,forced:c||!l},{findIndex:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}}),i("findIndex")},function(e,t,n){"use strict";var o=n(0),r=n(139),i=n(15),a=n(11),c=n(30),l=n(64);o({target:"Array",proto:!0},{flat:function(){var e=arguments.length?arguments[0]:undefined,t=i(this),n=a(t.length),o=l(t,0);return o.length=r(o,t,t,n,0,e===undefined?1:c(e)),o}})},function(e,t,n){"use strict";var o=n(0),r=n(139),i=n(15),a=n(11),c=n(31),l=n(64);o({target:"Array",proto:!0},{flatMap:function(e){var t,n=i(this),o=a(n.length);return c(e),(t=l(n,0)).length=r(t,n,n,o,0,1,e,arguments.length>1?arguments[1]:undefined),t}})},function(e,t,n){"use strict";var o=n(0),r=n(201);o({target:"Array",proto:!0,forced:[].forEach!=r},{forEach:r})},function(e,t,n){"use strict";var o=n(18).forEach,r=n(38),i=n(23),a=r("forEach"),c=i("forEach");e.exports=a&&c?[].forEach:function(e){return o(this,e,arguments.length>1?arguments[1]:undefined)}},function(e,t,n){"use strict";var o=n(0),r=n(203);o({target:"Array",stat:!0,forced:!n(74)((function(e){Array.from(e)}))},{from:r})},function(e,t,n){"use strict";var o=n(47),r=n(15),i=n(140),a=n(99),c=n(11),l=n(48),d=n(100);e.exports=function(e){var t,n,u,s,p,f,m=r(e),h="function"==typeof this?this:Array,g=arguments.length,C=g>1?arguments[1]:undefined,b=C!==undefined,v=d(m),N=0;if(b&&(C=o(C,g>2?arguments[2]:undefined,2)),v==undefined||h==Array&&a(v))for(n=new h(t=c(m.length));t>N;N++)f=b?C(m[N],N):m[N],l(n,N,f);else for(p=(s=v.call(m)).next,n=new h;!(u=p.call(s)).done;N++)f=b?i(s,C,[u.value,N],!0):u.value,l(n,N,f);return n.length=N,n}},function(e,t,n){"use strict";var o=n(0),r=n(61).includes,i=n(43);o({target:"Array",proto:!0,forced:!n(23)("indexOf",{ACCESSORS:!0,1:0})},{includes:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}}),i("includes")},function(e,t,n){"use strict";var o=n(0),r=n(61).indexOf,i=n(38),a=n(23),c=[].indexOf,l=!!c&&1/[1].indexOf(1,-0)<0,d=i("indexOf"),u=a("indexOf",{ACCESSORS:!0,1:0});o({target:"Array",proto:!0,forced:l||!d||!u},{indexOf:function(e){return l?c.apply(this,arguments)||0:r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";n(0)({target:"Array",stat:!0},{isArray:n(51)})},function(e,t,n){"use strict";var o=n(142).IteratorPrototype,r=n(41),i=n(45),a=n(42),c=n(66),l=function(){return this};e.exports=function(e,t,n){var d=t+" Iterator";return e.prototype=r(o,{next:i(1,n)}),a(e,d,!1,!0),c[d]=l,e}},function(e,t,n){"use strict";var o=n(0),r=n(58),i=n(25),a=n(38),c=[].join,l=r!=Object,d=a("join",",");o({target:"Array",proto:!0,forced:l||!d},{join:function(e){return c.call(i(this),e===undefined?",":e)}})},function(e,t,n){"use strict";var o=n(0),r=n(144);o({target:"Array",proto:!0,forced:r!==[].lastIndexOf},{lastIndexOf:r})},function(e,t,n){"use strict";var o=n(0),r=n(18).map,i=n(65),a=n(23),c=i("map"),l=a("map");o({target:"Array",proto:!0,forced:!c||!l},{map:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(48);o({target:"Array",stat:!0,forced:r((function(){function e(){}return!(Array.of.call(e)instanceof e)}))},{of:function(){for(var e=0,t=arguments.length,n=new("function"==typeof this?this:Array)(t);t>e;)i(n,e,arguments[e++]);return n.length=t,n}})},function(e,t,n){"use strict";var o=n(0),r=n(75).left,i=n(38),a=n(23),c=i("reduce"),l=a("reduce",{1:0});o({target:"Array",proto:!0,forced:!c||!l},{reduce:function(e){return r(this,e,arguments.length,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(75).right,i=n(38),a=n(23),c=i("reduceRight"),l=a("reduce",{1:0});o({target:"Array",proto:!0,forced:!c||!l},{reduceRight:function(e){return r(this,e,arguments.length,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(51),a=n(40),c=n(11),l=n(25),d=n(48),u=n(13),s=n(65),p=n(23),f=s("slice"),m=p("slice",{ACCESSORS:!0,0:0,1:2}),h=u("species"),g=[].slice,C=Math.max;o({target:"Array",proto:!0,forced:!f||!m},{slice:function(e,t){var n,o,u,s=l(this),p=c(s.length),f=a(e,p),m=a(t===undefined?p:t,p);if(i(s)&&("function"!=typeof(n=s.constructor)||n!==Array&&!i(n.prototype)?r(n)&&null===(n=n[h])&&(n=undefined):n=undefined,n===Array||n===undefined))return g.call(s,f,m);for(o=new(n===undefined?Array:n)(C(m-f,0)),u=0;f1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(31),i=n(15),a=n(5),c=n(38),l=[],d=l.sort,u=a((function(){l.sort(undefined)})),s=a((function(){l.sort(null)})),p=c("sort");o({target:"Array",proto:!0,forced:u||!s||!p},{sort:function(e){return e===undefined?d.call(i(this)):d.call(i(this),r(e))}})},function(e,t,n){"use strict";n(52)("Array")},function(e,t,n){"use strict";var o=n(0),r=n(40),i=n(30),a=n(11),c=n(15),l=n(64),d=n(48),u=n(65),s=n(23),p=u("splice"),f=s("splice",{ACCESSORS:!0,0:0,1:2}),m=Math.max,h=Math.min;o({target:"Array",proto:!0,forced:!p||!f},{splice:function(e,t){var n,o,u,s,p,f,g=c(this),C=a(g.length),b=r(e,C),v=arguments.length;if(0===v?n=o=0:1===v?(n=0,o=C-b):(n=v-2,o=h(m(i(t),0),C-b)),C+n-o>9007199254740991)throw TypeError("Maximum allowed length exceeded");for(u=l(g,o),s=0;sC-o+n;s--)delete g[s-1]}else if(n>o)for(s=C-o;s>b;s--)f=s+n-1,(p=s+o-1)in g?g[f]=g[p]:delete g[f];for(s=0;s>1,h=23===t?r(2,-24)-r(2,-77):0,g=e<0||0===e&&1/e<0?1:0,C=0;for((e=o(e))!=e||e===1/0?(d=e!=e?1:0,l=f):(l=i(a(e)/c),e*(u=r(2,-l))<1&&(l--,u*=2),(e+=l+m>=1?h/u:h*r(2,1-m))*u>=2&&(l++,u/=2),l+m>=f?(d=0,l=f):l+m>=1?(d=(e*u-1)*r(2,t),l+=m):(d=e*r(2,m-1)*r(2,t),l=0));t>=8;s[C++]=255&d,d/=256,t-=8);for(l=l<0;s[C++]=255&l,l/=256,p-=8);return s[--C]|=128*g,s},unpack:function(e,t){var n,o=e.length,i=8*o-t-1,a=(1<>1,l=i-7,d=o-1,u=e[d--],s=127&u;for(u>>=7;l>0;s=256*s+e[d],d--,l-=8);for(n=s&(1<<-l)-1,s>>=-l,l+=t;l>0;n=256*n+e[d],d--,l-=8);if(0===s)s=1-c;else{if(s===a)return n?NaN:u?-1/0:1/0;n+=r(2,t),s-=c}return(u?-1:1)*n*r(2,s-t)}}},function(e,t,n){"use strict";var o=n(0),r=n(10);o({target:"ArrayBuffer",stat:!0,forced:!r.NATIVE_ARRAY_BUFFER_VIEWS},{isView:r.isView})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(76),a=n(9),c=n(40),l=n(11),d=n(44),u=i.ArrayBuffer,s=i.DataView,p=u.prototype.slice;o({target:"ArrayBuffer",proto:!0,unsafe:!0,forced:r((function(){return!new u(2).slice(1,undefined).byteLength}))},{slice:function(e,t){if(p!==undefined&&t===undefined)return p.call(a(this),e);for(var n=a(this).byteLength,o=c(e,n),r=c(t===undefined?n:t,n),i=new(d(this,u))(l(r-o)),f=new s(this),m=new s(i),h=0;o9999?"+":"";return n+r(i(e),n?6:4,0)+"-"+r(this.getUTCMonth()+1,2,0)+"-"+r(this.getUTCDate(),2,0)+"T"+r(this.getUTCHours(),2,0)+":"+r(this.getUTCMinutes(),2,0)+":"+r(this.getUTCSeconds(),2,0)+"."+r(t,3,0)+"Z"}:l},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(15),a=n(33);o({target:"Date",proto:!0,forced:r((function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}))},{toJSON:function(e){var t=i(this),n=a(t);return"number"!=typeof n||isFinite(n)?t.toISOString():null}})},function(e,t,n){"use strict";var o=n(29),r=n(231),i=n(13)("toPrimitive"),a=Date.prototype;i in a||o(a,i,r)},function(e,t,n){"use strict";var o=n(9),r=n(33);e.exports=function(e){if("string"!==e&&"number"!==e&&"default"!==e)throw TypeError("Incorrect hint");return r(o(this),"number"!==e)}},function(e,t,n){"use strict";var o=n(22),r=Date.prototype,i=r.toString,a=r.getTime;new Date(NaN)+""!="Invalid Date"&&o(r,"toString",(function(){var e=a.call(this);return e==e?i.call(this):"Invalid Date"}))},function(e,t,n){"use strict";n(0)({target:"Function",proto:!0},{bind:n(146)})},function(e,t,n){"use strict";var o=n(7),r=n(14),i=n(35),a=n(13)("hasInstance"),c=Function.prototype;a in c||r.f(c,a,{value:function(e){if("function"!=typeof this||!o(e))return!1;if(!o(this.prototype))return e instanceof this;for(;e=i(e);)if(this.prototype===e)return!0;return!1}})},function(e,t,n){"use strict";var o=n(8),r=n(14).f,i=Function.prototype,a=i.toString,c=/^\s*function ([^ (]*)/;o&&!("name"in i)&&r(i,"name",{configurable:!0,get:function(){try{return a.call(this).match(c)[1]}catch(e){return""}}})},function(e,t,n){"use strict";var o=n(6);n(42)(o.JSON,"JSON",!0)},function(e,t,n){"use strict";var o=n(77),r=n(147);e.exports=o("Map",(function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}}),r)},function(e,t,n){"use strict";var o=n(0),r=n(148),i=Math.acosh,a=Math.log,c=Math.sqrt,l=Math.LN2;o({target:"Math",stat:!0,forced:!i||710!=Math.floor(i(Number.MAX_VALUE))||i(Infinity)!=Infinity},{acosh:function(e){return(e=+e)<1?NaN:e>94906265.62425156?a(e)+l:r(e-1+c(e-1)*c(e+1))}})},function(e,t,n){"use strict";var o=n(0),r=Math.asinh,i=Math.log,a=Math.sqrt;o({target:"Math",stat:!0,forced:!(r&&1/r(0)>0)},{asinh:function c(e){return isFinite(e=+e)&&0!=e?e<0?-c(-e):i(e+a(e*e+1)):e}})},function(e,t,n){"use strict";var o=n(0),r=Math.atanh,i=Math.log;o({target:"Math",stat:!0,forced:!(r&&1/r(-0)<0)},{atanh:function(e){return 0==(e=+e)?e:i((1+e)/(1-e))/2}})},function(e,t,n){"use strict";var o=n(0),r=n(107),i=Math.abs,a=Math.pow;o({target:"Math",stat:!0},{cbrt:function(e){return r(e=+e)*a(i(e),1/3)}})},function(e,t,n){"use strict";var o=n(0),r=Math.floor,i=Math.log,a=Math.LOG2E;o({target:"Math",stat:!0},{clz32:function(e){return(e>>>=0)?31-r(i(e+.5)*a):32}})},function(e,t,n){"use strict";var o=n(0),r=n(79),i=Math.cosh,a=Math.abs,c=Math.E;o({target:"Math",stat:!0,forced:!i||i(710)===Infinity},{cosh:function(e){var t=r(a(e)-1)+1;return(t+1/(t*c*c))*(c/2)}})},function(e,t,n){"use strict";var o=n(0),r=n(79);o({target:"Math",stat:!0,forced:r!=Math.expm1},{expm1:r})},function(e,t,n){"use strict";n(0)({target:"Math",stat:!0},{fround:n(246)})},function(e,t,n){"use strict";var o=n(107),r=Math.abs,i=Math.pow,a=i(2,-52),c=i(2,-23),l=i(2,127)*(2-c),d=i(2,-126);e.exports=Math.fround||function(e){var t,n,i=r(e),u=o(e);return il||n!=n?u*Infinity:u*n}},function(e,t,n){"use strict";var o=n(0),r=Math.hypot,i=Math.abs,a=Math.sqrt;o({target:"Math",stat:!0,forced:!!r&&r(Infinity,NaN)!==Infinity},{hypot:function(e,t){for(var n,o,r=0,c=0,l=arguments.length,d=0;c0?(o=n/d)*o:n;return d===Infinity?Infinity:d*a(r)}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=Math.imul;o({target:"Math",stat:!0,forced:r((function(){return-5!=i(4294967295,5)||2!=i.length}))},{imul:function(e,t){var n=+e,o=+t,r=65535&n,i=65535&o;return 0|r*i+((65535&n>>>16)*i+r*(65535&o>>>16)<<16>>>0)}})},function(e,t,n){"use strict";var o=n(0),r=Math.log,i=Math.LOG10E;o({target:"Math",stat:!0},{log10:function(e){return r(e)*i}})},function(e,t,n){"use strict";n(0)({target:"Math",stat:!0},{log1p:n(148)})},function(e,t,n){"use strict";var o=n(0),r=Math.log,i=Math.LN2;o({target:"Math",stat:!0},{log2:function(e){return r(e)/i}})},function(e,t,n){"use strict";n(0)({target:"Math",stat:!0},{sign:n(107)})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(79),a=Math.abs,c=Math.exp,l=Math.E;o({target:"Math",stat:!0,forced:r((function(){return-2e-17!=Math.sinh(-2e-17)}))},{sinh:function(e){return a(e=+e)<1?(i(e)-i(-e))/2:(c(e-1)-c(-e-1))*(l/2)}})},function(e,t,n){"use strict";var o=n(0),r=n(79),i=Math.exp;o({target:"Math",stat:!0},{tanh:function(e){var t=r(e=+e),n=r(-e);return t==Infinity?1:n==Infinity?-1:(t-n)/(i(e)+i(-e))}})},function(e,t,n){"use strict";n(42)(Math,"Math",!0)},function(e,t,n){"use strict";var o=n(0),r=Math.ceil,i=Math.floor;o({target:"Math",stat:!0},{trunc:function(e){return(e>0?i:r)(e)}})},function(e,t,n){"use strict";var o=n(8),r=n(6),i=n(62),a=n(22),c=n(17),l=n(32),d=n(78),u=n(33),s=n(5),p=n(41),f=n(46).f,m=n(19).f,h=n(14).f,g=n(54).trim,C=r.Number,b=C.prototype,v="Number"==l(p(b)),N=function(e){var t,n,o,r,i,a,c,l,d=u(e,!1);if("string"==typeof d&&d.length>2)if(43===(t=(d=g(d)).charCodeAt(0))||45===t){if(88===(n=d.charCodeAt(2))||120===n)return NaN}else if(48===t){switch(d.charCodeAt(1)){case 66:case 98:o=2,r=49;break;case 79:case 111:o=8,r=55;break;default:return+d}for(a=(i=d.slice(2)).length,c=0;cr)return NaN;return parseInt(i,o)}return+d};if(i("Number",!C(" 0o1")||!C("0b1")||C("+0x1"))){for(var V,y=function(e){var t=arguments.length<1?0:e,n=this;return n instanceof y&&(v?s((function(){b.valueOf.call(n)})):"Number"!=l(n))?d(new C(N(t)),n,y):N(t)},x=o?f(C):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),k=0;x.length>k;k++)c(C,V=x[k])&&!c(y,V)&&h(y,V,m(C,V));y.prototype=b,b.constructor=y,a(r,"Number",y)}},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{EPSILON:Math.pow(2,-52)})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{isFinite:n(260)})},function(e,t,n){"use strict";var o=n(6).isFinite;e.exports=Number.isFinite||function(e){return"number"==typeof e&&o(e)}},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{isInteger:n(149)})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{isNaN:function(e){return e!=e}})},function(e,t,n){"use strict";var o=n(0),r=n(149),i=Math.abs;o({target:"Number",stat:!0},{isSafeInteger:function(e){return r(e)&&i(e)<=9007199254740991}})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{MAX_SAFE_INTEGER:9007199254740991})},function(e,t,n){"use strict";n(0)({target:"Number",stat:!0},{MIN_SAFE_INTEGER:-9007199254740991})},function(e,t,n){"use strict";var o=n(0),r=n(267);o({target:"Number",stat:!0,forced:Number.parseFloat!=r},{parseFloat:r})},function(e,t,n){"use strict";var o=n(6),r=n(54).trim,i=n(80),a=o.parseFloat,c=1/a(i+"-0")!=-Infinity;e.exports=c?function(e){var t=r(String(e)),n=a(t);return 0===n&&"-"==t.charAt(0)?-0:n}:a},function(e,t,n){"use strict";var o=n(0),r=n(150);o({target:"Number",stat:!0,forced:Number.parseInt!=r},{parseInt:r})},function(e,t,n){"use strict";var o=n(0),r=n(30),i=n(270),a=n(106),c=n(5),l=1..toFixed,d=Math.floor,u=function s(e,t,n){return 0===t?n:t%2==1?s(e,t-1,n*e):s(e*e,t/2,n)};o({target:"Number",proto:!0,forced:l&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!c((function(){l.call({})}))},{toFixed:function(e){var t,n,o,c,l=i(this),s=r(e),p=[0,0,0,0,0,0],f="",m="0",h=function(e,t){for(var n=-1,o=t;++n<6;)o+=e*p[n],p[n]=o%1e7,o=d(o/1e7)},g=function(e){for(var t=6,n=0;--t>=0;)n+=p[t],p[t]=d(n/e),n=n%e*1e7},C=function(){for(var e=6,t="";--e>=0;)if(""!==t||0===e||0!==p[e]){var n=String(p[e]);t=""===t?n:t+a.call("0",7-n.length)+n}return t};if(s<0||s>20)throw RangeError("Incorrect fraction digits");if(l!=l)return"NaN";if(l<=-1e21||l>=1e21)return String(l);if(l<0&&(f="-",l=-l),l>1e-21)if(n=(t=function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}(l*u(2,69,1))-69)<0?l*u(2,-t,1):l/u(2,t,1),n*=4503599627370496,(t=52-t)>0){for(h(0,n),o=s;o>=7;)h(1e7,0),o-=7;for(h(u(10,o,1),0),o=t-1;o>=23;)g(1<<23),o-=23;g(1<0?f+((c=m.length)<=s?"0."+a.call("0",s-c)+m:m.slice(0,c-s)+"."+m.slice(c-s)):f+m}})},function(e,t,n){"use strict";var o=n(32);e.exports=function(e){if("number"!=typeof e&&"Number"!=o(e))throw TypeError("Incorrect invocation");return+e}},function(e,t,n){"use strict";var o=n(0),r=n(272);o({target:"Object",stat:!0,forced:Object.assign!==r},{assign:r})},function(e,t,n){"use strict";var o=n(8),r=n(5),i=n(63),a=n(95),c=n(70),l=n(15),d=n(58),u=Object.assign,s=Object.defineProperty;e.exports=!u||r((function(){if(o&&1!==u({b:1},u(s({},"a",{enumerable:!0,get:function(){s(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},n=Symbol();return e[n]=7,"abcdefghijklmnopqrst".split("").forEach((function(e){t[e]=e})),7!=u({},e)[n]||"abcdefghijklmnopqrst"!=i(u({},t)).join("")}))?function(e,t){for(var n=l(e),r=arguments.length,u=1,s=a.f,p=c.f;r>u;)for(var f,m=d(arguments[u++]),h=s?i(m).concat(s(m)):i(m),g=h.length,C=0;g>C;)f=h[C++],o&&!p.call(m,f)||(n[f]=m[f]);return n}:u},function(e,t,n){"use strict";n(0)({target:"Object",stat:!0,sham:!n(8)},{create:n(41)})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(31),l=n(14);r&&o({target:"Object",proto:!0,forced:i},{__defineGetter__:function(e,t){l.f(a(this),e,{get:c(t),enumerable:!0,configurable:!0})}})},function(e,t,n){"use strict";var o=n(0),r=n(8);o({target:"Object",stat:!0,forced:!r,sham:!r},{defineProperties:n(134)})},function(e,t,n){"use strict";var o=n(0),r=n(8);o({target:"Object",stat:!0,forced:!r,sham:!r},{defineProperty:n(14).f})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(31),l=n(14);r&&o({target:"Object",proto:!0,forced:i},{__defineSetter__:function(e,t){l.f(a(this),e,{set:c(t),enumerable:!0,configurable:!0})}})},function(e,t,n){"use strict";var o=n(0),r=n(151).entries;o({target:"Object",stat:!0},{entries:function(e){return r(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(68),i=n(5),a=n(7),c=n(50).onFreeze,l=Object.freeze;o({target:"Object",stat:!0,forced:i((function(){l(1)})),sham:!r},{freeze:function(e){return l&&a(e)?l(c(e)):e}})},function(e,t,n){"use strict";var o=n(0),r=n(69),i=n(48);o({target:"Object",stat:!0},{fromEntries:function(e){var t={};return r(e,(function(e,n){i(t,e,n)}),undefined,!0),t}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(25),a=n(19).f,c=n(8),l=r((function(){a(1)}));o({target:"Object",stat:!0,forced:!c||l,sham:!c},{getOwnPropertyDescriptor:function(e,t){return a(i(e),t)}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(93),a=n(25),c=n(19),l=n(48);o({target:"Object",stat:!0,sham:!r},{getOwnPropertyDescriptors:function(e){for(var t,n,o=a(e),r=c.f,d=i(o),u={},s=0;d.length>s;)(n=r(o,t=d[s++]))!==undefined&&l(u,t,n);return u}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(136).f;o({target:"Object",stat:!0,forced:r((function(){return!Object.getOwnPropertyNames(1)}))},{getOwnPropertyNames:i})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(15),a=n(35),c=n(103);o({target:"Object",stat:!0,forced:r((function(){a(1)})),sham:!c},{getPrototypeOf:function(e){return a(i(e))}})},function(e,t,n){"use strict";n(0)({target:"Object",stat:!0},{is:n(152)})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(7),a=Object.isExtensible;o({target:"Object",stat:!0,forced:r((function(){a(1)}))},{isExtensible:function(e){return!!i(e)&&(!a||a(e))}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(7),a=Object.isFrozen;o({target:"Object",stat:!0,forced:r((function(){a(1)}))},{isFrozen:function(e){return!i(e)||!!a&&a(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(5),i=n(7),a=Object.isSealed;o({target:"Object",stat:!0,forced:r((function(){a(1)}))},{isSealed:function(e){return!i(e)||!!a&&a(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(15),i=n(63);o({target:"Object",stat:!0,forced:n(5)((function(){i(1)}))},{keys:function(e){return i(r(e))}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(33),l=n(35),d=n(19).f;r&&o({target:"Object",proto:!0,forced:i},{__lookupGetter__:function(e){var t,n=a(this),o=c(e,!0);do{if(t=d(n,o))return t.get}while(n=l(n))}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(81),a=n(15),c=n(33),l=n(35),d=n(19).f;r&&o({target:"Object",proto:!0,forced:i},{__lookupSetter__:function(e){var t,n=a(this),o=c(e,!0);do{if(t=d(n,o))return t.set}while(n=l(n))}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(50).onFreeze,a=n(68),c=n(5),l=Object.preventExtensions;o({target:"Object",stat:!0,forced:c((function(){l(1)})),sham:!a},{preventExtensions:function(e){return l&&r(e)?l(i(e)):e}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(50).onFreeze,a=n(68),c=n(5),l=Object.seal;o({target:"Object",stat:!0,forced:c((function(){l(1)})),sham:!a},{seal:function(e){return l&&r(e)?l(i(e)):e}})},function(e,t,n){"use strict";n(0)({target:"Object",stat:!0},{setPrototypeOf:n(49)})},function(e,t,n){"use strict";var o=n(101),r=n(22),i=n(296);o||r(Object.prototype,"toString",i,{unsafe:!0})},function(e,t,n){"use strict";var o=n(101),r=n(73);e.exports=o?{}.toString:function(){return"[object "+r(this)+"]"}},function(e,t,n){"use strict";var o=n(0),r=n(151).values;o({target:"Object",stat:!0},{values:function(e){return r(e)}})},function(e,t,n){"use strict";var o=n(0),r=n(150);o({global:!0,forced:parseInt!=r},{parseInt:r})},function(e,t,n){"use strict";var o,r,i,a,c=n(0),l=n(37),d=n(6),u=n(36),s=n(153),p=n(22),f=n(67),m=n(42),h=n(52),g=n(7),C=n(31),b=n(53),v=n(32),N=n(91),V=n(69),y=n(74),x=n(44),k=n(108).set,_=n(155),w=n(156),L=n(300),B=n(157),S=n(301),I=n(34),E=n(62),T=n(13),A=n(97),O=T("species"),M="Promise",P=I.get,j=I.set,D=I.getterFor(M),F=s,R=d.TypeError,z=d.document,W=d.process,U=u("fetch"),K=B.f,H=K,Y="process"==v(W),q=!!(z&&z.createEvent&&d.dispatchEvent),G=E(M,(function(){if(!(N(F)!==String(F))){if(66===A)return!0;if(!Y&&"function"!=typeof PromiseRejectionEvent)return!0}if(l&&!F.prototype["finally"])return!0;if(A>=51&&/native code/.test(F))return!1;var e=F.resolve(1),t=function(e){e((function(){}),(function(){}))};return(e.constructor={})[O]=t,!(e.then((function(){}))instanceof t)})),$=G||!y((function(e){F.all(e)["catch"]((function(){}))})),X=function(e){var t;return!(!g(e)||"function"!=typeof(t=e.then))&&t},Q=function(e,t,n){if(!t.notified){t.notified=!0;var o=t.reactions;_((function(){for(var r=t.value,i=1==t.state,a=0;o.length>a;){var c,l,d,u=o[a++],s=i?u.ok:u.fail,p=u.resolve,f=u.reject,m=u.domain;try{s?(i||(2===t.rejection&&te(e,t),t.rejection=1),!0===s?c=r:(m&&m.enter(),c=s(r),m&&(m.exit(),d=!0)),c===u.promise?f(R("Promise-chain cycle")):(l=X(c))?l.call(c,p,f):p(c)):f(r)}catch(h){m&&!d&&m.exit(),f(h)}}t.reactions=[],t.notified=!1,n&&!t.rejection&&Z(e,t)}))}},J=function(e,t,n){var o,r;q?((o=z.createEvent("Event")).promise=t,o.reason=n,o.initEvent(e,!1,!0),d.dispatchEvent(o)):o={promise:t,reason:n},(r=d["on"+e])?r(o):"unhandledrejection"===e&&L("Unhandled promise rejection",n)},Z=function(e,t){k.call(d,(function(){var n,o=t.value;if(ee(t)&&(n=S((function(){Y?W.emit("unhandledRejection",o,e):J("unhandledrejection",e,o)})),t.rejection=Y||ee(t)?2:1,n.error))throw n.value}))},ee=function(e){return 1!==e.rejection&&!e.parent},te=function(e,t){k.call(d,(function(){Y?W.emit("rejectionHandled",e):J("rejectionhandled",e,t.value)}))},ne=function(e,t,n,o){return function(r){e(t,n,r,o)}},oe=function(e,t,n,o){t.done||(t.done=!0,o&&(t=o),t.value=n,t.state=2,Q(e,t,!0))},re=function ie(e,t,n,o){if(!t.done){t.done=!0,o&&(t=o);try{if(e===n)throw R("Promise can't be resolved itself");var r=X(n);r?_((function(){var o={done:!1};try{r.call(n,ne(ie,e,o,t),ne(oe,e,o,t))}catch(i){oe(e,o,i,t)}})):(t.value=n,t.state=1,Q(e,t,!1))}catch(i){oe(e,{done:!1},i,t)}}};G&&(F=function(e){b(this,F,M),C(e),o.call(this);var t=P(this);try{e(ne(re,this,t),ne(oe,this,t))}catch(n){oe(this,t,n)}},(o=function(e){j(this,{type:M,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:undefined})}).prototype=f(F.prototype,{then:function(e,t){var n=D(this),o=K(x(this,F));return o.ok="function"!=typeof e||e,o.fail="function"==typeof t&&t,o.domain=Y?W.domain:undefined,n.parent=!0,n.reactions.push(o),0!=n.state&&Q(this,n,!1),o.promise},"catch":function(e){return this.then(undefined,e)}}),r=function(){var e=new o,t=P(e);this.promise=e,this.resolve=ne(re,e,t),this.reject=ne(oe,e,t)},B.f=K=function(e){return e===F||e===i?new r(e):H(e)},l||"function"!=typeof s||(a=s.prototype.then,p(s.prototype,"then",(function(e,t){var n=this;return new F((function(e,t){a.call(n,e,t)})).then(e,t)}),{unsafe:!0}),"function"==typeof U&&c({global:!0,enumerable:!0,forced:!0},{fetch:function(e){return w(F,U.apply(d,arguments))}}))),c({global:!0,wrap:!0,forced:G},{Promise:F}),m(F,M,!1,!0),h(M),i=u(M),c({target:M,stat:!0,forced:G},{reject:function(e){var t=K(this);return t.reject.call(undefined,e),t.promise}}),c({target:M,stat:!0,forced:l||G},{resolve:function(e){return w(l&&this===i?F:this,e)}}),c({target:M,stat:!0,forced:$},{all:function(e){var t=this,n=K(t),o=n.resolve,r=n.reject,i=S((function(){var n=C(t.resolve),i=[],a=0,c=1;V(e,(function(e){var l=a++,d=!1;i.push(undefined),c++,n.call(t,e).then((function(e){d||(d=!0,i[l]=e,--c||o(i))}),r)})),--c||o(i)}));return i.error&&r(i.value),n.promise},race:function(e){var t=this,n=K(t),o=n.reject,r=S((function(){var r=C(t.resolve);V(e,(function(e){r.call(t,e).then(n.resolve,o)}))}));return r.error&&o(r.value),n.promise}})},function(e,t,n){"use strict";var o=n(6);e.exports=function(e,t){var n=o.console;n&&n.error&&(1===arguments.length?n.error(e):n.error(e,t))}},function(e,t,n){"use strict";e.exports=function(e){try{return{error:!1,value:e()}}catch(t){return{error:!0,value:t}}}},function(e,t,n){"use strict";var o=n(0),r=n(37),i=n(153),a=n(5),c=n(36),l=n(44),d=n(156),u=n(22);o({target:"Promise",proto:!0,real:!0,forced:!!i&&a((function(){i.prototype["finally"].call({then:function(){}},(function(){}))}))},{"finally":function(e){var t=l(this,c("Promise")),n="function"==typeof e;return this.then(n?function(n){return d(t,e()).then((function(){return n}))}:e,n?function(n){return d(t,e()).then((function(){throw n}))}:e)}}),r||"function"!=typeof i||i.prototype["finally"]||u(i.prototype,"finally",c("Promise").prototype["finally"])},function(e,t,n){"use strict";var o=n(0),r=n(36),i=n(31),a=n(9),c=n(5),l=r("Reflect","apply"),d=Function.apply;o({target:"Reflect",stat:!0,forced:!c((function(){l((function(){}))}))},{apply:function(e,t,n){return i(e),a(n),l?l(e,t,n):d.call(e,t,n)}})},function(e,t,n){"use strict";var o=n(0),r=n(36),i=n(31),a=n(9),c=n(7),l=n(41),d=n(146),u=n(5),s=r("Reflect","construct"),p=u((function(){function e(){}return!(s((function(){}),[],e)instanceof e)})),f=!u((function(){s((function(){}))})),m=p||f;o({target:"Reflect",stat:!0,forced:m,sham:m},{construct:function(e,t){i(e),a(t);var n=arguments.length<3?e:i(arguments[2]);if(f&&!p)return s(e,t,n);if(e==n){switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3])}var o=[null];return o.push.apply(o,t),new(d.apply(e,o))}var r=n.prototype,u=l(c(r)?r:Object.prototype),m=Function.apply.call(e,u,t);return c(m)?m:u}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(9),a=n(33),c=n(14);o({target:"Reflect",stat:!0,forced:n(5)((function(){Reflect.defineProperty(c.f({},1,{value:1}),1,{value:2})})),sham:!r},{defineProperty:function(e,t,n){i(e);var o=a(t,!0);i(n);try{return c.f(e,o,n),!0}catch(r){return!1}}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(19).f;o({target:"Reflect",stat:!0},{deleteProperty:function(e,t){var n=i(r(e),t);return!(n&&!n.configurable)&&delete e[t]}})},function(e,t,n){"use strict";var o=n(0),r=n(7),i=n(9),a=n(17),c=n(19),l=n(35);o({target:"Reflect",stat:!0},{get:function d(e,t){var n,o,u=arguments.length<3?e:arguments[2];return i(e)===u?e[t]:(n=c.f(e,t))?a(n,"value")?n.value:n.get===undefined?undefined:n.get.call(u):r(o=l(e))?d(o,t,u):void 0}})},function(e,t,n){"use strict";var o=n(0),r=n(8),i=n(9),a=n(19);o({target:"Reflect",stat:!0,sham:!r},{getOwnPropertyDescriptor:function(e,t){return a.f(i(e),t)}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(35);o({target:"Reflect",stat:!0,sham:!n(103)},{getPrototypeOf:function(e){return i(r(e))}})},function(e,t,n){"use strict";n(0)({target:"Reflect",stat:!0},{has:function(e,t){return t in e}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=Object.isExtensible;o({target:"Reflect",stat:!0},{isExtensible:function(e){return r(e),!i||i(e)}})},function(e,t,n){"use strict";n(0)({target:"Reflect",stat:!0},{ownKeys:n(93)})},function(e,t,n){"use strict";var o=n(0),r=n(36),i=n(9);o({target:"Reflect",stat:!0,sham:!n(68)},{preventExtensions:function(e){i(e);try{var t=r("Object","preventExtensions");return t&&t(e),!0}catch(n){return!1}}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(7),a=n(17),c=n(5),l=n(14),d=n(19),u=n(35),s=n(45);o({target:"Reflect",stat:!0,forced:c((function(){var e=l.f({},"a",{configurable:!0});return!1!==Reflect.set(u(e),"a",1,e)}))},{set:function p(e,t,n){var o,c,f=arguments.length<4?e:arguments[3],m=d.f(r(e),t);if(!m){if(i(c=u(e)))return p(c,t,n,f);m=s(0)}if(a(m,"value")){if(!1===m.writable||!i(f))return!1;if(o=d.f(f,t)){if(o.get||o.set||!1===o.writable)return!1;o.value=n,l.f(f,t,o)}else l.f(f,t,s(0,n));return!0}return m.set!==undefined&&(m.set.call(f,n),!0)}})},function(e,t,n){"use strict";var o=n(0),r=n(9),i=n(143),a=n(49);a&&o({target:"Reflect",stat:!0},{setPrototypeOf:function(e,t){r(e),i(t);try{return a(e,t),!0}catch(n){return!1}}})},function(e,t,n){"use strict";var o=n(8),r=n(6),i=n(62),a=n(78),c=n(14).f,l=n(46).f,d=n(109),u=n(82),s=n(110),p=n(22),f=n(5),m=n(34).set,h=n(52),g=n(13)("match"),C=r.RegExp,b=C.prototype,v=/a/g,N=/a/g,V=new C(v)!==v,y=s.UNSUPPORTED_Y;if(o&&i("RegExp",!V||y||f((function(){return N[g]=!1,C(v)!=v||C(N)==N||"/a/i"!=C(v,"i")})))){for(var x=function(e,t){var n,o=this instanceof x,r=d(e),i=t===undefined;if(!o&&r&&e.constructor===x&&i)return e;V?r&&!i&&(e=e.source):e instanceof x&&(i&&(t=u.call(e)),e=e.source),y&&(n=!!t&&t.indexOf("y")>-1)&&(t=t.replace(/y/g,""));var c=a(V?new C(e,t):C(e,t),o?this:b,x);return y&&n&&m(c,{sticky:n}),c},k=function(e){e in x||c(x,e,{configurable:!0,get:function(){return C[e]},set:function(t){C[e]=t}})},_=l(C),w=0;_.length>w;)k(_[w++]);b.constructor=x,x.prototype=b,p(r,"RegExp",x)}h("RegExp")},function(e,t,n){"use strict";var o=n(8),r=n(14),i=n(82),a=n(110).UNSUPPORTED_Y;o&&("g"!=/./g.flags||a)&&r.f(RegExp.prototype,"flags",{configurable:!0,get:i})},function(e,t,n){"use strict";var o=n(22),r=n(9),i=n(5),a=n(82),c=RegExp.prototype,l=c.toString,d=i((function(){return"/a/b"!=l.call({source:"a",flags:"b"})})),u="toString"!=l.name;(d||u)&&o(RegExp.prototype,"toString",(function(){var e=r(this),t=String(e.source),n=e.flags;return"/"+t+"/"+String(n===undefined&&e instanceof RegExp&&!("flags"in c)?a.call(e):n)}),{unsafe:!0})},function(e,t,n){"use strict";var o=n(77),r=n(147);e.exports=o("Set",(function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}}),r)},function(e,t,n){"use strict";var o=n(0),r=n(111).codeAt;o({target:"String",proto:!0},{codePointAt:function(e){return r(this,e)}})},function(e,t,n){"use strict";var o,r=n(0),i=n(19).f,a=n(11),c=n(112),l=n(21),d=n(113),u=n(37),s="".endsWith,p=Math.min,f=d("endsWith");r({target:"String",proto:!0,forced:!!(u||f||(o=i(String.prototype,"endsWith"),!o||o.writable))&&!f},{endsWith:function(e){var t=String(l(this));c(e);var n=arguments.length>1?arguments[1]:undefined,o=a(t.length),r=n===undefined?o:p(a(n),o),i=String(e);return s?s.call(t,i,r):t.slice(r-i.length,r)===i}})},function(e,t,n){"use strict";var o=n(0),r=n(40),i=String.fromCharCode,a=String.fromCodePoint;o({target:"String",stat:!0,forced:!!a&&1!=a.length},{fromCodePoint:function(e){for(var t,n=[],o=arguments.length,a=0;o>a;){if(t=+arguments[a++],r(t,1114111)!==t)throw RangeError(t+" is not a valid code point");n.push(t<65536?i(t):i(55296+((t-=65536)>>10),t%1024+56320))}return n.join("")}})},function(e,t,n){"use strict";var o=n(0),r=n(112),i=n(21);o({target:"String",proto:!0,forced:!n(113)("includes")},{includes:function(e){return!!~String(i(this)).indexOf(r(e),arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(111).charAt,r=n(34),i=n(102),a=r.set,c=r.getterFor("String Iterator");i(String,"String",(function(e){a(this,{type:"String Iterator",string:String(e),index:0})}),(function(){var e,t=c(this),n=t.string,r=t.index;return r>=n.length?{value:undefined,done:!0}:(e=o(n,r),t.index+=e.length,{value:e,done:!1})}))},function(e,t,n){"use strict";var o=n(84),r=n(9),i=n(11),a=n(21),c=n(114),l=n(85);o("match",1,(function(e,t,n){return[function(t){var n=a(this),o=t==undefined?undefined:t[e];return o!==undefined?o.call(t,n):new RegExp(t)[e](String(n))},function(e){var o=n(t,e,this);if(o.done)return o.value;var a=r(e),d=String(this);if(!a.global)return l(a,d);var u=a.unicode;a.lastIndex=0;for(var s,p=[],f=0;null!==(s=l(a,d));){var m=String(s[0]);p[f]=m,""===m&&(a.lastIndex=c(d,i(a.lastIndex),u)),f++}return 0===f?null:p}]}))},function(e,t,n){"use strict";var o=n(0),r=n(105).end;o({target:"String",proto:!0,forced:n(159)},{padEnd:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(105).start;o({target:"String",proto:!0,forced:n(159)},{padStart:function(e){return r(this,e,arguments.length>1?arguments[1]:undefined)}})},function(e,t,n){"use strict";var o=n(0),r=n(25),i=n(11);o({target:"String",stat:!0},{raw:function(e){for(var t=r(e.raw),n=i(t.length),o=arguments.length,a=[],c=0;n>c;)a.push(String(t[c++])),c]*>)/g,h=/\$([$&'`]|\d\d?)/g;o("replace",2,(function(e,t,n,o){var g=o.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,C=o.REPLACE_KEEPS_$0,b=g?"$":"$0";return[function(n,o){var r=l(this),i=n==undefined?undefined:n[e];return i!==undefined?i.call(n,r,o):t.call(String(r),n,o)},function(e,o){if(!g&&C||"string"==typeof o&&-1===o.indexOf(b)){var i=n(t,e,this,o);if(i.done)return i.value}var l=r(e),f=String(this),m="function"==typeof o;m||(o=String(o));var h=l.global;if(h){var N=l.unicode;l.lastIndex=0}for(var V=[];;){var y=u(l,f);if(null===y)break;if(V.push(y),!h)break;""===String(y[0])&&(l.lastIndex=d(f,a(l.lastIndex),N))}for(var x,k="",_=0,w=0;w=_&&(k+=f.slice(_,B)+A,_=B+L.length)}return k+f.slice(_)}];function v(e,n,o,r,a,c){var l=o+e.length,d=r.length,u=h;return a!==undefined&&(a=i(a),u=m),t.call(c,u,(function(t,i){var c;switch(i.charAt(0)){case"$":return"$";case"&":return e;case"`":return n.slice(0,o);case"'":return n.slice(l);case"<":c=a[i.slice(1,-1)];break;default:var u=+i;if(0===u)return t;if(u>d){var s=f(u/10);return 0===s?t:s<=d?r[s-1]===undefined?i.charAt(1):r[s-1]+i.charAt(1):t}c=r[u-1]}return c===undefined?"":c}))}}))},function(e,t,n){"use strict";var o=n(84),r=n(9),i=n(21),a=n(152),c=n(85);o("search",1,(function(e,t,n){return[function(t){var n=i(this),o=t==undefined?undefined:t[e];return o!==undefined?o.call(t,n):new RegExp(t)[e](String(n))},function(e){var o=n(t,e,this);if(o.done)return o.value;var i=r(e),l=String(this),d=i.lastIndex;a(d,0)||(i.lastIndex=0);var u=c(i,l);return a(i.lastIndex,d)||(i.lastIndex=d),null===u?-1:u.index}]}))},function(e,t,n){"use strict";var o=n(84),r=n(109),i=n(9),a=n(21),c=n(44),l=n(114),d=n(11),u=n(85),s=n(83),p=n(5),f=[].push,m=Math.min,h=!p((function(){return!RegExp(4294967295,"y")}));o("split",2,(function(e,t,n){var o;return o="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(e,n){var o=String(a(this)),i=n===undefined?4294967295:n>>>0;if(0===i)return[];if(e===undefined)return[o];if(!r(e))return t.call(o,e,i);for(var c,l,d,u=[],p=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),m=0,h=new RegExp(e.source,p+"g");(c=s.call(h,o))&&!((l=h.lastIndex)>m&&(u.push(o.slice(m,c.index)),c.length>1&&c.index=i));)h.lastIndex===c.index&&h.lastIndex++;return m===o.length?!d&&h.test("")||u.push(""):u.push(o.slice(m)),u.length>i?u.slice(0,i):u}:"0".split(undefined,0).length?function(e,n){return e===undefined&&0===n?[]:t.call(this,e,n)}:t,[function(t,n){var r=a(this),i=t==undefined?undefined:t[e];return i!==undefined?i.call(t,r,n):o.call(String(r),t,n)},function(e,r){var a=n(o,e,this,r,o!==t);if(a.done)return a.value;var s=i(e),p=String(this),f=c(s,RegExp),g=s.unicode,C=(s.ignoreCase?"i":"")+(s.multiline?"m":"")+(s.unicode?"u":"")+(h?"y":"g"),b=new f(h?s:"^(?:"+s.source+")",C),v=r===undefined?4294967295:r>>>0;if(0===v)return[];if(0===p.length)return null===u(b,p)?[p]:[];for(var N=0,V=0,y=[];V1?arguments[1]:undefined,t.length)),o=String(e);return s?s.call(t,o,n):t.slice(n,n+o.length)===o}})},function(e,t,n){"use strict";var o=n(0),r=n(54).trim;o({target:"String",proto:!0,forced:n(115)("trim")},{trim:function(){return r(this)}})},function(e,t,n){"use strict";var o=n(0),r=n(54).end,i=n(115)("trimEnd"),a=i?function(){return r(this)}:"".trimEnd;o({target:"String",proto:!0,forced:i},{trimEnd:a,trimRight:a})},function(e,t,n){"use strict";var o=n(0),r=n(54).start,i=n(115)("trimStart"),a=i?function(){return r(this)}:"".trimStart;o({target:"String",proto:!0,forced:i},{trimStart:a,trimLeft:a})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("anchor")},{anchor:function(e){return r(this,"a","name",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("big")},{big:function(){return r(this,"big","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("blink")},{blink:function(){return r(this,"blink","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("bold")},{bold:function(){return r(this,"b","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("fixed")},{fixed:function(){return r(this,"tt","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("fontcolor")},{fontcolor:function(e){return r(this,"font","color",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("fontsize")},{fontsize:function(e){return r(this,"font","size",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("italics")},{italics:function(){return r(this,"i","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("link")},{link:function(e){return r(this,"a","href",e)}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("small")},{small:function(){return r(this,"small","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("strike")},{strike:function(){return r(this,"strike","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("sub")},{sub:function(){return r(this,"sub","","")}})},function(e,t,n){"use strict";var o=n(0),r=n(27);o({target:"String",proto:!0,forced:n(28)("sup")},{sup:function(){return r(this,"sup","","")}})},function(e,t,n){"use strict";n(39)("Float32",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";var o=n(30);e.exports=function(e){var t=o(e);if(t<0)throw RangeError("The argument can't be less than 0");return t}},function(e,t,n){"use strict";n(39)("Float64",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Int8",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Int16",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Int32",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Uint8",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Uint8",(function(e){return function(t,n,o){return e(this,t,n,o)}}),!0)},function(e,t,n){"use strict";n(39)("Uint16",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";n(39)("Uint32",(function(e){return function(t,n,o){return e(this,t,n,o)}}))},function(e,t,n){"use strict";var o=n(10),r=n(138),i=o.aTypedArray;(0,o.exportTypedArrayMethod)("copyWithin",(function(e,t){return r.call(i(this),e,t,arguments.length>2?arguments[2]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).every,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("every",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(98),i=o.aTypedArray;(0,o.exportTypedArrayMethod)("fill",(function(e){return r.apply(i(this),arguments)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).filter,i=n(44),a=o.aTypedArray,c=o.aTypedArrayConstructor;(0,o.exportTypedArrayMethod)("filter",(function(e){for(var t=r(a(this),e,arguments.length>1?arguments[1]:undefined),n=i(this,this.constructor),o=0,l=t.length,d=new(c(n))(l);l>o;)d[o]=t[o++];return d}))},function(e,t,n){"use strict";var o=n(10),r=n(18).find,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("find",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).findIndex,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("findIndex",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).forEach,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("forEach",(function(e){r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(116);(0,n(10).exportTypedArrayStaticMethod)("from",n(161),o)},function(e,t,n){"use strict";var o=n(10),r=n(61).includes,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("includes",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(61).indexOf,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("indexOf",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(6),r=n(10),i=n(141),a=n(13)("iterator"),c=o.Uint8Array,l=i.values,d=i.keys,u=i.entries,s=r.aTypedArray,p=r.exportTypedArrayMethod,f=c&&c.prototype[a],m=!!f&&("values"==f.name||f.name==undefined),h=function(){return l.call(s(this))};p("entries",(function(){return u.call(s(this))})),p("keys",(function(){return d.call(s(this))})),p("values",h,!m),p(a,h,!m)},function(e,t,n){"use strict";var o=n(10),r=o.aTypedArray,i=o.exportTypedArrayMethod,a=[].join;i("join",(function(e){return a.apply(r(this),arguments)}))},function(e,t,n){"use strict";var o=n(10),r=n(144),i=o.aTypedArray;(0,o.exportTypedArrayMethod)("lastIndexOf",(function(e){return r.apply(i(this),arguments)}))},function(e,t,n){"use strict";var o=n(10),r=n(18).map,i=n(44),a=o.aTypedArray,c=o.aTypedArrayConstructor;(0,o.exportTypedArrayMethod)("map",(function(e){return r(a(this),e,arguments.length>1?arguments[1]:undefined,(function(e,t){return new(c(i(e,e.constructor)))(t)}))}))},function(e,t,n){"use strict";var o=n(10),r=n(116),i=o.aTypedArrayConstructor;(0,o.exportTypedArrayStaticMethod)("of",(function(){for(var e=0,t=arguments.length,n=new(i(this))(t);t>e;)n[e]=arguments[e++];return n}),r)},function(e,t,n){"use strict";var o=n(10),r=n(75).left,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("reduce",(function(e){return r(i(this),e,arguments.length,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=n(75).right,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("reduceRight",(function(e){return r(i(this),e,arguments.length,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=o.aTypedArray,i=o.exportTypedArrayMethod,a=Math.floor;i("reverse",(function(){for(var e,t=r(this).length,n=a(t/2),o=0;o1?arguments[1]:undefined,1),n=this.length,o=a(e),c=r(o.length),d=0;if(c+t>n)throw RangeError("Wrong length");for(;di;)u[i]=n[i++];return u}),i((function(){new Int8Array(1).slice()})))},function(e,t,n){"use strict";var o=n(10),r=n(18).some,i=o.aTypedArray;(0,o.exportTypedArrayMethod)("some",(function(e){return r(i(this),e,arguments.length>1?arguments[1]:undefined)}))},function(e,t,n){"use strict";var o=n(10),r=o.aTypedArray,i=o.exportTypedArrayMethod,a=[].sort;i("sort",(function(e){return a.call(r(this),e)}))},function(e,t,n){"use strict";var o=n(10),r=n(11),i=n(40),a=n(44),c=o.aTypedArray;(0,o.exportTypedArrayMethod)("subarray",(function(e,t){var n=c(this),o=n.length,l=i(e,o);return new(a(n,n.constructor))(n.buffer,n.byteOffset+l*n.BYTES_PER_ELEMENT,r((t===undefined?o:i(t,o))-l))}))},function(e,t,n){"use strict";var o=n(6),r=n(10),i=n(5),a=o.Int8Array,c=r.aTypedArray,l=r.exportTypedArrayMethod,d=[].toLocaleString,u=[].slice,s=!!a&&i((function(){d.call(new a(1))}));l("toLocaleString",(function(){return d.apply(s?u.call(c(this)):c(this),arguments)}),i((function(){return[1,2].toLocaleString()!=new a([1,2]).toLocaleString()}))||!i((function(){a.prototype.toLocaleString.call([1,2])})))},function(e,t,n){"use strict";var o=n(10).exportTypedArrayMethod,r=n(5),i=n(6).Uint8Array,a=i&&i.prototype||{},c=[].toString,l=[].join;r((function(){c.call({})}))&&(c=function(){return l.call(this)});var d=a.toString!=c;o("toString",c,d)},function(e,t,n){"use strict";var o,r=n(6),i=n(67),a=n(50),c=n(77),l=n(162),d=n(7),u=n(34).enforce,s=n(129),p=!r.ActiveXObject&&"ActiveXObject"in r,f=Object.isExtensible,m=function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}},h=e.exports=c("WeakMap",m,l);if(s&&p){o=l.getConstructor(m,"WeakMap",!0),a.REQUIRED=!0;var g=h.prototype,C=g["delete"],b=g.has,v=g.get,N=g.set;i(g,{"delete":function(e){if(d(e)&&!f(e)){var t=u(this);return t.frozen||(t.frozen=new o),C.call(this,e)||t.frozen["delete"](e)}return C.call(this,e)},has:function(e){if(d(e)&&!f(e)){var t=u(this);return t.frozen||(t.frozen=new o),b.call(this,e)||t.frozen.has(e)}return b.call(this,e)},get:function(e){if(d(e)&&!f(e)){var t=u(this);return t.frozen||(t.frozen=new o),b.call(this,e)?v.call(this,e):t.frozen.get(e)}return v.call(this,e)},set:function(e,t){if(d(e)&&!f(e)){var n=u(this);n.frozen||(n.frozen=new o),b.call(this,e)?N.call(this,e,t):n.frozen.set(e,t)}else N.call(this,e,t);return this}})}},function(e,t,n){"use strict";n(77)("WeakSet",(function(e){return function(){return e(this,arguments.length?arguments[0]:undefined)}}),n(162))},function(e,t,n){"use strict";var o=n(0),r=n(6),i=n(108);o({global:!0,bind:!0,enumerable:!0,forced:!r.setImmediate||!r.clearImmediate},{setImmediate:i.set,clearImmediate:i.clear})},function(e,t,n){"use strict";var o=n(0),r=n(6),i=n(155),a=n(32),c=r.process,l="process"==a(c);o({global:!0,enumerable:!0,noTargetGet:!0},{queueMicrotask:function(e){var t=l&&c.domain;i(t?t.bind(e):e)}})},function(e,t,n){"use strict";var o=n(0),r=n(6),i=n(72),a=[].slice,c=function(e){return function(t,n){var o=arguments.length>2,r=o?a.call(arguments,2):undefined;return e(o?function(){("function"==typeof t?t:Function(t)).apply(this,r)}:t,n)}};o({global:!0,bind:!0,forced:/MSIE .\./.test(i)},{setTimeout:c(r.setTimeout),setInterval:c(r.setInterval)})},function(e,t,n){"use strict";t.__esModule=!0,t._CI=Be,t._HI=j,t._M=Se,t._MCCC=Ae,t._ME=Ee,t._MFCC=Oe,t._MP=we,t._MR=be,t.__render=Fe,t.createComponentVNode=function(e,t,n,o,r){var a=new S(1,null,null,e=function(e,t){if(12&e)return e;if(t.prototype&&t.prototype.render)return 4;if(t.render)return 32776;return 8}(e,t),o,function(e,t,n){var o=(32768&e?t.render:t).defaultProps;if(i(o))return n;if(i(n))return u(o,null);return L(n,o)}(e,t,n),function(e,t,n){if(4&e)return n;var o=(32768&e?t.render:t).defaultHooks;if(i(o))return n;if(i(n))return o;return L(n,o)}(e,t,r),t);k.createVNode&&k.createVNode(a);return a},t.createFragment=T,t.createPortal=function(e,t){var n=j(e);return I(1024,1024,null,n,0,null,n.key,t)},t.createRef=function(){return{current:null}},t.createRenderer=function(e){return function(t,n,o,r){e||(e=t),Re(n,e,o,r)}},t.createTextVNode=E,t.createVNode=I,t.directClone=A,t.findDOMfromVNode=v,t.forwardRef=function(e){return{render:e}},t.getFlagsForElementVnode=function(e){switch(e){case"svg":return 32;case"input":return 64;case"select":return 256;case"textarea":return 128;case"$F":return 8192;default:return 1}},t.linkEvent=function(e,t){if(c(t))return{data:e,event:t};return null},t.normalizeProps=function(e){var t=e.props;if(t){var n=e.flags;481&n&&(void 0!==t.children&&i(e.children)&&P(e,t.children),void 0!==t.className&&(e.className=t.className||null,t.className=undefined)),void 0!==t.key&&(e.key=t.key,t.key=undefined),void 0!==t.ref&&(e.ref=8&n?u(e.ref,t.ref):t.ref,t.ref=undefined)}return e},t.render=Re,t.rerender=Ye,t.version=t.options=t.Fragment=t.EMPTY_OBJ=t.Component=void 0;var o=Array.isArray;function r(e){var t=typeof e;return"string"===t||"number"===t}function i(e){return null==e}function a(e){return null===e||!1===e||!0===e||void 0===e}function c(e){return"function"==typeof e}function l(e){return"string"==typeof e}function d(e){return null===e}function u(e,t){var n={};if(e)for(var o in e)n[o]=e[o];if(t)for(var r in t)n[r]=t[r];return n}function s(e){return!d(e)&&"object"==typeof e}var p={};t.EMPTY_OBJ=p;function f(e){return e.substr(2).toLowerCase()}function m(e,t){e.appendChild(t)}function h(e,t,n){d(n)?m(e,t):e.insertBefore(t,n)}function g(e,t){e.removeChild(t)}function C(e){for(var t=0;t0,m=d(p),h=l(p)&&"$"===p[0];f||m||h?(n=n||t.slice(0,u),(f||h)&&(s=A(s)),(m||h)&&(s.key="$"+u),n.push(s)):n&&n.push(s),s.flags|=65536}}i=0===(n=n||t).length?1:8}else(n=t).flags|=65536,81920&t.flags&&(n=A(t)),i=2;return e.children=n,e.childFlags=i,e}function j(e){return a(e)||r(e)?E(e,null):o(e)?T(e,0,null):16384&e.flags?A(e):e}var D="http://www.w3.org/1999/xlink",F="http://www.w3.org/XML/1998/namespace",R={"xlink:actuate":D,"xlink:arcrole":D,"xlink:href":D,"xlink:role":D,"xlink:show":D,"xlink:title":D,"xlink:type":D,"xml:base":F,"xml:lang":F,"xml:space":F};function z(e){return{onClick:e,onDblClick:e,onFocusIn:e,onFocusOut:e,onKeyDown:e,onKeyPress:e,onKeyUp:e,onMouseDown:e,onMouseMove:e,onMouseUp:e,onTouchEnd:e,onTouchMove:e,onTouchStart:e}}var W=z(0),U=z(null),K=z(!0);function H(e,t){var n=t.$EV;return n||(n=t.$EV=z(null)),n[e]||1==++W[e]&&(U[e]=function(e){var t="onClick"===e||"onDblClick"===e?function(e){return function(t){0===t.button?q(t,!0,e,Q(t)):t.stopPropagation()}}(e):function(e){return function(t){q(t,!1,e,Q(t))}}(e);return document.addEventListener(f(e),t),t}(e)),n}function Y(e,t){var n=t.$EV;n&&n[e]&&(0==--W[e]&&(document.removeEventListener(f(e),U[e]),U[e]=null),n[e]=null)}function q(e,t,n,o){var r=function(e){return c(e.composedPath)?e.composedPath()[0]:e.target}(e);do{if(t&&r.disabled)return;var i=r.$EV;if(i){var a=i[n];if(a&&(o.dom=r,a.event?a.event(a.data,e):a(e),e.cancelBubble))return}r=r.parentNode}while(!d(r))}function G(){this.cancelBubble=!0,this.immediatePropagationStopped||this.stopImmediatePropagation()}function $(){return this.defaultPrevented}function X(){return this.cancelBubble}function Q(e){var t={dom:document};return e.isDefaultPrevented=$,e.isPropagationStopped=X,e.stopPropagation=G,Object.defineProperty(e,"currentTarget",{configurable:!0,get:function(){return t.dom}}),t}function J(e,t,n){if(e[t]){var o=e[t];o.event?o.event(o.data,n):o(n)}else{var r=t.toLowerCase();e[r]&&e[r](n)}}function Z(e,t){var n=function(n){var o=this.$V;if(o){var r=o.props||p,i=o.dom;if(l(e))J(r,e,n);else for(var a=0;a-1&&t.options[a]&&(c=t.options[a].value),n&&i(c)&&(c=e.defaultValue),ae(o,c)}}var de,ue,se=Z("onInput",fe),pe=Z("onChange");function fe(e,t,n){var o=e.value,r=t.value;if(i(o)){if(n){var a=e.defaultValue;i(a)||a===r||(t.defaultValue=a,t.value=a)}}else r!==o&&(t.defaultValue=o,t.value=o)}function me(e,t,n,o,r,i){64&e?ie(o,n):256&e?le(o,n,r,t):128&e&&fe(o,n,r),i&&(n.$V=t)}function he(e,t,n){64&e?function(e,t){te(t.type)?(ee(e,"change",oe),ee(e,"click",re)):ee(e,"input",ne)}(t,n):256&e?function(e){ee(e,"change",ce)}(t):128&e&&function(e,t){ee(e,"input",se),t.onChange&&ee(e,"change",pe)}(t,n)}function ge(e){return e.type&&te(e.type)?!i(e.checked):!i(e.value)}function Ce(e){e&&!B(e,null)&&e.current&&(e.current=null)}function be(e,t,n){e&&(c(e)||void 0!==e.current)&&n.push((function(){B(e,t)||void 0===e.current||(e.current=t)}))}function ve(e,t){Ne(e),N(e,t)}function Ne(e){var t,n=e.flags,o=e.children;if(481&n){t=e.ref;var r=e.props;Ce(t);var a=e.childFlags;if(!d(r))for(var l=Object.keys(r),u=0,s=l.length;u0;for(var c in a&&(i=ge(n))&&he(t,o,n),n)_e(c,null,n[c],o,r,i,null);a&&me(t,e,o,n,!0,i)}function Le(e,t,n){var o=j(e.render(t,e.state,n)),r=n;return c(e.getChildContext)&&(r=u(n,e.getChildContext())),e.$CX=r,o}function Be(e,t,n,o,r,i){var a=new t(n,o),l=a.$N=Boolean(t.getDerivedStateFromProps||a.getSnapshotBeforeUpdate);if(a.$SVG=r,a.$L=i,e.children=a,a.$BS=!1,a.context=o,a.props===p&&(a.props=n),l)a.state=y(a,n,a.state);else if(c(a.componentWillMount)){a.$BR=!0,a.componentWillMount();var u=a.$PS;if(!d(u)){var s=a.state;if(d(s))a.state=u;else for(var f in u)s[f]=u[f];a.$PS=null}a.$BR=!1}return a.$LI=Le(a,n,o),a}function Se(e,t,n,o,r,i){var a=e.flags|=16384;481&a?Ee(e,t,n,o,r,i):4&a?function(e,t,n,o,r,i){var a=Be(e,e.type,e.props||p,n,o,i);Se(a.$LI,t,a.$CX,o,r,i),Ae(e.ref,a,i)}(e,t,n,o,r,i):8&a?(!function(e,t,n,o,r,i){Se(e.children=j(function(e,t){return 32768&e.flags?e.type.render(e.props||p,e.ref,t):e.type(e.props||p,t)}(e,n)),t,n,o,r,i)}(e,t,n,o,r,i),Oe(e,i)):512&a||16&a?Ie(e,t,r):8192&a?function(e,t,n,o,r,i){var a=e.children,c=e.childFlags;12&c&&0===a.length&&(c=e.childFlags=2,a=e.children=O());2===c?Se(a,n,r,o,r,i):Te(a,n,t,o,r,i)}(e,n,t,o,r,i):1024&a&&function(e,t,n,o,r){Se(e.children,e.ref,t,!1,null,r);var i=O();Ie(i,n,o),e.dom=i.dom}(e,n,t,r,i)}function Ie(e,t,n){var o=e.dom=document.createTextNode(e.children);d(t)||h(t,o,n)}function Ee(e,t,n,o,r,a){var c=e.flags,l=e.props,u=e.className,s=e.children,p=e.childFlags,f=e.dom=function(e,t){return t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}(e.type,o=o||(32&c)>0);if(i(u)||""===u||(o?f.setAttribute("class",u):f.className=u),16===p)_(f,s);else if(1!==p){var m=o&&"foreignObject"!==e.type;2===p?(16384&s.flags&&(e.children=s=A(s)),Se(s,f,n,m,null,a)):8!==p&&4!==p||Te(s,f,n,m,null,a)}d(t)||h(t,f,r),d(l)||we(e,c,l,f,o),be(e.ref,f,a)}function Te(e,t,n,o,r,i){for(var a=0;a0,d!==u){var m=d||p;if((c=u||p)!==p)for(var h in(s=(448&r)>0)&&(f=ge(c)),c){var g=m[h],C=c[h];g!==C&&_e(h,g,C,l,o,f,e)}if(m!==p)for(var b in m)i(c[b])&&!i(m[b])&&_e(b,m[b],null,l,o,f,e)}var v=t.children,N=t.className;e.className!==N&&(i(N)?l.removeAttribute("class"):o?l.setAttribute("class",N):l.className=N);4096&r?function(e,t){e.textContent!==t&&(e.textContent=t)}(l,v):Pe(e.childFlags,t.childFlags,e.children,v,l,n,o&&"foreignObject"!==t.type,null,e,a);s&&me(r,t,l,c,!1,f);var V=t.ref,y=e.ref;y!==V&&(Ce(y),be(V,l,a))}(e,t,o,r,f,s):4&f?function(e,t,n,o,r,i,a){var l=t.children=e.children;if(d(l))return;l.$L=a;var s=t.props||p,f=t.ref,m=e.ref,h=l.state;if(!l.$N){if(c(l.componentWillReceiveProps)){if(l.$BR=!0,l.componentWillReceiveProps(s,o),l.$UN)return;l.$BR=!1}d(l.$PS)||(h=u(h,l.$PS),l.$PS=null)}je(l,h,s,n,o,r,!1,i,a),m!==f&&(Ce(m),be(f,l,a))}(e,t,n,o,r,l,s):8&f?function(e,t,n,o,r,a,l){var d=!0,u=t.props||p,s=t.ref,f=e.props,m=!i(s),h=e.children;m&&c(s.onComponentShouldUpdate)&&(d=s.onComponentShouldUpdate(f,u));if(!1!==d){m&&c(s.onComponentWillUpdate)&&s.onComponentWillUpdate(f,u);var g=t.type,C=j(32768&t.flags?g.render(u,s,o):g(u,o));Me(h,C,n,o,r,a,l),t.children=C,m&&c(s.onComponentDidUpdate)&&s.onComponentDidUpdate(f,u)}else t.children=h}(e,t,n,o,r,l,s):16&f?function(e,t){var n=t.children,o=t.dom=e.dom;n!==e.children&&(o.nodeValue=n)}(e,t):512&f?t.dom=e.dom:8192&f?function(e,t,n,o,r,i){var a=e.children,c=t.children,l=e.childFlags,d=t.childFlags,u=null;12&d&&0===c.length&&(d=t.childFlags=2,c=t.children=O());var s=0!=(2&d);if(12&l){var p=a.length;(8&l&&8&d||s||!s&&c.length>p)&&(u=v(a[p-1],!1).nextSibling)}Pe(l,d,a,c,n,o,r,u,e,i)}(e,t,n,o,r,s):function(e,t,n,o){var r=e.ref,i=t.ref,c=t.children;if(Pe(e.childFlags,t.childFlags,e.children,c,r,n,!1,null,e,o),t.dom=e.dom,r!==i&&!a(c)){var l=c.dom;g(r,l),m(i,l)}}(e,t,o,s)}function Pe(e,t,n,o,r,i,a,c,l,d){switch(e){case 2:switch(t){case 2:Me(n,o,r,i,a,c,d);break;case 1:ve(n,r);break;case 16:Ne(n),_(r,o);break;default:!function(e,t,n,o,r,i){Ne(e),Te(t,n,o,r,v(e,!0),i),N(e,n)}(n,o,r,i,a,d)}break;case 1:switch(t){case 2:Se(o,r,i,a,c,d);break;case 1:break;case 16:_(r,o);break;default:Te(o,r,i,a,c,d)}break;case 16:switch(t){case 16:!function(e,t,n){e!==t&&(""!==e?n.firstChild.nodeValue=t:_(n,t))}(n,o,r);break;case 2:ye(r),Se(o,r,i,a,c,d);break;case 1:ye(r);break;default:ye(r),Te(o,r,i,a,c,d)}break;default:switch(t){case 16:Ve(n),_(r,o);break;case 2:xe(r,l,n),Se(o,r,i,a,c,d);break;case 1:xe(r,l,n);break;default:var u=0|n.length,s=0|o.length;0===u?s>0&&Te(o,r,i,a,c,d):0===s?xe(r,l,n):8===t&&8===e?function(e,t,n,o,r,i,a,c,l,d){var u,s,p=i-1,f=a-1,m=0,h=e[m],g=t[m];e:{for(;h.key===g.key;){if(16384&g.flags&&(t[m]=g=A(g)),Me(h,g,n,o,r,c,d),e[m]=g,++m>p||m>f)break e;h=e[m],g=t[m]}for(h=e[p],g=t[f];h.key===g.key;){if(16384&g.flags&&(t[f]=g=A(g)),Me(h,g,n,o,r,c,d),e[p]=g,p--,f--,m>p||m>f)break e;h=e[p],g=t[f]}}if(m>p){if(m<=f)for(s=(u=f+1)f)for(;m<=p;)ve(e[m++],n);else!function(e,t,n,o,r,i,a,c,l,d,u,s,p){var f,m,h,g=0,C=c,b=c,N=i-c+1,y=a-c+1,x=new Int32Array(y+1),k=N===o,_=!1,w=0,L=0;if(r<4||(N|y)<32)for(g=C;g<=i;++g)if(f=e[g],Lc?_=!0:w=c,16384&m.flags&&(t[c]=m=A(m)),Me(f,m,l,n,d,u,p),++L;break}!k&&c>a&&ve(f,l)}else k||ve(f,l);else{var B={};for(g=b;g<=a;++g)B[t[g].key]=g;for(g=C;g<=i;++g)if(f=e[g],LC;)ve(e[C++],l);x[c-b]=g+1,w>c?_=!0:w=c,16384&(m=t[c]).flags&&(t[c]=m=A(m)),Me(f,m,l,n,d,u,p),++L}else k||ve(f,l);else k||ve(f,l)}if(k)xe(l,s,e),Te(t,l,n,d,u,p);else if(_){var S=function(e){var t=0,n=0,o=0,r=0,i=0,a=0,c=0,l=e.length;l>De&&(De=l,de=new Int32Array(l),ue=new Int32Array(l));for(;n>1]]0&&(ue[n]=de[i-1]),de[i]=n)}i=r+1;var d=new Int32Array(i);a=de[i-1];for(;i-- >0;)d[i]=a,a=ue[a],de[i]=0;return d}(x);for(c=S.length-1,g=y-1;g>=0;g--)0===x[g]?(16384&(m=t[w=g+b]).flags&&(t[w]=m=A(m)),Se(m,l,n,d,(h=w+1)=0;g--)0===x[g]&&(16384&(m=t[w=g+b]).flags&&(t[w]=m=A(m)),Se(m,l,n,d,(h=w+1)a?a:i,p=0;pa)for(p=s;p=0;--r){var i=this.tryEntries[r],a=i.completion;if("root"===i.tryLoc)return o("end");if(i.tryLoc<=this.prev){var c=n.call(i,"catchLoc"),l=n.call(i,"finallyLoc");if(c&&l){if(this.prev=0;--o){var r=this.tryEntries[o];if(r.tryLoc<=this.prev&&n.call(r,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),y(n),u}},"catch":function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var o=n.completion;if("throw"===o.type){var r=o.arg;y(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:x(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),u}},e}(e.exports);try{regeneratorRuntime=o}catch(r){Function("r","regeneratorRuntime = r")(o)}},function(e,t,n){"use strict";t.__esModule=!0,t.vecNormalize=t.vecLength=t.vecInverse=t.vecScale=t.vecDivide=t.vecMultiply=t.vecSubtract=t.vecAdd=t.vecCreate=void 0;var o=n(69);t.vecCreate=function(){for(var e=arguments.length,t=new Array(e),n=0;n3?c(a):null,C=String(a.key),N=String(a.char),y=a.location,V=a.keyCode||(a.keyCode=C)&&C.charCodeAt(0)||0,x=a.charCode||(a.charCode=N)&&N.charCodeAt(0)||0,w=a.bubbles,k=a.cancelable,_=a.repeat,L=a.locale,S=a.view||e;if(a.which||(a.which=a.keyCode),"initKeyEvent"in f)f.initKeyEvent(t,w,k,S,p,h,m,g,V,x);else if(0>>0),t=Element.prototype,n=t.querySelector,o=t.querySelectorAll;function r(t,n,o){t.setAttribute(e,null);var r=n.call(t,String(o).replace(/(^|,\s*)(:scope([ >]|$))/g,(function(t,n,o,r){return n+"["+e+"]"+(r||" ")})));return t.removeAttribute(e),r}t.querySelector=function(e){return r(this,n,e)},t.querySelectorAll=function(e){return r(this,o,e)}}()}}(window),function(e){var t=e.WeakMap||function(){var e,t=0,n=!1,o=!1;function r(t,r,i){o=i,n=!1,e=undefined,t.dispatchEvent(r)}function i(e){this.value=e}function c(){t++,this.__ce__=new a("@DOMMap:"+t+Math.random())}return i.prototype.handleEvent=function(t){n=!0,o?t.currentTarget.removeEventListener(t.type,this,!1):e=this.value},c.prototype={constructor:c,"delete":function(e){return r(e,this.__ce__,!0),n},get:function(t){r(t,this.__ce__,!1);var n=e;return e=undefined,n},has:function(e){return r(e,this.__ce__,!1),n},set:function(e,t){return r(e,this.__ce__,!0),e.addEventListener(this.__ce__.type,new i(t),!1),this}},c}();function n(){}function o(e,t,n){function r(e){r.once&&(e.currentTarget.removeEventListener(e.type,t,r),r.removed=!0),r.passive&&(e.preventDefault=o.preventDefault),"function"==typeof r.callback?r.callback.call(this,e):r.callback&&r.callback.handleEvent(e),r.passive&&delete e.preventDefault}return r.type=e,r.callback=t,r.capture=!!n.capture,r.passive=!!n.passive,r.once=!!n.once,r.removed=!1,r}n.prototype=(Object.create||Object)(null),o.preventDefault=function(){};var r,i,a=e.CustomEvent,c=e.dispatchEvent,l=e.addEventListener,u=e.removeEventListener,s=0,d=function(){s++},f=[].indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},p=function(e){return"".concat(e.capture?"1":"0",e.passive?"1":"0",e.once?"1":"0")};try{l("_",d,{once:!0}),c(new a("_")),c(new a("_")),u("_",d,{once:!0})}catch(m){}1!==s&&(i=new t,r=function(e){if(e){var t=e.prototype;t.addEventListener=function(e){return function(t,r,a){if(a&&"boolean"!=typeof a){var c,l,u,s=i.get(this),d=p(a);s||i.set(this,s=new n),t in s||(s[t]={handler:[],wrap:[]}),l=s[t],(c=f.call(l.handler,r))<0?(c=l.handler.push(r)-1,l.wrap[c]=u=new n):u=l.wrap[c],d in u||(u[d]=o(t,r,a),e.call(this,t,u[d],u[d].capture))}else e.call(this,t,r,a)}}(t.addEventListener),t.removeEventListener=function(e){return function(t,n,o){if(o&&"boolean"!=typeof o){var r,a,c,l,u=i.get(this);if(u&&t in u&&(c=u[t],-1<(a=f.call(c.handler,n))&&(r=p(o))in(l=c.wrap[a]))){for(r in e.call(this,t,l[r],l[r].capture),delete l[r],l)return;c.handler.splice(a,1),c.wrap.splice(a,1),0===c.handler.length&&delete u[t]}}else e.call(this,t,n,o)}}(t.removeEventListener)}},e.EventTarget?r(EventTarget):(r(e.Text),r(e.Element||e.HTMLElement),r(e.HTMLDocument),r(e.Window||{prototype:e}),r(e.XMLHttpRequest)))}(window)},function(e,t,n){"use strict";!function(t,n){var o,r,i=t.html5||{},a=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,c=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,l=0,u={};function s(){var e=m.elements;return"string"==typeof e?e.split(" "):e}function d(e){var t=u[e._html5shiv];return t||(t={},l++,e._html5shiv=l,u[l]=t),t}function f(e,t,o){return t||(t=n),r?t.createElement(e):(o||(o=d(t)),!(i=o.cache[e]?o.cache[e].cloneNode():c.test(e)?(o.cache[e]=o.createElem(e)).cloneNode():o.createElem(e)).canHaveChildren||a.test(e)||i.tagUrn?i:o.frag.appendChild(i));var i}function p(e){e||(e=n);var t=d(e);return!m.shivCSS||o||t.hasCSS||(t.hasCSS=!!function(e,t){var n=e.createElement("p"),o=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x",o.insertBefore(n.lastChild,o.firstChild)}(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),r||function(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return m.shivMethods?f(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+s().join().replace(/[\w\-:]+/g,(function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'}))+");return n}")(m,t.frag)}(e,t),e}!function(){try{var e=n.createElement("a");e.innerHTML="",o="hidden"in e,r=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){o=!0,r=!0}}();var m={elements:i.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:"3.7.3",shivCSS:!1!==i.shivCSS,supportsUnknownElements:r,shivMethods:!1!==i.shivMethods,type:"default",shivDocument:p,createElement:f,createDocumentFragment:function(e,t){if(e||(e=n),r)return e.createDocumentFragment();for(var o=(t=t||d(e)).frag.cloneNode(),i=0,a=s(),c=a.length;i=0;--r){var i=this.tryEntries[r],a=i.completion;if("root"===i.tryLoc)return o("end");if(i.tryLoc<=this.prev){var c=n.call(i,"catchLoc"),l=n.call(i,"finallyLoc");if(c&&l){if(this.prev=0;--o){var r=this.tryEntries[o];if(r.tryLoc<=this.prev&&n.call(r,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),V(n),d}},"catch":function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var o=n.completion;if("throw"===o.type){var r=o.arg;V(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:x(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),d}},e}(e.exports);try{regeneratorRuntime=o}catch(r){Function("r","regeneratorRuntime = r")(o)}},function(e,t,n){"use strict";t.__esModule=!0,t.vecNormalize=t.vecLength=t.vecInverse=t.vecScale=t.vecDivide=t.vecMultiply=t.vecSubtract=t.vecAdd=t.vecCreate=void 0;var o=n(56);t.vecCreate=function(){for(var e=arguments.length,t=new Array(e),n=0;n3?c(a):null,v=String(a.key),N=String(a.char),V=a.location,y=a.keyCode||(a.keyCode=v)&&v.charCodeAt(0)||0,x=a.charCode||(a.charCode=N)&&N.charCodeAt(0)||0,k=a.bubbles,_=a.cancelable,w=a.repeat,L=a.locale,B=a.view||e;if(a.which||(a.which=a.keyCode),"initKeyEvent"in p)p.initKeyEvent(t,k,_,B,f,h,m,g,y,x);else if(0>>0),t=Element.prototype,n=t.querySelector,o=t.querySelectorAll;function r(t,n,o){t.setAttribute(e,null);var r=n.call(t,String(o).replace(/(^|,\s*)(:scope([ >]|$))/g,(function(t,n,o,r){return n+"["+e+"]"+(r||" ")})));return t.removeAttribute(e),r}t.querySelector=function(e){return r(this,n,e)},t.querySelectorAll=function(e){return r(this,o,e)}}()}}(window),function(e){var t=e.WeakMap||function(){var e,t=0,n=!1,o=!1;function r(t,r,i){o=i,n=!1,e=undefined,t.dispatchEvent(r)}function i(e){this.value=e}function c(){t++,this.__ce__=new a("@DOMMap:"+t+Math.random())}return i.prototype.handleEvent=function(t){n=!0,o?t.currentTarget.removeEventListener(t.type,this,!1):e=this.value},c.prototype={constructor:c,"delete":function(e){return r(e,this.__ce__,!0),n},get:function(t){r(t,this.__ce__,!1);var n=e;return e=undefined,n},has:function(e){return r(e,this.__ce__,!1),n},set:function(e,t){return r(e,this.__ce__,!0),e.addEventListener(this.__ce__.type,new i(t),!1),this}},c}();function n(){}function o(e,t,n){function r(e){r.once&&(e.currentTarget.removeEventListener(e.type,t,r),r.removed=!0),r.passive&&(e.preventDefault=o.preventDefault),"function"==typeof r.callback?r.callback.call(this,e):r.callback&&r.callback.handleEvent(e),r.passive&&delete e.preventDefault}return r.type=e,r.callback=t,r.capture=!!n.capture,r.passive=!!n.passive,r.once=!!n.once,r.removed=!1,r}n.prototype=(Object.create||Object)(null),o.preventDefault=function(){};var r,i,a=e.CustomEvent,c=e.dispatchEvent,l=e.addEventListener,d=e.removeEventListener,u=0,s=function(){u++},p=[].indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},f=function(e){return"".concat(e.capture?"1":"0",e.passive?"1":"0",e.once?"1":"0")};try{l("_",s,{once:!0}),c(new a("_")),c(new a("_")),d("_",s,{once:!0})}catch(m){}1!==u&&(i=new t,r=function(e){if(e){var t=e.prototype;t.addEventListener=function(e){return function(t,r,a){if(a&&"boolean"!=typeof a){var c,l,d,u=i.get(this),s=f(a);u||i.set(this,u=new n),t in u||(u[t]={handler:[],wrap:[]}),l=u[t],(c=p.call(l.handler,r))<0?(c=l.handler.push(r)-1,l.wrap[c]=d=new n):d=l.wrap[c],s in d||(d[s]=o(t,r,a),e.call(this,t,d[s],d[s].capture))}else e.call(this,t,r,a)}}(t.addEventListener),t.removeEventListener=function(e){return function(t,n,o){if(o&&"boolean"!=typeof o){var r,a,c,l,d=i.get(this);if(d&&t in d&&(c=d[t],-1<(a=p.call(c.handler,n))&&(r=f(o))in(l=c.wrap[a]))){for(r in e.call(this,t,l[r],l[r].capture),delete l[r],l)return;c.handler.splice(a,1),c.wrap.splice(a,1),0===c.handler.length&&delete d[t]}}else e.call(this,t,n,o)}}(t.removeEventListener)}},e.EventTarget?r(EventTarget):(r(e.Text),r(e.Element||e.HTMLElement),r(e.HTMLDocument),r(e.Window||{prototype:e}),r(e.XMLHttpRequest)))}(window)},function(e,t,n){"use strict";!function(t,n){var o,r,i=t.html5||{},a=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,c=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,l=0,d={};function u(){var e=m.elements;return"string"==typeof e?e.split(" "):e}function s(e){var t=d[e._html5shiv];return t||(t={},l++,e._html5shiv=l,d[l]=t),t}function p(e,t,o){return t||(t=n),r?t.createElement(e):(o||(o=s(t)),!(i=o.cache[e]?o.cache[e].cloneNode():c.test(e)?(o.cache[e]=o.createElem(e)).cloneNode():o.createElem(e)).canHaveChildren||a.test(e)||i.tagUrn?i:o.frag.appendChild(i));var i}function f(e){e||(e=n);var t=s(e);return!m.shivCSS||o||t.hasCSS||(t.hasCSS=!!function(e,t){var n=e.createElement("p"),o=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x",o.insertBefore(n.lastChild,o.firstChild)}(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),r||function(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return m.shivMethods?p(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+u().join().replace(/[\w\-:]+/g,(function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'}))+");return n}")(m,t.frag)}(e,t),e}!function(){try{var e=n.createElement("a");e.innerHTML="",o="hidden"in e,r=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){o=!0,r=!0}}();var m={elements:i.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:"3.7.3",shivCSS:!1!==i.shivCSS,supportsUnknownElements:r,shivMethods:!1!==i.shivMethods,type:"default",shivDocument:f,createElement:p,createDocumentFragment:function(e,t){if(e||(e=n),r)return e.createDocumentFragment();for(var o=(t=t||s(e)).frag.cloneNode(),i=0,a=u(),c=a.length;i1?r-1:0),a=1;a1?t-1:0),o=1;o=0||(r[n]=e[n]);return r}(e,["className"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["BlockQuote",t])},n)))}},function(e,t,n){"use strict";var o,r;t.__esModule=!0,t.VNodeFlags=t.ChildFlags=void 0,t.VNodeFlags=o,function(e){e[e.HtmlElement=1]="HtmlElement",e[e.ComponentUnknown=2]="ComponentUnknown",e[e.ComponentClass=4]="ComponentClass",e[e.ComponentFunction=8]="ComponentFunction",e[e.Text=16]="Text",e[e.SvgElement=32]="SvgElement",e[e.InputElement=64]="InputElement",e[e.TextareaElement=128]="TextareaElement",e[e.SelectElement=256]="SelectElement",e[e.Void=512]="Void",e[e.Portal=1024]="Portal",e[e.ReCreate=2048]="ReCreate",e[e.ContentEditable=4096]="ContentEditable",e[e.Fragment=8192]="Fragment",e[e.InUse=16384]="InUse",e[e.ForwardRef=32768]="ForwardRef",e[e.Normalized=65536]="Normalized",e[e.ForwardRefComponent=32776]="ForwardRefComponent",e[e.FormElement=448]="FormElement",e[e.Element=481]="Element",e[e.Component=14]="Component",e[e.DOMRef=2033]="DOMRef",e[e.InUseOrNormalized=81920]="InUseOrNormalized",e[e.ClearInUse=-16385]="ClearInUse",e[e.ComponentKnown=12]="ComponentKnown"}(o||(t.VNodeFlags=o={})),t.ChildFlags=r,function(e){e[e.UnknownChildren=0]="UnknownChildren",e[e.HasInvalidChildren=1]="HasInvalidChildren",e[e.HasVNodeChildren=2]="HasVNodeChildren",e[e.HasNonKeyedChildren=4]="HasNonKeyedChildren",e[e.HasKeyedChildren=8]="HasKeyedChildren",e[e.HasTextChildren=16]="HasTextChildren",e[e.MultipleChildren=12]="MultipleChildren"}(r||(t.ChildFlags=r={}))},function(e,t,n){"use strict";t.__esModule=!0,t.ByondUi=void 0;var o=n(1),r=n(12),i=n(411),a=n(24),c=n(55),l=n(16);function u(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var s=(0,c.createLogger)("ByondUi"),d=[];window.addEventListener("beforeunload",(function(){for(var e=0;e=0||(r[n]=e[n]);return r}(t,["data","rangeX","rangeY","fillColor","strokeColor","strokeWidth"]),g=this.state.viewBox,v=function(e,t,n,o){if(0===e.length)return[];var i=(0,r.zipWith)(Math.min).apply(void 0,e),a=(0,r.zipWith)(Math.max).apply(void 0,e);return n!==undefined&&(i[0]=n[0],a[0]=n[1]),o!==undefined&&(i[1]=o[0],a[1]=o[1]),(0,r.map)((function(e){return(0,r.zipWith)((function(e,t,n,o){return(e-t)/(n-t)*o}))(e,i,a,t)}))(e)}(i,g,a,l);if(v.length>0){var b=v[0],C=v[v.length-1];v.push([g[0]+m,C[1]]),v.push([g[0]+m,-m]),v.push([-m,-m]),v.push([-m,b[1]])}var N=function(e){for(var t="",n=0;n=0||(r[n]=e[n]);return r}(t,["children","color","title","buttons"]);return(0,o.createVNode)(1,"div","Collapsible",[(0,o.createVNode)(1,"div","Table",[(0,o.createVNode)(1,"div","Table__cell",(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Button,Object.assign({fluid:!0,color:l,icon:n?"chevron-down":"chevron-right",onClick:function(){return e.setState({open:!n})}},d,{children:u}))),2),s&&(0,o.createVNode)(1,"div","Table__cell Table__cell--collapsing",s,0)],0),n&&(0,o.createComponentVNode)(2,r.Box,{mt:1,children:a})],0)},a}(o.Component);t.Collapsible=a},function(e,t,n){"use strict";t.__esModule=!0,t.ColorBox=void 0;var o=n(1),r=n(12),i=n(16);var a=function(e){var t=e.content,n=(e.children,e.className),a=e.color,c=e.backgroundColor,l=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["content","children","className","color","backgroundColor"]);return l.color=t?null:"transparent",l.backgroundColor=a||c,(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,r.classes)(["ColorBox",n,(0,i.computeBoxClassName)(l)]),t||".",0,Object.assign({},(0,i.computeBoxProps)(l))))};t.ColorBox=a,a.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.Dropdown=void 0;var o=n(1),r=n(12),i=n(16),a=n(120);function c(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var l=function(e){var t,n;function l(t){var n;return(n=e.call(this,t)||this).state={selected:t.selected,open:!1},n.handleClick=function(){n.state.open&&n.setOpen(!1)},n}n=e,(t=l).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var u=l.prototype;return u.componentWillUnmount=function(){window.removeEventListener("click",this.handleClick)},u.setOpen=function(e){var t=this;this.setState({open:e}),e?(setTimeout((function(){return window.addEventListener("click",t.handleClick)})),this.menuRef.focus()):window.removeEventListener("click",this.handleClick)},u.setSelected=function(e){this.setState({selected:e}),this.setOpen(!1),this.props.onSelected(e)},u.buildMenu=function(){var e=this,t=this.props.options,n=(void 0===t?[]:t).map((function(t){return(0,o.createVNode)(1,"div","Dropdown__menuentry",t,0,{onClick:function(){e.setSelected(t)}},t)}));return n.length?n:"No Options Found"},u.render=function(){var e=this,t=this.props,n=t.color,l=void 0===n?"default":n,u=t.over,s=t.noscroll,d=t.nochevron,f=t.width,p=(t.onClick,t.selected,t.disabled),m=c(t,["color","over","noscroll","nochevron","width","onClick","selected","disabled"]),h=m.className,g=c(m,["className"]),v=u?!this.state.open:this.state.open,b=this.state.open?(0,o.createVNode)(1,"div",(0,r.classes)([s?"Dropdown__menu-noscroll":"Dropdown__menu",u&&"Dropdown__over"]),this.buildMenu(),0,{tabIndex:"-1",style:{width:f}},null,(function(t){e.menuRef=t})):null;return(0,o.createVNode)(1,"div","Dropdown",[(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({width:f,className:(0,r.classes)(["Dropdown__control","Button","Button--color--"+l,p&&"Button--disabled",h])},g,{onClick:function(){p&&!e.state.open||e.setOpen(!e.state.open)},children:[(0,o.createVNode)(1,"span","Dropdown__selected-text",this.state.selected,0),!!d||(0,o.createVNode)(1,"span","Dropdown__arrow-button",(0,o.createComponentVNode)(2,a.Icon,{name:v?"chevron-up":"chevron-down"}),2)]}))),b],0)},l}(o.Component);t.Dropdown=l},function(e,t,n){"use strict";t.__esModule=!0,t.GridColumn=t.Grid=void 0;var o=n(1),r=n(86),i=n(12);function a(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var c=function(e){var t=e.children,n=a(e,["children"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Table,Object.assign({},n,{children:(0,o.createComponentVNode)(2,r.Table.Row,{children:t})})))};t.Grid=c,c.defaultHooks=i.pureComponentHooks;var l=function(e){var t=e.size,n=void 0===t?1:t,i=e.style,c=a(e,["size","style"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Table.Cell,Object.assign({style:Object.assign({width:n+"%"},i)},c)))};t.GridColumn=l,c.defaultHooks=i.pureComponentHooks,c.Column=l},function(e,t,n){"use strict";t.__esModule=!0,t.Input=void 0;var o=n(1),r=n(12),i=n(16);function a(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var c=function(e){return(0,r.isFalsy)(e)?"":e},l=function(e){var t,n;function l(){var t;return(t=e.call(this)||this).inputRef=(0,o.createRef)(),t.state={editing:!1},t.handleInput=function(e){var n=t.state.editing,o=t.props.onInput;n||t.setEditing(!0),o&&o(e,e.target.value)},t.handleFocus=function(e){t.state.editing||t.setEditing(!0)},t.handleBlur=function(e){var n=t.state.editing,o=t.props.onChange;n&&(t.setEditing(!1),o&&o(e,e.target.value))},t.handleKeyDown=function(e){var n=t.props,o=n.onInput,r=n.onChange,i=n.onEnter;return 13===e.keyCode?(t.setEditing(!1),r&&r(e,e.target.value),o&&o(e,e.target.value),i&&i(e,e.target.value),void(t.props.selfClear?e.target.value="":e.target.blur())):27===e.keyCode?(t.setEditing(!1),e.target.value=c(t.props.value),void e.target.blur()):void 0},t}n=e,(t=l).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var u=l.prototype;return u.componentDidMount=function(){var e=this.props.value,t=this.inputRef.current;t&&(t.value=c(e),this.props.autofocus&&(t.focus(),t.selectionStart=0,t.selectionEnd=t.value.length))},u.componentDidUpdate=function(e,t){var n=this.state.editing,o=e.value,r=this.props.value,i=this.inputRef.current;i&&!n&&o!==r&&(i.value=c(r))},u.setEditing=function(e){this.setState({editing:e})},u.render=function(){var e=this.props,t=(e.selfClear,e.onInput,e.onChange,e.onEnter,e.value,e.maxLength),n=e.placeholder,c=(e.autofocus,a(e,["selfClear","onInput","onChange","onEnter","value","maxLength","placeholder","autofocus"])),l=c.className,u=c.fluid,s=a(c,["className","fluid"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["Input",u&&"Input--fluid",l])},s,{children:[(0,o.createVNode)(1,"div","Input__baseline",".",16),(0,o.createVNode)(64,"input","Input__input",null,1,{placeholder:n,onInput:this.handleInput,onFocus:this.handleFocus,onBlur:this.handleBlur,onKeyDown:this.handleKeyDown,maxLength:t},null,this.inputRef)]})))},l}(o.Component);t.Input=l},function(e,t,n){"use strict";t.__esModule=!0,t.Knob=void 0;var o=n(1),r=n(20),i=n(12),a=n(24),c=n(16),l=n(167),u=n(121);t.Knob=function(e){if(a.IS_IE8)return(0,o.normalizeProps)((0,o.createComponentVNode)(2,u.NumberInput,Object.assign({},e)));var t=e.animated,n=e.format,s=e.maxValue,d=e.minValue,f=e.onChange,p=e.onDrag,m=e.step,h=e.stepPixelSize,g=e.suppressFlicker,v=e.unit,b=e.value,C=e.className,N=e.style,y=e.fillValue,V=e.color,x=e.ranges,w=void 0===x?{}:x,k=e.size,_=e.bipolar,L=(e.children,e.popUpPosition),S=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","style","fillValue","color","ranges","size","bipolar","children","popUpPosition"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,l.DraggableControl,Object.assign({dragMatrix:[0,-1]},{animated:t,format:n,maxValue:s,minValue:d,onChange:f,onDrag:p,step:m,stepPixelSize:h,suppressFlicker:g,unit:v,value:b},{children:function(e){var t=e.dragging,n=(e.editing,e.value),a=e.displayValue,l=e.displayElement,u=e.inputElement,f=e.handleDragStart,p=(0,r.scale)(null!=y?y:a,d,s),m=(0,r.scale)(a,d,s),h=V||(0,r.keyOfMatchingRange)(null!=y?y:n,w)||"default",g=270*(m-.5);return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,i.classes)(["Knob","Knob--color--"+h,_&&"Knob--bipolar",C,(0,c.computeBoxClassName)(S)]),[(0,o.createVNode)(1,"div","Knob__circle",(0,o.createVNode)(1,"div","Knob__cursorBox",(0,o.createVNode)(1,"div","Knob__cursor"),2,{style:{transform:"rotate("+g+"deg)"}}),2),t&&(0,o.createVNode)(1,"div",(0,i.classes)(["Knob__popupValue",L&&"Knob__popupValue--"+L]),l,0),(0,o.createVNode)(32,"svg","Knob__ring Knob__ringTrackPivot",(0,o.createVNode)(32,"circle","Knob__ringTrack",null,1,{cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),(0,o.createVNode)(32,"svg","Knob__ring Knob__ringFillPivot",(0,o.createVNode)(32,"circle","Knob__ringFill",null,1,{style:{"stroke-dashoffset":((_?2.75:2)-1.5*p)*Math.PI*50},cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),u],0,Object.assign({},(0,c.computeBoxProps)(Object.assign({style:Object.assign({"font-size":k+"rem"},N)},S)),{onMouseDown:f})))}})))}},function(e,t,n){"use strict";t.__esModule=!0,t.LabeledControls=void 0;var o=n(1),r=n(166);function i(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var a=function(e){var t=e.children,n=i(e,["children"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Flex,Object.assign({mx:-.5,align:"stretch",justify:"space-between"},n,{children:t})))};t.LabeledControls=a;a.Item=function(e){var t=e.label,n=e.children,a=i(e,["label","children"]);return(0,o.createComponentVNode)(2,r.Flex.Item,{mx:1,children:(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Flex,Object.assign({minWidth:"52px",height:"100%",direction:"column",align:"center",textAlign:"center",justify:"space-between"},a,{children:[(0,o.createComponentVNode)(2,r.Flex.Item),(0,o.createComponentVNode)(2,r.Flex.Item,{children:n}),(0,o.createComponentVNode)(2,r.Flex.Item,{color:"label",children:t})]})))})}},function(e,t,n){"use strict";t.__esModule=!0,t.NanoMap=void 0;var o=n(1),r=n(4),i=n(3),a=function(e,t){var n=(0,i.useBackend)(t).config,a=e.onClick;return(0,o.createComponentVNode)(2,r.Box,{className:"NanoMap__container",children:(0,o.createComponentVNode)(2,r.Box,{as:"img",src:n.map+"_nanomap_z1.png",style:{width:"512px",height:"512px"},onClick:a})})};t.NanoMap=a;a.Marker=function(e){var t=e.x,n=e.y,i=e.icon,a=e.tooltip,c=e.color;return(0,o.createComponentVNode)(2,r.Box,{position:"absolute",className:"NanoMap__marker",top:2*(255-n)+2+"px",left:2*t+2+"px",children:[(0,o.createComponentVNode)(2,r.Icon,{name:i,color:c,size:.5}),(0,o.createComponentVNode)(2,r.Tooltip,{content:a})]})}},function(e,t,n){"use strict";t.__esModule=!0,t.Modal=void 0;var o=n(1),r=n(12),i=n(16),a=n(164);t.Modal=function(e){var t,n=e.className,c=e.children,l=e.onEnter,u=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","children","onEnter"]);return l&&(t=function(e){13===e.keyCode&&l(e)}),(0,o.createComponentVNode)(2,a.Dimmer,{onKeyDown:t,children:(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,r.classes)(["Modal",n,(0,i.computeBoxClassName)(u)]),c,0,Object.assign({},(0,i.computeBoxProps)(u))))})}},function(e,t,n){"use strict";t.__esModule=!0,t.NoticeBox=void 0;var o=n(1),r=n(12),i=n(16);var a=function(e){var t=e.className,n=e.color,a=e.info,c=(e.warning,e.success),l=e.danger,u=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","color","info","warning","success","danger"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["NoticeBox",n&&"NoticeBox--color--"+n,a&&"NoticeBox--type--info",c&&"NoticeBox--type--success",l&&"NoticeBox--type--danger",t])},u)))};t.NoticeBox=a,a.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.ProgressBar=void 0;var o=n(1),r=n(20),i=n(12),a=n(16);var c=function(e){var t=e.className,n=e.value,c=e.minValue,l=void 0===c?0:c,u=e.maxValue,s=void 0===u?1:u,d=e.color,f=e.ranges,p=void 0===f?{}:f,m=e.children,h=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","value","minValue","maxValue","color","ranges","children"]),g=(0,r.scale)(n,l,s),v=m!==undefined,b=d||(0,r.keyOfMatchingRange)(n,p)||"default";return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,i.classes)(["ProgressBar","ProgressBar--color--"+b,t,(0,a.computeBoxClassName)(h)]),[(0,o.createVNode)(1,"div","ProgressBar__fill ProgressBar__fill--animated",null,1,{style:{width:100*(0,r.clamp01)(g)+"%"}}),(0,o.createVNode)(1,"div","ProgressBar__content",v?m:(0,r.toFixed)(100*g)+"%",0)],4,Object.assign({},(0,a.computeBoxProps)(h))))};t.ProgressBar=c,c.defaultHooks=i.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.Section=void 0;var o=n(1),r=n(12),i=n(16);var a=function(e){var t=e.className,n=e.title,a=e.level,c=void 0===a?1:a,l=e.buttons,u=e.content,s=e.stretchContents,d=e.noTopPadding,f=e.children,p=(e.scrollable,function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","title","level","buttons","content","stretchContents","noTopPadding","children","scrollable"])),m=!(0,r.isFalsy)(n)||!(0,r.isFalsy)(l),h=!(0,r.isFalsy)(u)||!(0,r.isFalsy)(f);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["Section","Section--level--"+c,e.flexGrow&&"Section--flex",t])},p,{children:[m&&(0,o.createVNode)(1,"div","Section__title",[(0,o.createVNode)(1,"span","Section__titleText",n,0),(0,o.createVNode)(1,"div","Section__buttons",l,0)],4),h&&(0,o.createComponentVNode)(2,i.Box,{className:(0,r.classes)(["Section__content",!!s&&"Section__content--stretchContents",!!d&&"Section__content--noTopPadding"]),children:[u,f]})]})))};t.Section=a,a.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.Slider=void 0;var o=n(1),r=n(20),i=n(12),a=n(24),c=n(16),l=n(167),u=n(121);t.Slider=function(e){if(a.IS_IE8)return(0,o.normalizeProps)((0,o.createComponentVNode)(2,u.NumberInput,Object.assign({},e)));var t=e.animated,n=e.format,s=e.maxValue,d=e.minValue,f=e.onChange,p=e.onDrag,m=e.step,h=e.stepPixelSize,g=e.suppressFlicker,v=e.unit,b=e.value,C=e.className,N=e.fillValue,y=e.color,V=e.ranges,x=void 0===V?{}:V,w=e.children,k=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","fillValue","color","ranges","children"]),_=w!==undefined;return(0,o.normalizeProps)((0,o.createComponentVNode)(2,l.DraggableControl,Object.assign({dragMatrix:[1,0]},{animated:t,format:n,maxValue:s,minValue:d,onChange:f,onDrag:p,step:m,stepPixelSize:h,suppressFlicker:g,unit:v,value:b},{children:function(e){var t=e.dragging,n=(e.editing,e.value),a=e.displayValue,l=e.displayElement,u=e.inputElement,f=e.handleDragStart,p=N!==undefined&&null!==N,m=((0,r.scale)(n,d,s),(0,r.scale)(null!=N?N:a,d,s)),h=(0,r.scale)(a,d,s),g=y||(0,r.keyOfMatchingRange)(null!=N?N:n,x)||"default";return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,i.classes)(["Slider","ProgressBar","ProgressBar--color--"+g,C,(0,c.computeBoxClassName)(k)]),[(0,o.createVNode)(1,"div",(0,i.classes)(["ProgressBar__fill",p&&"ProgressBar__fill--animated"]),null,1,{style:{width:100*(0,r.clamp01)(m)+"%",opacity:.4}}),(0,o.createVNode)(1,"div","ProgressBar__fill",null,1,{style:{width:100*(0,r.clamp01)(Math.min(m,h))+"%"}}),(0,o.createVNode)(1,"div","Slider__cursorOffset",[(0,o.createVNode)(1,"div","Slider__cursor"),(0,o.createVNode)(1,"div","Slider__pointer"),t&&(0,o.createVNode)(1,"div","Slider__popupValue",l,0)],0,{style:{width:100*(0,r.clamp01)(h)+"%"}}),(0,o.createVNode)(1,"div","ProgressBar__content",_?w:l,0),u],0,Object.assign({},(0,c.computeBoxProps)(k),{onMouseDown:f})))}})))}},function(e,t,n){"use strict";t.__esModule=!0,t.Tabs=void 0;var o=n(1),r=n(12),i=n(16),a=n(119);function c(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var l=function(e){var t=e.className,n=e.vertical,a=e.children,l=c(e,["className","vertical","children"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,r.classes)(["Tabs",n?"Tabs--vertical":"Tabs--horizontal",t,(0,i.computeBoxClassName)(l)]),(0,o.createVNode)(1,"div","Tabs__tabBox",a,0),2,Object.assign({},(0,i.computeBoxProps)(l))))};t.Tabs=l;l.Tab=function(e){var t=e.className,n=e.selected,i=e.altSelection,l=c(e,["className","selected","altSelection"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Button,Object.assign({className:(0,r.classes)(["Tabs__tab",n&&"Tabs__tab--selected",i&&n&&"Tabs__tab--altSelection",t]),selected:!i&&n,color:"transparent"},l)))}},function(e,t,n){var o={"./APC.js":428,"./AiAirlock.js":430,"./AtmosAlertConsole.js":431,"./BlueSpaceArtilleryControl.js":432,"./BodyScanner.js":433,"./Canister.js":434,"./ChemDispenser.js":435,"./ChemHeater.js":439,"./ChemMaster.js":440,"./CloningConsole.js":441,"./CrewMonitor.js":442,"./Cryo.js":443,"./DNAModifier.js":444,"./DisposalBin.js":445,"./Electropack.js":446,"./FaxMachine.js":447,"./Instrument.js":448,"./MechBayConsole.js":449,"./MedicalRecords.js":450,"./MiningVendor.js":454,"./NtosStationAlertConsole.js":455,"./OperatingComputer.js":456,"./PortableTurret.js":457,"./Radio.js":459,"./RoboticsControlConsole.js":460,"./ShuttleConsole.js":461,"./Sleeper.js":462,"./SlotMachine.js":463,"./Smes.js":464,"./StationAlertConsole.js":172,"./SupermatterMonitor.js":465,"./Tank.js":466,"./TransferValve.js":467,"./Vending.js":468,"./Wires.js":469};function r(e){var t=i(e);return n(t)}function i(e){if(!n.o(o,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return o[e]}r.keys=function(){return Object.keys(o)},r.resolve=i,e.exports=r,r.id=427},function(e,t,n){"use strict";t.__esModule=!0,t.APC=void 0;var o=n(1),r=n(3),i=n(4),a=n(6),c=n(429);t.APC=function(e,t){return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,s)})})};var l={2:{color:"good",externalPowerText:"External Power",chargingText:"Fully Charged"},1:{color:"average",externalPowerText:"Low External Power",chargingText:"Charging"},0:{color:"bad",externalPowerText:"No External Power",chargingText:"Not Charging"}},u={1:{icon:"terminal",content:"Override Programming",action:"hack"},2:{icon:"caret-square-down",content:"Shunt Core Process",action:"occupy"},3:{icon:"caret-square-left",content:"Return to Main Core",action:"deoccupy"},4:{icon:"caret-square-down",content:"Shunt Core Process",action:"occupy"}},s=function(e,t){var n=(0,r.useBackend)(t),a=n.act,s=n.data,d=s.locked&&!s.siliconUser,f=(s.normallyLocked,l[s.externalPower]||l[0]),p=l[s.chargingStatus]||l[0],m=s.powerChannels||[],h=u[s.malfStatus]||u[0],g=s.powerCellStatus/100;return(0,o.createFragment)([(0,o.createComponentVNode)(2,c.InterfaceLockNoticeBox),(0,o.createComponentVNode)(2,i.Section,{title:"Power Status",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Main Breaker",color:f.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:s.isOperating?"power-off":"times",content:s.isOperating?"On":"Off",selected:s.isOperating&&!d,color:s.isOperating?"":"bad",disabled:d,onClick:function(){return a("breaker")}}),children:["[ ",f.externalPowerText," ]"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power Cell",children:(0,o.createComponentVNode)(2,i.ProgressBar,{color:"good",value:g})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Charge Mode",color:p.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:s.chargeMode?"sync":"times",content:s.chargeMode?"Auto":"Off",selected:s.chargeMode,disabled:d,onClick:function(){return a("charge")}}),children:["[ ",p.chargingText," ]"]})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Power Channels",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[m.map((function(e){var t=e.topicParams;return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.title,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{inline:!0,mx:2,color:e.status>=2?"good":"bad",children:e.status>=2?"On":"Off"}),(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Auto",selected:!d&&(1===e.status||3===e.status),disabled:d,onClick:function(){return a("channel",t.auto)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",content:"On",selected:!d&&2===e.status,disabled:d,onClick:function(){return a("channel",t.on)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Off",selected:!d&&0===e.status,disabled:d,onClick:function(){return a("channel",t.off)}})],4),children:[e.powerLoad," W"]},e.title)})),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Total Load",children:(0,o.createVNode)(1,"b",null,[s.totalLoad,(0,o.createTextVNode)(" W")],0)})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Misc",buttons:!!s.siliconUser&&(0,o.createFragment)([!!s.malfStatus&&(0,o.createComponentVNode)(2,i.Button,{icon:h.icon,content:h.content,color:"bad",onClick:function(){return a(h.action)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",content:"Overload",onClick:function(){return a("overload")}})],0),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cover Lock",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:s.coverLocked?"lock":"unlock",content:s.coverLocked?"Engaged":"Disengaged",selected:s.coverLocked,disabled:d,onClick:function(){return a("cover")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Night Shift Lighting",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",content:s.nightshiftLights?"Enabled":"Disabled",selected:s.nightshiftLights,onClick:function(){return a("toggle_nightshift")}})})]})})],4)}},function(e,t,n){"use strict";t.__esModule=!0,t.InterfaceLockNoticeBox=void 0;var o=n(1),r=n(3),i=n(4);t.InterfaceLockNoticeBox=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=e.siliconUser,u=void 0===l?c.siliconUser:l,s=e.locked,d=void 0===s?c.locked:s,f=e.normallyLocked,p=void 0===f?c.normallyLocked:f,m=e.onLockStatusChange,h=void 0===m?function(){return a("lock")}:m,g=e.accessText,v=void 0===g?"an ID card":g;return u?(0,o.createComponentVNode)(2,i.NoticeBox,{color:u&&"grey",children:(0,o.createComponentVNode)(2,i.Flex,{align:"center",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{children:"Interface lock status:"}),(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1"}),(0,o.createComponentVNode)(2,i.Flex.Item,{children:(0,o.createComponentVNode)(2,i.Button,{m:"0",color:p?"red":"green",icon:p?"lock":"unlock",content:p?"Locked":"Unlocked",onClick:function(){h&&h(!d)}})})]})}):(0,o.createComponentVNode)(2,i.NoticeBox,{children:["Swipe ",v," ","to ",d?"unlock":"lock"," this interface."]})}},function(e,t,n){"use strict";t.__esModule=!0,t.AiAirlock=void 0;var o=n(1),r=n(3),i=n(4),a=n(6),c={2:{color:"good",localStatusText:"Offline"},1:{color:"average",localStatusText:"Caution"},0:{color:"bad",localStatusText:"Optimal"}};t.AiAirlock=function(e,t){var n=(0,r.useBackend)(t),l=n.act,u=n.data,s=c[u.power.main]||c[0],d=c[u.power.backup]||c[0],f=c[u.shock]||c[0];return(0,o.createComponentVNode)(2,a.Window,{width:500,height:390,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Power Status",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Main",color:s.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",disabled:!u.power.main,content:"Disrupt",onClick:function(){return l("disrupt-main")}}),children:[u.power.main?"Online":"Offline"," ",u.wires.main_power?u.power.main_timeleft>0&&"["+u.power.main_timeleft+"s]":"[Wires have been cut!]"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Backup",color:d.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",disabled:!u.power.backup,content:"Disrupt",onClick:function(){return l("disrupt-backup")}}),children:[u.power.backup?"Online":"Offline"," ",u.wires.backup_power?u.power.backup_timeleft>0&&"["+u.power.backup_timeleft+"s]":"[Wires have been cut!]"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Electrify",color:f.color,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"wrench",disabled:!(u.wires.shock&&2!==u.shock),content:"Restore",onClick:function(){return l("shock-restore")}}),(0,o.createComponentVNode)(2,i.Button,{icon:"bolt",disabled:!u.wires.shock,content:"Temporary",onClick:function(){return l("shock-temp")}}),(0,o.createComponentVNode)(2,i.Button,{icon:"bolt",disabled:!u.wires.shock||0===u.shock,content:"Permanent",onClick:function(){return l("shock-perm")}})],4),children:[2===u.shock?"Safe":"Electrified"," ",(u.wires.shock?u.shock_timeleft>0&&"["+u.shock_timeleft+"s]":"[Wires have been cut!]")||-1===u.shock_timeleft&&"[Permanent]"]})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Access and Door Control",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"ID Scan",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.id_scanner?"power-off":"times",content:u.id_scanner?"Enabled":"Disabled",selected:u.id_scanner,disabled:!u.wires.id_scanner,onClick:function(){return l("idscan-toggle")}}),children:!u.wires.id_scanner&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Emergency Access",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.emergency?"power-off":"times",content:u.emergency?"Enabled":"Disabled",selected:u.emergency,onClick:function(){return l("emergency-toggle")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Bolts",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.locked?"lock":"unlock",content:u.locked?"Lowered":"Raised",selected:u.locked,disabled:!u.wires.bolts,onClick:function(){return l("bolt-toggle")}}),children:!u.wires.bolts&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Bolt Lights",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.lights?"power-off":"times",content:u.lights?"Enabled":"Disabled",selected:u.lights,disabled:!u.wires.lights,onClick:function(){return l("light-toggle")}}),children:!u.wires.lights&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Force Sensors",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.safe?"power-off":"times",content:u.safe?"Enabled":"Disabled",selected:u.safe,disabled:!u.wires.safe,onClick:function(){return l("safe-toggle")}}),children:!u.wires.safe&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Timing Safety",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.speed?"power-off":"times",content:u.speed?"Enabled":"Disabled",selected:u.speed,disabled:!u.wires.timing,onClick:function(){return l("speed-toggle")}}),children:!u.wires.timing&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Control",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.opened?"sign-out-alt":"sign-in-alt",content:u.opened?"Open":"Closed",selected:u.opened,disabled:u.locked||u.welded,onClick:function(){return l("open-close")}}),children:!(!u.locked&&!u.welded)&&(0,o.createVNode)(1,"span",null,[(0,o.createTextVNode)("[Door is "),u.locked?"bolted":"",u.locked&&u.welded?" and ":"",u.welded?"welded":"",(0,o.createTextVNode)("!]")],0)})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.AtmosAlertConsole=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.AtmosAlertConsole=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,u=l.priority||[],s=l.minor||[];return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:(0,o.createComponentVNode)(2,i.Section,{title:"Alarms",children:(0,o.createVNode)(1,"ul",null,[0===u.length&&(0,o.createVNode)(1,"li","color-good","No Priority Alerts",16),u.map((function(e){return(0,o.createVNode)(1,"li",null,(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:e,color:"bad",onClick:function(){return c("clear",{zone:e})}}),2,null,e)})),0===s.length&&(0,o.createVNode)(1,"li","color-good","No Minor Alerts",16),s.map((function(e){return(0,o.createVNode)(1,"li",null,(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:e,color:"average",onClick:function(){return c("clear",{zone:e})}}),2,null,e)}))],0)})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.BlueSpaceArtilleryControl=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.BlueSpaceArtilleryControl=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,u=c.data;return n=u.ready?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:"green",children:"Ready"}):u.reloadtime_text?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Reloading In",color:"red",children:u.reloadtime_text}):(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:"red",children:"No cannon connected!"}),(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[u.notice&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Alert",color:"red",children:u.notice}),n,(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target",children:(0,o.createComponentVNode)(2,i.Button,{icon:"crosshairs",content:u.target?u.target:"None",onClick:function(){return l("recalibrate")}})}),1===u.ready&&!!u.target&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Firing",children:(0,o.createComponentVNode)(2,i.Button,{icon:"skull",content:"FIRE!",color:"red",onClick:function(){return l("fire")}})}),!u.connected&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Maintenance",children:(0,o.createComponentVNode)(2,i.Button,{icon:"wrench",content:"Complete Deployment",onClick:function(){return l("build")}})})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.BodyScanner=void 0;var o=n(1),r=n(20),i=n(3),a=n(4),c=n(6),l=[["good","Alive"],["average","Critical"],["bad","DEAD"]],u=[["hasBorer","bad","Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended."],["hasVirus","bad","Viral pathogen detected in blood stream."],["blind","average","Cataracts detected."],["colourblind","average","Photoreceptor abnormalities detected."],["nearsighted","average","Retinal misalignment detected."]],s=[["Respiratory","oxyLoss"],["Brain","brainLoss"],["Toxin","toxLoss"],["Radioactive","radLoss"],["Brute","bruteLoss"],["Genetic","cloneLoss"],["Burn","fireLoss"],["Paralysis","paralysis"]],d={average:[.25,.5],bad:[.5,Infinity]},f=function(e,t){for(var n=[],o=0;o0?e.filter((function(e){return!!e&&e.length>0})).reduce((function(e,t){return null===e?[t]:(0,o.createFragment)([e,(0,o.createVNode)(1,"br"),t],0,t)}),null):null},m=function(e){if(e>100){if(e<300)return"mild infection";if(e<400)return"mild infection+";if(e<500)return"mild infection++";if(e<700)return"acute infection";if(e<800)return"acute infection+";if(e<900)return"acute infection++";if(e>=900)return"septic"}return""};t.BodyScanner=function(e,t){var n=(0,i.useBackend)(t).data,r=n.occupied,a=n.occupant,l=void 0===a?{}:a,u=r?(0,o.createComponentVNode)(2,h,{occupant:l}):(0,o.createComponentVNode)(2,V);return(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:u})})};var h=function(e){var t=e.occupant;return(0,o.createComponentVNode)(2,a.Box,{children:[(0,o.createComponentVNode)(2,g,{occupant:t}),(0,o.createComponentVNode)(2,v,{occupant:t}),(0,o.createComponentVNode)(2,b,{occupant:t}),(0,o.createComponentVNode)(2,N,{organs:t.extOrgan}),(0,o.createComponentVNode)(2,y,{organs:t.intOrgan})]})},g=function(e,t){var n=(0,i.useBackend)(t),c=n.act,u=n.data.occupant;return(0,o.createComponentVNode)(2,a.Section,{title:"Occupant",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{icon:"user-slash",onClick:function(){return c("ejectify")},children:"Eject"}),(0,o.createComponentVNode)(2,a.Button,{icon:"print",onClick:function(){return c("print_p")},children:"Print Report"})],4),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Name",children:u.name}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:u.maxHealth,value:u.health/u.maxHealth,ranges:{good:[.5,Infinity],average:[0,.5],bad:[-Infinity,0]}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",color:l[u.stat][0],children:l[u.stat][1]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Temperature",children:[(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:(0,r.round)(u.bodyTempC,0)}),"\xb0C,\xa0",(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:(0,r.round)(u.bodyTempF,0)}),"\xb0F"]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Implants",children:u.implant_len?(0,o.createComponentVNode)(2,a.Box,{children:u.implant.map((function(e){return e.name})).join(", ")}):(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"None"})})]})})},v=function(e){var t=e.occupant;return t.hasBorer||t.blind||t.colourblind||t.nearsighted||t.hasVirus?(0,o.createComponentVNode)(2,a.Section,{title:"Abnormalities",children:u.map((function(e,n){if(t[e[0]])return(0,o.createComponentVNode)(2,a.Box,{color:e[1],bold:"bad"===e[1],children:e[2]})}))}):(0,o.createComponentVNode)(2,a.Section,{title:"Abnormalities",children:(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"No abnormalities found."})})},b=function(e){var t=e.occupant;return(0,o.createComponentVNode)(2,a.Section,{title:"Damage",children:(0,o.createComponentVNode)(2,a.Table,{children:f(s,(function(e,n,r){return(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Table.Row,{color:"label",children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:[e[0],":"]}),(0,o.createComponentVNode)(2,a.Table.Cell,{children:!!n&&n[0]+":"})]}),(0,o.createComponentVNode)(2,a.Table.Row,{children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:(0,o.createComponentVNode)(2,C,{value:t[e[1]],marginBottom:r0&&"0.5rem",value:e.totalLoss/100,ranges:d,children:[(0,o.createComponentVNode)(2,a.Box,{float:"left",display:"inline",children:[!!e.bruteLoss&&(0,o.createComponentVNode)(2,a.Box,{display:"inline",position:"relative",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"bone"}),(0,r.round)(e.bruteLoss,0),"\xa0",(0,o.createComponentVNode)(2,a.Tooltip,{position:"top",content:"Brute damage"})]}),!!e.fireLoss&&(0,o.createComponentVNode)(2,a.Box,{display:"inline",position:"relative",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"fire"}),(0,r.round)(e.fireLoss,0),(0,o.createComponentVNode)(2,a.Tooltip,{position:"top",content:"Burn damage"})]})]}),(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:(0,r.round)(e.totalLoss,0)})]})}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"right",width:"33%",children:[(0,o.createComponentVNode)(2,a.Box,{color:"average",display:"inline",children:p([e.internalBleeding&&"Internal bleeding",e.lungRuptured&&"Ruptured lung",!!e.status.broken&&e.status.broken,m(e.germ_level),!!e.open&&"Open incision"])}),(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:[p([!!e.status.splinted&&"Splinted",!!e.status.robotic&&"Robotic",!!e.status.dead&&(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"DEAD"})]),p(e.shrapnel.map((function(e){return e.known?e.name:"Unknown object"})))]})]})]},t)}))]})})},y=function(e){return 0===e.organs.length?(0,o.createComponentVNode)(2,a.Section,{title:"Internal Organs",children:(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"N/A"})}):(0,o.createComponentVNode)(2,a.Section,{title:"Internal Organs",children:(0,o.createComponentVNode)(2,a.Table,{children:[(0,o.createComponentVNode)(2,a.Table.Row,{header:!0,children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:"Name"}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"center",children:"Damage"}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"right",children:"Injuries"})]}),e.organs.map((function(e,t){return(0,o.createComponentVNode)(2,a.Table.Row,{textTransform:"capitalize",children:[(0,o.createComponentVNode)(2,a.Table.Cell,{width:"33%",children:e.name}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"center",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:e.maxHealth,value:e.damage/100,mt:t>0&&"0.5rem",ranges:d,children:(0,r.round)(e.damage,0)})}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"right",width:"33%",children:[(0,o.createComponentVNode)(2,a.Box,{color:"average",display:"inline",children:p([m(e.germ_level)])}),(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:p([1===e.robotic&&"Robotic",2===e.robotic&&"Assisted",!!e.dead&&(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"DEAD"})])})]})]},t)}))]})})},V=function(){return(0,o.createComponentVNode)(2,a.Section,{textAlign:"center",flexGrow:"1",children:(0,o.createComponentVNode)(2,a.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",align:"center",color:"label",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant detected."]})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Canister=void 0;var o=n(1),r=n(20),i=n(3),a=n(4),c=n(171),l=n(6);t.Canister=function(e,t){var n=(0,i.useBackend)(t),u=n.act,s=n.data,d=s.portConnected,f=s.tankPressure,p=s.releasePressure,m=s.defaultReleasePressure,h=s.minReleasePressure,g=s.maxReleasePressure,v=s.valveOpen,b=s.name,C=s.canLabel,N=s.colorContainer,y=s.color_index,V=s.hasHoldingTank,x=s.holdingTank,w="";y.prim&&(w=N.prim.options[y.prim].name);var k="";y.sec&&(k=N.sec.options[y.sec].name);var _="";y.ter&&(_=N.ter.options[y.ter].name);var L="";y.quart&&(L=N.quart.options[y.quart].name);var S=[],B=[],E=[],I=[],T=0;for(T=0;T0}),(0,o.createComponentVNode)(2,f,{mode:v,bufferReagents:h}),(0,o.createComponentVNode)(2,p,{isCondiment:i,bufferNonEmpty:h.length>0}),(0,o.createComponentVNode)(2,g)]})]})};var d=function(e,t){var n=(0,r.useBackend)(t).act,a=e.beaker,s=e.beakerReagents,d=e.bufferNonEmpty;return(0,o.createComponentVNode)(2,i.Section,{title:"Beaker",flexGrow:"0",flexBasis:"300px",buttons:d?(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"eject",disabled:!a,content:"Eject and Clear Buffer",onClick:function(){return n("eject")}}):(0,o.createComponentVNode)(2,i.Button,{icon:"eject",disabled:!a,content:"Eject and Clear Buffer",onClick:function(){return n("eject")}}),children:a?(0,o.createComponentVNode)(2,c.BeakerContents,{beakerLoaded:!0,beakerContents:s,buttons:function(e,r){return(0,o.createComponentVNode)(2,i.Box,{mb:r0?(0,o.createComponentVNode)(2,c.BeakerContents,{beakerLoaded:!0,beakerContents:d,buttons:function(e,r){return(0,o.createComponentVNode)(2,i.Box,{mb:r0?l.desc:"N/A"}),l.blood_type&&(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Blood type",children:l.blood_type}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Blood DNA",className:"LabeledList__breakContents",children:l.blood_dna})],4),!c.condi&&(0,o.createComponentVNode)(2,i.Button,{icon:c.printing?"spinner":"print",disabled:c.printing,iconSpin:!!c.printing,ml:"0.5rem",content:"Print",onClick:function(){return a("print",{idx:l.idx,beaker:e.args.beaker})}})]})})})}))},function(e,t,n){"use strict";t.__esModule=!0,t.CloningConsole=void 0;var o=n(1),r=n(20),i=n(3),a=n(4),c=n(68),l=n(87),u=n(6),s=function(e,t){var n=(0,i.useBackend)(t),r=n.act,l=n.data,u=e.args,s=u.activerecord,d=u.realname,f=u.health,p=u.unidentity,m=u.strucenzymes,h=f.split(" - ");return(0,o.createComponentVNode)(2,a.Section,{level:2,m:"-1rem",pb:"1rem",title:"Records of "+d,children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Name",children:d}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Damage",children:h.length>1?(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.oxy,display:"inline",children:h[0]}),(0,o.createTextVNode)("\xa0|\xa0"),(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.toxin,display:"inline",children:h[2]}),(0,o.createTextVNode)("\xa0|\xa0"),(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.brute,display:"inline",children:h[3]}),(0,o.createTextVNode)("\xa0|\xa0"),(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.burn,display:"inline",children:h[1]})],4):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"Unknown"})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"UI",className:"LabeledList__breakContents",children:p}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"SE",className:"LabeledList__breakContents",children:m}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Disk",children:[(0,o.createComponentVNode)(2,a.Button.Confirm,{disabled:!l.disk,icon:"arrow-circle-down",content:"Import",onClick:function(){return r("disk",{option:"load"})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l.disk,icon:"arrow-circle-up",content:"Export UI",onClick:function(){return r("disk",{option:"save",savetype:"ui"})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l.disk,icon:"arrow-circle-up",content:"Export UI and UE",onClick:function(){return r("disk",{option:"save",savetype:"ue"})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l.disk,icon:"arrow-circle-up",content:"Export SE",onClick:function(){return r("disk",{option:"save",savetype:"se"})}})]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Actions",children:[(0,o.createComponentVNode)(2,a.Button,{disabled:!l.podready,icon:"user-plus",content:"Clone",onClick:function(){return r("clone",{ref:s})}}),(0,o.createComponentVNode)(2,a.Button,{icon:"trash",content:"Delete",onClick:function(){return r("del_rec")}})]})]})})};t.CloningConsole=function(e,t){var n=(0,i.useBackend)(t);n.act,n.data.menu;return(0,l.modalRegisterBodyOverride)("view_rec",s),(0,o.createComponentVNode)(2,u.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,l.ComplexModal,{maxWidth:"75%",maxHeight:"75%"}),(0,o.createComponentVNode)(2,u.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,h),(0,o.createComponentVNode)(2,g),(0,o.createComponentVNode)(2,d),(0,o.createComponentVNode)(2,a.Section,{noTopPadding:!0,flexGrow:"1",children:(0,o.createComponentVNode)(2,f)})]})]})};var d=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data.menu;return(0,o.createComponentVNode)(2,a.Tabs,{children:[(0,o.createComponentVNode)(2,a.Tabs.Tab,{selected:1===c,icon:"home",onClick:function(){return r("menu",{num:1})},children:"Main"}),(0,o.createComponentVNode)(2,a.Tabs.Tab,{selected:2===c,icon:"folder",onClick:function(){return r("menu",{num:2})},children:"Records"})]})},f=function(e,t){var n,r=(0,i.useBackend)(t).data.menu;return 1===r?n=(0,o.createComponentVNode)(2,p):2===r&&(n=(0,o.createComponentVNode)(2,m)),n},p=function(e,t){var n=(0,i.useBackend)(t),c=n.act,l=n.data,u=l.loading,s=l.scantemp,d=l.occupant,f=l.locked,p=l.can_brainscan,m=l.scan_mode,h=l.numberofpods,g=l.pods,v=l.selected_pod,b=f&&!!d;return(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Section,{title:"Scanner",level:"2",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{display:"inline",color:"label",children:"Scanner Lock:\xa0"}),(0,o.createComponentVNode)(2,a.Button,{disabled:!d,selected:b,icon:b?"toggle-on":"toggle-off",content:b?"Engaged":"Disengaged",onClick:function(){return c("lock")}}),(0,o.createComponentVNode)(2,a.Button,{disabled:b||!d,icon:"user-slash",content:"Eject Occupant",onClick:function(){return c("eject")}})],4),children:[(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",children:u?(0,o.createComponentVNode)(2,a.Box,{color:"average",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"spinner",spin:!0}),"\xa0 Scanning..."]}):(0,o.createComponentVNode)(2,a.Box,{color:s.color,children:s.text})}),!!p&&(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Scan Mode",children:(0,o.createComponentVNode)(2,a.Button,{icon:m?"brain":"male",content:m?"Brain":"Body",onClick:function(){return c("toggle_mode")}})})]}),(0,o.createComponentVNode)(2,a.Button,{disabled:!d||u,icon:"user",content:"Scan Occupant",mt:"0.5rem",mb:"0",onClick:function(){return c("scan")}})]}),(0,o.createComponentVNode)(2,a.Section,{title:"Pods",level:"2",children:h?g.map((function(e,t){var n;return n="cloning"===e.status?(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:"100",value:e.progress/100,ranges:{good:[.75,Infinity],average:[.25,.75],bad:[-Infinity,.25]},mt:"0.5rem",children:(0,o.createComponentVNode)(2,a.Box,{textAlign:"center",children:(0,r.round)(e.progress,0)+"%"})}):"mess"===e.status?(0,o.createComponentVNode)(2,a.Box,{bold:!0,color:"bad",mt:"0.5rem",children:"ERROR"}):(0,o.createComponentVNode)(2,a.Button,{selected:v===e.pod,icon:v===e.pod&&"check",content:"Select",mt:"0.5rem",onClick:function(){return c("selectpod",{ref:e.pod})}}),(0,o.createComponentVNode)(2,a.Box,{width:"64px",textAlign:"center",display:"inline-block",mr:"0.5rem",children:[(0,o.createVNode)(1,"img",null,null,1,{src:"pod_"+e.status+".gif",style:{width:"100%","-ms-interpolation-mode":"nearest-neighbor"}}),(0,o.createComponentVNode)(2,a.Box,{color:"label",children:["Pod #",t+1]}),(0,o.createComponentVNode)(2,a.Box,{bold:!0,color:e.biomass>=150?"good":"bad",display:"inline",children:[(0,o.createComponentVNode)(2,a.Icon,{name:e.biomass>=150?"circle":"circle-o"}),"\xa0",e.biomass]}),n]},t)})):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"No pods detected. Unable to clone."})})],4)},m=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data.records;return c.length?(0,o.createComponentVNode)(2,a.Box,{mt:"0.5rem",children:c.map((function(e,t){return(0,o.createComponentVNode)(2,a.Button,{icon:"user",mb:"0.5rem",content:e.realname,onClick:function(){return r("view_rec",{ref:e.record})}},t)}))}):(0,o.createComponentVNode)(2,a.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",align:"center",textAlign:"center",color:"label",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No records found."]})})},h=function(e,t){var n,r=(0,i.useBackend)(t),c=r.act,l=r.data.temp;if(l&&l.text&&!(l.text.length<=0)){var u=((n={})[l.style]=!0,n);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.NoticeBox,Object.assign({},u,{children:[(0,o.createComponentVNode)(2,a.Box,{display:"inline-block",verticalAlign:"middle",children:l.text}),(0,o.createComponentVNode)(2,a.Button,{icon:"times-circle",float:"right",onClick:function(){return c("cleartemp")}}),(0,o.createComponentVNode)(2,a.Box,{clear:"both"})]})))}},g=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.scanner,u=c.numberofpods,s=c.autoallowed,d=c.autoprocess,f=c.disk;return(0,o.createComponentVNode)(2,a.Section,{title:"Status",buttons:(0,o.createFragment)([!!s&&(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{display:"inline",color:"label",children:"Auto-processing:\xa0"}),(0,o.createComponentVNode)(2,a.Button,{selected:d,icon:d?"toggle-on":"toggle-off",content:d?"Enabled":"Disabled",onClick:function(){return r("autoprocess",{on:d?0:1})}})],4),(0,o.createComponentVNode)(2,a.Button,{disabled:!f,icon:"eject",content:"Eject Disk",onClick:function(){return r("disk",{option:"eject"})}})],0),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Scanner",children:l?(0,o.createComponentVNode)(2,a.Box,{color:"good",children:"Connected"}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"Not connected!"})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Pods",children:u?(0,o.createComponentVNode)(2,a.Box,{color:"good",children:[u," connected"]}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"None connected!"})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.CrewMonitor=void 0;var o=n(1),r=n(69),i=n(3),a=n(4),c=n(86),l=n(6);t.CrewMonitor=function(e,t){var n=(0,i.useBackend)(t),u=n.act,s=n.data,d=(0,r.sortBy)((function(e){return e.name}))(s.crewmembers||[]);return(0,o.createComponentVNode)(2,l.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,l.Window.Content,{className:"Layout__content--noMargin",children:[(0,o.createComponentVNode)(2,a.Box,{m:1,children:[d.filter((function(e){return 3===e.sensor_type})).map((function(e){return(0,o.createComponentVNode)(2,a.NanoMap.Marker,{x:e.x,y:e.y,icon:"circle",tooltip:e.name,color:e.dead?"red":"green"},e.ref)})),(0,o.createComponentVNode)(2,a.NanoMap)]}),(0,o.createComponentVNode)(2,a.Box,{className:"NanoMap__contentOffset",children:(0,o.createComponentVNode)(2,a.Box,{bold:!0,m:2,children:(0,o.createComponentVNode)(2,a.Table,{children:[(0,o.createComponentVNode)(2,a.Table.Row,{header:!0,children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:"Name"}),(0,o.createComponentVNode)(2,a.Table.Cell,{children:"Status"}),(0,o.createComponentVNode)(2,a.Table.Cell,{children:"Location"})]}),d.map((function(e){return(0,o.createComponentVNode)(2,a.Table.Row,{children:[(0,o.createComponentVNode)(2,c.TableCell,{children:[e.name," (",e.assignment,")"]}),(0,o.createComponentVNode)(2,c.TableCell,{children:[(0,o.createComponentVNode)(2,a.Box,{inline:!0,color:e.dead?"red":"green",children:e.dead?"Deceased":"Living"}),e.sensor_type>=2?(0,o.createComponentVNode)(2,a.Box,{inline:!0,children:["(",(0,o.createComponentVNode)(2,a.Box,{inline:!0,color:"red",children:e.brute}),"|",(0,o.createComponentVNode)(2,a.Box,{inline:!0,color:"orange",children:e.fire}),"|",(0,o.createComponentVNode)(2,a.Box,{inline:!0,color:"green",children:e.tox}),"|",(0,o.createComponentVNode)(2,a.Box,{inline:!0,color:"blue",children:e.oxy}),")"]}):null]}),(0,o.createComponentVNode)(2,c.TableCell,{children:3===e.sensor_type?s.isAI?(0,o.createComponentVNode)(2,a.Button,{fluid:!0,content:e.area+" ("+e.x+", "+e.y+")",onClick:function(){return u("track",{track:e.ref})}}):e.area+" ("+e.x+", "+e.y+")":"Not Available"})]},e.name)}))]})})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Cryo=void 0;var o=n(1),r=n(3),i=n(4),a=n(6),c=[{label:"Resp.",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"}],l=[["good","Conscious"],["average","Unconscious"],["bad","DEAD"]];t.Cryo=function(e,t){return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{className:"Layout__content--flexColumn",children:(0,o.createComponentVNode)(2,u)})})};var u=function(e,t){var n=(0,r.useBackend)(t),a=n.act,u=n.data,d=u.isOperating,f=u.hasOccupant,p=u.occupant,m=void 0===p?[]:p,h=u.cellTemperature,g=u.cellTemperatureStatus,v=u.isBeakerLoaded,b=u.auto_eject_healthy,C=u.auto_eject_dead;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"Occupant",flexGrow:"1",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"user-slash",onClick:function(){return a("ejectOccupant")},disabled:!f,children:"Eject"}),children:f?(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Occupant",children:m.name||"Unknown"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,i.ProgressBar,{min:m.health,max:m.maxHealth,value:m.health/m.maxHealth,color:m.health>0?"good":"average",children:(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:Math.round(m.health)})})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:l[m.stat][0],children:l[m.stat][1]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",children:[(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:Math.round(m.bodyTemperature)})," K"]}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),c.map((function(e){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.label,children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:m[e.type]/100,ranges:{bad:[.01,Infinity]},children:(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:Math.round(m[e.type])})})},e.id)}))]}):(0,o.createComponentVNode)(2,i.Flex,{height:"100%",textAlign:"center",children:(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",align:"center",color:"label",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant detected."]})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Cell",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",onClick:function(){return a("ejectBeaker")},disabled:!v,children:"Eject Beaker"}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",onClick:function(){return a(d?"switchOff":"switchOn")},selected:d,children:d?"On":"Off"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",color:g,children:[(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:h})," K"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Beaker",children:(0,o.createComponentVNode)(2,s)}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Auto-eject healthy occupants",children:(0,o.createComponentVNode)(2,i.Button,{icon:b?"toggle-on":"toggle-off",selected:b,onClick:function(){return a(b?"auto_eject_healthy_off":"auto_eject_healthy_on")},children:b?"On":"Off"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Auto-eject dead occupants",children:(0,o.createComponentVNode)(2,i.Button,{icon:C?"toggle-on":"toggle-off",selected:C,onClick:function(){return a(C?"auto_eject_dead_off":"auto_eject_dead_on")},children:C?"On":"Off"})})]})})],4)},s=function(e,t){var n=(0,r.useBackend)(t),a=(n.act,n.data),c=a.isBeakerLoaded,l=a.beakerLabel,u=a.beakerVolume;return c?(0,o.createFragment)([l||(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"No label"}),(0,o.createComponentVNode)(2,i.Box,{color:!u&&"bad",children:u?(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:u,format:function(e){return Math.round(e)+" units remaining"}}):"Beaker is empty"})],0):(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"No beaker loaded"})}},function(e,t,n){"use strict";t.__esModule=!0,t.DNAModifier=void 0;var o=n(1),r=n(3),i=n(4),a=n(6),c=n(87),l=[["good","Alive"],["average","Critical"],["bad","DEAD"]],u=[["ui","Modify U.I.","dna"],["se","Modify S.E.","dna"],["buffer","Transfer Buffers","syringe"],["rejuvenators","Rejuvenators","flask"]],s=[5,10,20,30,50];t.DNAModifier=function(e,t){var n,i=(0,r.useBackend)(t),l=(i.act,i.data),u=l.irradiating,s=l.dnaBlockSize,p=l.occupant;return t.dnaBlockSize=s,t.isDNAInvalid=!p.isViableSubject||!p.uniqueIdentity||!p.structuralEnzymes,u&&(n=(0,o.createComponentVNode)(2,N,{duration:u})),(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,c.ComplexModal),n,(0,o.createComponentVNode)(2,a.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,d),(0,o.createComponentVNode)(2,f)]})]})};var d=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,u=c.locked,s=c.hasOccupant,d=c.occupant;return(0,o.createComponentVNode)(2,i.Section,{title:"Occupant",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{color:"label",display:"inline",mr:"0.5rem",children:"Door Lock:"}),(0,o.createComponentVNode)(2,i.Button,{disabled:!s,selected:u,icon:u?"toggle-on":"toggle-off",content:u?"Engaged":"Disengaged",onClick:function(){return a("toggleLock")}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!s||u,icon:"user-slash",content:"Eject",onClick:function(){return a("ejectOccupant")}})],4),children:s?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Name",children:d.name}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,i.ProgressBar,{min:d.minHealth,max:d.maxHealth,value:d.health/d.maxHealth,ranges:{good:[.5,Infinity],average:[0,.5],bad:[-Infinity,0]}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:l[d.stat][0],children:l[d.stat][1]}),(0,o.createComponentVNode)(2,i.LabeledList.Divider)]})}),t.isDNAInvalid?(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"exclamation-circle"}),"\xa0 The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure."]}):(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Radiation",children:(0,o.createComponentVNode)(2,i.ProgressBar,{min:"0",max:"100",value:d.radiationLevel/100,color:"average"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Unique Enzymes",children:c.occupant.uniqueEnzymes?c.occupant.uniqueEnzymes:(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"exclamation-circle"}),"\xa0 Unknown"]})})]})],0):(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"Cell unoccupied."})})},f=function(e,t){var n,a=(0,r.useBackend)(t),c=a.act,l=a.data,s=l.selectedMenuKey,d=l.hasOccupant;l.occupant;return d?t.isDNAInvalid?(0,o.createComponentVNode)(2,i.Section,{flexGrow:"1",children:(0,o.createComponentVNode)(2,i.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",align:"center",textAlign:"center",color:"label",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No operation possible on this subject."]})})}):("ui"===s?n=(0,o.createFragment)([(0,o.createComponentVNode)(2,p),(0,o.createComponentVNode)(2,h)],4):"se"===s?n=(0,o.createFragment)([(0,o.createComponentVNode)(2,m),(0,o.createComponentVNode)(2,h)],4):"buffer"===s?n=(0,o.createComponentVNode)(2,g):"rejuvenators"===s&&(n=(0,o.createComponentVNode)(2,C)),(0,o.createComponentVNode)(2,i.Section,{flexGrow:"1",children:[(0,o.createComponentVNode)(2,i.Tabs,{children:u.map((function(e,t){return(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:s===e[0],onClick:function(){return c("selectMenuKey",{key:e[0]})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:e[2]}),e[1]]},t)}))}),n]})):(0,o.createComponentVNode)(2,i.Section,{flexGrow:"1",children:(0,o.createComponentVNode)(2,i.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",align:"center",textAlign:"center",color:"label",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant in DNA modifier."]})})})},p=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.selectedUIBlock,u=c.selectedUISubBlock,s=c.selectedUITarget,d=c.occupant;return(0,o.createComponentVNode)(2,i.Section,{title:"Modify Unique Identifier",level:"2",children:[(0,o.createComponentVNode)(2,y,{dnaString:d.uniqueIdentity,selectedBlock:l,selectedSubblock:u,blockSize:t.dnaBlockSize,action:"selectUIBlock"}),(0,o.createComponentVNode)(2,i.LabeledList,{children:(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target",children:(0,o.createComponentVNode)(2,i.Knob,{minValue:"1",maxValue:"15",stepPixelSize:"20",value:s,format:function(e){return e.toString(16).toUpperCase()},ml:"0",onChange:function(e,t){return a("changeUITarget",{value:t})}})})}),(0,o.createComponentVNode)(2,i.Button,{icon:"radiation",content:"Irradiate Block",mt:"0.5rem",onClick:function(){return a("pulseUIRadiation")}})]})},m=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.selectedSEBlock,u=c.selectedSESubBlock,s=c.occupant;return(0,o.createComponentVNode)(2,i.Section,{title:"Modify Structural Enzymes",level:"2",children:[(0,o.createComponentVNode)(2,y,{dnaString:s.structuralEnzymes,selectedBlock:l,selectedSubblock:u,blockSize:t.dnaBlockSize,action:"selectSEBlock"}),(0,o.createComponentVNode)(2,i.Button,{icon:"radiation",content:"Irradiate Block",onClick:function(){return a("pulseSERadiation")}})]})},h=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.radiationIntensity,u=c.radiationDuration;return(0,o.createComponentVNode)(2,i.Section,{title:"Radiation Emitter",level:"2",children:[(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Intensity",children:(0,o.createComponentVNode)(2,i.Knob,{minValue:"1",maxValue:"10",stepPixelSize:"20",value:l,popUpPosition:"right",ml:"0",onChange:function(e,t){return a("radiationIntensity",{value:t})}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Duration",children:(0,o.createComponentVNode)(2,i.Knob,{minValue:"1",maxValue:"20",stepPixelSize:"10",unit:"s",value:u,popUpPosition:"right",ml:"0",onChange:function(e,t){return a("radiationDuration",{value:t})}})})]}),(0,o.createComponentVNode)(2,i.Button,{icon:"radiation",content:"Pulse Radiation",tooltip:"Mutates a random block of either the occupant's UI or SE.",tooltipPosition:"top-right",mt:"0.5rem",onClick:function(){return a("pulseRadiation")}})]})},g=function(e,t){var n=(0,r.useBackend)(t),a=(n.act,n.data.buffers.map((function(e,t){return(0,o.createComponentVNode)(2,v,{id:t+1,name:"Buffer "+(t+1),buffer:e},t)})));return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"Buffers",level:"2",children:a}),(0,o.createComponentVNode)(2,b)],4)},v=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=e.id,u=e.name,s=e.buffer,d=c.isInjectorReady,f=u+(s.data?" - "+s.label:"");return(0,o.createComponentVNode)(2,i.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,o.createComponentVNode)(2,i.Section,{title:f,level:"3",mx:"0",lineHeight:"18px",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button.Confirm,{disabled:!s.data,icon:"trash",content:"Clear",onClick:function(){return a("bufferOption",{option:"clear",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!s.data,icon:"pen",content:"Rename",onClick:function(){return a("bufferOption",{option:"changeLabel",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!s.data||!c.hasDisk,icon:"save",content:"Export",tooltip:"Exports this buffer to the currently loaded data disk.",tooltipPosition:"bottom-left",onClick:function(){return a("bufferOption",{option:"saveDisk",id:l})}})],4),children:[(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Write",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",content:"Subject U.I",mb:"0",onClick:function(){return a("bufferOption",{option:"saveUI",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",content:"Subject U.I and U.E.",mb:"0",onClick:function(){return a("bufferOption",{option:"saveUIAndUE",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",content:"Subject S.E.",mb:"0",onClick:function(){return a("bufferOption",{option:"saveSE",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!c.hasDisk||!c.disk.data,icon:"arrow-circle-down",content:"From Disk",mb:"0",onClick:function(){return a("bufferOption",{option:"loadDisk",id:l})}})]}),!!s.data&&(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Subject",children:s.owner||(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"Unknown"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Data Type",children:["ui"===s.type?"Unique Identifiers":"Structural Enzymes",!!s.ue&&" and Unique Enzymes"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Transfer to",children:[(0,o.createComponentVNode)(2,i.Button,{disabled:!d,icon:d?"syringe":"spinner",iconSpin:!d,content:"Injector",mb:"0",onClick:function(){return a("bufferOption",{option:"createInjector",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!d,icon:d?"syringe":"spinner",iconSpin:!d,content:"Block Injector",mb:"0",onClick:function(){return a("bufferOption",{option:"createInjector",id:l,block:1})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"user",content:"Subject",mb:"0",onClick:function(){return a("bufferOption",{option:"transfer",id:l})}})]})],4)]}),!s.data&&(0,o.createComponentVNode)(2,i.Box,{color:"label",mt:"0.5rem",children:"This buffer is empty."})]})})},b=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.hasDisk,u=c.disk;return(0,o.createComponentVNode)(2,i.Section,{title:"Data Disk",level:"2",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button.Confirm,{disabled:!l||!u.data,icon:"trash",content:"Wipe",onClick:function(){return a("wipeDisk")}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!l,icon:"eject",content:"Eject",onClick:function(){return a("ejectDisk")}})],4),children:l?u.data?(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Label",children:u.label?u.label:"No label"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Subject",children:u.owner?u.owner:(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"Unknown"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Data Type",children:["ui"===u.type?"Unique Identifiers":"Structural Enzymes",!!u.ue&&" and Unique Enzymes"]})]}):(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"Disk is blank."}):(0,o.createComponentVNode)(2,i.Box,{color:"label",textAlign:"center",my:"1rem",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"save-o",size:"4"}),(0,o.createVNode)(1,"br"),"No disk inserted."]})})},C=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.isBeakerLoaded,u=c.beakerVolume,d=c.beakerLabel;return(0,o.createComponentVNode)(2,i.Section,{title:"Rejuvenators and Beaker",level:"2",buttons:(0,o.createComponentVNode)(2,i.Button,{disabled:!l,icon:"eject",content:"Eject",onClick:function(){return a("ejectBeaker")}}),children:l?(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Inject",children:[s.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{disabled:e>u,icon:"syringe",content:e,onClick:function(){return a("injectRejuvenators",{amount:e})}},t)})),(0,o.createComponentVNode)(2,i.Button,{disabled:u<=0,icon:"syringe",content:"All",onClick:function(){return a("injectRejuvenators",{amount:u})}})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Beaker",children:[(0,o.createComponentVNode)(2,i.Box,{mb:"0.5rem",children:d||"No label"}),u?(0,o.createComponentVNode)(2,i.Box,{color:"good",children:[u," unit",1===u?"":"s"," remaining"]}):(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"Empty"})]})]}):(0,o.createComponentVNode)(2,i.Box,{color:"label",textAlign:"center",my:"25%",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"exclamation-triangle",size:"4"}),(0,o.createVNode)(1,"br"),"No beaker loaded."]})})},N=function(e,t){return(0,o.createComponentVNode)(2,i.Dimmer,{textAlign:"center",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"spinner",size:"5",spin:!0}),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Box,{color:"average",children:(0,o.createVNode)(1,"h1",null,[(0,o.createComponentVNode)(2,i.Icon,{name:"radiation"}),(0,o.createTextVNode)("\xa0Irradiating occupant\xa0"),(0,o.createComponentVNode)(2,i.Icon,{name:"radiation"})],4)}),(0,o.createComponentVNode)(2,i.Box,{color:"label",children:(0,o.createVNode)(1,"h3",null,[(0,o.createTextVNode)("For "),e.duration,(0,o.createTextVNode)(" second"),1===e.duration?"":"s"],0)})]})},y=function(e,t){for(var n=(0,r.useBackend)(t),a=n.act,c=(n.data,e.dnaString),l=e.selectedBlock,u=e.selectedSubblock,s=e.blockSize,d=e.action,f=c.split(""),p=[],m=function(e){for(var t=e/s+1,n=[],r=function(r){var c=r+1;n.push((0,o.createComponentVNode)(2,i.Button,{selected:l===t&&u===c,content:f[e+r],mb:"0",onClick:function(){return a(d,{block:t,subblock:c})}}))},c=0;c=g,content:"-",as:"span",mr:"0.5rem",onClick:function(){return c("tempo",{"new":m+v})}}),(0,r.round)(600/m)," BPM",(0,o.createComponentVNode)(2,a.Button,{disabled:m<=h,content:"+",as:"span",ml:"0.5rem",onClick:function(){return c("tempo",{"new":m-v})}})]})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Volume",children:(0,o.createComponentVNode)(2,a.Slider,{animated:!0,minValue:C,maxValue:N,value:b,stepPixelSize:"6",onDrag:function(e,t){return c("setvolume",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",children:y?(0,o.createComponentVNode)(2,a.Box,{color:"good",children:"Ready"}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"Instrument Definition Error!"})})]}),(0,o.createComponentVNode)(2,s)]})},s=function(e,t){var n,c,l=(0,i.useBackend)(t),u=l.act,s=l.data,d=s.allowedInstrumentNames,f=s.instrumentLoaded,p=s.instrument,m=s.canNoteShift,h=s.noteShift,g=s.noteShiftMin,v=s.noteShiftMax,b=s.sustainMode,C=s.sustainLinearDuration,N=s.sustainExponentialDropoff,y=s.legacy,V=s.sustainDropoffVolume,x=s.sustainHeldNote;return 1===b?(n="Linear",c=(0,o.createComponentVNode)(2,a.Slider,{minValue:"0.1",maxValue:"5",value:C,step:"0.5",stepPixelSize:"85",format:function(e){return(0,r.round)(100*e)/100+" seconds"},onChange:function(e,t){return u("setlinearfalloff",{"new":t/10})}})):2===b&&(n="Exponential",c=(0,o.createComponentVNode)(2,a.Slider,{minValue:"1.025",maxValue:"10",value:N,step:"0.01",format:function(e){return(0,r.round)(1e3*e)/1e3+"% per decisecond"},onChange:function(e,t){return u("setexpfalloff",{"new":t})}})),d.sort(),(0,o.createComponentVNode)(2,a.Box,{my:-1,children:(0,o.createComponentVNode)(2,a.Collapsible,{mt:"1rem",mb:"0",title:"Advanced",children:(0,o.createComponentVNode)(2,a.Section,{mt:-1,children:[(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Type",children:y?"Legacy":"Synthesized"}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Current",children:f?(0,o.createComponentVNode)(2,a.Dropdown,{options:d,selected:p,width:"40%",onSelected:function(e){return u("switchinstrument",{name:e})}}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"None!"})}),!(y||!m)&&(0,o.createFragment)([(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Note Shift/Note Transpose",children:(0,o.createComponentVNode)(2,a.Slider,{minValue:g,maxValue:v,value:h,stepPixelSize:"2",format:function(e){return e+" keys / "+(0,r.round)(e/12*100)/100+" octaves"},onChange:function(e,t){return u("setnoteshift",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Sustain Mode",children:[(0,o.createComponentVNode)(2,a.Dropdown,{options:["Linear","Exponential"],selected:n,onSelected:function(e){return u("setsustainmode",{"new":e})}}),c]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Volume Dropoff Threshold",children:(0,o.createComponentVNode)(2,a.Slider,{animated:!0,minValue:"0.01",maxValue:"100",value:V,stepPixelSize:"6",onChange:function(e,t){return u("setdropoffvolume",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Sustain indefinitely last held note",children:(0,o.createComponentVNode)(2,a.Button,{selected:x,icon:x?"toggle-on":"toggle-off",content:x?"Yes":"No",onClick:function(){return u("togglesustainhold")}})})],4)]}),(0,o.createComponentVNode)(2,a.Button,{icon:"redo",content:"Reset to Default",mt:"0.5rem",onClick:function(){return u("reset")}})]})})})},d=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.playing,u=c.lines,s=c.editing;return(0,o.createComponentVNode)(2,a.Section,{title:"Editor",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{disabled:!s||l,icon:"plus",content:"Add Line",onClick:function(){return r("newline",{line:u.length+1})}}),(0,o.createComponentVNode)(2,a.Button,{selected:!s,icon:s?"chevron-up":"chevron-down",onClick:function(){return r("edit")}})],4),children:!!s&&(u.length>0?(0,o.createComponentVNode)(2,a.LabeledList,{children:u.map((function(e,t){return(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:t+1,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{disabled:l,icon:"pen",onClick:function(){return r("modifyline",{line:t+1})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:l,icon:"trash",onClick:function(){return r("deleteline",{line:t+1})}})],4),children:e},t)}))}):(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"Song is empty."}))})}},function(e,t,n){"use strict";t.__esModule=!0,t.MechBayConsole=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.MechBayConsole=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data.recharge_port,u=l&&l.mech,s=u&&u.cell,d=u&&u.name;return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{title:d?"Mech status: "+d:"Mech status",textAlign:"center",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Sync",onClick:function(){return c("reconnect")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Integrity",children:!l&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No power port detected. Please re-sync."})||!u&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No mech detected."})||(0,o.createComponentVNode)(2,i.ProgressBar,{value:u.health/u.maxhealth,ranges:{good:[.7,Infinity],average:[.3,.7],bad:[-Infinity,.3]}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:!l&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No power port detected. Please re-sync."})||!u&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No mech detected."})||!s&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No cell is installed."})||(0,o.createComponentVNode)(2,i.ProgressBar,{value:s.charge/s.maxcharge,ranges:{good:[.7,Infinity],average:[.3,.7],bad:[-Infinity,.3]},children:[(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:s.charge})," / "+s.maxcharge]})})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.MedicalRecords=void 0;var o=n(1),r=n(3),i=n(4),a=n(87),c=n(6),l=n(451),u=n(452),s=n(453),d={Minor:"good",Medium:"average","Dangerous!":"bad",Harmful:"bad","BIOHAZARD THREAT!":"bad"},f=function(e,t){(0,a.modalOpen)(e,"edit",{field:t.edit,value:t.value})};t.MedicalRecords=function(e,t){var n,d=(0,r.useBackend)(t).data,f=d.authenticated,g=d.screen;return f?(2===g?n=(0,o.createComponentVNode)(2,p):3===g?n=(0,o.createComponentVNode)(2,m):4===g?n=(0,o.createComponentVNode)(2,h):5===g?n=(0,o.createComponentVNode)(2,b):6===g&&(n=(0,o.createComponentVNode)(2,C)),(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,a.ComplexModal),(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,l.LoginInfo),(0,o.createComponentVNode)(2,s.TemporaryNotice),(0,o.createComponentVNode)(2,N),(0,o.createComponentVNode)(2,i.Section,{height:"100%",flexGrow:"1",children:n})]})]})):(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{children:(0,o.createComponentVNode)(2,u.LoginScreen)})})};var p=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data.records;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Input,{fluid:!0,placeholder:"Search by Name, DNA, or ID",onChange:function(e,t){return a("search",{t1:t})}}),(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:c.map((function(e,t){return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"user",mb:"0.5rem",content:e.id+": "+e.name,onClick:function(){return a("d_rec",{d_rec:e.ref})}}),(0,o.createVNode)(1,"br")],4,t)}))})],4)},m=function(e,t){var n=(0,r.useBackend)(t).act;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"download",content:"Backup to Disk",disabled:!0}),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Button,{icon:"upload",content:"Upload from Disk",my:"0.5rem",disabled:!0}),(0,o.createTextVNode)(" "),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"trash",content:"Delete All Medical Records",onClick:function(){return n("del_all")}})],4)},h=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.medical,u=c.printing;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"General Data",level:2,mt:"-6px",children:(0,o.createComponentVNode)(2,g)}),(0,o.createComponentVNode)(2,i.Section,{title:"Medical Data",level:2,children:(0,o.createComponentVNode)(2,v)}),(0,o.createComponentVNode)(2,i.Section,{title:"Actions",level:2,children:[(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"trash",disabled:!!l.empty,content:"Delete Medical Record",color:"bad",onClick:function(){return a("del_r")}}),(0,o.createComponentVNode)(2,i.Button,{icon:u?"spinner":"print",disabled:u,iconSpin:!!u,content:"Print Entry",ml:"0.5rem",onClick:function(){return a("print_p")}}),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-left",content:"Back",mt:"0.5rem",onClick:function(){return a("screen",{screen:2})}})]})],4)},g=function(e,t){var n=(0,r.useBackend)(t).data.general;return n&&n.fields?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{width:"50%",float:"left",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:n.fields.map((function(e,n){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.field,children:[(0,o.createComponentVNode)(2,i.Box,{height:"20px",display:"inline-block",children:e.value}),!!e.edit&&(0,o.createComponentVNode)(2,i.Button,{icon:"pen",ml:"0.5rem",onClick:function(){return f(t,e)}})]},n)}))})}),(0,o.createComponentVNode)(2,i.Box,{width:"50%",float:"right",textAlign:"right",children:!!n.has_photos&&n.photos.map((function(e,t){return(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",textAlign:"center",color:"label",children:[(0,o.createVNode)(1,"img",null,null,1,{src:e.substr(1,e.length-1),style:{width:"96px","margin-bottom":"0.5rem","-ms-interpolation-mode":"nearest-neighbor"}}),(0,o.createVNode)(1,"br"),"Photo #",t+1]},t)}))})],4):(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"General records lost!"})},v=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data.medical;return l&&l.fields?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList,{children:l.fields.map((function(e,n){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.field,children:[e.value,(0,o.createComponentVNode)(2,i.Button,{icon:"pen",ml:"0.5rem",mb:e.line_break?"1rem":"initial",onClick:function(){return f(t,e)}})]},n)}))}),(0,o.createComponentVNode)(2,i.Section,{title:"Comments/Log",level:2,children:[0===l.comments.length?(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"No comments found."}):l.comments.map((function(e,t){return(0,o.createComponentVNode)(2,i.Box,{children:[(0,o.createComponentVNode)(2,i.Box,{color:"label",display:"inline",children:e.header}),(0,o.createVNode)(1,"br"),e.text,(0,o.createComponentVNode)(2,i.Button,{icon:"comment-slash",color:"bad",ml:"0.5rem",onClick:function(){return c("del_c",{del_c:t+1})}})]},t)})),(0,o.createComponentVNode)(2,i.Button,{icon:"comment-medical",content:"Add Entry",color:"good",mt:"0.5rem",mb:"0",onClick:function(){return(0,a.modalOpen)(t,"add_c")}})]})],4):(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:["Medical records lost!",(0,o.createComponentVNode)(2,i.Button,{icon:"pen",content:"New Record",ml:"0.5rem",onClick:function(){return c("new")}})]})},b=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data.virus;return c.sort((function(e,t){return e.name>t.name?1:-1})),c.map((function(e,t){return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"flask",content:e.name,mb:"0.5rem",onClick:function(){return a("vir",{vir:e.D})}}),(0,o.createVNode)(1,"br")],4,t)}))},C=function(e,t){var n=(0,r.useBackend)(t).data.medbots;return 0===n.length?(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"There are no Medbots."}):n.map((function(e,t){return(0,o.createComponentVNode)(2,i.Collapsible,{open:!0,title:e.name,children:(0,o.createComponentVNode)(2,i.Box,{px:"0.5rem",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Location",children:[e.area||"Unknown"," (",e.x,", ",e.y,")"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",children:e.on?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{color:"good",children:"Online"}),(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:e.use_beaker?"Reservoir: "+e.total_volume+"/"+e.maximum_volume:"Using internal synthesizer."})],4):(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"Offline"})})]})})},t)}))},N=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data.screen;return(0,o.createComponentVNode)(2,i.Tabs,{children:[(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:2===c,onClick:function(){return a("screen",{screen:2})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"list"}),"List Records"]}),(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:5===c,onClick:function(){return a("screen",{screen:5})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"database"}),"Virus Database"]}),(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:6===c,onClick:function(){return a("screen",{screen:6})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"plus-square"}),"Medbot Tracking"]}),(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:3===c,onClick:function(){return a("screen",{screen:3})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"wrench"}),"Record Maintenance"]})]})};(0,a.modalRegisterBodyOverride)("virus",(function(e,t){var n=e.args;return(0,o.createComponentVNode)(2,i.Section,{level:2,m:"-1rem",pb:"1rem",title:n.name||"Virus",children:(0,o.createComponentVNode)(2,i.Box,{mx:"0.5rem",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Number of stages",children:n.max_stages}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Spread",children:[n.spread_text," Transmission"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Possible cure",children:n.cure}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Notes",children:n.desc}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Severity",color:d[n.severity],children:n.severity})]})})})}))},function(e,t,n){"use strict";t.__esModule=!0,t.LoginInfo=void 0;var o=n(1),r=n(3),i=n(4);t.LoginInfo=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.authenticated,u=c.rank;if(c)return(0,o.createComponentVNode)(2,i.NoticeBox,{info:!0,children:[(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",verticalAlign:"middle",children:["Logged in as: ",l," (",u,")"]}),(0,o.createComponentVNode)(2,i.Button,{icon:"sign-out-alt",content:"Logout and Eject ID",color:"good",float:"right",onClick:function(){return a("logout")}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]})}},function(e,t,n){"use strict";t.__esModule=!0,t.LoginScreen=void 0;var o=n(1),r=n(3),i=n(4);t.LoginScreen=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.scan,u=c.isAI,s=c.isRobot;return(0,o.createComponentVNode)(2,i.Section,{title:"Welcome",height:"100%",stretchContents:!0,children:(0,o.createComponentVNode)(2,i.Flex,{height:"100%",align:"center",justify:"center",children:(0,o.createComponentVNode)(2,i.Flex.Item,{textAlign:"center",mt:"-2rem",children:[(0,o.createComponentVNode)(2,i.Box,{fontSize:"1.5rem",bold:!0,children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-circle",verticalAlign:"middle",size:3,mr:"1rem"}),"Guest"]}),(0,o.createComponentVNode)(2,i.Box,{color:"label",my:"1rem",children:["ID:",(0,o.createComponentVNode)(2,i.Button,{icon:"id-card",content:l||"----------",ml:"0.5rem",onClick:function(){return a("scan")}})]}),(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",disabled:!l,content:"Login",onClick:function(){return a("login",{login_type:1})}}),!!u&&(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",content:"Login as AI",onClick:function(){return a("login",{login_type:2})}}),!!s&&(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",content:"Login as Cyborg",onClick:function(){return a("login",{login_type:3})}})]})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.TemporaryNotice=void 0;var o=n(1),r=n(3),i=n(4);t.TemporaryNotice=function(e,t){var n,a=(0,r.useBackend)(t),c=a.act,l=a.data.temp;if(l){var u=((n={})[l.style]=!0,n);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.NoticeBox,Object.assign({},u,{children:[(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",verticalAlign:"middle",children:l.text}),(0,o.createComponentVNode)(2,i.Button,{icon:"times-circle",float:"right",onClick:function(){return c("cleartemp")}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]})))}}},function(e,t,n){"use strict";t.__esModule=!0,t.MiningVendor=void 0;var o=n(1),r=n(170),i=n(3),a=n(4),c=n(6);var l={Alphabetical:function(e,t){return e-t},"By availability":function(e,t){return-(e.affordable-t.affordable)},"By price":function(e,t){return e.price-t.price}};t.MiningVendor=function(e,t){return(0,o.createComponentVNode)(2,c.Window,{children:(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,u),(0,o.createComponentVNode)(2,d),(0,o.createComponentVNode)(2,s)]})})};var u=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.has_id,u=c.id;return(0,o.createComponentVNode)(2,a.NoticeBox,{success:l,children:l?(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{display:"inline-block",verticalAlign:"middle",style:{float:"left"},children:["Logged in as ",u.name,".",(0,o.createVNode)(1,"br"),"You have ",u.points.toLocaleString("en-US")," points."]}),(0,o.createComponentVNode)(2,a.Button,{icon:"eject",content:"Eject ID",style:{float:"right"},onClick:function(){return r("logoff")}}),(0,o.createComponentVNode)(2,a.Box,{style:{clear:"both"}})],4):"Please insert an ID in order to make purchases."})},s=function(e,t){var n=(0,i.useBackend)(t),c=(n.act,n.data),u=c.has_id,s=c.id,d=c.items,p=(0,i.useLocalState)(t,"search",""),m=p[0],h=(p[1],(0,i.useLocalState)(t,"sort","Alphabetical")),g=h[0],v=(h[1],(0,i.useLocalState)(t,"descending",!1)),b=v[0],C=(v[1],(0,r.createSearch)(m,(function(e){return e[0]}))),N=!1,y=Object.entries(d).map((function(e,t){var n=Object.entries(e[1]).filter(C).map((function(e){return e[1].affordable=u&&s.points>=e[1].price,e[1]})).sort(l[g]);if(0!==n.length)return b&&(n=n.reverse()),N=!0,(0,o.createComponentVNode)(2,f,{title:e[0],items:n},e[0])}));return(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",overflow:"auto",children:(0,o.createComponentVNode)(2,a.Section,{children:N?y:(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"No items matching your criteria was found!"})})})},d=function(e,t){var n=(0,i.useLocalState)(t,"search",""),r=(n[0],n[1]),c=(0,i.useLocalState)(t,"sort",""),u=(c[0],c[1]),s=(0,i.useLocalState)(t,"descending",!1),d=s[0],f=s[1];return(0,o.createComponentVNode)(2,a.Box,{mb:"0.5rem",children:(0,o.createComponentVNode)(2,a.Flex,{width:"100%",children:[(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",mr:"0.5rem",children:(0,o.createComponentVNode)(2,a.Input,{placeholder:"Search by item name..",width:"100%",onInput:function(e,t){return r(t)}})}),(0,o.createComponentVNode)(2,a.Flex.Item,{basis:"30%",children:(0,o.createComponentVNode)(2,a.Dropdown,{selected:"Alphabetical",options:Object.keys(l),width:"100%",lineHeight:"19px",onSelected:function(e){return u(e)}})}),(0,o.createComponentVNode)(2,a.Flex.Item,{children:(0,o.createComponentVNode)(2,a.Button,{icon:d?"arrow-down":"arrow-up",height:"19px",tooltip:d?"Descending order":"Ascending order",tooltipPosition:"bottom-left",ml:"0.5rem",onClick:function(){return f(!d)}})})]})})},f=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=e.title,u=e.items,s=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["title","items"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Collapsible,Object.assign({open:!0,title:l},s,{children:u.map((function(e){return(0,o.createComponentVNode)(2,a.Box,{children:[(0,o.createComponentVNode)(2,a.Box,{display:"inline-block",verticalAlign:"middle",lineHeight:"20px",style:{float:"left"},children:e.name}),(0,o.createComponentVNode)(2,a.Button,{disabled:!c.has_id||c.id.points=e.length?{done:!0}:{done:!1,value:e[t++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(t=e[Symbol.iterator]()).next.bind(t)}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n50?"good":"bad",value:e.health/100})}),"number"==typeof e.charge&&(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cell Charge",children:(0,o.createComponentVNode)(2,i.ProgressBar,{color:e.charge>30?"good":"bad",value:e.charge/100})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cell Capacity",children:(0,o.createComponentVNode)(2,i.Box,{color:e.cell_capacity<3e4?"average":"good",children:e.cell_capacity})})],4)||(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cell",children:(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"No Power Cell"})}),!!e.is_hacked&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Safeties",children:(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"DISABLED"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Module",children:e.module}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Master AI",children:(0,o.createComponentVNode)(2,i.Box,{color:e.synchronization?"default":"average",children:e.synchronization||"None"})})]})},e.uid)})):(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No cyborg units detected within access parameters."})}},function(e,t,n){"use strict";t.__esModule=!0,t.ShuttleConsole=void 0;var o=n(1),r=n(3),i=n(4),a=n(6),c=n(168);t.ShuttleConsole=function(e,t){var n=(0,r.useBackend)(t),l=n.act,u=n.data;return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Location",children:u.status?u.status:(0,o.createComponentVNode)(2,i.NoticeBox,{color:"red",children:"Shuttle Missing"})}),!!u.shuttle&&(!!u.docking_ports_len&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Send to ",children:u.docking_ports.map((function(e){return(0,o.createComponentVNode)(2,i.Button,{icon:"chevron-right",content:e.name,onClick:function(){return l("move",{move:e.id})}},e.name)}))})||(0,o.createFragment)([(0,o.createComponentVNode)(2,c.LabeledListItem,{label:"Status",color:"red",children:(0,o.createComponentVNode)(2,i.NoticeBox,{color:"red",children:"Shuttle Locked"})}),!!u.admin_controlled&&(0,o.createComponentVNode)(2,c.LabeledListItem,{label:"Authorization",children:(0,o.createComponentVNode)(2,i.Button,{icon:"exclamation-circle",content:"Request Authorization",disabled:!u.status,onClick:function(){return l("request")}})})],0))]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Sleeper=void 0;var o=n(1),r=n(20),i=n(3),a=n(4),c=n(6),l=[["good","Alive"],["average","Critical"],["bad","DEAD"]],u=[["Resp.","oxyLoss"],["Toxin","toxLoss"],["Brute","bruteLoss"],["Burn","fireLoss"]],s={average:[.25,.5],bad:[.5,Infinity]},d=["bad","average","average","good","average","average","bad"];t.Sleeper=function(e,t){var n=(0,i.useBackend)(t),r=(n.act,n.data.hasOccupant?(0,o.createComponentVNode)(2,f):(0,o.createComponentVNode)(2,v));return(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:r})})};var f=function(e,t){var n=(0,i.useBackend)(t);n.act,n.data.occupant;return(0,o.createFragment)([(0,o.createComponentVNode)(2,p),(0,o.createComponentVNode)(2,m),(0,o.createComponentVNode)(2,g),(0,o.createComponentVNode)(2,h)],4)},p=function(e,t){var n=(0,i.useBackend)(t),c=n.act,u=n.data,s=u.occupant,f=u.auto_eject_dead;return(0,o.createComponentVNode)(2,a.Section,{title:"Occupant",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{color:"label",display:"inline",children:"Auto-eject if dead:\xa0"}),(0,o.createComponentVNode)(2,a.Button,{icon:f?"toggle-on":"toggle-off",selected:f,content:f?"On":"Off",onClick:function(){return c("auto_eject_dead_"+(f?"off":"on"))}}),(0,o.createComponentVNode)(2,a.Button,{icon:"user-slash",content:"Eject",onClick:function(){return c("ejectify")}})],4),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Name",children:s.name}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:s.maxHealth,value:s.health/s.maxHealth,ranges:{good:[.5,Infinity],average:[0,.5],bad:[-Infinity,0]},children:(0,r.round)(s.health,0)})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",color:l[s.stat][0],children:l[s.stat][1]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Temperature",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:s.maxTemp,value:s.bodyTemperature/s.maxTemp,color:d[s.temperatureSuitability+3],children:[(0,r.round)(s.btCelsius,0),"\xb0C,",(0,r.round)(s.btFaren,0),"\xb0F"]})}),!!s.hasBlood&&(0,o.createFragment)([(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Blood Level",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:s.bloodMax,value:s.bloodLevel/s.bloodMax,ranges:{bad:[-Infinity,.6],average:[.6,.9],good:[.6,Infinity]},children:[s.bloodPercent,"%, ",s.bloodLevel,"cl"]})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Pulse",verticalAlign:"middle",children:[s.pulse," BPM"]})],4)]})})},m=function(e,t){var n=(0,i.useBackend)(t).data.occupant;return(0,o.createComponentVNode)(2,a.Section,{title:"Damage",children:(0,o.createComponentVNode)(2,a.LabeledList,{children:u.map((function(e,t){return(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:e[0],children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:"100",value:n[e[1]]/100,ranges:s,children:(0,r.round)(n[e[1]],0)},t)},t)}))})})},h=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.isBeakerLoaded,u=c.beakerMaxSpace,s=c.beakerFreeSpace,d=c.dialysis&&s>0;return(0,o.createComponentVNode)(2,a.Section,{title:"Dialysis",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{disabled:!l||s<=0,selected:d,icon:d?"toggle-on":"toggle-off",content:d?"Active":"Inactive",onClick:function(){return r("togglefilter")}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l,icon:"eject",content:"Eject",onClick:function(){return r("removebeaker")}})],4),children:l?(0,o.createComponentVNode)(2,a.LabeledList,{children:(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Remaining Space",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:u,value:s/u,ranges:{good:[.5,Infinity],average:[.25,.5],bad:[-Infinity,.25]},children:[s,"u"]})})}):(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"No beaker loaded."})})},g=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.occupant,u=c.chemicals,s=c.maxchem,d=c.amounts;return(0,o.createComponentVNode)(2,a.Section,{title:"Chemicals",flexGrow:"1",children:u.map((function(e,t){var n,i="";return e.overdosing?(i="bad",n=(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"exclamation-circle"}),"\xa0 Overdosing!"]})):e.od_warning&&(i="average",n=(0,o.createComponentVNode)(2,a.Box,{color:"average",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"exclamation-triangle"}),"\xa0 Close to overdosing"]})),(0,o.createComponentVNode)(2,a.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,o.createComponentVNode)(2,a.Section,{title:e.title,level:"3",mx:"0",lineHeight:"18px",buttons:n,children:(0,o.createComponentVNode)(2,a.Flex,{align:"flex-start",children:[(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:s,value:e.occ_amount/s,color:i,mr:"0.5rem",children:[e.pretty_amount,"/",s,"u"]}),d.map((function(t,n){return(0,o.createComponentVNode)(2,a.Button,{disabled:!e.injectable||e.occ_amount+t>s||2===l.stat,icon:"syringe",content:t,mb:"0",height:"19px",onClick:function(){return r("chemical",{chemid:e.id,amount:t})}},n)}))]})})},t)}))})},v=function(e,t){return(0,o.createComponentVNode)(2,a.Section,{textAlign:"center",flexGrow:"1",children:(0,o.createComponentVNode)(2,a.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",align:"center",color:"label",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant detected."]})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.SlotMachine=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.SlotMachine=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,u=c.data;return null===u.money?(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:[(0,o.createComponentVNode)(2,i.Box,{children:"Could not scan your card or could not find account!"}),(0,o.createComponentVNode)(2,i.Box,{children:"Please wear or hold your ID and try again."})]})})}):(n=1===u.plays?u.plays+" player has tried their luck today!":u.plays+" players have tried their luck today!",(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:[(0,o.createComponentVNode)(2,i.Box,{lineHeight:2,children:n}),(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Credits Remaining",children:(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:u.money})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"10 credits to spin",children:(0,o.createComponentVNode)(2,i.Button,{icon:"coins",disabled:u.working,content:u.working?"Spinning...":"Spin",onClick:function(){return l("spin")}})})]}),(0,o.createComponentVNode)(2,i.Box,{bold:!0,lineHeight:2,color:u.resultlvl,children:u.result})]})})}))}},function(e,t,n){"use strict";t.__esModule=!0,t.Smes=void 0;var o=n(1),r=n(3),i=n(4),a=n(171),c=n(6);t.Smes=function(e,t){var n=(0,r.useBackend)(t),l=n.act,u=n.data,s=u.capacityPercent,d=(u.capacity,u.charge),f=u.inputAttempt,p=u.inputting,m=u.inputLevel,h=u.inputLevelMax,g=u.inputAvailable,v=u.outputAttempt,b=u.outputting,C=u.outputLevel,N=u.outputLevelMax,y=u.outputUsed,V=(s>=100?"good":p&&"average")||"bad",x=(b?"good":d>0&&"average")||"bad";return(0,o.createComponentVNode)(2,c.Window,{children:(0,o.createComponentVNode)(2,c.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Stored Energy",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:.01*s,ranges:{good:[.5,Infinity],average:[.15,.5],bad:[-Infinity,.15]}})}),(0,o.createComponentVNode)(2,i.Section,{title:"Input",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Charge Mode",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:f?"sync-alt":"times",selected:f,onClick:function(){return l("tryinput")},children:f?"Auto":"Off"}),children:(0,o.createComponentVNode)(2,i.Box,{color:V,children:(s>=100?"Fully Charged":p&&"Charging")||"Not Charging"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target Input",children:(0,o.createComponentVNode)(2,i.Flex,{inline:!0,width:"100%",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",disabled:0===m,onClick:function(){return l("input",{target:"min"})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"backward",disabled:0===m,onClick:function(){return l("input",{adjust:-1e4})}})]}),(0,o.createComponentVNode)(2,i.Flex.Item,{grow:1,mx:1,children:(0,o.createComponentVNode)(2,i.Slider,{value:m/1e3,fillValue:g/1e3,minValue:0,maxValue:h/1e3,step:5,stepPixelSize:4,format:function(e){return(0,a.formatPower)(1e3*e,1)},onChange:function(e,t){return l("input",{target:1e3*t})}})}),(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"forward",disabled:m===h,onClick:function(){return l("input",{adjust:1e4})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",disabled:m===h,onClick:function(){return l("input",{target:"max"})}})]})]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Available",children:(0,a.formatPower)(g)})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Output",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Output Mode",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:v?"power-off":"times",selected:v,onClick:function(){return l("tryoutput")},children:v?"On":"Off"}),children:(0,o.createComponentVNode)(2,i.Box,{color:x,children:b?"Sending":d>0?"Not Sending":"No Charge"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target Output",children:(0,o.createComponentVNode)(2,i.Flex,{inline:!0,width:"100%",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",disabled:0===C,onClick:function(){return l("output",{target:"min"})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"backward",disabled:0===C,onClick:function(){return l("output",{adjust:-1e4})}})]}),(0,o.createComponentVNode)(2,i.Flex.Item,{grow:1,mx:1,children:(0,o.createComponentVNode)(2,i.Slider,{value:C/1e3,minValue:0,maxValue:N/1e3,step:5,stepPixelSize:4,format:function(e){return(0,a.formatPower)(1e3*e,1)},onChange:function(e,t){return l("output",{target:1e3*t})}})}),(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"forward",disabled:C===N,onClick:function(){return l("output",{adjust:1e4})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",disabled:C===N,onClick:function(){return l("output",{target:"max"})}})]})]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Outputting",children:(0,a.formatPower)(y)})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.SupermatterMonitor=void 0;var o=n(1),r=n(3),i=n(4),a=n(6),c=n(86);t.SupermatterMonitor=function(e,t){var n=(0,r.useBackend)(t);n.act;return 0===n.data.active?(0,o.createComponentVNode)(2,l):(0,o.createComponentVNode)(2,u)};var l=function(e,t){var n=(0,r.useBackend)(t),l=n.act,u=n.data;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:(0,o.createComponentVNode)(2,i.Section,{title:"Detected Supermatter Shards",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Refresh",onClick:function(){return l("refresh")}}),children:(0,o.createComponentVNode)(2,i.Box,{m:1,children:0===u.supermatters.length?(0,o.createVNode)(1,"h3",null,"No shards detected",16):(0,o.createComponentVNode)(2,i.Table,{children:[(0,o.createComponentVNode)(2,i.Table.Row,{header:!0,children:[(0,o.createComponentVNode)(2,c.TableCell,{children:"Area"}),(0,o.createComponentVNode)(2,c.TableCell,{children:"Integrity"}),(0,o.createComponentVNode)(2,c.TableCell,{children:"Details"})]}),u.supermatters.map((function(e){return(0,o.createComponentVNode)(2,c.TableRow,{children:[(0,o.createComponentVNode)(2,c.TableCell,{children:e.area_name}),(0,o.createComponentVNode)(2,c.TableCell,{children:[e.integrity,"%"]}),(0,o.createComponentVNode)(2,c.TableCell,{children:(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",content:"View",onClick:function(){return l("view",{view:e.uid})}})})]},e)}))]})})})})})},u=function(e,t){var n,c,l,u=(0,r.useBackend)(t),s=u.act,d=u.data;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Crystal Status",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"caret-square-left",content:"Back",onClick:function(){return s("back")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Core Integrity",children:(0,o.createComponentVNode)(2,i.ProgressBar,{ranges:{good:[95,Infinity],average:[80,94],bad:[-Infinity,79]},minValue:"0",maxValue:"100",value:d.SM_integrity,children:[d.SM_integrity,"%"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Relative EER",children:(0,o.createComponentVNode)(2,i.Box,{color:(l=d.SM_power,l>300?"bad":l>150?"average":"good"),children:[d.SM_power," MeV/cm3"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",children:(0,o.createComponentVNode)(2,i.Box,{color:(c=d.SM_ambienttemp,c>5e3?"bad":c>4e3?"average":"good"),children:[d.SM_ambienttemp," K"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Pressure",children:(0,o.createComponentVNode)(2,i.Box,{color:(n=d.SM_ambientpressure,n>1e4?"bad":n>5e3?"average":"good"),children:[d.SM_ambientpressure," kPa"]})})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Gas Composition",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Oxygen",children:[d.SM_gas_O2,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Carbon Dioxide",children:[d.SM_gas_CO2,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Nitrogen",children:[d.SM_gas_N2,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Plasma",children:[d.SM_gas_PL,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Other",children:[d.SM_gas_OTHER,"%"]})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Tank=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.Tank=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,u=c.data;return n=u.has_mask?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Mask",children:(0,o.createComponentVNode)(2,i.Button,{icon:u.connected?"check":"times",content:u.connected?"Internals On":"Internals Off",selected:u.connected,onClick:function(){return l("internals")}})}):(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Mask",color:"red",children:"No Mask Equipped"}),(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Tank Pressure",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:u.tankPressure/1013,ranges:{good:[.35,Infinity],average:[.15,.35],bad:[-Infinity,.15]},children:u.tankPressure+" kPa"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Release Pressure",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",disabled:u.ReleasePressure===u.minReleasePressure,tooltip:"Min",onClick:function(){return l("pressure",{pressure:"min"})}}),(0,o.createComponentVNode)(2,i.NumberInput,{animated:!0,value:parseFloat(u.releasePressure),width:"65px",unit:"kPa",minValue:u.minReleasePressure,maxValue:u.maxReleasePressure,onChange:function(e,t){return l("pressure",{pressure:t})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",disabled:u.ReleasePressure===u.maxReleasePressure,tooltip:"Max",onClick:function(){return l("pressure",{pressure:"max"})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"undo",content:"",disabled:u.ReleasePressure===u.defaultReleasePressure,tooltip:"Reset",onClick:function(){return l("pressure",{pressure:"reset"})}})]}),n]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.TransferValve=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.TransferValve=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,u=l.tank_one,s=l.tank_two,d=l.attached_device,f=l.valve;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Valve Status",children:(0,o.createComponentVNode)(2,i.Button,{icon:f?"unlock":"lock",content:f?"Open":"Closed",disabled:!u||!s,onClick:function(){return c("toggle")}})})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Assembly",buttons:(0,o.createComponentVNode)(2,i.Button,{textAlign:"center",width:"150px",icon:"cog",content:"Configure Assembly",disabled:!d,onClick:function(){return c("device")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:d?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Attachment",children:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:d,disabled:!d,onClick:function(){return c("remove_device")}})}):(0,o.createComponentVNode)(2,i.NoticeBox,{textAlign:"center",children:"Attach Assembly"})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Attachment One",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:u?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Attachment",children:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:u,disabled:!u,onClick:function(){return c("tankone")}})}):(0,o.createComponentVNode)(2,i.NoticeBox,{textAlign:"center",children:"Attach Tank"})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Attachment Two",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:s?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Attachment",children:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:s,disabled:!s,onClick:function(){return c("tanktwo")}})}):(0,o.createComponentVNode)(2,i.NoticeBox,{textAlign:"center",children:"Attach Tank"})})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Vending=void 0;var o=n(1),r=(n(12),n(3)),i=n(4),a=n(6),c=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=e.product,u=e.productStock,s=e.productImage,d=c.chargesMoney,f=(c.user,c.userMoney),p=c.vend_ready,m=c.coin_name,h=(c.inserted_item_name,!d||0===l.price),g="ERROR!",v="";l.req_coin?(g="COIN",v="circle"):h?(g="FREE",v="arrow-circle-down"):(g=l.price,v="shopping-cart");var b=!p||!m&&l.req_coin||0===u||!h&&l.price>f;return(0,o.createComponentVNode)(2,i.Table.Row,{children:[(0,o.createComponentVNode)(2,i.Table.Cell,{collapsing:!0,children:(0,o.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+s,style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px"}})}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:l.name}),(0,o.createComponentVNode)(2,i.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,o.createComponentVNode)(2,i.Box,{color:(u<=0?"bad":u<=l.max_amount/2&&"average")||"good",children:[u," in stock"]})}),(0,o.createComponentVNode)(2,i.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,o.createComponentVNode)(2,i.Button,{fluid:!0,disabled:b,icon:v,content:g,textAlign:"left",onClick:function(){return a("vend",{inum:l.inum})}})})]})};t.Vending=function(e,t){var n,l=(0,r.useBackend)(t),u=l.act,s=l.data,d=s.user,f=s.guestNotice,p=s.userMoney,m=s.chargesMoney,h=s.product_records,g=void 0===h?[]:h,v=s.coin_records,b=void 0===v?[]:v,C=s.hidden_records,N=void 0===C?[]:C,y=s.stock,V=(s.vend_ready,s.coin_name),x=s.inserted_item_name,w=s.panel_open,k=s.speaker,_=s.imagelist;return n=[].concat(g,b),s.extended_inventory&&(n=[].concat(n,N)),n=n.filter((function(e){return!!e})),(0,o.createComponentVNode)(2,a.Window,{title:"Vending Machine",resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:[!!m&&(0,o.createComponentVNode)(2,i.Section,{title:"User",children:d&&(0,o.createComponentVNode)(2,i.Box,{children:["Welcome, ",(0,o.createVNode)(1,"b",null,d.name,0),","," ",(0,o.createVNode)(1,"b",null,d.job||"Unemployed",0),"!",(0,o.createVNode)(1,"br"),"Your balance is ",(0,o.createVNode)(1,"b",null,[p,(0,o.createTextVNode)(" credits")],0),"."]})||(0,o.createComponentVNode)(2,i.Box,{color:"light-grey",children:f})}),!!V&&(0,o.createComponentVNode)(2,i.Section,{title:"Coin",buttons:(0,o.createComponentVNode)(2,i.Button,{fluid:!0,icon:"eject",content:"Remove Coin",onClick:function(){return u("remove_coin",{})}}),children:(0,o.createComponentVNode)(2,i.Box,{children:V})}),!!x&&(0,o.createComponentVNode)(2,i.Section,{title:"Item",buttons:(0,o.createComponentVNode)(2,i.Button,{fluid:!0,icon:"eject",content:"Eject Item",onClick:function(){return u("eject_item",{})}}),children:(0,o.createComponentVNode)(2,i.Box,{children:x})}),!!w&&(0,o.createComponentVNode)(2,i.Section,{title:"Maintenance",children:(0,o.createComponentVNode)(2,i.Button,{icon:k?"check":"volume-mute",selected:k,content:"Speaker",textAlign:"left",onClick:function(){return u("toggle_voice",{})}})}),(0,o.createComponentVNode)(2,i.Section,{title:"Products",children:(0,o.createComponentVNode)(2,i.Table,{children:n.map((function(e){return(0,o.createComponentVNode)(2,c,{product:e,productStock:y[e.name],productImage:_[e.path]},e.name)}))})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Wires=void 0;var o=n(1),r=n(3),i=n(4),a=n(6);t.Wires=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,u=l.wires||[],s=l.status||[];return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:u.map((function(e){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{className:"candystripe",label:e.color_name,labelColor:e.seen_color,color:e.seen_color,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{content:e.cut?"Mend":"Cut",onClick:function(){return c("cut",{wire:e.color})}}),(0,o.createComponentVNode)(2,i.Button,{content:"Pulse",onClick:function(){return c("pulse",{wire:e.color})}}),(0,o.createComponentVNode)(2,i.Button,{content:e.attached?"Detach":"Attach",onClick:function(){return c("attach",{wire:e.color})}})],4),children:!!e.wire&&(0,o.createVNode)(1,"i",null,[(0,o.createTextVNode)("("),e.wire,(0,o.createTextVNode)(")")],0)},e.seen_color)}))})}),!!s.length&&(0,o.createComponentVNode)(2,i.Section,{children:s.map((function(e){return(0,o.createComponentVNode)(2,i.Box,{color:"lightgray",mt:.1,children:e},e)}))})]})})}}]); \ No newline at end of file +if(!document.createEvent){var t,n=!0,o=!1,r="__IE8__"+Math.random(),i=Object.defineProperty||function(e,t,n){e[t]=n.value},a=Object.defineProperties||function(t,n){for(var o in n)if(l.call(n,o))try{i(t,o,n[o])}catch(r){e.console}},c=Object.getOwnPropertyDescriptor,l=Object.prototype.hasOwnProperty,d=e.Element.prototype,u=e.Text.prototype,s=/^[a-z]+$/,p=/loaded|complete/,f={},m=document.createElement("div"),h=document.documentElement,g=h.removeAttribute,C=h.setAttribute,b=function(e){return{enumerable:!0,writable:!0,configurable:!0,value:e}};x(e.HTMLCommentElement.prototype,d,"nodeValue"),x(e.HTMLScriptElement.prototype,null,"text"),x(u,null,"nodeValue"),x(e.HTMLTitleElement.prototype,null,"text"),i(e.HTMLStyleElement.prototype,"textContent",(t=c(e.CSSStyleSheet.prototype,"cssText"),y((function(){return t.get.call(this.styleSheet)}),(function(e){t.set.call(this.styleSheet,e)}))));var v=/\b\s*alpha\s*\(\s*opacity\s*=\s*(\d+)\s*\)/;i(e.CSSStyleDeclaration.prototype,"opacity",{get:function(){var e=this.filter.match(v);return e?(e[1]/100).toString():""},set:function(e){this.zoom=1;var t=!1;e=e<1?" alpha(opacity="+Math.round(100*e)+")":"",this.filter=this.filter.replace(v,(function(){return t=!0,e})),!t&&e&&(this.filter+=e)}}),a(d,{textContent:{get:_,set:S},firstElementChild:{get:function(){for(var e=this.childNodes||[],t=0,n=e.length;t1?r-1:0),a=1;a1?t-1:0),o=1;o=0||(r[n]=e[n]);return r}(e,["className"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["BlockQuote",t])},n)))}},function(e,t,n){"use strict";var o,r;t.__esModule=!0,t.VNodeFlags=t.ChildFlags=void 0,t.VNodeFlags=o,function(e){e[e.HtmlElement=1]="HtmlElement",e[e.ComponentUnknown=2]="ComponentUnknown",e[e.ComponentClass=4]="ComponentClass",e[e.ComponentFunction=8]="ComponentFunction",e[e.Text=16]="Text",e[e.SvgElement=32]="SvgElement",e[e.InputElement=64]="InputElement",e[e.TextareaElement=128]="TextareaElement",e[e.SelectElement=256]="SelectElement",e[e.Void=512]="Void",e[e.Portal=1024]="Portal",e[e.ReCreate=2048]="ReCreate",e[e.ContentEditable=4096]="ContentEditable",e[e.Fragment=8192]="Fragment",e[e.InUse=16384]="InUse",e[e.ForwardRef=32768]="ForwardRef",e[e.Normalized=65536]="Normalized",e[e.ForwardRefComponent=32776]="ForwardRefComponent",e[e.FormElement=448]="FormElement",e[e.Element=481]="Element",e[e.Component=14]="Component",e[e.DOMRef=2033]="DOMRef",e[e.InUseOrNormalized=81920]="InUseOrNormalized",e[e.ClearInUse=-16385]="ClearInUse",e[e.ComponentKnown=12]="ComponentKnown"}(o||(t.VNodeFlags=o={})),t.ChildFlags=r,function(e){e[e.UnknownChildren=0]="UnknownChildren",e[e.HasInvalidChildren=1]="HasInvalidChildren",e[e.HasVNodeChildren=2]="HasVNodeChildren",e[e.HasNonKeyedChildren=4]="HasNonKeyedChildren",e[e.HasKeyedChildren=8]="HasKeyedChildren",e[e.HasTextChildren=16]="HasTextChildren",e[e.MultipleChildren=12]="MultipleChildren"}(r||(t.ChildFlags=r={}))},function(e,t,n){"use strict";t.__esModule=!0,t.ByondUi=void 0;var o=n(1),r=n(12),i=n(413),a=n(24),c=n(57),l=n(16);function d(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var u=(0,c.createLogger)("ByondUi"),s=[];window.addEventListener("beforeunload",(function(){for(var e=0;e=0||(r[n]=e[n]);return r}(t,["data","rangeX","rangeY","fillColor","strokeColor","strokeWidth"]),g=this.state.viewBox,C=function(e,t,n,o){if(0===e.length)return[];var i=(0,r.zipWith)(Math.min).apply(void 0,e),a=(0,r.zipWith)(Math.max).apply(void 0,e);return n!==undefined&&(i[0]=n[0],a[0]=n[1]),o!==undefined&&(i[1]=o[0],a[1]=o[1]),(0,r.map)((function(e){return(0,r.zipWith)((function(e,t,n,o){return(e-t)/(n-t)*o}))(e,i,a,t)}))(e)}(i,g,a,l);if(C.length>0){var b=C[0],v=C[C.length-1];C.push([g[0]+m,v[1]]),C.push([g[0]+m,-m]),C.push([-m,-m]),C.push([-m,b[1]])}var N=function(e){for(var t="",n=0;n=0||(r[n]=e[n]);return r}(t,["children","color","title","buttons"]);return(0,o.createVNode)(1,"div","Collapsible",[(0,o.createVNode)(1,"div","Table",[(0,o.createVNode)(1,"div","Table__cell",(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Button,Object.assign({fluid:!0,color:l,icon:n?"chevron-down":"chevron-right",onClick:function(){return e.setState({open:!n})}},s,{children:d}))),2),u&&(0,o.createVNode)(1,"div","Table__cell Table__cell--collapsing",u,0)],0),n&&(0,o.createComponentVNode)(2,r.Box,{mt:1,children:a})],0)},a}(o.Component);t.Collapsible=a},function(e,t,n){"use strict";t.__esModule=!0,t.ColorBox=void 0;var o=n(1),r=n(12),i=n(16);var a=function(e){var t=e.content,n=(e.children,e.className),a=e.color,c=e.backgroundColor,l=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["content","children","className","color","backgroundColor"]);return l.color=t?null:"transparent",l.backgroundColor=a||c,(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,r.classes)(["ColorBox",n,(0,i.computeBoxClassName)(l)]),t||".",0,Object.assign({},(0,i.computeBoxProps)(l))))};t.ColorBox=a,a.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.Dropdown=void 0;var o=n(1),r=n(12),i=n(16),a=n(122);function c(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var l=function(e){var t,n;function l(t){var n;return(n=e.call(this,t)||this).state={selected:t.selected,open:!1},n.handleClick=function(){n.state.open&&n.setOpen(!1)},n}n=e,(t=l).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var d=l.prototype;return d.componentWillUnmount=function(){window.removeEventListener("click",this.handleClick)},d.setOpen=function(e){var t=this;this.setState({open:e}),e?(setTimeout((function(){return window.addEventListener("click",t.handleClick)})),this.menuRef.focus()):window.removeEventListener("click",this.handleClick)},d.setSelected=function(e){this.setState({selected:e}),this.setOpen(!1),this.props.onSelected(e)},d.buildMenu=function(){var e=this,t=this.props.options,n=(void 0===t?[]:t).map((function(t){return(0,o.createVNode)(1,"div","Dropdown__menuentry",t,0,{onClick:function(){e.setSelected(t)}},t)}));return n.length?n:"No Options Found"},d.render=function(){var e=this,t=this.props,n=t.color,l=void 0===n?"default":n,d=t.over,u=t.noscroll,s=t.nochevron,p=t.width,f=(t.onClick,t.selected,t.disabled),m=c(t,["color","over","noscroll","nochevron","width","onClick","selected","disabled"]),h=m.className,g=c(m,["className"]),C=d?!this.state.open:this.state.open,b=this.state.open?(0,o.createVNode)(1,"div",(0,r.classes)([u?"Dropdown__menu-noscroll":"Dropdown__menu",d&&"Dropdown__over"]),this.buildMenu(),0,{tabIndex:"-1",style:{width:p}},null,(function(t){e.menuRef=t})):null;return(0,o.createVNode)(1,"div","Dropdown",[(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({width:p,className:(0,r.classes)(["Dropdown__control","Button","Button--color--"+l,f&&"Button--disabled",h])},g,{onClick:function(){f&&!e.state.open||e.setOpen(!e.state.open)},children:[(0,o.createVNode)(1,"span","Dropdown__selected-text",this.state.selected,0),!!s||(0,o.createVNode)(1,"span","Dropdown__arrow-button",(0,o.createComponentVNode)(2,a.Icon,{name:C?"chevron-up":"chevron-down"}),2)]}))),b],0)},l}(o.Component);t.Dropdown=l},function(e,t,n){"use strict";t.__esModule=!0,t.Input=void 0;var o=n(1),r=n(12),i=n(16);function a(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var c=function(e){return(0,r.isFalsy)(e)?"":e},l=function(e){var t,n;function l(){var t;return(t=e.call(this)||this).inputRef=(0,o.createRef)(),t.state={editing:!1},t.handleInput=function(e){var n=t.state.editing,o=t.props.onInput;n||t.setEditing(!0),o&&o(e,e.target.value)},t.handleFocus=function(e){t.state.editing||t.setEditing(!0)},t.handleBlur=function(e){var n=t.state.editing,o=t.props.onChange;n&&(t.setEditing(!1),o&&o(e,e.target.value))},t.handleKeyDown=function(e){var n=t.props,o=n.onInput,r=n.onChange,i=n.onEnter;return 13===e.keyCode?(t.setEditing(!1),r&&r(e,e.target.value),o&&o(e,e.target.value),i&&i(e,e.target.value),void(t.props.selfClear?e.target.value="":e.target.blur())):27===e.keyCode?(t.setEditing(!1),e.target.value=c(t.props.value),void e.target.blur()):void 0},t}n=e,(t=l).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var d=l.prototype;return d.componentDidMount=function(){var e=this.props.value,t=this.inputRef.current;t&&(t.value=c(e),this.props.autofocus&&(t.focus(),t.selectionStart=0,t.selectionEnd=t.value.length))},d.componentDidUpdate=function(e,t){var n=this.state.editing,o=e.value,r=this.props.value,i=this.inputRef.current;i&&!n&&o!==r&&(i.value=c(r))},d.setEditing=function(e){this.setState({editing:e})},d.render=function(){var e=this.props,t=(e.selfClear,e.onInput,e.onChange,e.onEnter,e.value,e.maxLength),n=e.placeholder,c=(e.autofocus,a(e,["selfClear","onInput","onChange","onEnter","value","maxLength","placeholder","autofocus"])),l=c.className,d=c.fluid,u=a(c,["className","fluid"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["Input",d&&"Input--fluid",l])},u,{children:[(0,o.createVNode)(1,"div","Input__baseline",".",16),(0,o.createVNode)(64,"input","Input__input",null,1,{placeholder:n,onInput:this.handleInput,onFocus:this.handleFocus,onBlur:this.handleBlur,onKeyDown:this.handleKeyDown,maxLength:t},null,this.inputRef)]})))},l}(o.Component);t.Input=l},function(e,t,n){"use strict";t.__esModule=!0,t.Knob=void 0;var o=n(1),r=n(20),i=n(12),a=n(24),c=n(16),l=n(170),d=n(123);t.Knob=function(e){if(a.IS_IE8)return(0,o.normalizeProps)((0,o.createComponentVNode)(2,d.NumberInput,Object.assign({},e)));var t=e.animated,n=e.format,u=e.maxValue,s=e.minValue,p=e.onChange,f=e.onDrag,m=e.step,h=e.stepPixelSize,g=e.suppressFlicker,C=e.unit,b=e.value,v=e.className,N=e.style,V=e.fillValue,y=e.color,x=e.ranges,k=void 0===x?{}:x,_=e.size,w=e.bipolar,L=(e.children,e.popUpPosition),B=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["animated","format","maxValue","minValue","onChange","onDrag","step","stepPixelSize","suppressFlicker","unit","value","className","style","fillValue","color","ranges","size","bipolar","children","popUpPosition"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,l.DraggableControl,Object.assign({dragMatrix:[0,-1]},{animated:t,format:n,maxValue:u,minValue:s,onChange:p,onDrag:f,step:m,stepPixelSize:h,suppressFlicker:g,unit:C,value:b},{children:function(e){var t=e.dragging,n=(e.editing,e.value),a=e.displayValue,l=e.displayElement,d=e.inputElement,p=e.handleDragStart,f=(0,r.scale)(null!=V?V:a,s,u),m=(0,r.scale)(a,s,u),h=y||(0,r.keyOfMatchingRange)(null!=V?V:n,k)||"default",g=270*(m-.5);return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,i.classes)(["Knob","Knob--color--"+h,w&&"Knob--bipolar",v,(0,c.computeBoxClassName)(B)]),[(0,o.createVNode)(1,"div","Knob__circle",(0,o.createVNode)(1,"div","Knob__cursorBox",(0,o.createVNode)(1,"div","Knob__cursor"),2,{style:{transform:"rotate("+g+"deg)"}}),2),t&&(0,o.createVNode)(1,"div",(0,i.classes)(["Knob__popupValue",L&&"Knob__popupValue--"+L]),l,0),(0,o.createVNode)(32,"svg","Knob__ring Knob__ringTrackPivot",(0,o.createVNode)(32,"circle","Knob__ringTrack",null,1,{cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),(0,o.createVNode)(32,"svg","Knob__ring Knob__ringFillPivot",(0,o.createVNode)(32,"circle","Knob__ringFill",null,1,{style:{"stroke-dashoffset":((w?2.75:2)-1.5*f)*Math.PI*50},cx:"50",cy:"50",r:"50"}),2,{viewBox:"0 0 100 100"}),d],0,Object.assign({},(0,c.computeBoxProps)(Object.assign({style:Object.assign({"font-size":_+"rem"},N)},B)),{onMouseDown:p})))}})))}},function(e,t,n){"use strict";t.__esModule=!0,t.LabeledControls=void 0;var o=n(1),r=n(168);function i(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var a=function(e){var t=e.children,n=i(e,["children"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Flex,Object.assign({mx:-.5,align:"stretch",justify:"space-between"},n,{children:t})))};t.LabeledControls=a;a.Item=function(e){var t=e.label,n=e.children,a=i(e,["label","children"]);return(0,o.createComponentVNode)(2,r.Flex.Item,{mx:1,children:(0,o.normalizeProps)((0,o.createComponentVNode)(2,r.Flex,Object.assign({minWidth:"52px",height:"100%",direction:"column",align:"center",textAlign:"center",justify:"space-between"},a,{children:[(0,o.createComponentVNode)(2,r.Flex.Item),(0,o.createComponentVNode)(2,r.Flex.Item,{children:n}),(0,o.createComponentVNode)(2,r.Flex.Item,{color:"label",children:t})]})))})}},function(e,t,n){"use strict";t.__esModule=!0,t.NanoMap=void 0;var o=n(1),r=n(3),i=n(2),a=n(124),c=n(171);var l=function(e){return e.stopPropagation&&e.stopPropagation(),e.preventDefault&&e.preventDefault(),e.cancelBubble=!0,e.returnValue=!1,!1},d=function(e){var t,n;function a(t){var n;n=e.call(this,t)||this;window.innerWidth,window.innerHeight;return n.state={offsetX:128,offsetY:48,transform:"none",dragging:!1,originX:null,originY:null,zoom:1},n.handleDragStart=function(e){n.ref=e.target,n.setState({dragging:!1,originX:e.screenX,originY:e.screenY}),document.addEventListener("mousemove",n.handleDragMove),document.addEventListener("mouseup",n.handleDragEnd),l(e)},n.handleDragMove=function(e){n.setState((function(t){var n=Object.assign({},t),o=e.screenX-n.originX,r=e.screenY-n.originY;return t.dragging?(n.offsetX+=o,n.offsetY+=r,n.originX=e.screenX,n.originY=e.screenY):n.dragging=!0,n})),l(e)},n.handleDragEnd=function(e){n.setState({dragging:!1,originX:null,originY:null}),document.removeEventListener("mousemove",n.handleDragMove),document.removeEventListener("mouseup",n.handleDragEnd),l(e)},n.handleZoom=function(e,o){n.setState((function(e){var n=Math.min(Math.max(o,1),8),r=1.5*(n-e.zoom);return e.zoom=n,e.offsetX=e.offsetX-262*r,e.offsetY=e.offsetY-256*r,t.onZoom&&t.onZoom(e.zoom),e}))},n}return n=e,(t=a).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,a.prototype.render=function(){var e=(0,i.useBackend)(this.context).config,t=this.state,n=t.dragging,a=t.offsetX,c=t.offsetY,l=t.zoom,d=void 0===l?1:l,s=this.props.children,p=510*d+"px",f={width:p,height:p,"margin-top":c+"px","margin-left":a+"px",overflow:"hidden",position:"relative","background-image":"url("+e.map+"_nanomap_z1.png)","background-size":"cover","background-repeat":"no-repeat","text-align":"center",cursor:n?"move":"auto"};return(0,o.createComponentVNode)(2,r.Box,{className:"NanoMap__container",children:[(0,o.createComponentVNode)(2,r.Box,{style:f,textAlign:"center",onMouseDown:this.handleDragStart,children:(0,o.createComponentVNode)(2,r.Box,{children:s})}),(0,o.createComponentVNode)(2,u,{zoom:d,onZoom:this.handleZoom})]})},a}(o.Component);t.NanoMap=d;d.Marker=function(e,t){var n=e.x,i=e.y,a=e.zoom,c=void 0===a?1:a,l=e.icon,d=e.tooltip,u=e.color,s=2*n*c-c-3,p=2*i*c-c-3;return(0,o.createVNode)(1,"div",null,(0,o.createComponentVNode)(2,r.Box,{position:"absolute",className:"NanoMap__marker",lineHeight:"0",bottom:p+"px",left:s+"px",children:[(0,o.createComponentVNode)(2,r.Icon,{name:l,color:u,fontSize:"6px"}),(0,o.createComponentVNode)(2,r.Tooltip,{content:d})]}),2)};var u=function(e,t){return(0,o.createComponentVNode)(2,r.Box,{className:"NanoMap__zoomer",children:(0,o.createComponentVNode)(2,a.LabeledList,{children:(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Zoom",children:(0,o.createComponentVNode)(2,c.Slider,{minValue:"1",maxValue:"8",stepPixelSize:"10",format:function(e){return e+"x"},value:e.zoom,onDrag:function(t,n){return e.onZoom(t,n)}})})})})};d.Zoomer=u},function(e,t,n){"use strict";t.__esModule=!0,t.Modal=void 0;var o=n(1),r=n(12),i=n(16),a=n(166);t.Modal=function(e){var t,n=e.className,c=e.children,l=e.onEnter,d=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","children","onEnter"]);return l&&(t=function(e){13===e.keyCode&&l(e)}),(0,o.createComponentVNode)(2,a.Dimmer,{onKeyDown:t,children:(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,r.classes)(["Modal",n,(0,i.computeBoxClassName)(d)]),c,0,Object.assign({},(0,i.computeBoxProps)(d))))})}},function(e,t,n){"use strict";t.__esModule=!0,t.NoticeBox=void 0;var o=n(1),r=n(12),i=n(16);var a=function(e){var t=e.className,n=e.color,a=e.info,c=(e.warning,e.success),l=e.danger,d=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","color","info","warning","success","danger"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["NoticeBox",n&&"NoticeBox--color--"+n,a&&"NoticeBox--type--info",c&&"NoticeBox--type--success",l&&"NoticeBox--type--danger",t])},d)))};t.NoticeBox=a,a.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.ProgressBar=void 0;var o=n(1),r=n(20),i=n(12),a=n(16);var c=function(e){var t=e.className,n=e.value,c=e.minValue,l=void 0===c?0:c,d=e.maxValue,u=void 0===d?1:d,s=e.color,p=e.ranges,f=void 0===p?{}:p,m=e.children,h=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","value","minValue","maxValue","color","ranges","children"]),g=(0,r.scale)(n,l,u),C=m!==undefined,b=s||(0,r.keyOfMatchingRange)(n,f)||"default";return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,i.classes)(["ProgressBar","ProgressBar--color--"+b,t,(0,a.computeBoxClassName)(h)]),[(0,o.createVNode)(1,"div","ProgressBar__fill ProgressBar__fill--animated",null,1,{style:{width:100*(0,r.clamp01)(g)+"%"}}),(0,o.createVNode)(1,"div","ProgressBar__content",C?m:(0,r.toFixed)(100*g)+"%",0)],4,Object.assign({},(0,a.computeBoxProps)(h))))};t.ProgressBar=c,c.defaultHooks=i.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.Section=void 0;var o=n(1),r=n(12),i=n(16);var a=function(e){var t=e.className,n=e.title,a=e.level,c=void 0===a?1:a,l=e.buttons,d=e.content,u=e.stretchContents,s=e.noTopPadding,p=e.children,f=(e.scrollable,function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["className","title","level","buttons","content","stretchContents","noTopPadding","children","scrollable"])),m=!(0,r.isFalsy)(n)||!(0,r.isFalsy)(l),h=!(0,r.isFalsy)(d)||!(0,r.isFalsy)(p);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.Box,Object.assign({className:(0,r.classes)(["Section","Section--level--"+c,e.flexGrow&&"Section--flex",t])},f,{children:[m&&(0,o.createVNode)(1,"div","Section__title",[(0,o.createVNode)(1,"span","Section__titleText",n,0),(0,o.createVNode)(1,"div","Section__buttons",l,0)],4),h&&(0,o.createComponentVNode)(2,i.Box,{className:(0,r.classes)(["Section__content",!!u&&"Section__content--stretchContents",!!s&&"Section__content--noTopPadding"]),children:[d,p]})]})))};t.Section=a,a.defaultHooks=r.pureComponentHooks},function(e,t,n){"use strict";t.__esModule=!0,t.Tabs=void 0;var o=n(1),r=n(12),i=n(16),a=n(121);function c(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var l=function(e){var t=e.className,n=e.vertical,a=e.children,l=c(e,["className","vertical","children"]);return(0,o.normalizeProps)((0,o.createVNode)(1,"div",(0,r.classes)(["Tabs",n?"Tabs--vertical":"Tabs--horizontal",t,(0,i.computeBoxClassName)(l)]),(0,o.createVNode)(1,"div","Tabs__tabBox",a,0),2,Object.assign({},(0,i.computeBoxProps)(l))))};t.Tabs=l;l.Tab=function(e){var t=e.className,n=e.selected,i=e.altSelection,l=c(e,["className","selected","altSelection"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Button,Object.assign({className:(0,r.classes)(["Tabs__tab",n&&"Tabs__tab--selected",i&&n&&"Tabs__tab--altSelection",t]),selected:!i&&n,color:"transparent"},l)))}},function(e,t,n){var o={"./AICard.js":428,"./AIFixer.js":429,"./APC.js":430,"./AiAirlock.js":432,"./AtmosAlertConsole.js":433,"./AtmosFilter.js":434,"./AtmosMixer.js":435,"./AtmosPump.js":436,"./Autolathe.js":437,"./BlueSpaceArtilleryControl.js":438,"./BodyScanner.js":439,"./BrigTimer.js":440,"./Canister.js":441,"./CardComputer.js":442,"./ChemDispenser.js":443,"./ChemHeater.js":447,"./ChemMaster.js":448,"./CloningConsole.js":449,"./CommunicationsComputer.js":450,"./CrewMonitor.js":451,"./Cryo.js":452,"./DNAModifier.js":453,"./DisposalBin.js":454,"./ERTManager.js":455,"./Electropack.js":456,"./FaxMachine.js":457,"./GasFreezer.js":458,"./Instrument.js":459,"./KeycardAuth.js":460,"./MechBayConsole.js":461,"./MedicalRecords.js":462,"./MiningVendor.js":466,"./NuclearBomb.js":467,"./OperatingComputer.js":468,"./PortablePump.js":469,"./PortableTurret.js":470,"./Radio.js":471,"./RoboticsControlConsole.js":472,"./ShuttleConsole.js":473,"./Sleeper.js":474,"./SlotMachine.js":475,"./Smartfridge.js":476,"./Smes.js":477,"./SolarControl.js":478,"./SpawnersMenu.js":479,"./StationAlertConsole.js":480,"./SupermatterMonitor.js":481,"./Tank.js":482,"./Teleporter.js":483,"./TransferValve.js":484,"./Vending.js":485,"./Wires.js":486};function r(e){var t=i(e);return n(t)}function i(e){if(!n.o(o,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return o[e]}r.keys=function(){return Object.keys(o)},r.resolve=i,e.exports=r,r.id=427},function(e,t,n){"use strict";t.__esModule=!0,t.AICard=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.AICard=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data;if(0===l.has_ai)return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{title:"Stored AI",children:(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createVNode)(1,"h3",null,"No AI detected.",16)})})})});var d=null;return d=l.integrity>=75?"green":l.integrity>=25?"yellow":"red",(0,o.createComponentVNode)(2,a.Window,{scrollable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Stored AI",children:[(0,o.createComponentVNode)(2,i.Box,{bold:!0,display:"inline-block",children:(0,o.createVNode)(1,"h3",null,l.name,0)}),(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Integrity",children:(0,o.createComponentVNode)(2,i.ProgressBar,{color:d,value:l.integrity/100})})})}),(0,o.createComponentVNode)(2,i.Box,{color:"red",children:(0,o.createVNode)(1,"h2",null,1===l.flushing?"Wipe of AI in progress...":"",0)})]}),(0,o.createComponentVNode)(2,i.Section,{title:"Laws",children:!!l.has_laws&&(0,o.createComponentVNode)(2,i.Box,{children:l.laws.map((function(e,t){return(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",children:e},t)}))})||(0,o.createComponentVNode)(2,i.Box,{color:"red",children:(0,o.createVNode)(1,"h3",null,"No laws detected.",16)})}),(0,o.createComponentVNode)(2,i.Section,{title:"Actions",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Wireless Activity",children:(0,o.createComponentVNode)(2,i.Button,{icon:l.wireless?"check":"times",content:l.wireless?"Enabled":"Disabled",color:l.wireless?"green":"red",onClick:function(){return c("wireless")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Subspace Transceiver",children:(0,o.createComponentVNode)(2,i.Button,{icon:l.radio?"check":"times",content:l.radio?"Enabled":"Disabled",color:l.radio?"green":"red",onClick:function(){return c("radio")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Wipe",children:(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"trash-alt",confirmIcon:"trash-alt",disabled:l.flushing||0===l.integrity,confirmColor:"red",content:"Wipe AI",onClick:function(){return c("wipe")}})})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.AIFixer=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.AIFixer=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data;if(null===l.occupant)return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{title:"Stored AI",children:(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createVNode)(1,"h3",null,"No artificial intelligence detected.",16)})})})});var d=null;d=2!==l.stat&&null!==l.stat;var u=null;u=l.integrity>=75?"green":l.integrity>=25?"yellow":"red";var s=null;return s=l.integrity>=100,(0,o.createComponentVNode)(2,a.Window,{scrollable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Stored AI",children:(0,o.createComponentVNode)(2,i.Box,{bold:!0,children:(0,o.createVNode)(1,"h3",null,l.occupant,0)})}),(0,o.createComponentVNode)(2,i.Section,{title:"Information",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Integrity",children:(0,o.createComponentVNode)(2,i.ProgressBar,{color:u,value:l.integrity/100})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:d?"green":"red",children:d?"Functional":"Non-Functional"})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Laws",children:!!l.has_laws&&(0,o.createComponentVNode)(2,i.Box,{children:l.laws.map((function(e,t){return(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",children:e},t)}))})||(0,o.createComponentVNode)(2,i.Box,{color:"red",children:(0,o.createVNode)(1,"h3",null,"No laws detected.",16)})}),(0,o.createComponentVNode)(2,i.Section,{title:"Actions",children:[(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Wireless Activity",children:(0,o.createComponentVNode)(2,i.Button,{icon:l.wireless?"times":"check",content:l.wireless?"Disabled":"Enabled",color:l.wireless?"red":"green",onClick:function(){return c("wireless")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Subspace Transceiver",children:(0,o.createComponentVNode)(2,i.Button,{icon:l.radio?"times":"check",content:l.radio?"Disabled":"Enabled",color:l.radio?"red":"green",onClick:function(){return c("radio")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Start Repairs",children:(0,o.createComponentVNode)(2,i.Button,{icon:"wrench",disabled:s||l.active,content:s?"Already Repaired":"Repair",onClick:function(){return c("fix")}})})]}),(0,o.createComponentVNode)(2,i.Box,{color:"green",lineHeight:2,children:l.active?"Reconstruction in progress.":""})]})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.APC=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=n(431);t.APC=function(e,t){return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,u)})})};var l={2:{color:"good",externalPowerText:"External Power",chargingText:"Fully Charged"},1:{color:"average",externalPowerText:"Low External Power",chargingText:"Charging"},0:{color:"bad",externalPowerText:"No External Power",chargingText:"Not Charging"}},d={1:{icon:"terminal",content:"Override Programming",action:"hack"},2:{icon:"caret-square-down",content:"Shunt Core Process",action:"occupy"},3:{icon:"caret-square-left",content:"Return to Main Core",action:"deoccupy"},4:{icon:"caret-square-down",content:"Shunt Core Process",action:"occupy"}},u=function(e,t){var n=(0,r.useBackend)(t),a=n.act,u=n.data,s=u.locked&&!u.siliconUser,p=(u.normallyLocked,l[u.externalPower]||l[0]),f=l[u.chargingStatus]||l[0],m=u.powerChannels||[],h=d[u.malfStatus]||d[0],g=u.powerCellStatus/100;return(0,o.createFragment)([(0,o.createComponentVNode)(2,c.InterfaceLockNoticeBox),(0,o.createComponentVNode)(2,i.Section,{title:"Power Status",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Main Breaker",color:p.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.isOperating?"power-off":"times",content:u.isOperating?"On":"Off",selected:u.isOperating&&!s,color:u.isOperating?"":"bad",disabled:s,onClick:function(){return a("breaker")}}),children:["[ ",p.externalPowerText," ]"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power Cell",children:(0,o.createComponentVNode)(2,i.ProgressBar,{color:"good",value:g})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Charge Mode",color:f.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.chargeMode?"sync":"times",content:u.chargeMode?"Auto":"Off",selected:u.chargeMode,disabled:s,onClick:function(){return a("charge")}}),children:["[ ",f.chargingText," ]"]})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Power Channels",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[m.map((function(e){var t=e.topicParams;return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.title,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{inline:!0,mx:2,color:e.status>=2?"good":"bad",children:e.status>=2?"On":"Off"}),(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Auto",selected:!s&&(1===e.status||3===e.status),disabled:s,onClick:function(){return a("channel",t.auto)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",content:"On",selected:!s&&2===e.status,disabled:s,onClick:function(){return a("channel",t.on)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Off",selected:!s&&0===e.status,disabled:s,onClick:function(){return a("channel",t.off)}})],4),children:[e.powerLoad," W"]},e.title)})),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Total Load",children:(0,o.createVNode)(1,"b",null,[u.totalLoad,(0,o.createTextVNode)(" W")],0)})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Misc",buttons:!!u.siliconUser&&(0,o.createFragment)([!!u.malfStatus&&(0,o.createComponentVNode)(2,i.Button,{icon:h.icon,content:h.content,color:"bad",onClick:function(){return a(h.action)}}),(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",content:"Overload",onClick:function(){return a("overload")}})],0),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cover Lock",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:u.coverLocked?"lock":"unlock",content:u.coverLocked?"Engaged":"Disengaged",selected:u.coverLocked,disabled:s,onClick:function(){return a("cover")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Night Shift Lighting",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",content:u.nightshiftLights?"Enabled":"Disabled",selected:u.nightshiftLights,onClick:function(){return a("toggle_nightshift")}})})]})})],4)}},function(e,t,n){"use strict";t.__esModule=!0,t.InterfaceLockNoticeBox=void 0;var o=n(1),r=n(2),i=n(3);t.InterfaceLockNoticeBox=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=e.siliconUser,d=void 0===l?c.siliconUser:l,u=e.locked,s=void 0===u?c.locked:u,p=e.normallyLocked,f=void 0===p?c.normallyLocked:p,m=e.onLockStatusChange,h=void 0===m?function(){return a("lock")}:m,g=e.accessText,C=void 0===g?"an ID card":g;return d?(0,o.createComponentVNode)(2,i.NoticeBox,{color:d&&"grey",children:(0,o.createComponentVNode)(2,i.Flex,{align:"center",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{children:"Interface lock status:"}),(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1"}),(0,o.createComponentVNode)(2,i.Flex.Item,{children:(0,o.createComponentVNode)(2,i.Button,{m:"0",color:f?"red":"green",icon:f?"lock":"unlock",content:f?"Locked":"Unlocked",onClick:function(){h&&h(!s)}})})]})}):(0,o.createComponentVNode)(2,i.NoticeBox,{children:["Swipe ",C," ","to ",s?"unlock":"lock"," this interface."]})}},function(e,t,n){"use strict";t.__esModule=!0,t.AiAirlock=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c={2:{color:"good",localStatusText:"Offline"},1:{color:"average",localStatusText:"Caution"},0:{color:"bad",localStatusText:"Optimal"}};t.AiAirlock=function(e,t){var n=(0,r.useBackend)(t),l=n.act,d=n.data,u=c[d.power.main]||c[0],s=c[d.power.backup]||c[0],p=c[d.shock]||c[0];return(0,o.createComponentVNode)(2,a.Window,{width:500,height:390,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Power Status",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Main",color:u.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",disabled:!d.power.main,content:"Disrupt",onClick:function(){return l("disrupt-main")}}),children:[d.power.main?"Online":"Offline"," ",d.wires.main_power?d.power.main_timeleft>0&&"["+d.power.main_timeleft+"s]":"[Wires have been cut!]"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Backup",color:s.color,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"lightbulb-o",disabled:!d.power.backup,content:"Disrupt",onClick:function(){return l("disrupt-backup")}}),children:[d.power.backup?"Online":"Offline"," ",d.wires.backup_power?d.power.backup_timeleft>0&&"["+d.power.backup_timeleft+"s]":"[Wires have been cut!]"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Electrify",color:p.color,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"wrench",disabled:!(d.wires.shock&&2!==d.shock),content:"Restore",onClick:function(){return l("shock-restore")}}),(0,o.createComponentVNode)(2,i.Button,{icon:"bolt",disabled:!d.wires.shock,content:"Temporary",onClick:function(){return l("shock-temp")}}),(0,o.createComponentVNode)(2,i.Button,{icon:"bolt",disabled:!d.wires.shock||0===d.shock,content:"Permanent",onClick:function(){return l("shock-perm")}})],4),children:[2===d.shock?"Safe":"Electrified"," ",(d.wires.shock?d.shock_timeleft>0&&"["+d.shock_timeleft+"s]":"[Wires have been cut!]")||-1===d.shock_timeleft&&"[Permanent]"]})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Access and Door Control",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"ID Scan",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.id_scanner?"power-off":"times",content:d.id_scanner?"Enabled":"Disabled",selected:d.id_scanner,disabled:!d.wires.id_scanner,onClick:function(){return l("idscan-toggle")}}),children:!d.wires.id_scanner&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Emergency Access",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.emergency?"power-off":"times",content:d.emergency?"Enabled":"Disabled",selected:d.emergency,onClick:function(){return l("emergency-toggle")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Bolts",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.locked?"lock":"unlock",content:d.locked?"Lowered":"Raised",selected:d.locked,disabled:!d.wires.bolts,onClick:function(){return l("bolt-toggle")}}),children:!d.wires.bolts&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Bolt Lights",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.lights?"power-off":"times",content:d.lights?"Enabled":"Disabled",selected:d.lights,disabled:!d.wires.lights,onClick:function(){return l("light-toggle")}}),children:!d.wires.lights&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Force Sensors",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.safe?"power-off":"times",content:d.safe?"Enabled":"Disabled",selected:d.safe,disabled:!d.wires.safe,onClick:function(){return l("safe-toggle")}}),children:!d.wires.safe&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Timing Safety",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.speed?"power-off":"times",content:d.speed?"Enabled":"Disabled",selected:d.speed,disabled:!d.wires.timing,onClick:function(){return l("speed-toggle")}}),children:!d.wires.timing&&"[Wires have been cut!]"}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Door Control",color:"bad",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d.opened?"sign-out-alt":"sign-in-alt",content:d.opened?"Open":"Closed",selected:d.opened,disabled:d.locked||d.welded,onClick:function(){return l("open-close")}}),children:!(!d.locked&&!d.welded)&&(0,o.createVNode)(1,"span",null,[(0,o.createTextVNode)("[Door is "),d.locked?"bolted":"",d.locked&&d.welded?" and ":"",d.welded?"welded":"",(0,o.createTextVNode)("!]")],0)})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.AtmosAlertConsole=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.AtmosAlertConsole=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.priority||[],u=l.minor||[];return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:(0,o.createComponentVNode)(2,i.Section,{title:"Alarms",children:(0,o.createVNode)(1,"ul",null,[0===d.length&&(0,o.createVNode)(1,"li","color-good","No Priority Alerts",16),d.map((function(e){return(0,o.createVNode)(1,"li",null,(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:e,color:"bad",onClick:function(){return c("clear",{zone:e})}}),2,null,e)})),0===u.length&&(0,o.createVNode)(1,"li","color-good","No Minor Alerts",16),u.map((function(e){return(0,o.createVNode)(1,"li",null,(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:e,color:"average",onClick:function(){return c("clear",{zone:e})}}),2,null,e)}))],0)})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.AtmosFilter=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.AtmosFilter=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.on,u=l.pressure,s=l.max_pressure,p=l.filter_type,f=l.filter_type_list;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",content:d?"On":"Off",color:d?null:"red",selected:d,onClick:function(){return c("power")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Rate",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",textAlign:"center",disabled:0===u,width:2.2,onClick:function(){return c("min_pressure")}}),(0,o.createComponentVNode)(2,i.NumberInput,{animated:!0,unit:"kPa",width:6.1,lineHeight:1.5,step:10,minValue:0,maxValue:s,value:u,onDrag:function(e,t){return c("custom_pressure",{pressure:t})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",textAlign:"center",disabled:u===s,width:2.2,onClick:function(){return c("max_pressure")}})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Filter",children:f.map((function(e){return(0,o.createComponentVNode)(2,i.Button,{selected:e.gas_type===p,content:e.label,onClick:function(){return c("set_filter",{filter:e.gas_type})}},e.label)}))})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.AtmosMixer=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.AtmosMixer=function(e,t){var n=(0,r.useBackend)(t),l=n.act,d=n.data,u=d.on,s=d.pressure,p=d.max_pressure,f=d.node1_concentration,m=d.node2_concentration;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",content:u?"On":"Off",color:u?null:"red",selected:u,onClick:function(){return l("power")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Rate",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",textAlign:"center",disabled:0===s,width:2.2,onClick:function(){return l("min_pressure")}}),(0,o.createComponentVNode)(2,i.NumberInput,{animated:!0,unit:"kPa",width:6.1,lineHeight:1.5,step:10,minValue:0,maxValue:p,value:s,onDrag:function(e,t){return l("custom_pressure",{pressure:t})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",textAlign:"center",disabled:s===p,width:2.2,onClick:function(){return l("max_pressure")}})]}),(0,o.createComponentVNode)(2,c,{node_name:"Node 1",node_ref:f}),(0,o.createComponentVNode)(2,c,{node_name:"Node 2",node_ref:m})]})})})})};var c=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=(n.data,e.node_name),l=e.node_ref;return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:c,children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",textAlign:"center",width:2.2,disabled:0===l,onClick:function(){return a("set_node",{node_name:c,concentration:(l-10)/100})}}),(0,o.createComponentVNode)(2,i.NumberInput,{animated:!0,unit:"%",width:6.1,lineHeight:1.5,stepPixelSize:10,minValue:0,maxValue:100,value:l,onChange:function(e,t){return a("set_node",{node_name:c,concentration:t/100})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",textAlign:"center",width:2.2,disabled:100===l,onClick:function(){return a("set_node",{node_name:c,concentration:(l+10)/100})}})]})}},function(e,t,n){"use strict";t.__esModule=!0,t.AtmosPump=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.AtmosPump=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.on,u=l.rate,s=l.max_rate,p=l.gas_unit,f=l.step;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",content:d?"On":"Off",color:d?null:"red",selected:d,onClick:function(){return c("power")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Rate",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",textAlign:"center",disabled:0===u,width:2.2,onClick:function(){return c("min_rate")}}),(0,o.createComponentVNode)(2,i.NumberInput,{animated:!0,unit:p,width:6.1,lineHeight:1.5,step:f,minValue:0,maxValue:s,value:u,onDrag:function(e,t){return c("custom_rate",{rate:t})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",textAlign:"center",disabled:u===s,width:2.2,onClick:function(){return c("max_rate")}})]})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Autolathe=void 0;var o=n(1),r=n(117),i=n(56),a=n(2),c=n(3),l=n(4),d=n(87),u=function(e,t,n,o){return null===e.requirements||!(e.requirements.metal*o>t)&&!(e.requirements.glass*o>n)};t.Autolathe=function(e,t){var n=(0,a.useBackend)(t),s=n.act,p=n.data,f=p.total_amount,m=(p.max_amount,p.metal_amount),h=p.glass_amount,g=p.busyname,C=(p.busyamt,p.showhacked,p.buildQueue),b=p.buildQueueLen,v=p.recipes,N=p.categories,V=(0,a.useSharedState)(t,"category",0),y=V[0],x=V[1];0===y&&(y="Tools");var k=m.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,"),_=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,"),w=f.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,"),L=(0,a.useSharedState)(t,"search_text",""),B=L[0],S=L[1],I=(0,d.createSearch)(B,(function(e){return e.name})),E="";b>0&&(E=C.map((function(e,t){return(0,o.createComponentVNode)(2,c.Box,{children:(0,o.createComponentVNode)(2,c.Button,{icon:"times",content:C[t][0],onClick:function(){return s("remove_from_queue",{remove_from_queue:C.indexOf(e)+1})}},e)},t)})));var T=(0,r.flow)([(0,i.filter)((function(e){return(e.category.indexOf(y)>-1||B)&&(p.showhacked||!e.hacked)})),B&&(0,i.filter)(I),(0,i.sortBy)((function(e){return e.name.toLowerCase()}))])(v),A="Build";B?A="Results for: '"+B+"':":y&&(A="Build ("+y+")");return(0,o.createComponentVNode)(2,l.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,l.Window.Content,{scrollable:!0,children:[(0,o.createVNode)(1,"div",null,(0,o.createComponentVNode)(2,c.Section,{title:A,buttons:(0,o.createComponentVNode)(2,c.Dropdown,{width:"190px",options:N,selected:y,onSelected:function(e){return x(e)}}),children:[(0,o.createComponentVNode)(2,c.Input,{fluid:!0,placeholder:"Search for...",onInput:function(e,t){return S(t)},mb:1}),T.map((function(e){return(0,o.createComponentVNode)(2,c.Flex,{justify:"space-between",align:"center",children:[(0,o.createComponentVNode)(2,c.Flex.Item,{children:[(0,o.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+e.image,style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px"}}),(0,o.createComponentVNode)(2,c.Button,{icon:"hammer",selected:p.busyname===e.name&&1===p.busyamt,disabled:!u(e,p.metal_amount,p.glass_amount,1),onClick:function(){return s("make",{make:e.uid,multiplier:1})},children:(0,d.toTitleCase)(e.name)}),e.max_multiplier>=10&&(0,o.createComponentVNode)(2,c.Button,{icon:"hammer",selected:p.busyname===e.name&&10===p.busyamt,disabled:!u(e,p.metal_amount,p.glass_amount,10),onClick:function(){return s("make",{make:e.uid,multiplier:10})},children:"10x"}),e.max_multiplier>=25&&(0,o.createComponentVNode)(2,c.Button,{icon:"hammer",selected:p.busyname===e.name&&25===p.busyamt,disabled:!u(e,p.metal_amount,p.glass_amount,25),onClick:function(){return s("make",{make:e.uid,multiplier:25})},children:"25x"}),e.max_multiplier>25&&(0,o.createComponentVNode)(2,c.Button,{icon:"hammer",selected:p.busyname===e.name&&p.busyamt===e.max_multiplier,disabled:!u(e,p.metal_amount,p.glass_amount,e.max_multiplier),onClick:function(){return s("make",{make:e.uid,multiplier:e.max_multiplier})},children:[e.max_multiplier,"x"]})]}),(0,o.createComponentVNode)(2,c.Flex.Item,{children:e.requirements&&Object.keys(e.requirements).map((function(t){return(0,d.toTitleCase)(t)+": "+e.requirements[t]})).join(", ")||(0,o.createComponentVNode)(2,c.Box,{children:"No resources required."})})]},e.ref)}))]}),2,{style:{float:"left",width:"68%"}}),(0,o.createVNode)(1,"div",null,[(0,o.createComponentVNode)(2,c.Section,{title:"Materials",children:(0,o.createComponentVNode)(2,c.LabeledList,{children:[(0,o.createComponentVNode)(2,c.LabeledList.Item,{label:"Metal",children:k}),(0,o.createComponentVNode)(2,c.LabeledList.Item,{label:"Glass",children:_}),(0,o.createComponentVNode)(2,c.LabeledList.Item,{label:"Total",children:w}),(0,o.createComponentVNode)(2,c.LabeledList.Item,{label:"Storage",children:[p.fill_percent,"% Full"]})]})}),(0,o.createComponentVNode)(2,c.Section,{title:"Building",children:(0,o.createComponentVNode)(2,c.Box,{color:g?"green":"",children:g||"Nothing"})}),(0,o.createComponentVNode)(2,c.Section,{title:"Build Queue",children:[E,(0,o.createVNode)(1,"div",null,(0,o.createComponentVNode)(2,c.Button,{icon:"times",content:"Clear All",disabled:!p.buildQueueLen,onClick:function(){return s("clear_queue")}}),2,{align:"right"})]})],4,{style:{float:"right",width:"30%"}})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.BlueSpaceArtilleryControl=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.BlueSpaceArtilleryControl=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,d=c.data;return n=d.ready?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:"green",children:"Ready"}):d.reloadtime_text?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Reloading In",color:"red",children:d.reloadtime_text}):(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:"red",children:"No cannon connected!"}),(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[d.notice&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Alert",color:"red",children:d.notice}),n,(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target",children:(0,o.createComponentVNode)(2,i.Button,{icon:"crosshairs",content:d.target?d.target:"None",onClick:function(){return l("recalibrate")}})}),1===d.ready&&!!d.target&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Firing",children:(0,o.createComponentVNode)(2,i.Button,{icon:"skull",content:"FIRE!",color:"red",onClick:function(){return l("fire")}})}),!d.connected&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Maintenance",children:(0,o.createComponentVNode)(2,i.Button,{icon:"wrench",content:"Complete Deployment",onClick:function(){return l("build")}})})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.BodyScanner=void 0;var o=n(1),r=n(20),i=n(2),a=n(3),c=n(4),l=[["good","Alive"],["average","Critical"],["bad","DEAD"]],d=[["hasBorer","bad","Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended."],["hasVirus","bad","Viral pathogen detected in blood stream."],["blind","average","Cataracts detected."],["colourblind","average","Photoreceptor abnormalities detected."],["nearsighted","average","Retinal misalignment detected."]],u=[["Respiratory","oxyLoss"],["Brain","brainLoss"],["Toxin","toxLoss"],["Radioactive","radLoss"],["Brute","bruteLoss"],["Genetic","cloneLoss"],["Burn","fireLoss"],["Paralysis","paralysis"]],s={average:[.25,.5],bad:[.5,Infinity]},p=function(e,t){for(var n=[],o=0;o0?e.filter((function(e){return!!e&&e.length>0})).reduce((function(e,t){return null===e?[t]:(0,o.createFragment)([e,(0,o.createVNode)(1,"br"),t],0,t)}),null):null},m=function(e){if(e>100){if(e<300)return"mild infection";if(e<400)return"mild infection+";if(e<500)return"mild infection++";if(e<700)return"acute infection";if(e<800)return"acute infection+";if(e<900)return"acute infection++";if(e>=900)return"septic"}return""};t.BodyScanner=function(e,t){var n=(0,i.useBackend)(t).data,r=n.occupied,a=n.occupant,l=void 0===a?{}:a,d=r?(0,o.createComponentVNode)(2,h,{occupant:l}):(0,o.createComponentVNode)(2,y);return(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:d})})};var h=function(e){var t=e.occupant;return(0,o.createComponentVNode)(2,a.Box,{children:[(0,o.createComponentVNode)(2,g,{occupant:t}),(0,o.createComponentVNode)(2,C,{occupant:t}),(0,o.createComponentVNode)(2,b,{occupant:t}),(0,o.createComponentVNode)(2,N,{organs:t.extOrgan}),(0,o.createComponentVNode)(2,V,{organs:t.intOrgan})]})},g=function(e,t){var n=(0,i.useBackend)(t),c=n.act,d=n.data.occupant;return(0,o.createComponentVNode)(2,a.Section,{title:"Occupant",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{icon:"print",onClick:function(){return c("print_p")},children:"Print Report"}),(0,o.createComponentVNode)(2,a.Button,{icon:"user-slash",onClick:function(){return c("ejectify")},children:"Eject"})],4),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Name",children:d.name}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:d.maxHealth,value:d.health/d.maxHealth,ranges:{good:[.5,Infinity],average:[0,.5],bad:[-Infinity,0]}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",color:l[d.stat][0],children:l[d.stat][1]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Temperature",children:[(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:(0,r.round)(d.bodyTempC,0)}),"\xb0C,\xa0",(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:(0,r.round)(d.bodyTempF,0)}),"\xb0F"]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Implants",children:d.implant_len?(0,o.createComponentVNode)(2,a.Box,{children:d.implant.map((function(e){return e.name})).join(", ")}):(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"None"})})]})})},C=function(e){var t=e.occupant;return t.hasBorer||t.blind||t.colourblind||t.nearsighted||t.hasVirus?(0,o.createComponentVNode)(2,a.Section,{title:"Abnormalities",children:d.map((function(e,n){if(t[e[0]])return(0,o.createComponentVNode)(2,a.Box,{color:e[1],bold:"bad"===e[1],children:e[2]})}))}):(0,o.createComponentVNode)(2,a.Section,{title:"Abnormalities",children:(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"No abnormalities found."})})},b=function(e){var t=e.occupant;return(0,o.createComponentVNode)(2,a.Section,{title:"Damage",children:(0,o.createComponentVNode)(2,a.Table,{children:p(u,(function(e,n,r){return(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Table.Row,{color:"label",children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:[e[0],":"]}),(0,o.createComponentVNode)(2,a.Table.Cell,{children:!!n&&n[0]+":"})]}),(0,o.createComponentVNode)(2,a.Table.Row,{children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:(0,o.createComponentVNode)(2,v,{value:t[e[1]],marginBottom:r0&&"0.5rem",value:e.totalLoss/100,ranges:s,children:[(0,o.createComponentVNode)(2,a.Box,{float:"left",display:"inline",children:[!!e.bruteLoss&&(0,o.createComponentVNode)(2,a.Box,{display:"inline",position:"relative",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"bone"}),(0,r.round)(e.bruteLoss,0),"\xa0",(0,o.createComponentVNode)(2,a.Tooltip,{position:"top",content:"Brute damage"})]}),!!e.fireLoss&&(0,o.createComponentVNode)(2,a.Box,{display:"inline",position:"relative",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"fire"}),(0,r.round)(e.fireLoss,0),(0,o.createComponentVNode)(2,a.Tooltip,{position:"top",content:"Burn damage"})]})]}),(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:(0,r.round)(e.totalLoss,0)})]})}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"right",width:"33%",children:[(0,o.createComponentVNode)(2,a.Box,{color:"average",display:"inline",children:f([e.internalBleeding&&"Internal bleeding",e.lungRuptured&&"Ruptured lung",!!e.status.broken&&e.status.broken,m(e.germ_level),!!e.open&&"Open incision"])}),(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:[f([!!e.status.splinted&&"Splinted",!!e.status.robotic&&"Robotic",!!e.status.dead&&(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"DEAD"})]),f(e.shrapnel.map((function(e){return e.known?e.name:"Unknown object"})))]})]})]},t)}))]})})},V=function(e){return 0===e.organs.length?(0,o.createComponentVNode)(2,a.Section,{title:"Internal Organs",children:(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"N/A"})}):(0,o.createComponentVNode)(2,a.Section,{title:"Internal Organs",children:(0,o.createComponentVNode)(2,a.Table,{children:[(0,o.createComponentVNode)(2,a.Table.Row,{header:!0,children:[(0,o.createComponentVNode)(2,a.Table.Cell,{children:"Name"}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"center",children:"Damage"}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"right",children:"Injuries"})]}),e.organs.map((function(e,t){return(0,o.createComponentVNode)(2,a.Table.Row,{textTransform:"capitalize",children:[(0,o.createComponentVNode)(2,a.Table.Cell,{width:"33%",children:e.name}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"center",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:e.maxHealth,value:e.damage/100,mt:t>0&&"0.5rem",ranges:s,children:(0,r.round)(e.damage,0)})}),(0,o.createComponentVNode)(2,a.Table.Cell,{textAlign:"right",width:"33%",children:[(0,o.createComponentVNode)(2,a.Box,{color:"average",display:"inline",children:f([m(e.germ_level)])}),(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:f([1===e.robotic&&"Robotic",2===e.robotic&&"Assisted",!!e.dead&&(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"DEAD"})])})]})]},t)}))]})})},y=function(){return(0,o.createComponentVNode)(2,a.Section,{textAlign:"center",flexGrow:"1",children:(0,o.createComponentVNode)(2,a.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",align:"center",color:"label",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant detected."]})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.BrigTimer=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.BrigTimer=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data;l.nameText=l.occupant,l.timing&&(l.prisoner_hasrec?l.nameText=(0,o.createComponentVNode)(2,i.Box,{color:"green",children:l.occupant}):l.nameText=(0,o.createComponentVNode)(2,i.Box,{color:"red",children:l.occupant}));var d="pencil-alt";l.prisoner_name&&(l.prisoner_hasrec||(d="exclamation-triangle"));var u=[],s=0;for(s=0;se.current_positions&&(0,o.createComponentVNode)(2,i.Box,{color:"green",children:e.total_positions-e.current_positions})||(0,o.createComponentVNode)(2,i.Box,{color:"red",children:"0"})}),(0,o.createComponentVNode)(2,i.Table.Cell,{textAlign:"center",children:(0,o.createComponentVNode)(2,i.Button,{content:"-",disabled:u.cooldown_time||!e.can_close,onClick:function(){return d("make_job_unavailable",{job:e.title})}})}),(0,o.createComponentVNode)(2,i.Table.Cell,{textAlign:"center",children:(0,o.createComponentVNode)(2,i.Button,{content:"+",disabled:u.cooldown_time||!e.can_open,onClick:function(){return d("make_job_available",{job:e.title})}})}),(0,o.createComponentVNode)(2,i.Table.Cell,{textAlign:"center",children:u.target_dept&&(0,o.createComponentVNode)(2,i.Box,{color:"green",children:u.priority_jobs.indexOf(e.title)>-1?"Yes":""})||(0,o.createComponentVNode)(2,i.Button,{content:"Priority",selected:u.priority_jobs.indexOf(e.title)>-1,disabled:u.cooldown_time||!e.can_prioritize,onClick:function(){return d("prioritize_job",{job:e.title})}})})]},e.title)}))]})})],4):(0,o.createComponentVNode)(2,i.Section,{title:"Warning",color:"red",children:"Not logged in."});break;case 2:n=u.authenticated&&u.scan_name?u.modify_name?(0,o.createComponentVNode)(2,c.AccessList,{accesses:u.regions,selectedList:u.selectedAccess,accessMod:function(e){return d("set",{access:e})},grantAll:function(){return d("grant_all")},denyAll:function(){return d("clear_all")},grantDep:function(e){return d("grant_region",{region:e})},denyDep:function(e){return d("deny_region",{region:e})}}):(0,o.createComponentVNode)(2,i.Section,{title:"Card Missing",color:"red",children:"No card to modify."}):(0,o.createComponentVNode)(2,i.Section,{title:"Warning",color:"red",children:"Not logged in."});break;case 3:n=u.authenticated?u.records.length?(0,o.createComponentVNode)(2,i.Section,{title:"Records",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Delete All Records",disabled:!u.authenticated||0===u.records.length||u.target_dept,onClick:function(){return d("wipe_all_logs")}}),children:[(0,o.createComponentVNode)(2,i.Table,{children:[(0,o.createComponentVNode)(2,i.Table.Row,{children:[(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Crewman"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Old Rank"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"New Rank"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Authorized By"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Time"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Reason"}),!!u.iscentcom&&(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Deleted By"})]}),u.records.map((function(e){return(0,o.createComponentVNode)(2,i.Table.Row,{children:[(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.transferee}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.oldvalue}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.newvalue}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.whodidit}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.timestamp}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.reason}),!!u.iscentcom&&(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.deletedby})]},e.timestamp)}))]}),!!u.iscentcom&&(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createComponentVNode)(2,i.Button,{icon:"pencil-alt",content:"Delete MY Records",color:"purple",disabled:!u.authenticated||0===u.records.length,onClick:function(){return d("wipe_my_logs")}})})]}):(0,o.createComponentVNode)(2,i.Section,{title:"Records",children:"No records."}):(0,o.createComponentVNode)(2,i.Section,{title:"Warning",color:"red",children:"Not logged in."});break;case 4:n=u.authenticated&&u.scan_name?(0,o.createComponentVNode)(2,i.Section,{title:"Your Team",children:(0,o.createComponentVNode)(2,i.Table,{children:[(0,o.createComponentVNode)(2,i.Table.Row,{children:[(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Name"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Rank"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Sec Status"}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:"Actions"})]}),u.people_dept.map((function(e){return(0,o.createComponentVNode)(2,i.Table.Row,{children:[(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.name}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.title}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:e.crimstat}),(0,o.createComponentVNode)(2,i.Table.Cell,{children:(0,o.createComponentVNode)(2,i.Button,{content:e.buttontext,disabled:!e.demotable,onClick:function(){return d("remote_demote",{remote_demote:e.name})}})})]},e.title)}))]})}):(0,o.createComponentVNode)(2,i.Section,{title:"Warning",color:"red",children:"Not logged in."});break;default:n=(0,o.createComponentVNode)(2,i.Section,{title:"Warning",color:"red",children:"ERROR: Unknown Mode."})}return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:[s,p,n]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.ChemDispenser=void 0;var o=n(1),r=n(2),i=n(3),a=n(125),c=n(4),l=[1,5,10,20,30,50],d=[1,5,10];t.ChemDispenser=function(e,t){return(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,u),(0,o.createComponentVNode)(2,s),(0,o.createComponentVNode)(2,p)]})})};var u=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,d=c.amount,u=c.energy,s=c.maxEnergy;return(0,o.createComponentVNode)(2,i.Section,{title:"Settings",flex:"content",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Energy",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:u,minValue:0,maxValue:s,ranges:{good:[.5*s,Infinity],average:[.25*s,.5*s],bad:[-Infinity,.25*s]},children:[u," / ",s," Units"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Dispense",verticalAlign:"middle",children:(0,o.createComponentVNode)(2,i.Flex,{direction:"row",spacing:"1",children:l.map((function(e,t){return(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",width:"14%",display:"inline-block",children:(0,o.createComponentVNode)(2,i.Button,{icon:"cog",selected:d===e,content:e,m:"0",width:"100%",onClick:function(){return a("amount",{amount:e})}})},t)}))})})]})})},s=function(e,t){for(var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.chemicals,d=void 0===l?[]:l,u=[],s=0;s<(d.length+1)%3;s++)u.push(!0);return(0,o.createComponentVNode)(2,i.Section,{title:c.glass?"Drink Dispenser":"Chemical Dispenser",flexGrow:"1",children:(0,o.createComponentVNode)(2,i.Flex,{direction:"row",wrap:"wrap",height:"100%",spacingPrecise:"2",align:"flex-start",alignContent:"flex-start",children:[d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",basis:"25%",height:"20px",width:"30%",display:"inline-block",children:(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",overflow:"hidden",textOverflow:"ellipsis",width:"100%",height:"100%",align:"flex-start",content:e.title,onClick:function(){return a("dispense",{reagent:e.id})}})},t)})),u.map((function(e,t){return(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",basis:"25%",height:"20px"},t)}))]})})},p=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,u=l.isBeakerLoaded,s=l.beakerCurrentVolume,p=l.beakerMaxVolume,f=l.beakerContents,m=void 0===f?[]:f;return(0,o.createComponentVNode)(2,i.Section,{title:l.glass?"Glass":"Beaker",flex:"content",minHeight:"25%",buttons:(0,o.createComponentVNode)(2,i.Box,{children:[!!u&&(0,o.createComponentVNode)(2,i.Box,{inline:!0,color:"label",mr:2,children:[s," / ",p," units"]}),(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:"Eject",disabled:!u,onClick:function(){return c("ejectBeaker")}})]}),children:(0,o.createComponentVNode)(2,a.BeakerContents,{beakerLoaded:u,beakerContents:m,buttons:function(e){return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{content:"Isolate",icon:"compress-arrows-alt",onClick:function(){return c("remove",{reagent:e.id,amount:-1})}}),d.map((function(t,n){return(0,o.createComponentVNode)(2,i.Button,{content:t,onClick:function(){return c("remove",{reagent:e.id,amount:t})}},n)})),(0,o.createComponentVNode)(2,i.Button,{content:"ALL",onClick:function(){return c("remove",{reagent:e.id,amount:e.volume})}})],0)}})})}},function(e,t,n){"use strict";e.exports=n(445)()},function(e,t,n){"use strict";var o=n(446);function r(){}function i(){}i.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,i,a){if(a!==o){var c=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw c.name="Invariant Violation",c}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:r};return n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,n){"use strict";t.__esModule=!0,t.ChemHeater=void 0;var o=n(1),r=n(20),i=n(2),a=n(3),c=n(125),l=n(4);t.ChemHeater=function(e,t){return(0,o.createComponentVNode)(2,l.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,l.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,d),(0,o.createComponentVNode)(2,u)]})})};var d=function(e,t){var n=(0,i.useBackend)(t),c=n.act,l=n.data,d=l.targetTemp,u=l.targetTempReached,s=l.autoEject,p=l.isActive,f=l.currentTemp,m=l.isBeakerLoaded;return(0,o.createComponentVNode)(2,a.Section,{title:"Settings",flexBasis:"content",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{content:"Auto-eject",icon:s?"toggle-on":"toggle-off",selected:s,onClick:function(){return c("toggle_autoeject")}}),(0,o.createComponentVNode)(2,a.Button,{content:p?"On":"Off",icon:"power-off",selected:p,disabled:!m,onClick:function(){return c("toggle_on")}})],4),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Target",children:(0,o.createComponentVNode)(2,a.NumberInput,{width:"65px",unit:"K",step:10,stepPixelSize:3,value:(0,r.round)(d,0),minValue:0,maxValue:1e3,onDrag:function(e,t){return c("adjust_temperature",{target:t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Reading",color:u?"good":"average",children:m&&(0,o.createComponentVNode)(2,a.AnimatedNumber,{value:f,format:function(e){return(0,r.toFixed)(e)+" K"}})||"\u2014"})]})})},u=function(e,t){var n=(0,i.useBackend)(t),r=n.act,l=n.data,d=l.isBeakerLoaded,u=l.beakerCurrentVolume,s=l.beakerMaxVolume,p=l.beakerContents;return(0,o.createComponentVNode)(2,a.Section,{title:"Beaker",flexGrow:"1",buttons:!!d&&(0,o.createComponentVNode)(2,a.Box,{children:[(0,o.createComponentVNode)(2,a.Box,{inline:!0,color:"label",mr:2,children:[u," / ",s," units"]}),(0,o.createComponentVNode)(2,a.Button,{icon:"eject",content:"Eject",onClick:function(){return r("eject_beaker")}})]}),children:(0,o.createComponentVNode)(2,c.BeakerContents,{beakerLoaded:d,beakerContents:p})})}},function(e,t,n){"use strict";t.__esModule=!0,t.ChemMaster=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=n(125),l=n(88),d=[1,5,10],u=["bottle.png","small_bottle.png","wide_bottle.png","round_bottle.png","reagent_bottle.png"];t.ChemMaster=function(e,t){var n=(0,r.useBackend)(t).data,i=n.condi,c=n.beaker,d=n.beaker_reagents,u=void 0===d?[]:d,m=n.buffer_reagents,h=void 0===m?[]:m,C=n.mode;return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,l.ComplexModal),(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,s,{beaker:c,beakerReagents:u,bufferNonEmpty:h.length>0}),(0,o.createComponentVNode)(2,p,{mode:C,bufferReagents:h}),(0,o.createComponentVNode)(2,f,{isCondiment:i,bufferNonEmpty:h.length>0}),(0,o.createComponentVNode)(2,g)]})]})};var s=function(e,t){var n=(0,r.useBackend)(t).act,a=e.beaker,u=e.beakerReagents,s=e.bufferNonEmpty;return(0,o.createComponentVNode)(2,i.Section,{title:"Beaker",flexGrow:"0",flexBasis:"300px",buttons:s?(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"eject",disabled:!a,content:"Eject and Clear Buffer",onClick:function(){return n("eject")}}):(0,o.createComponentVNode)(2,i.Button,{icon:"eject",disabled:!a,content:"Eject and Clear Buffer",onClick:function(){return n("eject")}}),children:a?(0,o.createComponentVNode)(2,c.BeakerContents,{beakerLoaded:!0,beakerContents:u,buttons:function(e,r){return(0,o.createComponentVNode)(2,i.Box,{mb:r0?(0,o.createComponentVNode)(2,c.BeakerContents,{beakerLoaded:!0,beakerContents:s,buttons:function(e,r){return(0,o.createComponentVNode)(2,i.Box,{mb:r0?l.desc:"N/A"}),l.blood_type&&(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Blood type",children:l.blood_type}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Blood DNA",className:"LabeledList__breakContents",children:l.blood_dna})],4),!c.condi&&(0,o.createComponentVNode)(2,i.Button,{icon:c.printing?"spinner":"print",disabled:c.printing,iconSpin:!!c.printing,ml:"0.5rem",content:"Print",onClick:function(){return a("print",{idx:l.idx,beaker:e.args.beaker})}})]})})})}))},function(e,t,n){"use strict";t.__esModule=!0,t.CloningConsole=void 0;var o=n(1),r=n(20),i=n(2),a=n(3),c=n(55),l=n(88),d=n(4),u=function(e,t){var n=(0,i.useBackend)(t),r=n.act,l=n.data,d=e.args,u=d.activerecord,s=d.realname,p=d.health,f=d.unidentity,m=d.strucenzymes,h=p.split(" - ");return(0,o.createComponentVNode)(2,a.Section,{level:2,m:"-1rem",pb:"1rem",title:"Records of "+s,children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Name",children:s}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Damage",children:h.length>1?(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.oxy,display:"inline",children:h[0]}),(0,o.createTextVNode)("\xa0|\xa0"),(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.toxin,display:"inline",children:h[2]}),(0,o.createTextVNode)("\xa0|\xa0"),(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.brute,display:"inline",children:h[3]}),(0,o.createTextVNode)("\xa0|\xa0"),(0,o.createComponentVNode)(2,a.Box,{color:c.COLORS.damageType.burn,display:"inline",children:h[1]})],4):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"Unknown"})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"UI",className:"LabeledList__breakContents",children:f}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"SE",className:"LabeledList__breakContents",children:m}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Disk",children:[(0,o.createComponentVNode)(2,a.Button.Confirm,{disabled:!l.disk,icon:"arrow-circle-down",content:"Import",onClick:function(){return r("disk",{option:"load"})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l.disk,icon:"arrow-circle-up",content:"Export UI",onClick:function(){return r("disk",{option:"save",savetype:"ui"})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l.disk,icon:"arrow-circle-up",content:"Export UI and UE",onClick:function(){return r("disk",{option:"save",savetype:"ue"})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l.disk,icon:"arrow-circle-up",content:"Export SE",onClick:function(){return r("disk",{option:"save",savetype:"se"})}})]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Actions",children:[(0,o.createComponentVNode)(2,a.Button,{disabled:!l.podready,icon:"user-plus",content:"Clone",onClick:function(){return r("clone",{ref:u})}}),(0,o.createComponentVNode)(2,a.Button,{icon:"trash",content:"Delete",onClick:function(){return r("del_rec")}})]})]})})};t.CloningConsole=function(e,t){var n=(0,i.useBackend)(t);n.act,n.data.menu;return(0,l.modalRegisterBodyOverride)("view_rec",u),(0,o.createComponentVNode)(2,d.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,l.ComplexModal,{maxWidth:"75%",maxHeight:"75%"}),(0,o.createComponentVNode)(2,d.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,h),(0,o.createComponentVNode)(2,g),(0,o.createComponentVNode)(2,s),(0,o.createComponentVNode)(2,a.Section,{noTopPadding:!0,flexGrow:"1",children:(0,o.createComponentVNode)(2,p)})]})]})};var s=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data.menu;return(0,o.createComponentVNode)(2,a.Tabs,{children:[(0,o.createComponentVNode)(2,a.Tabs.Tab,{selected:1===c,icon:"home",onClick:function(){return r("menu",{num:1})},children:"Main"}),(0,o.createComponentVNode)(2,a.Tabs.Tab,{selected:2===c,icon:"folder",onClick:function(){return r("menu",{num:2})},children:"Records"})]})},p=function(e,t){var n,r=(0,i.useBackend)(t).data.menu;return 1===r?n=(0,o.createComponentVNode)(2,f):2===r&&(n=(0,o.createComponentVNode)(2,m)),n},f=function(e,t){var n=(0,i.useBackend)(t),c=n.act,l=n.data,d=l.loading,u=l.scantemp,s=l.occupant,p=l.locked,f=l.can_brainscan,m=l.scan_mode,h=l.numberofpods,g=l.pods,C=l.selected_pod,b=p&&!!s;return(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Section,{title:"Scanner",level:"2",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{display:"inline",color:"label",children:"Scanner Lock:\xa0"}),(0,o.createComponentVNode)(2,a.Button,{disabled:!s,selected:b,icon:b?"toggle-on":"toggle-off",content:b?"Engaged":"Disengaged",onClick:function(){return c("lock")}}),(0,o.createComponentVNode)(2,a.Button,{disabled:b||!s,icon:"user-slash",content:"Eject Occupant",onClick:function(){return c("eject")}})],4),children:[(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",children:d?(0,o.createComponentVNode)(2,a.Box,{color:"average",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"spinner",spin:!0}),"\xa0 Scanning..."]}):(0,o.createComponentVNode)(2,a.Box,{color:u.color,children:u.text})}),!!f&&(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Scan Mode",children:(0,o.createComponentVNode)(2,a.Button,{icon:m?"brain":"male",content:m?"Brain":"Body",onClick:function(){return c("toggle_mode")}})})]}),(0,o.createComponentVNode)(2,a.Button,{disabled:!s||d,icon:"user",content:"Scan Occupant",mt:"0.5rem",mb:"0",onClick:function(){return c("scan")}})]}),(0,o.createComponentVNode)(2,a.Section,{title:"Pods",level:"2",children:h?g.map((function(e,t){var n;return n="cloning"===e.status?(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:"100",value:e.progress/100,ranges:{good:[.75,Infinity],average:[.25,.75],bad:[-Infinity,.25]},mt:"0.5rem",children:(0,o.createComponentVNode)(2,a.Box,{textAlign:"center",children:(0,r.round)(e.progress,0)+"%"})}):"mess"===e.status?(0,o.createComponentVNode)(2,a.Box,{bold:!0,color:"bad",mt:"0.5rem",children:"ERROR"}):(0,o.createComponentVNode)(2,a.Button,{selected:C===e.pod,icon:C===e.pod&&"check",content:"Select",mt:"0.5rem",onClick:function(){return c("selectpod",{ref:e.pod})}}),(0,o.createComponentVNode)(2,a.Box,{width:"64px",textAlign:"center",display:"inline-block",mr:"0.5rem",children:[(0,o.createVNode)(1,"img",null,null,1,{src:"pod_"+e.status+".gif",style:{width:"100%","-ms-interpolation-mode":"nearest-neighbor"}}),(0,o.createComponentVNode)(2,a.Box,{color:"label",children:["Pod #",t+1]}),(0,o.createComponentVNode)(2,a.Box,{bold:!0,color:e.biomass>=150?"good":"bad",display:"inline",children:[(0,o.createComponentVNode)(2,a.Icon,{name:e.biomass>=150?"circle":"circle-o"}),"\xa0",e.biomass]}),n]},t)})):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"No pods detected. Unable to clone."})})],4)},m=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data.records;return c.length?(0,o.createComponentVNode)(2,a.Box,{mt:"0.5rem",children:c.map((function(e,t){return(0,o.createComponentVNode)(2,a.Button,{icon:"user",mb:"0.5rem",content:e.realname,onClick:function(){return r("view_rec",{ref:e.record})}},t)}))}):(0,o.createComponentVNode)(2,a.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",align:"center",textAlign:"center",color:"label",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No records found."]})})},h=function(e,t){var n,r=(0,i.useBackend)(t),c=r.act,l=r.data.temp;if(l&&l.text&&!(l.text.length<=0)){var d=((n={})[l.style]=!0,n);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.NoticeBox,Object.assign({},d,{children:[(0,o.createComponentVNode)(2,a.Box,{display:"inline-block",verticalAlign:"middle",children:l.text}),(0,o.createComponentVNode)(2,a.Button,{icon:"times-circle",float:"right",onClick:function(){return c("cleartemp")}}),(0,o.createComponentVNode)(2,a.Box,{clear:"both"})]})))}},g=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.scanner,d=c.numberofpods,u=c.autoallowed,s=c.autoprocess,p=c.disk;return(0,o.createComponentVNode)(2,a.Section,{title:"Status",buttons:(0,o.createFragment)([!!u&&(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{display:"inline",color:"label",children:"Auto-processing:\xa0"}),(0,o.createComponentVNode)(2,a.Button,{selected:s,icon:s?"toggle-on":"toggle-off",content:s?"Enabled":"Disabled",onClick:function(){return r("autoprocess",{on:s?0:1})}})],4),(0,o.createComponentVNode)(2,a.Button,{disabled:!p,icon:"eject",content:"Eject Disk",onClick:function(){return r("disk",{option:"eject"})}})],0),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Scanner",children:l?(0,o.createComponentVNode)(2,a.Box,{color:"good",children:"Connected"}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"Not connected!"})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Pods",children:d?(0,o.createComponentVNode)(2,a.Box,{color:"good",children:[d," connected"]}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"None connected!"})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.CommunicationsComputer=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.CommunicationsComputer=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,d=c.data;n=d.authenticated?d.is_ai?"AI":1===d.authenticated?"Command":2===d.authenticated?"Captain":"ERROR: Report This Bug!":"Not Logged In";var u="View ("+d.messages.length+")",s=(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"Authentication",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:d.is_ai&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Access Level",children:"AI"})||(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Actions",children:(0,o.createComponentVNode)(2,i.Button,{icon:d.authenticated?"sign-out-alt":"id-card",selected:d.authenticated,content:d.authenticated?"Log Out ("+n+")":"Log In",onClick:function(){return l("auth")}})})})}),!!d.esc_section&&(0,o.createComponentVNode)(2,i.Section,{title:"Escape Shuttle",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[!!d.esc_status&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",children:d.esc_status}),!!d.esc_callable&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Options",children:(0,o.createComponentVNode)(2,i.Button,{icon:"rocket",content:"Call Shuttle",disabled:!d.authenticated,onClick:function(){return l("callshuttle")}})}),!!d.esc_recallable&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Options",children:(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Recall Shuttle",disabled:!d.authenticated||d.is_ai,onClick:function(){return l("cancelshuttle")}})}),!!d.lastCallLoc&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Last Call/Recall From",children:d.lastCallLoc})]})})],0),p="Make Priority Announcement";d.msg_cooldown>0&&(p+=" ("+d.msg_cooldown+"s)");var f=d.emagged?"Message [UNKNOWN]":"Message CentComm",m="Request Authentication Codes";d.cc_cooldown>0&&(f+=" ("+d.cc_cooldown+"s)",m+=" ("+d.cc_cooldown+"s)");var h,g=d.str_security_level,C=d.levels.map((function(e){return(0,o.createComponentVNode)(2,i.Button,{icon:e.icon,content:e.name,disabled:!d.authmax||e.id===d.security_level,onClick:function(){return l("newalertlevel",{level:e.id})}},e.name)})),b=d.stat_display.presets.map((function(e){return(0,o.createComponentVNode)(2,i.Button,{content:e.label,selected:e.name===d.stat_display.type,disabled:!d.authenticated,onClick:function(){return l("setstat",{statdisp:e.name})}},e.name)})),v=d.stat_display.alerts.map((function(e){return(0,o.createComponentVNode)(2,i.Button,{content:e.label,selected:e.alert===d.stat_display.icon,disabled:!d.authenticated,onClick:function(){return l("setstat",{statdisp:"alert",alert:e.alert})}},e.alert)}));if(d.current_message_title)h=(0,o.createComponentVNode)(2,i.Section,{title:d.current_message_title,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Return To Message List",disabled:!d.authenticated,onClick:function(){return l("messagelist")}}),children:(0,o.createComponentVNode)(2,i.Box,{children:d.current_message})});else{var N=d.messages.map((function(e){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.title,children:[(0,o.createComponentVNode)(2,i.Button,{icon:"eye",content:"View",disabled:!d.authenticated||d.current_message_title===e.title,onClick:function(){return l("messagelist",{msgid:e.id})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Delete",disabled:!d.authenticated,onClick:function(){return l("delmessage",{msgid:e.id})}})]},e.id)}));h=(0,o.createComponentVNode)(2,i.Section,{title:"Messages Received",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){return l("main")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:N})})}switch(d.menu_state){case 1:return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:[s,(0,o.createComponentVNode)(2,i.Section,{title:"Captain-Only Actions",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Current Alert",color:d.security_level_color,children:g}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Change Alert",children:C}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Announcement",children:(0,o.createComponentVNode)(2,i.Button,{icon:"bullhorn",content:p,disabled:!d.authmax||d.msg_cooldown>0,onClick:function(){return l("announce")}})}),!!d.emagged&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Transmit",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"broadcast-tower",color:"red",content:f,disabled:!d.authmax||d.cc_cooldown>0,onClick:function(){return l("MessageSyndicate")}}),(0,o.createComponentVNode)(2,i.Button,{icon:"sync-alt",content:"Reset Relays",disabled:!d.authmax,onClick:function(){return l("RestoreBackup")}})]})||(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Transmit",children:(0,o.createComponentVNode)(2,i.Button,{icon:"broadcast-tower",content:f,disabled:!d.authmax||d.cc_cooldown>0,onClick:function(){return l("MessageCentcomm")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Nuclear Device",children:(0,o.createComponentVNode)(2,i.Button,{icon:"bomb",content:m,disabled:!d.authmax||d.cc_cooldown>0,onClick:function(){return l("nukerequest")}})})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Command Staff Actions",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Displays",children:(0,o.createComponentVNode)(2,i.Button,{icon:"tv",content:"Change Status Displays",disabled:!d.authenticated,onClick:function(){return l("status")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Incoming Messages",children:(0,o.createComponentVNode)(2,i.Button,{icon:"folder-open",content:u,disabled:!d.authenticated,onClick:function(){return l("messagelist")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Misc",children:(0,o.createComponentVNode)(2,i.Button,{icon:"sync-alt",content:"Restart Nano-Mob Hunter GO! Server",disabled:!d.authenticated,onClick:function(){return l("RestartNanoMob")}})})]})})]})});case 2:return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[s,(0,o.createComponentVNode)(2,i.Section,{title:"Modify Status Screens",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-left",content:"Back To Main Menu",onClick:function(){return l("main")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Presets",children:b}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Alerts",children:v}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Message Line 1",children:(0,o.createComponentVNode)(2,i.Button,{icon:"pencil-alt",content:d.stat_display.line_1,disabled:!d.authenticated,onClick:function(){return l("setmsg1")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Message Line 2",children:(0,o.createComponentVNode)(2,i.Button,{icon:"pencil-alt",content:d.stat_display.line_2,disabled:!d.authenticated,onClick:function(){return l("setmsg2")}})})]})})]})});case 3:return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[s,h]})});default:return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[s,"ERRROR. Unknown menu_state: ",d.menu_state,"Please report this to NT Technical Support."]})})}}},function(e,t,n){"use strict";t.__esModule=!0,t.CrewMonitor=void 0;var o=n(1),r=n(56),i=n(87),a=n(2),c=n(3),l=n(86),d=n(55),u=n(4),s=function(e){return e.dead?"Deceased":1===parseInt(e.stat,10)?"Unconscious":"Living"},p=function(e){return e.dead?"red":1===parseInt(e.stat,10)?"orange":"green"};t.CrewMonitor=function(e,t){var n=(0,a.useBackend)(t),r=(n.act,n.data,(0,a.useLocalState)(t,"tabIndex",0)),i=r[0],l=r[1];return(0,o.createComponentVNode)(2,u.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,u.Window.Content,{children:(0,o.createComponentVNode)(2,c.Box,{fillPositionedParent:!0,children:[(0,o.createComponentVNode)(2,c.Tabs,{children:[(0,o.createComponentVNode)(2,c.Tabs.Tab,{selected:0===i,onClick:function(){return l(0)},children:[(0,o.createComponentVNode)(2,c.Icon,{name:"table"})," Data View"]},"DataView"),(0,o.createComponentVNode)(2,c.Tabs.Tab,{selected:1===i,onClick:function(){return l(1)},children:[(0,o.createComponentVNode)(2,c.Icon,{name:"map-marked-alt"})," Map View"]},"MapView")]}),function(e){switch(e){case 0:return(0,o.createComponentVNode)(2,f);case 1:return(0,o.createComponentVNode)(2,m);default:return"WE SHOULDN'T BE HERE!"}}(i)]})})})};var f=function(e,t){var n=(0,a.useBackend)(t),u=n.act,f=n.data,m=(0,r.sortBy)((function(e){return e.name}))(f.crewmembers||[]),h=(0,a.useLocalState)(t,"search",""),g=h[0],C=h[1],b=(0,i.createSearch)(g,(function(e){return e.name+"|"+e.assignment+"|"+e.area}));return(0,o.createComponentVNode)(2,c.Box,{children:[(0,o.createComponentVNode)(2,c.Input,{placeholder:"Search by name, assignment or location..",width:"100%",onInput:function(e,t){return C(t)}}),(0,o.createComponentVNode)(2,c.Table,{m:"0.5rem",children:[(0,o.createComponentVNode)(2,c.Table.Row,{header:!0,children:[(0,o.createComponentVNode)(2,c.Table.Cell,{children:"Name"}),(0,o.createComponentVNode)(2,c.Table.Cell,{children:"Status"}),(0,o.createComponentVNode)(2,c.Table.Cell,{children:"Location"})]}),m.filter(b).map((function(e){return(0,o.createComponentVNode)(2,c.Table.Row,{bold:!!e.is_command,children:[(0,o.createComponentVNode)(2,l.TableCell,{children:[e.name," (",e.assignment,")"]}),(0,o.createComponentVNode)(2,l.TableCell,{children:[(0,o.createComponentVNode)(2,c.Box,{inline:!0,color:p(e),children:s(e)}),e.sensor_type>=2?(0,o.createComponentVNode)(2,c.Box,{inline:!0,children:["(",(0,o.createComponentVNode)(2,c.Box,{inline:!0,color:d.COLORS.damageType.oxy,children:e.oxy}),"|",(0,o.createComponentVNode)(2,c.Box,{inline:!0,color:d.COLORS.damageType.toxin,children:e.tox}),"|",(0,o.createComponentVNode)(2,c.Box,{inline:!0,color:d.COLORS.damageType.burn,children:e.fire}),"|",(0,o.createComponentVNode)(2,c.Box,{inline:!0,color:d.COLORS.damageType.brute,children:e.brute}),")"]}):null]}),(0,o.createComponentVNode)(2,l.TableCell,{children:3===e.sensor_type?f.isAI?(0,o.createComponentVNode)(2,c.Button,{fluid:!0,icon:"location-arrow",content:e.area+" ("+e.x+", "+e.y+")",onClick:function(){return u("track",{track:e.ref})}}):e.area+" ("+e.x+", "+e.y+")":"Not Available"})]},e.name)}))]})]})},m=function(e,t){var n=(0,a.useBackend)(t).data,r=(0,a.useLocalState)(t,"zoom",1),i=r[0],l=r[1];return(0,o.createComponentVNode)(2,c.Box,{height:"526px",mb:"0.5rem",overflow:"hidden",children:(0,o.createComponentVNode)(2,c.NanoMap,{onZoom:function(e){return l(e)},children:n.crewmembers.filter((function(e){return 3===e.sensor_type})).map((function(e){return(0,o.createComponentVNode)(2,c.NanoMap.Marker,{x:e.x,y:e.y,zoom:i,icon:"circle",tooltip:e.name+" ("+e.assignment+")",color:p(e)},e.ref)}))})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Cryo=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=[{label:"Resp.",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"}],l=[["good","Conscious"],["average","Unconscious"],["bad","DEAD"]];t.Cryo=function(e,t){return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{className:"Layout__content--flexColumn",children:(0,o.createComponentVNode)(2,d)})})};var d=function(e,t){var n=(0,r.useBackend)(t),a=n.act,d=n.data,s=d.isOperating,p=d.hasOccupant,f=d.occupant,m=void 0===f?[]:f,h=d.cellTemperature,g=d.cellTemperatureStatus,C=d.isBeakerLoaded,b=d.auto_eject_healthy,v=d.auto_eject_dead;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"Occupant",flexGrow:"1",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"user-slash",onClick:function(){return a("ejectOccupant")},disabled:!p,children:"Eject"}),children:p?(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Occupant",children:m.name||"Unknown"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,i.ProgressBar,{min:m.health,max:m.maxHealth,value:m.health/m.maxHealth,color:m.health>0?"good":"average",children:(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:Math.round(m.health)})})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:l[m.stat][0],children:l[m.stat][1]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",children:[(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:Math.round(m.bodyTemperature)})," K"]}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),c.map((function(e){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.label,children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:m[e.type]/100,ranges:{bad:[.01,Infinity]},children:(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:Math.round(m[e.type])})})},e.id)}))]}):(0,o.createComponentVNode)(2,i.Flex,{height:"100%",textAlign:"center",children:(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",align:"center",color:"label",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant detected."]})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Cell",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",onClick:function(){return a("ejectBeaker")},disabled:!C,children:"Eject Beaker"}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:(0,o.createComponentVNode)(2,i.Button,{icon:"power-off",onClick:function(){return a(s?"switchOff":"switchOn")},selected:s,children:s?"On":"Off"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",color:g,children:[(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:h})," K"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Beaker",children:(0,o.createComponentVNode)(2,u)}),(0,o.createComponentVNode)(2,i.LabeledList.Divider),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Auto-eject healthy occupants",children:(0,o.createComponentVNode)(2,i.Button,{icon:b?"toggle-on":"toggle-off",selected:b,onClick:function(){return a(b?"auto_eject_healthy_off":"auto_eject_healthy_on")},children:b?"On":"Off"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Auto-eject dead occupants",children:(0,o.createComponentVNode)(2,i.Button,{icon:v?"toggle-on":"toggle-off",selected:v,onClick:function(){return a(v?"auto_eject_dead_off":"auto_eject_dead_on")},children:v?"On":"Off"})})]})})],4)},u=function(e,t){var n=(0,r.useBackend)(t),a=(n.act,n.data),c=a.isBeakerLoaded,l=a.beakerLabel,d=a.beakerVolume;return c?(0,o.createFragment)([l||(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"No label"}),(0,o.createComponentVNode)(2,i.Box,{color:!d&&"bad",children:d?(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:d,format:function(e){return Math.round(e)+" units remaining"}}):"Beaker is empty"})],0):(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"No beaker loaded"})}},function(e,t,n){"use strict";t.__esModule=!0,t.DNAModifier=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=n(88),l=[["good","Alive"],["average","Critical"],["bad","DEAD"]],d=[["ui","Modify U.I.","dna"],["se","Modify S.E.","dna"],["buffer","Transfer Buffers","syringe"],["rejuvenators","Rejuvenators","flask"]],u=[5,10,20,30,50];t.DNAModifier=function(e,t){var n,i=(0,r.useBackend)(t),l=(i.act,i.data),d=l.irradiating,u=l.dnaBlockSize,f=l.occupant;return t.dnaBlockSize=u,t.isDNAInvalid=!f.isViableSubject||!f.uniqueIdentity||!f.structuralEnzymes,d&&(n=(0,o.createComponentVNode)(2,N,{duration:d})),(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,c.ComplexModal),n,(0,o.createComponentVNode)(2,a.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,s),(0,o.createComponentVNode)(2,p)]})]})};var s=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,d=c.locked,u=c.hasOccupant,s=c.occupant;return(0,o.createComponentVNode)(2,i.Section,{title:"Occupant",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{color:"label",display:"inline",mr:"0.5rem",children:"Door Lock:"}),(0,o.createComponentVNode)(2,i.Button,{disabled:!u,selected:d,icon:d?"toggle-on":"toggle-off",content:d?"Engaged":"Disengaged",onClick:function(){return a("toggleLock")}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!u||d,icon:"user-slash",content:"Eject",onClick:function(){return a("ejectOccupant")}})],4),children:u?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Name",children:s.name}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,i.ProgressBar,{min:s.minHealth,max:s.maxHealth,value:s.health/s.maxHealth,ranges:{good:[.5,Infinity],average:[0,.5],bad:[-Infinity,0]}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",color:l[s.stat][0],children:l[s.stat][1]}),(0,o.createComponentVNode)(2,i.LabeledList.Divider)]})}),t.isDNAInvalid?(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"exclamation-circle"}),"\xa0 The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure."]}):(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Radiation",children:(0,o.createComponentVNode)(2,i.ProgressBar,{min:"0",max:"100",value:s.radiationLevel/100,color:"average"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Unique Enzymes",children:c.occupant.uniqueEnzymes?c.occupant.uniqueEnzymes:(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"exclamation-circle"}),"\xa0 Unknown"]})})]})],0):(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"Cell unoccupied."})})},p=function(e,t){var n,a=(0,r.useBackend)(t),c=a.act,l=a.data,u=l.selectedMenuKey,s=l.hasOccupant;l.occupant;return s?t.isDNAInvalid?(0,o.createComponentVNode)(2,i.Section,{flexGrow:"1",children:(0,o.createComponentVNode)(2,i.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",align:"center",textAlign:"center",color:"label",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No operation possible on this subject."]})})}):("ui"===u?n=(0,o.createFragment)([(0,o.createComponentVNode)(2,f),(0,o.createComponentVNode)(2,h)],4):"se"===u?n=(0,o.createFragment)([(0,o.createComponentVNode)(2,m),(0,o.createComponentVNode)(2,h)],4):"buffer"===u?n=(0,o.createComponentVNode)(2,g):"rejuvenators"===u&&(n=(0,o.createComponentVNode)(2,v)),(0,o.createComponentVNode)(2,i.Section,{flexGrow:"1",children:[(0,o.createComponentVNode)(2,i.Tabs,{children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:u===e[0],onClick:function(){return c("selectMenuKey",{key:e[0]})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:e[2]}),e[1]]},t)}))}),n]})):(0,o.createComponentVNode)(2,i.Section,{flexGrow:"1",children:(0,o.createComponentVNode)(2,i.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,i.Flex.Item,{grow:"1",align:"center",textAlign:"center",color:"label",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant in DNA modifier."]})})})},f=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.selectedUIBlock,d=c.selectedUISubBlock,u=c.selectedUITarget,s=c.occupant;return(0,o.createComponentVNode)(2,i.Section,{title:"Modify Unique Identifier",level:"2",children:[(0,o.createComponentVNode)(2,V,{dnaString:s.uniqueIdentity,selectedBlock:l,selectedSubblock:d,blockSize:t.dnaBlockSize,action:"selectUIBlock"}),(0,o.createComponentVNode)(2,i.LabeledList,{children:(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target",children:(0,o.createComponentVNode)(2,i.Knob,{minValue:"1",maxValue:"15",stepPixelSize:"20",value:u,format:function(e){return e.toString(16).toUpperCase()},ml:"0",onChange:function(e,t){return a("changeUITarget",{value:t})}})})}),(0,o.createComponentVNode)(2,i.Button,{icon:"radiation",content:"Irradiate Block",mt:"0.5rem",onClick:function(){return a("pulseUIRadiation")}})]})},m=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.selectedSEBlock,d=c.selectedSESubBlock,u=c.occupant;return(0,o.createComponentVNode)(2,i.Section,{title:"Modify Structural Enzymes",level:"2",children:[(0,o.createComponentVNode)(2,V,{dnaString:u.structuralEnzymes,selectedBlock:l,selectedSubblock:d,blockSize:t.dnaBlockSize,action:"selectSEBlock"}),(0,o.createComponentVNode)(2,i.Button,{icon:"radiation",content:"Irradiate Block",onClick:function(){return a("pulseSERadiation")}})]})},h=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.radiationIntensity,d=c.radiationDuration;return(0,o.createComponentVNode)(2,i.Section,{title:"Radiation Emitter",level:"2",children:[(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Intensity",children:(0,o.createComponentVNode)(2,i.Knob,{minValue:"1",maxValue:"10",stepPixelSize:"20",value:l,popUpPosition:"right",ml:"0",onChange:function(e,t){return a("radiationIntensity",{value:t})}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Duration",children:(0,o.createComponentVNode)(2,i.Knob,{minValue:"1",maxValue:"20",stepPixelSize:"10",unit:"s",value:d,popUpPosition:"right",ml:"0",onChange:function(e,t){return a("radiationDuration",{value:t})}})})]}),(0,o.createComponentVNode)(2,i.Button,{icon:"radiation",content:"Pulse Radiation",tooltip:"Mutates a random block of either the occupant's UI or SE.",tooltipPosition:"top-right",mt:"0.5rem",onClick:function(){return a("pulseRadiation")}})]})},g=function(e,t){var n=(0,r.useBackend)(t),a=(n.act,n.data.buffers.map((function(e,t){return(0,o.createComponentVNode)(2,C,{id:t+1,name:"Buffer "+(t+1),buffer:e},t)})));return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"Buffers",level:"2",children:a}),(0,o.createComponentVNode)(2,b)],4)},C=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=e.id,d=e.name,u=e.buffer,s=c.isInjectorReady,p=d+(u.data?" - "+u.label:"");return(0,o.createComponentVNode)(2,i.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,o.createComponentVNode)(2,i.Section,{title:p,level:"3",mx:"0",lineHeight:"18px",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button.Confirm,{disabled:!u.data,icon:"trash",content:"Clear",onClick:function(){return a("bufferOption",{option:"clear",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!u.data,icon:"pen",content:"Rename",onClick:function(){return a("bufferOption",{option:"changeLabel",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!u.data||!c.hasDisk,icon:"save",content:"Export",tooltip:"Exports this buffer to the currently loaded data disk.",tooltipPosition:"bottom-left",onClick:function(){return a("bufferOption",{option:"saveDisk",id:l})}})],4),children:[(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Write",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",content:"Subject U.I",mb:"0",onClick:function(){return a("bufferOption",{option:"saveUI",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",content:"Subject U.I and U.E.",mb:"0",onClick:function(){return a("bufferOption",{option:"saveUIAndUE",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-down",content:"Subject S.E.",mb:"0",onClick:function(){return a("bufferOption",{option:"saveSE",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!c.hasDisk||!c.disk.data,icon:"arrow-circle-down",content:"From Disk",mb:"0",onClick:function(){return a("bufferOption",{option:"loadDisk",id:l})}})]}),!!u.data&&(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Subject",children:u.owner||(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"Unknown"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Data Type",children:["ui"===u.type?"Unique Identifiers":"Structural Enzymes",!!u.ue&&" and Unique Enzymes"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Transfer to",children:[(0,o.createComponentVNode)(2,i.Button,{disabled:!s,icon:s?"syringe":"spinner",iconSpin:!s,content:"Injector",mb:"0",onClick:function(){return a("bufferOption",{option:"createInjector",id:l})}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!s,icon:s?"syringe":"spinner",iconSpin:!s,content:"Block Injector",mb:"0",onClick:function(){return a("bufferOption",{option:"createInjector",id:l,block:1})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"user",content:"Subject",mb:"0",onClick:function(){return a("bufferOption",{option:"transfer",id:l})}})]})],4)]}),!u.data&&(0,o.createComponentVNode)(2,i.Box,{color:"label",mt:"0.5rem",children:"This buffer is empty."})]})})},b=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.hasDisk,d=c.disk;return(0,o.createComponentVNode)(2,i.Section,{title:"Data Disk",level:"2",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button.Confirm,{disabled:!l||!d.data,icon:"trash",content:"Wipe",onClick:function(){return a("wipeDisk")}}),(0,o.createComponentVNode)(2,i.Button,{disabled:!l,icon:"eject",content:"Eject",onClick:function(){return a("ejectDisk")}})],4),children:l?d.data?(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Label",children:d.label?d.label:"No label"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Subject",children:d.owner?d.owner:(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"Unknown"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Data Type",children:["ui"===d.type?"Unique Identifiers":"Structural Enzymes",!!d.ue&&" and Unique Enzymes"]})]}):(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"Disk is blank."}):(0,o.createComponentVNode)(2,i.Box,{color:"label",textAlign:"center",my:"1rem",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"save-o",size:"4"}),(0,o.createVNode)(1,"br"),"No disk inserted."]})})},v=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.isBeakerLoaded,d=c.beakerVolume,s=c.beakerLabel;return(0,o.createComponentVNode)(2,i.Section,{title:"Rejuvenators and Beaker",level:"2",buttons:(0,o.createComponentVNode)(2,i.Button,{disabled:!l,icon:"eject",content:"Eject",onClick:function(){return a("ejectBeaker")}}),children:l?(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Inject",children:[u.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{disabled:e>d,icon:"syringe",content:e,onClick:function(){return a("injectRejuvenators",{amount:e})}},t)})),(0,o.createComponentVNode)(2,i.Button,{disabled:d<=0,icon:"syringe",content:"All",onClick:function(){return a("injectRejuvenators",{amount:d})}})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Beaker",children:[(0,o.createComponentVNode)(2,i.Box,{mb:"0.5rem",children:s||"No label"}),d?(0,o.createComponentVNode)(2,i.Box,{color:"good",children:[d," unit",1===d?"":"s"," remaining"]}):(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"Empty"})]})]}):(0,o.createComponentVNode)(2,i.Box,{color:"label",textAlign:"center",my:"25%",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"exclamation-triangle",size:"4"}),(0,o.createVNode)(1,"br"),"No beaker loaded."]})})},N=function(e,t){return(0,o.createComponentVNode)(2,i.Dimmer,{textAlign:"center",children:[(0,o.createComponentVNode)(2,i.Icon,{name:"spinner",size:"5",spin:!0}),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Box,{color:"average",children:(0,o.createVNode)(1,"h1",null,[(0,o.createComponentVNode)(2,i.Icon,{name:"radiation"}),(0,o.createTextVNode)("\xa0Irradiating occupant\xa0"),(0,o.createComponentVNode)(2,i.Icon,{name:"radiation"})],4)}),(0,o.createComponentVNode)(2,i.Box,{color:"label",children:(0,o.createVNode)(1,"h3",null,[(0,o.createTextVNode)("For "),e.duration,(0,o.createTextVNode)(" second"),1===e.duration?"":"s"],0)})]})},V=function(e,t){for(var n=(0,r.useBackend)(t),a=n.act,c=(n.data,e.dnaString),l=e.selectedBlock,d=e.selectedSubblock,u=e.blockSize,s=e.action,p=c.split(""),f=[],m=function(e){for(var t=e/u+1,n=[],r=function(r){var c=r+1;n.push((0,o.createComponentVNode)(2,i.Button,{selected:l===t&&d===c,content:p[e+r],mb:"0",onClick:function(){return a(s,{block:t,subblock:c})}}))},c=0;c0?"Yes":"No",selected:l.com>0,onClick:function(){return c("toggle_com")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Security",children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{selected:l.sec===e,content:e,onClick:function(){return c("set_sec",{set_sec:e})}},"sec"+e)}))}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Medical",children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{selected:l.med===e,content:e,onClick:function(){return c("set_med",{set_med:e})}},"med"+e)}))}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Engineering",children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{selected:l.eng===e,content:e,onClick:function(){return c("set_eng",{set_eng:e})}},"eng"+e)}))}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Paranormal",children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{selected:l.par===e,content:e,onClick:function(){return c("set_par",{set_par:e})}},"par"+e)}))}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Janitor",children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{selected:l.jan===e,content:e,onClick:function(){return c("set_jan",{set_jan:e})}},"jan"+e)}))}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cyborg",children:d.map((function(e,t){return(0,o.createComponentVNode)(2,i.Button,{selected:l.cyb===e,content:e,onClick:function(){return c("set_cyb",{set_cyb:e})}},"cyb"+e)}))}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Total Slots",children:(0,o.createComponentVNode)(2,i.Box,{color:l.total>l.spawnpoints?"red":"green",children:[l.total," total, versus ",l.spawnpoints," spawnpoints"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Dispatch",children:(0,o.createComponentVNode)(2,i.Button,{icon:"ambulance",content:"Send ERT",onClick:function(){return c("dispatch_ert")}})})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Electropack=void 0;var o=n(1),r=n(20),i=n(2),a=n(3),c=n(4);t.Electropack=function(e,t){var n=(0,i.useBackend)(t),l=n.act,d=n.data,u=d.power,s=d.code,p=d.frequency,f=d.minFrequency,m=d.maxFrequency;return(0,o.createComponentVNode)(2,c.Window,{children:(0,o.createComponentVNode)(2,c.Window.Content,{children:(0,o.createComponentVNode)(2,a.Section,{children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Power",children:(0,o.createComponentVNode)(2,a.Button,{icon:u?"power-off":"times",content:u?"On":"Off",selected:u,onClick:function(){return l("power")}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Frequency",buttons:(0,o.createComponentVNode)(2,a.Button,{icon:"sync",content:"Reset",onClick:function(){return l("reset",{reset:"freq"})}}),children:(0,o.createComponentVNode)(2,a.NumberInput,{animate:!0,unit:"kHz",step:.2,stepPixelSize:6,minValue:f/10,maxValue:m/10,value:p/10,format:function(e){return(0,r.toFixed)(e,1)},width:"80px",onChange:function(e,t){return l("freq",{freq:t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Code",buttons:(0,o.createComponentVNode)(2,a.Button,{icon:"sync",content:"Reset",onClick:function(){return l("reset",{reset:"code"})}}),children:(0,o.createComponentVNode)(2,a.NumberInput,{animate:!0,step:1,stepPixelSize:6,minValue:1,maxValue:100,value:s,width:"80px",onChange:function(e,t){return l("code",{code:t})}})})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.FaxMachine=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.FaxMachine=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Authorization",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"ID Card",children:(0,o.createComponentVNode)(2,i.Button,{icon:l.scan_name?"eject":"id-card",selected:l.scan_name,content:l.scan_name?l.scan_name:"-----",tooltip:l.scan_name?"Eject ID":"Insert ID",onClick:function(){return c("scan")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Authorize",children:(0,o.createComponentVNode)(2,i.Button,{icon:l.authenticated?"sign-out-alt":"id-card",selected:l.authenticated,disabled:!l.scan_name&&!l.authenticated,content:l.authenticated?"Log Out":"Log In",onClick:function(){return c("auth")}})})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Fax Menu",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Network",children:l.network}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Document",children:[(0,o.createComponentVNode)(2,i.Button,{icon:l.paper?"eject":"paperclip",disabled:!l.authenticated&&!l.paper,content:l.paper?l.paper:"-----",onClick:function(){return c("paper")}}),!!l.paper&&(0,o.createComponentVNode)(2,i.Button,{icon:"pencil-alt",content:"Rename",onClick:function(){return c("rename")}})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Sending To",children:(0,o.createComponentVNode)(2,i.Button,{icon:"print",content:l.destination?l.destination:"-----",disabled:!l.authenticated,onClick:function(){return c("dept")}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Action",children:(0,o.createComponentVNode)(2,i.Button,{icon:"envelope",content:l.sendError?l.sendError:"Send",disabled:!l.paper||!l.destination||!l.authenticated||l.sendError,onClick:function(){return c("send")}})})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.GasFreezer=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.GasFreezer=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.on,u=l.pressure,s=l.temperature,p=l.temperatureCelsius,f=l.min,m=l.max,h=l.target,g=l.targetCelsius,C=(s-f)/(m-f);return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{title:"Status",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:d?"power-off":"times",content:d?"On":"Off",selected:d,onClick:function(){return c("power")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Pressure",children:[u," kpA"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",children:(0,o.createComponentVNode)(2,i.Flex,{direction:"row",justify:"space-between",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{width:"70%",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:C,ranges:{blue:[-Infinity,.5],red:[.5,Infinity]},children:"\xa0"})}),(0,o.createComponentVNode)(2,i.Flex.Item,{width:"30%",children:[C<.5&&(0,o.createComponentVNode)(2,i.Box,{inline:!0,color:"blue",ml:1,children:[s," K (",p,"\xb0C)"]}),C>=.5&&(0,o.createComponentVNode)(2,i.Box,{inline:!0,color:"red",ml:1,children:[s," K (",p,"\xb0C)"]})]})]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target temperature",children:(0,o.createComponentVNode)(2,i.Flex,{direction:"row",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{width:"70%",justify:"end",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:(h-f)/(m-f),children:"\xa0"})}),(0,o.createComponentVNode)(2,i.Flex.Item,{width:"30%",children:(0,o.createComponentVNode)(2,i.Box,{inline:!0,ml:1,children:[h," K (",g,"\xb0C)"]})})]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Set target temperature",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",title:"Minimum temperature",onClick:function(){return c("temp",{temp:f})}}),(0,o.createComponentVNode)(2,i.NumberInput,{value:Math.round(h),unit:"K",minValue:Math.round(f),maxValue:Math.round(m),step:5,stepPixelSize:3,onDrag:function(e,t){return c("temp",{temp:t})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",title:"Maximum Temperature",onClick:function(){return c("temp",{temp:m})}})]})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Instrument=void 0;var o=n(1),r=n(20),i=n(2),a=n(3),c=n(4);t.Instrument=function(e,t){var n=(0,i.useBackend)(t);n.act,n.data;return(0,o.createComponentVNode)(2,c.Window,{children:[(0,o.createComponentVNode)(2,l),(0,o.createComponentVNode)(2,c.Window.Content,{scrollable:!0,children:[(0,o.createComponentVNode)(2,d),(0,o.createComponentVNode)(2,s)]})]})};var l=function(e,t){var n=(0,i.useBackend)(t),r=n.act;if(n.data.help)return(0,o.createComponentVNode)(2,a.Modal,{maxWidth:"75%",height:.75*window.innerHeight+"px",mx:"auto",py:"0",px:"0.5rem",children:(0,o.createComponentVNode)(2,a.Section,{height:"100%",title:"Help",level:"2",overflow:"auto",children:(0,o.createComponentVNode)(2,a.Box,{px:"0.5rem",mt:"-0.5rem",children:[(0,o.createVNode)(1,"h1",null,"Making a Song",16),(0,o.createVNode)(1,"p",null,[(0,o.createTextVNode)("Lines are a series of chords, separated by commas\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"(,)"}),(0,o.createTextVNode)(", each with notes seperated by hyphens\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"(-)"}),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("Every note in a chord will play together, with the chord timed by the\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"tempo"}),(0,o.createTextVNode)(" as defined above.")],4),(0,o.createVNode)(1,"p",null,[(0,o.createTextVNode)("Notes are played by the\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"good",children:"names of the note"}),(0,o.createTextVNode)(", and optionally, the\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"accidental"}),(0,o.createTextVNode)(", and/or the "),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"bad",children:"octave number"}),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("By default, every note is\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"natural"}),(0,o.createTextVNode)(" and in\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"bad",children:"octave 3"}),(0,o.createTextVNode)(". Defining a different state for either is remembered for each "),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"good",children:"note"}),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"ul",null,[(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"Example:"}),(0,o.createTextVNode)("\xa0"),(0,o.createVNode)(1,"i",null,"C,D,E,F,G,A,B",16),(0,o.createTextVNode)(" will play a\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"good",children:"C"}),(0,o.createTextVNode)("\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"major"}),(0,o.createTextVNode)(" scale.")],4),(0,o.createVNode)(1,"li",null,[(0,o.createTextVNode)("After a note has an\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"accidental"}),(0,o.createTextVNode)(" or\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"bad",children:"octave"}),(0,o.createTextVNode)(" placed, it will be remembered:\xa0"),(0,o.createVNode)(1,"i",null,"C,C4,C#,C3",16),(0,o.createTextVNode)(" is "),(0,o.createVNode)(1,"i",null,"C3,C4,C4#,C3#",16)],4)],4)],4),(0,o.createVNode)(1,"p",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"Chords"}),(0,o.createTextVNode)("\xa0can be played simply by seperating each note with a hyphen: "),(0,o.createVNode)(1,"i",null,"A-C#,Cn-E,E-G#,Gn-B",16),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("A "),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"pause"}),(0,o.createTextVNode)("\xa0may be denoted by an empty chord: "),(0,o.createVNode)(1,"i",null,"C,E,,C,G",16),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("To make a chord be a different time, end it with /x, where the chord length will be length defined by\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"tempo / x"}),(0,o.createTextVNode)(",\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"eg:"}),(0,o.createTextVNode)(" "),(0,o.createVNode)(1,"i",null,"C,G/2,E/4",16),(0,o.createTextVNode)(".")],4),(0,o.createVNode)(1,"p",null,[(0,o.createTextVNode)("Combined, an example line is: "),(0,o.createVNode)(1,"i",null,"E-E4/4,F#/2,G#/8,B/8,E3-E4/4",16),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"ul",null,[(0,o.createVNode)(1,"li",null,"Lines may be up to 300 characters.",16),(0,o.createVNode)(1,"li",null,"A song may only contain up to 1,000 lines.",16)],4)],4),(0,o.createVNode)(1,"p",null,[(0,o.createTextVNode)("Lines are a series of chords, separated by commas\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"(,)"}),(0,o.createTextVNode)(", each with notes seperated by hyphens\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"(-)"}),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("Every note in a chord will play together, with the chord timed by the\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"tempo"}),(0,o.createTextVNode)(" as defined above.")],4),(0,o.createVNode)(1,"p",null,[(0,o.createTextVNode)("Notes are played by the\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"good",children:"names of the note"}),(0,o.createTextVNode)(", and optionally, the\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"accidental"}),(0,o.createTextVNode)(", and/or the "),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"bad",children:"octave number"}),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("By default, every note is\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"natural"}),(0,o.createTextVNode)(" and in\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"bad",children:"octave 3"}),(0,o.createTextVNode)(". Defining a different state for either is remembered for each "),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"good",children:"note"}),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"ul",null,[(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"Example:"}),(0,o.createTextVNode)("\xa0"),(0,o.createVNode)(1,"i",null,"C,D,E,F,G,A,B",16),(0,o.createTextVNode)(" will play a\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"good",children:"C"}),(0,o.createTextVNode)("\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"major"}),(0,o.createTextVNode)(" scale.")],4),(0,o.createVNode)(1,"li",null,[(0,o.createTextVNode)("After a note has an\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"average",children:"accidental"}),(0,o.createTextVNode)(" or\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"bad",children:"octave"}),(0,o.createTextVNode)(" placed, it will be remembered:\xa0"),(0,o.createVNode)(1,"i",null,"C,C4,C#,C3",16),(0,o.createTextVNode)(" is "),(0,o.createVNode)(1,"i",null,"C3,C4,C4#,C3#",16)],4)],4)],4),(0,o.createVNode)(1,"p",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"Chords"}),(0,o.createTextVNode)("\xa0can be played simply by seperating each note with a hyphen: "),(0,o.createVNode)(1,"i",null,"A-C#,Cn-E,E-G#,Gn-B",16),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("A "),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"pause"}),(0,o.createTextVNode)("\xa0may be denoted by an empty chord: "),(0,o.createVNode)(1,"i",null,"C,E,,C,G",16),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("To make a chord be a different time, end it with /x, where the chord length will be length defined by\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"tempo / x"}),(0,o.createTextVNode)(",\xa0"),(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"highlight",children:"eg:"}),(0,o.createTextVNode)(" "),(0,o.createVNode)(1,"i",null,"C,G/2,E/4",16),(0,o.createTextVNode)(".")],4),(0,o.createVNode)(1,"p",null,[(0,o.createTextVNode)("Combined, an example line is: "),(0,o.createVNode)(1,"i",null,"E-E4/4,F#/2,G#/8,B/8,E3-E4/4",16),(0,o.createTextVNode)("."),(0,o.createVNode)(1,"ul",null,[(0,o.createVNode)(1,"li",null,"Lines may be up to 300 characters.",16),(0,o.createVNode)(1,"li",null,"A song may only contain up to 1,000 lines.",16)],4)],4),(0,o.createVNode)(1,"h1",null,"Instrument Advanced Settings",16),(0,o.createVNode)(1,"ul",null,[(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"label",children:"Type:"}),(0,o.createTextVNode)("\xa0Whether the instrument is legacy or synthesized."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("Legacy instruments have a collection of sounds that are selectively used depending on the note to play."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("Synthesized instruments use a base sound and change its pitch to match the note to play.")],4),(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"label",children:"Current:"}),(0,o.createTextVNode)("\xa0Which instrument sample to play. Some instruments can be tuned to play different samples. Experiment!")],4),(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"label",children:"Note Shift/Note Transpose:"}),(0,o.createTextVNode)("\xa0The pitch to apply to all notes of the song.")],4),(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"label",children:"Sustain Mode:"}),(0,o.createTextVNode)("\xa0How a played note fades out."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("Linear sustain means a note will fade out at a constant rate."),(0,o.createVNode)(1,"br"),(0,o.createTextVNode)("Exponential sustain means a note will fade out at an exponential rate, sounding smoother.")],4),(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"label",children:"Volume Dropoff Threshold:"}),(0,o.createTextVNode)("\xa0The volume threshold at which a note is fully stopped.")],4),(0,o.createVNode)(1,"li",null,[(0,o.createComponentVNode)(2,a.Box,{as:"span",color:"label",children:"Sustain indefinitely last held note:"}),(0,o.createTextVNode)("\xa0Whether the last note should be sustained indefinitely.")],4)],4),(0,o.createComponentVNode)(2,a.Button,{color:"grey",content:"Close",onClick:function(){return r("help")}})]})})})},d=function(e,t){var n=(0,i.useBackend)(t),c=n.act,l=n.data,d=l.lines,s=l.playing,p=l.repeat,f=l.maxRepeats,m=l.tempo,h=l.minTempo,g=l.maxTempo,C=l.tickLag,b=l.volume,v=l.minVolume,N=l.maxVolume,V=l.ready;return(0,o.createComponentVNode)(2,a.Section,{title:"Instrument",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{icon:"info",content:"Help",onClick:function(){return c("help")}}),(0,o.createComponentVNode)(2,a.Button,{icon:"file",content:"New",onClick:function(){return c("newsong")}}),(0,o.createComponentVNode)(2,a.Button,{icon:"upload",content:"Import",onClick:function(){return c("import")}})],4),children:[(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Playback",children:[(0,o.createComponentVNode)(2,a.Button,{selected:s,disabled:0===d.length||p<0,icon:"play",content:"Play",onClick:function(){return c("play")}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!s,icon:"stop",content:"Stop",onClick:function(){return c("stop")}})]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Repeat",children:(0,o.createComponentVNode)(2,a.Slider,{animated:!0,minValue:"0",maxValue:f,value:p,stepPixelSize:"59",onChange:function(e,t){return c("repeat",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Tempo",children:(0,o.createComponentVNode)(2,a.Box,{children:[(0,o.createComponentVNode)(2,a.Button,{disabled:m>=g,content:"-",as:"span",mr:"0.5rem",onClick:function(){return c("tempo",{"new":m+C})}}),(0,r.round)(600/m)," BPM",(0,o.createComponentVNode)(2,a.Button,{disabled:m<=h,content:"+",as:"span",ml:"0.5rem",onClick:function(){return c("tempo",{"new":m-C})}})]})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Volume",children:(0,o.createComponentVNode)(2,a.Slider,{animated:!0,minValue:v,maxValue:N,value:b,stepPixelSize:"6",onDrag:function(e,t){return c("setvolume",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",children:V?(0,o.createComponentVNode)(2,a.Box,{color:"good",children:"Ready"}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"Instrument Definition Error!"})})]}),(0,o.createComponentVNode)(2,u)]})},u=function(e,t){var n,c,l=(0,i.useBackend)(t),d=l.act,u=l.data,s=u.allowedInstrumentNames,p=u.instrumentLoaded,f=u.instrument,m=u.canNoteShift,h=u.noteShift,g=u.noteShiftMin,C=u.noteShiftMax,b=u.sustainMode,v=u.sustainLinearDuration,N=u.sustainExponentialDropoff,V=u.legacy,y=u.sustainDropoffVolume,x=u.sustainHeldNote;return 1===b?(n="Linear",c=(0,o.createComponentVNode)(2,a.Slider,{minValue:"0.1",maxValue:"5",value:v,step:"0.5",stepPixelSize:"85",format:function(e){return(0,r.round)(100*e)/100+" seconds"},onChange:function(e,t){return d("setlinearfalloff",{"new":t/10})}})):2===b&&(n="Exponential",c=(0,o.createComponentVNode)(2,a.Slider,{minValue:"1.025",maxValue:"10",value:N,step:"0.01",format:function(e){return(0,r.round)(1e3*e)/1e3+"% per decisecond"},onChange:function(e,t){return d("setexpfalloff",{"new":t})}})),s.sort(),(0,o.createComponentVNode)(2,a.Box,{my:-1,children:(0,o.createComponentVNode)(2,a.Collapsible,{mt:"1rem",mb:"0",title:"Advanced",children:(0,o.createComponentVNode)(2,a.Section,{mt:-1,children:[(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Type",children:V?"Legacy":"Synthesized"}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Current",children:p?(0,o.createComponentVNode)(2,a.Dropdown,{options:s,selected:f,width:"40%",onSelected:function(e){return d("switchinstrument",{name:e})}}):(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:"None!"})}),!(V||!m)&&(0,o.createFragment)([(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Note Shift/Note Transpose",children:(0,o.createComponentVNode)(2,a.Slider,{minValue:g,maxValue:C,value:h,stepPixelSize:"2",format:function(e){return e+" keys / "+(0,r.round)(e/12*100)/100+" octaves"},onChange:function(e,t){return d("setnoteshift",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Sustain Mode",children:[(0,o.createComponentVNode)(2,a.Dropdown,{options:["Linear","Exponential"],selected:n,onSelected:function(e){return d("setsustainmode",{"new":e})}}),c]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Volume Dropoff Threshold",children:(0,o.createComponentVNode)(2,a.Slider,{animated:!0,minValue:"0.01",maxValue:"100",value:y,stepPixelSize:"6",onChange:function(e,t){return d("setdropoffvolume",{"new":t})}})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Sustain indefinitely last held note",children:(0,o.createComponentVNode)(2,a.Button,{selected:x,icon:x?"toggle-on":"toggle-off",content:x?"Yes":"No",onClick:function(){return d("togglesustainhold")}})})],4)]}),(0,o.createComponentVNode)(2,a.Button,{icon:"redo",content:"Reset to Default",mt:"0.5rem",onClick:function(){return d("reset")}})]})})})},s=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.playing,d=c.lines,u=c.editing;return(0,o.createComponentVNode)(2,a.Section,{title:"Editor",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{disabled:!u||l,icon:"plus",content:"Add Line",onClick:function(){return r("newline",{line:d.length+1})}}),(0,o.createComponentVNode)(2,a.Button,{selected:!u,icon:u?"chevron-up":"chevron-down",onClick:function(){return r("edit")}})],4),children:!!u&&(d.length>0?(0,o.createComponentVNode)(2,a.LabeledList,{children:d.map((function(e,t){return(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:t+1,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{disabled:l,icon:"pen",onClick:function(){return r("modifyline",{line:t+1})}}),(0,o.createComponentVNode)(2,a.Button,{disabled:l,icon:"trash",onClick:function(){return r("deleteline",{line:t+1})}})],4),children:e},t)}))}):(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"Song is empty."}))})}},function(e,t,n){"use strict";t.__esModule=!0,t.KeycardAuth=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.KeycardAuth=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=(0,o.createComponentVNode)(2,i.Section,{title:"Keycard Authentication Device",children:(0,o.createComponentVNode)(2,i.Box,{children:"This device is used to trigger certain high security events. It requires the simultaneous swipe of two high-level ID cards."})});if(l.swiping||l.busy){var u=(0,o.createComponentVNode)(2,i.Box,{color:"red",children:"Waiting for YOU to swipe your ID..."});return l.hasSwiped||l.ertreason||"Emergency Response Team"!==l.event?l.hasConfirm?u=(0,o.createComponentVNode)(2,i.Box,{color:"green",children:"Request Confirmed!"}):l.isRemote?u=(0,o.createComponentVNode)(2,i.Box,{color:"orange",children:"Swipe your card to CONFIRM the remote request."}):l.hasSwiped&&(u=(0,o.createComponentVNode)(2,i.Box,{color:"orange",children:"Waiting for second person to confirm..."})):u=(0,o.createComponentVNode)(2,i.Box,{color:"red",children:"Fill out the reason for your ERT request."}),(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[d,"Emergency Response Team"===l.event&&(0,o.createComponentVNode)(2,i.Section,{title:"Reason for ERT Call",children:(0,o.createComponentVNode)(2,i.Box,{children:(0,o.createComponentVNode)(2,i.Button,{color:l.ertreason?"":"red",icon:l.ertreason?"check":"pencil-alt",content:l.ertreason?l.ertreason:"-----",disabled:l.busy,onClick:function(){return c("ert")}})})}),(0,o.createComponentVNode)(2,i.Section,{title:l.event,buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-circle-left",content:"Back",disabled:l.busy||l.hasConfirm,onClick:function(){return c("reset")}}),children:u})]})})}return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[d,(0,o.createComponentVNode)(2,i.Section,{title:"Choose Action",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Red Alert",children:(0,o.createComponentVNode)(2,i.Button,{icon:"exclamation-triangle",disabled:!l.redAvailable,onClick:function(){return c("triggerevent",{triggerevent:"Red Alert"})},content:"Red Alert"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"ERT",children:(0,o.createComponentVNode)(2,i.Button,{icon:"broadcast-tower",onClick:function(){return c("triggerevent",{triggerevent:"Emergency Response Team"})},content:"Call ERT"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Emergency Maint Access",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"door-open",onClick:function(){return c("triggerevent",{triggerevent:"Grant Emergency Maintenance Access"})},content:"Grant"}),(0,o.createComponentVNode)(2,i.Button,{icon:"door-closed",onClick:function(){return c("triggerevent",{triggerevent:"Revoke Emergency Maintenance Access"})},content:"Revoke"})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Emergency Station-Wide Access",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"door-open",onClick:function(){return c("triggerevent",{triggerevent:"Activate Station-Wide Emergency Access"})},content:"Grant"}),(0,o.createComponentVNode)(2,i.Button,{icon:"door-closed",onClick:function(){return c("triggerevent",{triggerevent:"Deactivate Station-Wide Emergency Access"})},content:"Revoke"})]})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.MechBayConsole=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.MechBayConsole=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data.recharge_port,d=l&&l.mech,u=d&&d.cell,s=d&&d.name;return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{title:s?"Mech status: "+s:"Mech status",textAlign:"center",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Sync",onClick:function(){return c("reconnect")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Integrity",children:!l&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No power port detected. Please re-sync."})||!d&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No mech detected."})||(0,o.createComponentVNode)(2,i.ProgressBar,{value:d.health/d.maxhealth,ranges:{good:[.7,Infinity],average:[.3,.7],bad:[-Infinity,.3]}})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power",children:!l&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No power port detected. Please re-sync."})||!d&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No mech detected."})||!u&&(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No cell is installed."})||(0,o.createComponentVNode)(2,i.ProgressBar,{value:u.charge/u.maxcharge,ranges:{good:[.7,Infinity],average:[.3,.7],bad:[-Infinity,.3]},children:[(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:u.charge})," / "+u.maxcharge]})})]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.MedicalRecords=void 0;var o=n(1),r=n(2),i=n(3),a=n(88),c=n(4),l=n(463),d=n(464),u=n(465),s={Minor:"good",Medium:"average","Dangerous!":"bad",Harmful:"bad","BIOHAZARD THREAT!":"bad"},p=function(e,t){(0,a.modalOpen)(e,"edit",{field:t.edit,value:t.value})};t.MedicalRecords=function(e,t){var n,s=(0,r.useBackend)(t).data,p=s.authenticated,g=s.screen;return p?(2===g?n=(0,o.createComponentVNode)(2,f):3===g?n=(0,o.createComponentVNode)(2,m):4===g?n=(0,o.createComponentVNode)(2,h):5===g?n=(0,o.createComponentVNode)(2,b):6===g&&(n=(0,o.createComponentVNode)(2,v)),(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:[(0,o.createComponentVNode)(2,a.ComplexModal),(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,l.LoginInfo),(0,o.createComponentVNode)(2,u.TemporaryNotice),(0,o.createComponentVNode)(2,N),(0,o.createComponentVNode)(2,i.Section,{height:"100%",flexGrow:"1",children:n})]})]})):(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{children:(0,o.createComponentVNode)(2,d.LoginScreen)})})};var f=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data.records;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Input,{fluid:!0,placeholder:"Search by Name, DNA, or ID",onChange:function(e,t){return a("search",{t1:t})}}),(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:c.map((function(e,t){return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"user",mb:"0.5rem",content:e.id+": "+e.name,onClick:function(){return a("d_rec",{d_rec:e.ref})}}),(0,o.createVNode)(1,"br")],4,t)}))})],4)},m=function(e,t){var n=(0,r.useBackend)(t).act;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"download",content:"Backup to Disk",disabled:!0}),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Button,{icon:"upload",content:"Upload from Disk",my:"0.5rem",disabled:!0}),(0,o.createTextVNode)(" "),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"trash",content:"Delete All Medical Records",onClick:function(){return n("del_all")}})],4)},h=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.medical,d=c.printing;return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"General Data",level:2,mt:"-6px",children:(0,o.createComponentVNode)(2,g)}),(0,o.createComponentVNode)(2,i.Section,{title:"Medical Data",level:2,children:(0,o.createComponentVNode)(2,C)}),(0,o.createComponentVNode)(2,i.Section,{title:"Actions",level:2,children:[(0,o.createComponentVNode)(2,i.Button.Confirm,{icon:"trash",disabled:!!l.empty,content:"Delete Medical Record",color:"bad",onClick:function(){return a("del_r")}}),(0,o.createComponentVNode)(2,i.Button,{icon:d?"spinner":"print",disabled:d,iconSpin:!!d,content:"Print Entry",ml:"0.5rem",onClick:function(){return a("print_p")}}),(0,o.createVNode)(1,"br"),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-left",content:"Back",mt:"0.5rem",onClick:function(){return a("screen",{screen:2})}})]})],4)},g=function(e,t){var n=(0,r.useBackend)(t).data.general;return n&&n.fields?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{width:"50%",float:"left",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:n.fields.map((function(e,n){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.field,children:[(0,o.createComponentVNode)(2,i.Box,{height:"20px",display:"inline-block",children:e.value}),!!e.edit&&(0,o.createComponentVNode)(2,i.Button,{icon:"pen",ml:"0.5rem",onClick:function(){return p(t,e)}})]},n)}))})}),(0,o.createComponentVNode)(2,i.Box,{width:"50%",float:"right",textAlign:"right",children:!!n.has_photos&&n.photos.map((function(e,t){return(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",textAlign:"center",color:"label",children:[(0,o.createVNode)(1,"img",null,null,1,{src:e.substr(1,e.length-1),style:{width:"96px","margin-bottom":"0.5rem","-ms-interpolation-mode":"nearest-neighbor"}}),(0,o.createVNode)(1,"br"),"Photo #",t+1]},t)}))})],4):(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"General records lost!"})},C=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data.medical;return l&&l.fields?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList,{children:l.fields.map((function(e,n){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:e.field,children:[e.value,(0,o.createComponentVNode)(2,i.Button,{icon:"pen",ml:"0.5rem",mb:e.line_break?"1rem":"initial",onClick:function(){return p(t,e)}})]},n)}))}),(0,o.createComponentVNode)(2,i.Section,{title:"Comments/Log",level:2,children:[0===l.comments.length?(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"No comments found."}):l.comments.map((function(e,t){return(0,o.createComponentVNode)(2,i.Box,{children:[(0,o.createComponentVNode)(2,i.Box,{color:"label",display:"inline",children:e.header}),(0,o.createVNode)(1,"br"),e.text,(0,o.createComponentVNode)(2,i.Button,{icon:"comment-slash",color:"bad",ml:"0.5rem",onClick:function(){return c("del_c",{del_c:t+1})}})]},t)})),(0,o.createComponentVNode)(2,i.Button,{icon:"comment-medical",content:"Add Entry",color:"good",mt:"0.5rem",mb:"0",onClick:function(){return(0,a.modalOpen)(t,"add_c")}})]})],4):(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:["Medical records lost!",(0,o.createComponentVNode)(2,i.Button,{icon:"pen",content:"New Record",ml:"0.5rem",onClick:function(){return c("new")}})]})},b=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data.virus;return c.sort((function(e,t){return e.name>t.name?1:-1})),c.map((function(e,t){return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"flask",content:e.name,mb:"0.5rem",onClick:function(){return a("vir",{vir:e.D})}}),(0,o.createVNode)(1,"br")],4,t)}))},v=function(e,t){var n=(0,r.useBackend)(t).data.medbots;return 0===n.length?(0,o.createComponentVNode)(2,i.Box,{color:"label",children:"There are no Medbots."}):n.map((function(e,t){return(0,o.createComponentVNode)(2,i.Collapsible,{open:!0,title:e.name,children:(0,o.createComponentVNode)(2,i.Box,{px:"0.5rem",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Location",children:[e.area||"Unknown"," (",e.x,", ",e.y,")"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Status",children:e.on?(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Box,{color:"good",children:"Online"}),(0,o.createComponentVNode)(2,i.Box,{mt:"0.5rem",children:e.use_beaker?"Reservoir: "+e.total_volume+"/"+e.maximum_volume:"Using internal synthesizer."})],4):(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"Offline"})})]})})},t)}))},N=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data.screen;return(0,o.createComponentVNode)(2,i.Tabs,{children:[(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:2===c,onClick:function(){return a("screen",{screen:2})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"list"}),"List Records"]}),(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:5===c,onClick:function(){return a("screen",{screen:5})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"database"}),"Virus Database"]}),(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:6===c,onClick:function(){return a("screen",{screen:6})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"plus-square"}),"Medbot Tracking"]}),(0,o.createComponentVNode)(2,i.Tabs.Tab,{selected:3===c,onClick:function(){return a("screen",{screen:3})},children:[(0,o.createComponentVNode)(2,i.Icon,{name:"wrench"}),"Record Maintenance"]})]})};(0,a.modalRegisterBodyOverride)("virus",(function(e,t){var n=e.args;return(0,o.createComponentVNode)(2,i.Section,{level:2,m:"-1rem",pb:"1rem",title:n.name||"Virus",children:(0,o.createComponentVNode)(2,i.Box,{mx:"0.5rem",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Number of stages",children:n.max_stages}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Spread",children:[n.spread_text," Transmission"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Possible cure",children:n.cure}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Notes",children:n.desc}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Severity",color:s[n.severity],children:n.severity})]})})})}))},function(e,t,n){"use strict";t.__esModule=!0,t.LoginInfo=void 0;var o=n(1),r=n(2),i=n(3);t.LoginInfo=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.authenticated,d=c.rank;if(c)return(0,o.createComponentVNode)(2,i.NoticeBox,{info:!0,children:[(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",verticalAlign:"middle",children:["Logged in as: ",l," (",d,")"]}),(0,o.createComponentVNode)(2,i.Button,{icon:"sign-out-alt",content:"Logout and Eject ID",color:"good",float:"right",onClick:function(){return a("logout")}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]})}},function(e,t,n){"use strict";t.__esModule=!0,t.LoginScreen=void 0;var o=n(1),r=n(2),i=n(3);t.LoginScreen=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=c.scan,d=c.isAI,u=c.isRobot;return(0,o.createComponentVNode)(2,i.Section,{title:"Welcome",height:"100%",stretchContents:!0,children:(0,o.createComponentVNode)(2,i.Flex,{height:"100%",align:"center",justify:"center",children:(0,o.createComponentVNode)(2,i.Flex.Item,{textAlign:"center",mt:"-2rem",children:[(0,o.createComponentVNode)(2,i.Box,{fontSize:"1.5rem",bold:!0,children:[(0,o.createComponentVNode)(2,i.Icon,{name:"user-circle",verticalAlign:"middle",size:3,mr:"1rem"}),"Guest"]}),(0,o.createComponentVNode)(2,i.Box,{color:"label",my:"1rem",children:["ID:",(0,o.createComponentVNode)(2,i.Button,{icon:"id-card",content:l||"----------",ml:"0.5rem",onClick:function(){return a("scan")}})]}),(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",disabled:!l,content:"Login",onClick:function(){return a("login",{login_type:1})}}),!!d&&(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",content:"Login as AI",onClick:function(){return a("login",{login_type:2})}}),!!u&&(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",content:"Login as Cyborg",onClick:function(){return a("login",{login_type:3})}})]})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.TemporaryNotice=void 0;var o=n(1),r=n(2),i=n(3);t.TemporaryNotice=function(e,t){var n,a=(0,r.useBackend)(t),c=a.act,l=a.data.temp;if(l){var d=((n={})[l.style]=!0,n);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,i.NoticeBox,Object.assign({},d,{children:[(0,o.createComponentVNode)(2,i.Box,{display:"inline-block",verticalAlign:"middle",children:l.text}),(0,o.createComponentVNode)(2,i.Button,{icon:"times-circle",float:"right",onClick:function(){return c("cleartemp")}}),(0,o.createComponentVNode)(2,i.Box,{clear:"both"})]})))}}},function(e,t,n){"use strict";t.__esModule=!0,t.MiningVendor=void 0;var o=n(1),r=n(87),i=n(2),a=n(3),c=n(4);var l={Alphabetical:function(e,t){return e-t},"By availability":function(e,t){return-(e.affordable-t.affordable)},"By price":function(e,t){return e.price-t.price}};t.MiningVendor=function(e,t){return(0,o.createComponentVNode)(2,c.Window,{children:(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:[(0,o.createComponentVNode)(2,d),(0,o.createComponentVNode)(2,s),(0,o.createComponentVNode)(2,u)]})})};var d=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.has_id,d=c.id;return(0,o.createComponentVNode)(2,a.NoticeBox,{success:l,children:l?(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{display:"inline-block",verticalAlign:"middle",style:{float:"left"},children:["Logged in as ",d.name,".",(0,o.createVNode)(1,"br"),"You have ",d.points.toLocaleString("en-US")," points."]}),(0,o.createComponentVNode)(2,a.Button,{icon:"eject",content:"Eject ID",style:{float:"right"},onClick:function(){return r("logoff")}}),(0,o.createComponentVNode)(2,a.Box,{style:{clear:"both"}})],4):"Please insert an ID in order to make purchases."})},u=function(e,t){var n=(0,i.useBackend)(t),c=(n.act,n.data),d=c.has_id,u=c.id,s=c.items,f=(0,i.useLocalState)(t,"search",""),m=f[0],h=(f[1],(0,i.useLocalState)(t,"sort","Alphabetical")),g=h[0],C=(h[1],(0,i.useLocalState)(t,"descending",!1)),b=C[0],v=(C[1],(0,r.createSearch)(m,(function(e){return e[0]}))),N=!1,V=Object.entries(s).map((function(e,t){var n=Object.entries(e[1]).filter(v).map((function(e){return e[1].affordable=d&&u.points>=e[1].price,e[1]})).sort(l[g]);if(0!==n.length)return b&&(n=n.reverse()),N=!0,(0,o.createComponentVNode)(2,p,{title:e[0],items:n},e[0])}));return(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",overflow:"auto",children:(0,o.createComponentVNode)(2,a.Section,{children:N?V:(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"No items matching your criteria was found!"})})})},s=function(e,t){var n=(0,i.useLocalState)(t,"search",""),r=(n[0],n[1]),c=(0,i.useLocalState)(t,"sort",""),d=(c[0],c[1]),u=(0,i.useLocalState)(t,"descending",!1),s=u[0],p=u[1];return(0,o.createComponentVNode)(2,a.Box,{mb:"0.5rem",children:(0,o.createComponentVNode)(2,a.Flex,{width:"100%",children:[(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",mr:"0.5rem",children:(0,o.createComponentVNode)(2,a.Input,{placeholder:"Search by item name..",width:"100%",onInput:function(e,t){return r(t)}})}),(0,o.createComponentVNode)(2,a.Flex.Item,{basis:"30%",children:(0,o.createComponentVNode)(2,a.Dropdown,{selected:"Alphabetical",options:Object.keys(l),width:"100%",lineHeight:"19px",onSelected:function(e){return d(e)}})}),(0,o.createComponentVNode)(2,a.Flex.Item,{children:(0,o.createComponentVNode)(2,a.Button,{icon:s?"arrow-down":"arrow-up",height:"19px",tooltip:s?"Descending order":"Ascending order",tooltipPosition:"bottom-left",ml:"0.5rem",onClick:function(){return p(!s)}})})]})})},p=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=e.title,d=e.items,u=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,["title","items"]);return(0,o.normalizeProps)((0,o.createComponentVNode)(2,a.Collapsible,Object.assign({open:!0,title:l},u,{children:d.map((function(e){return(0,o.createComponentVNode)(2,a.Box,{children:[(0,o.createComponentVNode)(2,a.Box,{display:"inline-block",verticalAlign:"middle",lineHeight:"20px",style:{float:"left"},children:e.name}),(0,o.createComponentVNode)(2,a.Button,{disabled:!c.has_id||c.id.points50?"good":"bad",value:e.health/100})}),"number"==typeof e.charge&&(0,o.createFragment)([(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cell Charge",children:(0,o.createComponentVNode)(2,i.ProgressBar,{color:e.charge>30?"good":"bad",value:e.charge/100})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cell Capacity",children:(0,o.createComponentVNode)(2,i.Box,{color:e.cell_capacity<3e4?"average":"good",children:e.cell_capacity})})],4)||(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Cell",children:(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"No Power Cell"})}),!!e.is_hacked&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Safeties",children:(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"DISABLED"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Module",children:e.module}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Master AI",children:(0,o.createComponentVNode)(2,i.Box,{color:e.synchronization?"default":"average",children:e.synchronization||"None"})})]})},e.uid)})):(0,o.createComponentVNode)(2,i.NoticeBox,{children:"No cyborg units detected within access parameters."})}},function(e,t,n){"use strict";t.__esModule=!0,t.ShuttleConsole=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=n(124);t.ShuttleConsole=function(e,t){var n=(0,r.useBackend)(t),l=n.act,d=n.data;return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Location",children:d.status?d.status:(0,o.createComponentVNode)(2,i.NoticeBox,{color:"red",children:"Shuttle Missing"})}),!!d.shuttle&&(!!d.docking_ports_len&&(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Send to ",children:d.docking_ports.map((function(e){return(0,o.createComponentVNode)(2,i.Button,{icon:"chevron-right",content:e.name,onClick:function(){return l("move",{move:e.id})}},e.name)}))})||(0,o.createFragment)([(0,o.createComponentVNode)(2,c.LabeledListItem,{label:"Status",color:"red",children:(0,o.createComponentVNode)(2,i.NoticeBox,{color:"red",children:"Shuttle Locked"})}),!!d.admin_controlled&&(0,o.createComponentVNode)(2,c.LabeledListItem,{label:"Authorization",children:(0,o.createComponentVNode)(2,i.Button,{icon:"exclamation-circle",content:"Request Authorization",disabled:!d.status,onClick:function(){return l("request")}})})],0))]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Sleeper=void 0;var o=n(1),r=n(20),i=n(2),a=n(3),c=n(4),l=[["good","Alive"],["average","Critical"],["bad","DEAD"]],d=[["Resp.","oxyLoss"],["Toxin","toxLoss"],["Brute","bruteLoss"],["Burn","fireLoss"]],u={average:[.25,.5],bad:[.5,Infinity]},s=["bad","average","average","good","average","average","bad"];t.Sleeper=function(e,t){var n=(0,i.useBackend)(t),r=(n.act,n.data.hasOccupant?(0,o.createComponentVNode)(2,p):(0,o.createComponentVNode)(2,C));return(0,o.createComponentVNode)(2,c.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,c.Window.Content,{className:"Layout__content--flexColumn",children:r})})};var p=function(e,t){var n=(0,i.useBackend)(t);n.act,n.data.occupant;return(0,o.createFragment)([(0,o.createComponentVNode)(2,f),(0,o.createComponentVNode)(2,m),(0,o.createComponentVNode)(2,g),(0,o.createComponentVNode)(2,h)],4)},f=function(e,t){var n=(0,i.useBackend)(t),c=n.act,d=n.data,u=d.occupant,p=d.auto_eject_dead;return(0,o.createComponentVNode)(2,a.Section,{title:"Occupant",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Box,{color:"label",display:"inline",children:"Auto-eject if dead:\xa0"}),(0,o.createComponentVNode)(2,a.Button,{icon:p?"toggle-on":"toggle-off",selected:p,content:p?"On":"Off",onClick:function(){return c("auto_eject_dead_"+(p?"off":"on"))}}),(0,o.createComponentVNode)(2,a.Button,{icon:"user-slash",content:"Eject",onClick:function(){return c("ejectify")}})],4),children:(0,o.createComponentVNode)(2,a.LabeledList,{children:[(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Name",children:u.name}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Health",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:u.maxHealth,value:u.health/u.maxHealth,ranges:{good:[.5,Infinity],average:[0,.5],bad:[-Infinity,0]},children:(0,r.round)(u.health,0)})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Status",color:l[u.stat][0],children:l[u.stat][1]}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Temperature",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:u.maxTemp,value:u.bodyTemperature/u.maxTemp,color:s[u.temperatureSuitability+3],children:[(0,r.round)(u.btCelsius,0),"\xb0C,",(0,r.round)(u.btFaren,0),"\xb0F"]})}),!!u.hasBlood&&(0,o.createFragment)([(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Blood Level",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:u.bloodMax,value:u.bloodLevel/u.bloodMax,ranges:{bad:[-Infinity,.6],average:[.6,.9],good:[.6,Infinity]},children:[u.bloodPercent,"%, ",u.bloodLevel,"cl"]})}),(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Pulse",verticalAlign:"middle",children:[u.pulse," BPM"]})],4)]})})},m=function(e,t){var n=(0,i.useBackend)(t).data.occupant;return(0,o.createComponentVNode)(2,a.Section,{title:"Damage",children:(0,o.createComponentVNode)(2,a.LabeledList,{children:d.map((function(e,t){return(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:e[0],children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:"100",value:n[e[1]]/100,ranges:u,children:(0,r.round)(n[e[1]],0)},t)},t)}))})})},h=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.isBeakerLoaded,d=c.beakerMaxSpace,u=c.beakerFreeSpace,s=c.dialysis&&u>0;return(0,o.createComponentVNode)(2,a.Section,{title:"Dialysis",buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,a.Button,{disabled:!l||u<=0,selected:s,icon:s?"toggle-on":"toggle-off",content:s?"Active":"Inactive",onClick:function(){return r("togglefilter")}}),(0,o.createComponentVNode)(2,a.Button,{disabled:!l,icon:"eject",content:"Eject",onClick:function(){return r("removebeaker")}})],4),children:l?(0,o.createComponentVNode)(2,a.LabeledList,{children:(0,o.createComponentVNode)(2,a.LabeledList.Item,{label:"Remaining Space",children:(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:d,value:u/d,ranges:{good:[.5,Infinity],average:[.25,.5],bad:[-Infinity,.25]},children:[u,"u"]})})}):(0,o.createComponentVNode)(2,a.Box,{color:"label",children:"No beaker loaded."})})},g=function(e,t){var n=(0,i.useBackend)(t),r=n.act,c=n.data,l=c.occupant,d=c.chemicals,u=c.maxchem,s=c.amounts;return(0,o.createComponentVNode)(2,a.Section,{title:"Chemicals",flexGrow:"1",children:d.map((function(e,t){var n,i="";return e.overdosing?(i="bad",n=(0,o.createComponentVNode)(2,a.Box,{color:"bad",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"exclamation-circle"}),"\xa0 Overdosing!"]})):e.od_warning&&(i="average",n=(0,o.createComponentVNode)(2,a.Box,{color:"average",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"exclamation-triangle"}),"\xa0 Close to overdosing"]})),(0,o.createComponentVNode)(2,a.Box,{backgroundColor:"rgba(0, 0, 0, 0.33)",mb:"0.5rem",children:(0,o.createComponentVNode)(2,a.Section,{title:e.title,level:"3",mx:"0",lineHeight:"18px",buttons:n,children:(0,o.createComponentVNode)(2,a.Flex,{align:"flex-start",children:[(0,o.createComponentVNode)(2,a.ProgressBar,{min:"0",max:u,value:e.occ_amount/u,color:i,mr:"0.5rem",children:[e.pretty_amount,"/",u,"u"]}),s.map((function(t,n){return(0,o.createComponentVNode)(2,a.Button,{disabled:!e.injectable||e.occ_amount+t>u||2===l.stat,icon:"syringe",content:t,mb:"0",height:"19px",onClick:function(){return r("chemical",{chemid:e.id,amount:t})}},n)}))]})})},t)}))})},C=function(e,t){return(0,o.createComponentVNode)(2,a.Section,{textAlign:"center",flexGrow:"1",children:(0,o.createComponentVNode)(2,a.Flex,{height:"100%",children:(0,o.createComponentVNode)(2,a.Flex.Item,{grow:"1",align:"center",color:"label",children:[(0,o.createComponentVNode)(2,a.Icon,{name:"user-slash",mb:"0.5rem",size:"5"}),(0,o.createVNode)(1,"br"),"No occupant detected."]})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.SlotMachine=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.SlotMachine=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,d=c.data;return null===d.money?(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:[(0,o.createComponentVNode)(2,i.Box,{children:"Could not scan your card or could not find account!"}),(0,o.createComponentVNode)(2,i.Box,{children:"Please wear or hold your ID and try again."})]})})}):(n=1===d.plays?d.plays+" player has tried their luck today!":d.plays+" players have tried their luck today!",(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:[(0,o.createComponentVNode)(2,i.Box,{lineHeight:2,children:n}),(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Credits Remaining",children:(0,o.createComponentVNode)(2,i.AnimatedNumber,{value:d.money})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"10 credits to spin",children:(0,o.createComponentVNode)(2,i.Button,{icon:"coins",disabled:d.working,content:d.working?"Spinning...":"Spin",onClick:function(){return l("spin")}})})]}),(0,o.createComponentVNode)(2,i.Box,{bold:!0,lineHeight:2,color:d.resultlvl,children:d.result})]})})}))}},function(e,t,n){"use strict";t.__esModule=!0,t.Smartfridge=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.Smartfridge=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.secure,u=l.can_dry,s=l.drying,p=l.contents;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[!!d&&(0,o.createComponentVNode)(2,i.Section,{title:"Secure",children:(0,o.createComponentVNode)(2,i.NoticeBox,{children:"Secure Access: Please have your identification ready."})}),!!u&&(0,o.createComponentVNode)(2,i.Section,{title:"Drying rack",children:(0,o.createComponentVNode)(2,i.Button,{icon:s?"power-off":"times",content:s?"On":"Off",selected:s,onClick:function(){return c("drying")}})}),(0,o.createComponentVNode)(2,i.Section,{title:"Contents",children:[!p&&(0,o.createComponentVNode)(2,i.Box,{color:"average",children:" No products loaded. "}),!!p&&p.map((function(e){return(0,o.createComponentVNode)(2,i.Flex,{direction:"row",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{width:"45%",children:e.display_name}),(0,o.createComponentVNode)(2,i.Flex.Item,{width:"25%",children:["(",e.quantity," in stock)"]}),(0,o.createComponentVNode)(2,i.Flex.Item,{width:"30%",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-down",tooltip:"Dispense one.",content:"1",onClick:function(){return c("vend",{index:e.vend,amount:1})}}),(0,o.createComponentVNode)(2,i.NumberInput,{width:"40px",minValue:0,value:0,maxValue:e.quantity,step:1,stepPixelSize:3,onDrag:function(t,n){return c("vend",{index:e.vend,amount:n})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"arrow-down",content:"All",tooltip:"Dispense all. ",onClick:function(){return c("vend",{index:e.vend,amount:e.quantity})}})]})]},e)}))]})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Smes=void 0;var o=n(1),r=n(2),i=n(3),a=n(173),c=n(4);t.Smes=function(e,t){var n=(0,r.useBackend)(t),l=n.act,d=n.data,u=d.capacityPercent,s=(d.capacity,d.charge),p=d.inputAttempt,f=d.inputting,m=d.inputLevel,h=d.inputLevelMax,g=d.inputAvailable,C=d.outputAttempt,b=d.outputting,v=d.outputLevel,N=d.outputLevelMax,V=d.outputUsed,y=(u>=100?"good":f&&"average")||"bad",x=(b?"good":s>0&&"average")||"bad";return(0,o.createComponentVNode)(2,c.Window,{children:(0,o.createComponentVNode)(2,c.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Stored Energy",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:.01*u,ranges:{good:[.5,Infinity],average:[.15,.5],bad:[-Infinity,.15]}})}),(0,o.createComponentVNode)(2,i.Section,{title:"Input",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Charge Mode",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:p?"sync-alt":"times",selected:p,onClick:function(){return l("tryinput")},children:p?"Auto":"Off"}),children:(0,o.createComponentVNode)(2,i.Box,{color:y,children:(u>=100?"Fully Charged":f&&"Charging")||"Not Charging"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target Input",children:(0,o.createComponentVNode)(2,i.Flex,{inline:!0,width:"100%",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",disabled:0===m,onClick:function(){return l("input",{target:"min"})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"backward",disabled:0===m,onClick:function(){return l("input",{adjust:-1e4})}})]}),(0,o.createComponentVNode)(2,i.Flex.Item,{grow:1,mx:1,children:(0,o.createComponentVNode)(2,i.Slider,{value:m/1e3,fillValue:g/1e3,minValue:0,maxValue:h/1e3,step:5,stepPixelSize:4,format:function(e){return(0,a.formatPower)(1e3*e,1)},onChange:function(e,t){return l("input",{target:1e3*t})}})}),(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"forward",disabled:m===h,onClick:function(){return l("input",{adjust:1e4})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",disabled:m===h,onClick:function(){return l("input",{target:"max"})}})]})]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Available",children:(0,a.formatPower)(g)})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Output",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Output Mode",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:C?"power-off":"times",selected:C,onClick:function(){return l("tryoutput")},children:C?"On":"Off"}),children:(0,o.createComponentVNode)(2,i.Box,{color:x,children:b?"Sending":s>0?"Not Sending":"No Charge"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Target Output",children:(0,o.createComponentVNode)(2,i.Flex,{inline:!0,width:"100%",children:[(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",disabled:0===v,onClick:function(){return l("output",{target:"min"})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"backward",disabled:0===v,onClick:function(){return l("output",{adjust:-1e4})}})]}),(0,o.createComponentVNode)(2,i.Flex.Item,{grow:1,mx:1,children:(0,o.createComponentVNode)(2,i.Slider,{value:v/1e3,minValue:0,maxValue:N/1e3,step:5,stepPixelSize:4,format:function(e){return(0,a.formatPower)(1e3*e,1)},onChange:function(e,t){return l("output",{target:1e3*t})}})}),(0,o.createComponentVNode)(2,i.Flex.Item,{children:[(0,o.createComponentVNode)(2,i.Button,{icon:"forward",disabled:v===N,onClick:function(){return l("output",{adjust:1e4})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",disabled:v===N,onClick:function(){return l("output",{target:"max"})}})]})]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Outputting",children:(0,a.formatPower)(V)})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.SolarControl=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.SolarControl=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.generated,u=l.generated_ratio,s=l.tracking_state,p=l.tracking_rate,f=l.connected_panels,m=l.connected_tracker,h=l.cdir,g=l.direction,C=l.rotating_direction;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Status",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Scan for new hardware",onClick:function(){return c("refresh")}}),children:(0,o.createComponentVNode)(2,i.Grid,{children:[(0,o.createComponentVNode)(2,i.Grid.Column,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Solar tracker",color:m?"good":"bad",children:m?"OK":"N/A"}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Solar panels",color:f>0?"good":"bad",children:f})]})}),(0,o.createComponentVNode)(2,i.Grid.Column,{size:2,children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Power output",children:(0,o.createComponentVNode)(2,i.ProgressBar,{ranges:{good:[.66,Infinity],average:[.33,.66],bad:[-Infinity,.33]},minValue:0,maxValue:1,value:u,children:d+" W"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Panel orientation",children:[h,"\xb0 (",g,")"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Tracker rotation",children:[2===s&&(0,o.createComponentVNode)(2,i.Box,{children:" Automated "}),1===s&&(0,o.createComponentVNode)(2,i.Box,{children:[" ",p,"\xb0/h (",C,") "]}),0===s&&(0,o.createComponentVNode)(2,i.Box,{children:" Tracker offline "})]})]})})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Controls",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Panel orientation",children:[2!==s&&(0,o.createComponentVNode)(2,i.NumberInput,{unit:"\xb0",step:1,stepPixelSize:1,minValue:0,maxValue:359,value:h,onDrag:function(e,t){return c("cdir",{cdir:t})}}),2===s&&(0,o.createComponentVNode)(2,i.Box,{lineHeight:"19px",children:" Automated "})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Tracker status",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"times",content:"Off",selected:0===s,onClick:function(){return c("track",{track:0})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"clock-o",content:"Timed",selected:1===s,onClick:function(){return c("track",{track:1})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Auto",selected:2===s,disabled:!m,onClick:function(){return c("track",{track:2})}})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Tracker rotation",children:[1===s&&(0,o.createComponentVNode)(2,i.NumberInput,{unit:"\xb0/h",step:1,stepPixelSize:1,minValue:-7200,maxValue:7200,value:p,format:function(e){return(Math.sign(e)>0?"+":"-")+Math.abs(e)},onDrag:function(e,t){return c("tdir",{tdir:t})}}),0===s&&(0,o.createComponentVNode)(2,i.Box,{lineHeight:"19px",children:" Tracker offline "}),2===s&&(0,o.createComponentVNode)(2,i.Box,{lineHeight:"19px",children:" Automated "})]})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.SpawnersMenu=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.SpawnersMenu=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data.spawners||[];return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:(0,o.createComponentVNode)(2,i.Section,{children:l.map((function(e){return(0,o.createComponentVNode)(2,i.Section,{mb:.5,title:e.name+" ("+e.amount_left+" left)",level:2,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{icon:"chevron-circle-right",content:"Jump",onClick:function(){return c("jump",{ID:e.uids})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"chevron-circle-right",content:"Spawn",onClick:function(){return c("spawn",{ID:e.uids})}})],4),children:[(0,o.createComponentVNode)(2,i.Box,{style:{"white-space":"pre-wrap"},mb:1,fontSize:"16px",children:e.desc}),!!e.fluff&&(0,o.createComponentVNode)(2,i.Box,{style:{"white-space":"pre-wrap"},textColor:"#878787",fontSize:"14px",children:e.fluff}),!!e.important_info&&(0,o.createComponentVNode)(2,i.Box,{style:{"white-space":"pre-wrap"},mt:1,bold:!0,color:"red",fontSize:"18px",children:e.important_info})]},e.name)}))})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.StationAlertConsoleContent=t.StationAlertConsole=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.StationAlertConsole=function(){return(0,o.createComponentVNode)(2,a.Window,{resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:(0,o.createComponentVNode)(2,c)})})};var c=function(e,t){var n=(0,r.useBackend)(t).data.alarms||[],a=n.Fire||[],c=n.Atmosphere||[],l=n.Power||[];return(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Section,{title:"Fire Alarms",children:(0,o.createVNode)(1,"ul",null,[0===a.length&&(0,o.createVNode)(1,"li","color-good","Systems Nominal",16),a.map((function(e){return(0,o.createVNode)(1,"li","color-average",e,0,null,e)}))],0)}),(0,o.createComponentVNode)(2,i.Section,{title:"Atmospherics Alarms",children:(0,o.createVNode)(1,"ul",null,[0===c.length&&(0,o.createVNode)(1,"li","color-good","Systems Nominal",16),c.map((function(e){return(0,o.createVNode)(1,"li","color-average",e,0,null,e)}))],0)}),(0,o.createComponentVNode)(2,i.Section,{title:"Power Alarms",children:(0,o.createVNode)(1,"ul",null,[0===l.length&&(0,o.createVNode)(1,"li","color-good","Systems Nominal",16),l.map((function(e){return(0,o.createVNode)(1,"li","color-average",e,0,null,e)}))],0)})],4)};t.StationAlertConsoleContent=c},function(e,t,n){"use strict";t.__esModule=!0,t.SupermatterMonitor=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=n(86);t.SupermatterMonitor=function(e,t){var n=(0,r.useBackend)(t);n.act;return 0===n.data.active?(0,o.createComponentVNode)(2,l):(0,o.createComponentVNode)(2,d)};var l=function(e,t){var n=(0,r.useBackend)(t),l=n.act,d=n.data;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:(0,o.createComponentVNode)(2,i.Section,{title:"Detected Supermatter Shards",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"sync",content:"Refresh",onClick:function(){return l("refresh")}}),children:(0,o.createComponentVNode)(2,i.Box,{m:1,children:0===d.supermatters.length?(0,o.createVNode)(1,"h3",null,"No shards detected",16):(0,o.createComponentVNode)(2,i.Table,{children:[(0,o.createComponentVNode)(2,i.Table.Row,{header:!0,children:[(0,o.createComponentVNode)(2,c.TableCell,{children:"Area"}),(0,o.createComponentVNode)(2,c.TableCell,{children:"Integrity"}),(0,o.createComponentVNode)(2,c.TableCell,{children:"Details"})]}),d.supermatters.map((function(e){return(0,o.createComponentVNode)(2,c.TableRow,{children:[(0,o.createComponentVNode)(2,c.TableCell,{children:e.area_name}),(0,o.createComponentVNode)(2,c.TableCell,{children:[e.integrity,"%"]}),(0,o.createComponentVNode)(2,c.TableCell,{children:(0,o.createComponentVNode)(2,i.Button,{icon:"sign-in-alt",content:"View",onClick:function(){return l("view",{view:e.uid})}})})]},e)}))]})})})})})},d=function(e,t){var n,c,l,d=(0,r.useBackend)(t),u=d.act,s=d.data;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{title:"Crystal Status",buttons:(0,o.createComponentVNode)(2,i.Button,{icon:"caret-square-left",content:"Back",onClick:function(){return u("back")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Core Integrity",children:(0,o.createComponentVNode)(2,i.ProgressBar,{ranges:{good:[95,Infinity],average:[80,94],bad:[-Infinity,79]},minValue:"0",maxValue:"100",value:s.SM_integrity,children:[s.SM_integrity,"%"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Relative EER",children:(0,o.createComponentVNode)(2,i.Box,{color:(l=s.SM_power,l>300?"bad":l>150?"average":"good"),children:[s.SM_power," MeV/cm3"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Temperature",children:(0,o.createComponentVNode)(2,i.Box,{color:(c=s.SM_ambienttemp,c>5e3?"bad":c>4e3?"average":"good"),children:[s.SM_ambienttemp," K"]})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Pressure",children:(0,o.createComponentVNode)(2,i.Box,{color:(n=s.SM_ambientpressure,n>1e4?"bad":n>5e3?"average":"good"),children:[s.SM_ambientpressure," kPa"]})})]})}),(0,o.createComponentVNode)(2,i.Section,{title:"Gas Composition",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Oxygen",children:[s.SM_gas_O2,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Carbon Dioxide",children:[s.SM_gas_CO2,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Nitrogen",children:[s.SM_gas_N2,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Plasma",children:[s.SM_gas_PL,"%"]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Other",children:[s.SM_gas_OTHER,"%"]})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Tank=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.Tank=function(e,t){var n,c=(0,r.useBackend)(t),l=c.act,d=c.data;return n=d.has_mask?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Mask",children:(0,o.createComponentVNode)(2,i.Button,{icon:d.connected?"check":"times",content:d.connected?"Internals On":"Internals Off",selected:d.connected,onClick:function(){return l("internals")}})}):(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Mask",color:"red",children:"No Mask Equipped"}),(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Tank Pressure",children:(0,o.createComponentVNode)(2,i.ProgressBar,{value:d.tankPressure/1013,ranges:{good:[.35,Infinity],average:[.15,.35],bad:[-Infinity,.15]},children:d.tankPressure+" kPa"})}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Release Pressure",children:[(0,o.createComponentVNode)(2,i.Button,{icon:"fast-backward",disabled:d.ReleasePressure===d.minReleasePressure,tooltip:"Min",onClick:function(){return l("pressure",{pressure:"min"})}}),(0,o.createComponentVNode)(2,i.NumberInput,{animated:!0,value:parseFloat(d.releasePressure),width:"65px",unit:"kPa",minValue:d.minReleasePressure,maxValue:d.maxReleasePressure,onChange:function(e,t){return l("pressure",{pressure:t})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"fast-forward",disabled:d.ReleasePressure===d.maxReleasePressure,tooltip:"Max",onClick:function(){return l("pressure",{pressure:"max"})}}),(0,o.createComponentVNode)(2,i.Button,{icon:"undo",content:"",disabled:d.ReleasePressure===d.defaultReleasePressure,tooltip:"Reset",onClick:function(){return l("pressure",{pressure:"reset"})}})]}),n]})})})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Teleporter=void 0;var o=n(1),r=n(2),i=n(3),a=n(4),c=n(169);t.Teleporter=function(e,t){var n=(0,r.useBackend)(t),l=n.act,d=n.data,u=d.targetsTeleport?d.targetsTeleport:{},s=d.calibrated,p=d.calibrating,f=d.powerstation,m=d.regime,h=d.teleporterhub,g=d.target,C=d.locked;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(!f||!h)&&(0,o.createComponentVNode)(2,i.Section,{title:"Error",children:[h,!f&&(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:" Powerstation not linked "}),f&&!h&&(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:" Teleporter hub not linked "})]}),f&&h&&(0,o.createComponentVNode)(2,i.Section,{title:"Status",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:[(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Regime",children:[(0,o.createComponentVNode)(2,i.Button,{tooltip:"Teleport to another teleport hub. ",color:1===m?"good":null,onClick:function(){return l("setregime",{regime:1})},children:"Gate"}),(0,o.createComponentVNode)(2,i.Button,{tooltip:"One-way teleport. ",color:0===m?"good":null,onClick:function(){return l("setregime",{regime:0})},children:"Teleporter"}),(0,o.createComponentVNode)(2,i.Button,{tooltip:"Teleport to a location stored in a GPS device. ",color:2===m?"good":null,disabled:!C,onClick:function(){return l("setregime",{regime:2})},children:"GPS"})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Teleport target",children:[0===m&&(0,o.createComponentVNode)(2,i.Dropdown,{width:"220px",selected:g,options:Object.keys(u),color:"None"!==g?"default":"bad",onSelected:function(e){return l("settarget",{x:u[e].x,y:u[e].y,z:u[e].z})}}),1===m&&(0,o.createComponentVNode)(2,i.Dropdown,{width:"220px",selected:g,options:Object.keys(u),color:"None"!==g?"default":"bad",onSelected:function(e){return l("settarget",{x:u[e].x,y:u[e].y,z:u[e].z})}}),2===m&&(0,o.createComponentVNode)(2,i.Box,{children:g})]}),(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Calibration",children:["None"!==g&&(0,o.createComponentVNode)(2,i.Grid,{children:[(0,o.createComponentVNode)(2,c.GridColumn,{size:"2",children:p&&(0,o.createComponentVNode)(2,i.Box,{color:"average",children:"In Progress"})||s&&(0,o.createComponentVNode)(2,i.Box,{color:"good",children:"Optimal"})||(0,o.createComponentVNode)(2,i.Box,{color:"bad",children:"Sub-Optimal"})}),(0,o.createComponentVNode)(2,c.GridColumn,{size:"3",children:(0,o.createComponentVNode)(2,i.Box,{"class":"ml-1",children:(0,o.createComponentVNode)(2,i.Button,{icon:"sync-alt",tooltip:"Calibrates the hub. Accidents may occur when the calibration is not optimal.",disabled:!(!s&&!p),onClick:function(){return l("calibrate")}})})})]}),"None"===g&&(0,o.createComponentVNode)(2,i.Box,{lineHeight:"21px",children:"No target set"})]})]})}),!!(C&&f&&h&&2===m)&&(0,o.createComponentVNode)(2,i.Section,{title:"GPS",children:(0,o.createComponentVNode)(2,i.Flex,{direction:"row",justify:"space-around",children:[(0,o.createComponentVNode)(2,i.Button,{content:"Upload GPS data",tooltip:"Loads the GPS data from the device.",icon:"upload",onClick:function(){return l("load")}}),(0,o.createComponentVNode)(2,i.Button,{content:"Eject",tooltip:"Ejects the GPS device",icon:"eject",onClick:function(){return l("eject")}})]})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.TransferValve=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.TransferValve=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.tank_one,u=l.tank_two,s=l.attached_device,p=l.valve;return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Valve Status",children:(0,o.createComponentVNode)(2,i.Button,{icon:p?"unlock":"lock",content:p?"Open":"Closed",disabled:!d||!u,onClick:function(){return c("toggle")}})})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Assembly",buttons:(0,o.createComponentVNode)(2,i.Button,{textAlign:"center",width:"150px",icon:"cog",content:"Configure Assembly",disabled:!s,onClick:function(){return c("device")}}),children:(0,o.createComponentVNode)(2,i.LabeledList,{children:s?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Attachment",children:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:s,disabled:!s,onClick:function(){return c("remove_device")}})}):(0,o.createComponentVNode)(2,i.NoticeBox,{textAlign:"center",children:"Attach Assembly"})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Attachment One",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:d?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Attachment",children:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:d,disabled:!d,onClick:function(){return c("tankone")}})}):(0,o.createComponentVNode)(2,i.NoticeBox,{textAlign:"center",children:"Attach Tank"})})}),(0,o.createComponentVNode)(2,i.Section,{title:"Attachment Two",children:(0,o.createComponentVNode)(2,i.LabeledList,{children:u?(0,o.createComponentVNode)(2,i.LabeledList.Item,{label:"Attachment",children:(0,o.createComponentVNode)(2,i.Button,{icon:"eject",content:u,disabled:!u,onClick:function(){return c("tanktwo")}})}):(0,o.createComponentVNode)(2,i.NoticeBox,{textAlign:"center",children:"Attach Tank"})})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Vending=void 0;var o=n(1),r=(n(12),n(2)),i=n(3),a=n(4),c=function(e,t){var n=(0,r.useBackend)(t),a=n.act,c=n.data,l=e.product,d=e.productStock,u=e.productImage,s=c.chargesMoney,p=(c.user,c.userMoney),f=c.vend_ready,m=c.coin_name,h=(c.inserted_item_name,!s||0===l.price),g="ERROR!",C="";l.req_coin?(g="COIN",C="circle"):h?(g="FREE",C="arrow-circle-down"):(g=l.price,C="shopping-cart");var b=!f||!m&&l.req_coin||0===d||!h&&l.price>p;return(0,o.createComponentVNode)(2,i.Table.Row,{children:[(0,o.createComponentVNode)(2,i.Table.Cell,{collapsing:!0,children:(0,o.createVNode)(1,"img",null,null,1,{src:"data:image/jpeg;base64,"+u,style:{"vertical-align":"middle",width:"32px",margin:"0px","margin-left":"0px"}})}),(0,o.createComponentVNode)(2,i.Table.Cell,{bold:!0,children:l.name}),(0,o.createComponentVNode)(2,i.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,o.createComponentVNode)(2,i.Box,{color:(d<=0?"bad":d<=l.max_amount/2&&"average")||"good",children:[d," in stock"]})}),(0,o.createComponentVNode)(2,i.Table.Cell,{collapsing:!0,textAlign:"center",children:(0,o.createComponentVNode)(2,i.Button,{fluid:!0,disabled:b,icon:C,content:g,textAlign:"left",onClick:function(){return a("vend",{inum:l.inum})}})})]})};t.Vending=function(e,t){var n,l=(0,r.useBackend)(t),d=l.act,u=l.data,s=u.user,p=u.guestNotice,f=u.userMoney,m=u.chargesMoney,h=u.product_records,g=void 0===h?[]:h,C=u.coin_records,b=void 0===C?[]:C,v=u.hidden_records,N=void 0===v?[]:v,V=u.stock,y=(u.vend_ready,u.coin_name),x=u.inserted_item_name,k=u.panel_open,_=u.speaker,w=u.imagelist;return n=[].concat(g,b),u.extended_inventory&&(n=[].concat(n,N)),n=n.filter((function(e){return!!e})),(0,o.createComponentVNode)(2,a.Window,{title:"Vending Machine",resizable:!0,children:(0,o.createComponentVNode)(2,a.Window.Content,{scrollable:!0,children:[!!m&&(0,o.createComponentVNode)(2,i.Section,{title:"User",children:s&&(0,o.createComponentVNode)(2,i.Box,{children:["Welcome, ",(0,o.createVNode)(1,"b",null,s.name,0),","," ",(0,o.createVNode)(1,"b",null,s.job||"Unemployed",0),"!",(0,o.createVNode)(1,"br"),"Your balance is ",(0,o.createVNode)(1,"b",null,[f,(0,o.createTextVNode)(" credits")],0),"."]})||(0,o.createComponentVNode)(2,i.Box,{color:"light-grey",children:p})}),!!y&&(0,o.createComponentVNode)(2,i.Section,{title:"Coin",buttons:(0,o.createComponentVNode)(2,i.Button,{fluid:!0,icon:"eject",content:"Remove Coin",onClick:function(){return d("remove_coin",{})}}),children:(0,o.createComponentVNode)(2,i.Box,{children:y})}),!!x&&(0,o.createComponentVNode)(2,i.Section,{title:"Item",buttons:(0,o.createComponentVNode)(2,i.Button,{fluid:!0,icon:"eject",content:"Eject Item",onClick:function(){return d("eject_item",{})}}),children:(0,o.createComponentVNode)(2,i.Box,{children:x})}),!!k&&(0,o.createComponentVNode)(2,i.Section,{title:"Maintenance",children:(0,o.createComponentVNode)(2,i.Button,{icon:_?"check":"volume-mute",selected:_,content:"Speaker",textAlign:"left",onClick:function(){return d("toggle_voice",{})}})}),(0,o.createComponentVNode)(2,i.Section,{title:"Products",children:(0,o.createComponentVNode)(2,i.Table,{children:n.map((function(e){return(0,o.createComponentVNode)(2,c,{product:e,productStock:V[e.name],productImage:w[e.path]},e.name)}))})})]})})}},function(e,t,n){"use strict";t.__esModule=!0,t.Wires=void 0;var o=n(1),r=n(2),i=n(3),a=n(4);t.Wires=function(e,t){var n=(0,r.useBackend)(t),c=n.act,l=n.data,d=l.wires||[],u=l.status||[];return(0,o.createComponentVNode)(2,a.Window,{children:(0,o.createComponentVNode)(2,a.Window.Content,{children:[(0,o.createComponentVNode)(2,i.Section,{children:(0,o.createComponentVNode)(2,i.LabeledList,{children:d.map((function(e){return(0,o.createComponentVNode)(2,i.LabeledList.Item,{className:"candystripe",label:e.color_name,labelColor:e.seen_color,color:e.seen_color,buttons:(0,o.createFragment)([(0,o.createComponentVNode)(2,i.Button,{content:e.cut?"Mend":"Cut",onClick:function(){return c("cut",{wire:e.color})}}),(0,o.createComponentVNode)(2,i.Button,{content:"Pulse",onClick:function(){return c("pulse",{wire:e.color})}}),(0,o.createComponentVNode)(2,i.Button,{content:e.attached?"Detach":"Attach",onClick:function(){return c("attach",{wire:e.color})}})],4),children:!!e.wire&&(0,o.createVNode)(1,"i",null,[(0,o.createTextVNode)("("),e.wire,(0,o.createTextVNode)(")")],0)},e.seen_color)}))})}),!!u.length&&(0,o.createComponentVNode)(2,i.Section,{children:u.map((function(e){return(0,o.createComponentVNode)(2,i.Box,{color:"lightgray",mt:.1,children:e},e)}))})]})})}}]); \ No newline at end of file diff --git a/tgui/packages/tgui/styles/components/Modal.scss b/tgui/packages/tgui/styles/components/Modal.scss index 9addf356b21..c2d4d0c60ad 100644 --- a/tgui/packages/tgui/styles/components/Modal.scss +++ b/tgui/packages/tgui/styles/components/Modal.scss @@ -1,3 +1,4 @@ +@use 'sass:color'; @use '../base.scss'; $color-background: base.$color-bg !default; @@ -6,4 +7,26 @@ $color-background: base.$color-bg !default; background-color: $color-background; max-width: calc(100% - 1rem); padding: 1rem; + + scrollbar-base-color: color.scale( + base.$color-bg, + $lightness: -25%); + scrollbar-face-color: color.scale( + base.$color-bg, + $lightness: 10%); + scrollbar-3dlight-color: color.scale( + base.$color-bg, + $lightness: 0%); + scrollbar-highlight-color: color.scale( + base.$color-bg, + $lightness: 0%); + scrollbar-track-color: color.scale( + base.$color-bg, + $lightness: -25%); + scrollbar-arrow-color: color.scale( + base.$color-bg, + $lightness: 50%); + scrollbar-shadow-color: color.scale( + base.$color-bg, + $lightness: 10%); } diff --git a/tgui/packages/tgui/styles/components/NanoMap.scss b/tgui/packages/tgui/styles/components/NanoMap.scss index cbacd7c5828..d53365f3662 100644 --- a/tgui/packages/tgui/styles/components/NanoMap.scss +++ b/tgui/packages/tgui/styles/components/NanoMap.scss @@ -1,20 +1,23 @@ $color-background: rgba(0, 0, 0, 0.33) !default; -.NanoMap__contentOffset { - position: absolute; - top: 0; - bottom: 0; - left: 524px; - right: 0; - background-color: $color-background; - overflow-y: scroll; -} - .NanoMap__container { - position: absolute; + overflow: hiddden; + width: 100%; z-index: 1; } .NanoMap__marker { z-index: 10; + padding: 0px; + margin: 0px; +} + +.NanoMap__zoomer { + z-index: 20; + background-color: $color-background; + position: absolute; + top: 30px; + left: 0; + padding: 0.5rem; + width: 20%; } diff --git a/tools/github-actions/README.MD b/tools/github-actions/README.MD index 74b31f5bdd6..b6a3542a884 100644 --- a/tools/github-actions/README.MD +++ b/tools/github-actions/README.MD @@ -4,3 +4,4 @@ This folder contains all the script and tools required for GitHub actions. If yo - `nanomap-renderer` - A linux application to render NanoMap images of the ingame maps automatically. Based off of SpacemanDMM (Modified source [here](https://github.com/AffectedArc07/ParaSpacemanDMM), original source [here](https://github.com/Spacemaniac/SpacemanDMM)) - `nanomap-renderer-invoker.sh` - A script which invokes the render tool and clones the maps to the correct directory +- `doc-generator` - A linux application to generate documentation of game code automatically. Based off of SpacemanDMM (Modified source [here](https://github.com/AffectedArc07/ParaSpacemanDMM), original source [here](https://github.com/Spacemaniac/SpacemanDMM)) diff --git a/tools/github-actions/doc-generator b/tools/github-actions/doc-generator new file mode 100755 index 00000000000..ce0b4fa25f5 Binary files /dev/null and b/tools/github-actions/doc-generator differ diff --git a/tools/github-actions/nanomap-renderer b/tools/github-actions/nanomap-renderer index 69fa906c94e..bd655ccb1f7 100755 Binary files a/tools/github-actions/nanomap-renderer and b/tools/github-actions/nanomap-renderer differ diff --git a/tools/github-actions/nanomap-renderer-invoker.sh b/tools/github-actions/nanomap-renderer-invoker.sh index b6fadfac5f1..a74b99de0db 100755 --- a/tools/github-actions/nanomap-renderer-invoker.sh +++ b/tools/github-actions/nanomap-renderer-invoker.sh @@ -1,14 +1,14 @@ #!/bin/bash # Generate maps -tools/github-actions/nanomap-renderer minimap "./_maps/map_files/cyberiad/cyberiad.dmm" -tools/github-actions/nanomap-renderer minimap "./_maps/map_files/Delta/delta.dmm" -tools/github-actions/nanomap-renderer minimap "./_maps/map_files/MetaStation/MetaStation.v41A.II.dmm" +tools/github-actions/nanomap-renderer minimap -w 2040 -h 2040 "./_maps/map_files/cyberiad/cyberiad.dmm" +tools/github-actions/nanomap-renderer minimap -w 2040 -h 2040 "./_maps/map_files/Delta/delta.dmm" +tools/github-actions/nanomap-renderer minimap -w 2040 -h 2040 "./_maps/map_files/MetaStation/MetaStation.v41A.II.dmm" # Move and rename files so the game understands them cd "data/nanomaps" mv "cyberiad_nanomap_z1.png" "Cyberiad_nanomap_z1.png" mv "delta_nanomap_z1.png" "Delta_nanomap_z1.png" mv "MetaStation.v41A.II_nanomap_z1.png" "MetaStation_nanomap_z1.png" cd "../../" -cp "data/nanomaps/Cyberiad_nanomap_z1.png" "nano/images" -cp "data/nanomaps/Delta_nanomap_z1.png" "nano/images" -cp "data/nanomaps/MetaStation_nanomap_z1.png" "nano/images" +cp "data/nanomaps/Cyberiad_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Delta_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/MetaStation_nanomap_z1.png" "icons/_nanomaps" diff --git a/tools/py-midi2piano/midi2piano.py b/tools/py-midi2piano/midi2piano.py index f4494801d3e..b4584a9f767 100644 --- a/tools/py-midi2piano/midi2piano.py +++ b/tools/py-midi2piano/midi2piano.py @@ -7,8 +7,8 @@ import midi as mi import easygui as egui import pyperclip as pclip -LINE_LENGTH_LIM = 50 -LINES_LIMIT = 200 +LINE_LENGTH_LIM = 300 +LINES_LIMIT = 10000 TICK_LAG = 0.5 OVERALL_IMPORT_LIM = 2*LINE_LENGTH_LIM*LINES_LIMIT END_OF_LINE_CHAR = """